### Install Dependencies and Run Development Mode Source: https://dockfries.github.io/infernus/quick-start.html Use 'pnpm install' to install project dependencies. 'pnpm dev' starts the server in development mode, automatically compiling and restarting on changes. ```sh # installation dependency pnpm install # run development mode commands (start compilation, listen for changes and restart automatically) pnpm dev ``` -------------------------------- ### Install All Dependencies with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Use 'infernus install' to install all dependencies listed in the project configuration, similar to 'sampctl ensure'. Use -p for production mode. ```sh # Install all existing dependencies, similar to sampctl ensure infernus install # same as above, production mode install deps (not copy inc files) infernus install -p ``` -------------------------------- ### Installing and Using @infernus/fs Source: https://dockfries.github.io/infernus/essentials/use.html Provides instructions to install the @infernus/fs package using pnpm and demonstrates how to use the A51Base filterscript with GameMode.use. ```shell pnpm install @infernus/fs ``` ```typescript import { GameMode } from "@infernus/core"; import { A51Base } from "@infernus/fs"; GameMode.use(A51Base, { debug: true }); ``` -------------------------------- ### Example Error Messages During Server Startup Source: https://dockfries.github.io/infernus/plugins/introduction.html These error messages indicate that functions or files are not found, often due to incorrect plugin loading or configuration. ```text [Error] Function not registered: CA_DestroyObject [Error] File or function is not found ``` -------------------------------- ### Install and Update Infernus CLI Tool Source: https://dockfries.github.io/infernus/quick-start.html Install the Infernus CLI tool globally to manage project dependencies. Use the update command to ensure you have the latest version. ```sh # Install the CLI tool globally pnpm add @infernus/create-app -g # If installed globally pnpm update @infernus/create-app -g ``` -------------------------------- ### Inject Vehicle Creation Hook Source: https://dockfries.github.io/infernus/essentials/hooks.html For classes like Vehicle that have special encapsulated methods, use the `__inject__` static method for injection. This example shows how to hook the `create` method to log when a new vehicle is created. ```typescript import { Vehicle, type LimitsEnum } from "@infernus/core"; export const orig_CreateVehicle = Vehicle.__inject__.create; export function my_CreateVehicle( ...args: Parameters ) { const id = orig_CreateVehicle(...args); if (id > 0 && id < LimitsEnum.MAX_VEHICLES) { console.log(`hook: vehicle ${id} created`); } return id; } Vehicle.__inject__.create = my_CreateVehicle; ``` -------------------------------- ### Defining and Using a Custom Event Source: https://dockfries.github.io/infernus/essentials/events.html Define a custom event using defineEvent for extending functionality. This example shows triggering a 'PlayerDanger' event based on player health. ```typescript import type { Player } from "@infernus/core"; import { defineEvent, PlayerEvent } from "@infernus/core"; const healthDangerSet = new Set(); const [onPlayerDanger, trigger] = defineEvent({ // Only the commonly used parts are listed isNative: false, // It is not a native event, that is, our custom event. // If it is true, it means the native event in pwn or the native event of the plugin. name: "OnPlayerDanger", // Please raise a unique, do not conflict with the existing event name, usually in this format defaultValue: true, // Define the default return value of middleware as true // If your custom event has callback parameters, be sure to write beforeEach to enhance the ts type prompt // BeforeEach is executed before all the middleware is executed to enhance the parameters beforeEach(player: Player, health: number) { // You are required to return an object return { player, health }; }, // AfterEach is used to execute after all middleware is executed (waiting for all async ones to finish) afterEach({ player, health }) {} }); PlayerEvent.onUpdate(({ player, next }) => { const isDanger = healthDangerSet.has(player); const health = player.getHealth(); if (!isDanger && health <= 10) { healthDangerSet.add(player); const ret = trigger(player, health); if (!ret) return false; } if (isDanger && health > 10) { healthDangerSet.delete(player); } return next(); }); onPlayerDanger(({ player, health, next }) => { player.sendClientMessage( "#ff0", `DANGER! Your health is only ${health}, and the system will automatically return blood for you after 3 seconds.`, ); setTimeout(() => { player.setHealth(100); }, 3000); return next(); }); ``` -------------------------------- ### Get Player Instances Source: https://dockfries.github.io/infernus/essentials/events.html Retrieve all player instances or a specific player instance by ID within an event handler. This is useful for iterating over all connected players or targeting a single player. ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onConnect(({ player, next }) => { const players = Player.getInstances(); // Get an array of all player instances players.forEach((p) => { p.sendClientMessage("#fff", `player ${player.getName()} connected`); }); const player = Player.getInstance(0); // Get the instance of a player whose id is 0 console.log(player); return next(); }); ``` -------------------------------- ### Build for Production and Serve Source: https://dockfries.github.io/infernus/quick-start.html Execute 'pnpm build' to create a production-ready build of the server. 'pnpm serve' then runs the server using the production build. ```sh # build for production environment pnpm build # run the server pnpm serve ``` -------------------------------- ### Create Infernus App with CLI Source: https://dockfries.github.io/infernus/quick-start.html Use this command to initiate the creation of a new Infernus project via the command line interface. Follow the prompts to configure your project. ```sh pnpm dlx @infernus/create-app@latest create ``` -------------------------------- ### Create Project with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Use the 'infernus create' command followed by your desired application name to generate a new project structure. ```sh infernus create ``` -------------------------------- ### Register and Show Dialog - TypeScript Source: https://dockfries.github.io/infernus/essentials/dialogs.html Demonstrates how to register a command that displays a password dialog, captures user input, and reuses the dialog instance with updated information for a second input. Ensure the necessary imports are present. ```typescript import { PlayerEvent, Dialog, DialogStylesEnum } from "@infernus/core"; PlayerEvent.onCommandText("register", async ({ player, next }) => { const dialog = new Dialog({ style: DialogStylesEnum.PASSWORD, caption: "Register", info: "Please enter your password", button1: "ok", }); const { inputText: password } = await dialog.show(player); // You can reuse an existing dialog instance, modify its information, and then use it again later. // There are many setter besides info. dialog.info = "Please enter your password again"; const { inputText: againPassword } = await dialog.show(player); if (password !== againPassword) { player.sendClientMessage( "#f00", "The password you entered twice is not the same, please try again!" ); } return next(); }); ``` -------------------------------- ### Clone Infernus Starter Template Source: https://dockfries.github.io/infernus/quick-start.html Clone the infernus-starter template repository from GitHub using either HTTPS or SSH protocol. An alternative branch for RakNet is also available. ```sh # Clone the repository through https protocol. git clone https://github.com/dockfries/infernus-starter.git # or use ssh protocol. git clone git@github.com:dockfries/infernus-starter.git # If you need raknet, clone the raknet branch # git clone https://github.com/dockfries/infernus-starter.git -b raknet # or use ssh protocol. # git clone git@github.com:dockfries/infernus-starter.git -b raknet # you can also download the repository directly from the github page. ``` -------------------------------- ### Defining and Using a Custom Script Source: https://dockfries.github.io/infernus/essentials/use.html Demonstrates how to define a custom script with load and unload functions and then register it with GameMode.use. Options can be passed to the load method. ```typescript import { GameMode } from "@infernus/core"; import type { IFilterScript } from "@infernus/core"; interface IMyScriptOptions { debug?: boolean; } interface IMyScript extends IFilterScript { load(options: IMyScriptOptions): ReturnType; } const MyScript: IMyScript = { name: "my_script", load(...args) { console.log('My script loaded.', args); }, unload() { console.log('My script unloaded.'); } }; // No parameters are passed to the load method GameMode.use(MyScript); // Pass parameters to the load method GameMode.use(MyScript, 'arg1', 'arg2', "arg..."); ``` -------------------------------- ### Correctly Set Weather in GameMode Source: https://dockfries.github.io/infernus/essentials/life-cycle.html Place game-related API calls within the `onInit` callback to ensure they are ready. Avoid calling them directly at the top level. ```typescript import { GameMode } from "@infernus/core"; // Don't do this. This is invalid code. GameMode.setWeather(10); // To do this. GameMode.onInit(({ next }) => { GameMode.setWeather(10); return next(); }); ``` -------------------------------- ### Registering GameMode Events Source: https://dockfries.github.io/infernus/essentials/events.html Use GameMode.onInit, GameMode.onExit, and GameMode.onIncomingConnection to hook into game mode lifecycle events. Ensure to call next() to proceed. ```typescript import { GameMode } from "@infernus/core"; GameMode.onInit(({ next }) => { console.log("GameMode is initialized."); return next(); }); GameMode.onExit(({ next }) => { console.log("GameMode is exited."); return next(); }); GameMode.onIncomingConnection(({ next, playerId, ipAddress, port }) => { console.log( `player id:${playerId},ip:${ipAddress},port:${port} try to connect` ); return next(); }); ``` -------------------------------- ### Add Dependencies with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Add project dependencies by specifying the package name and optionally a version. Use the --component flag for component dependencies and -p for production mode. ```sh # Install one or more dependencies, # all operations' dependencies can be followed by a version number, # it is similar to the syntax of npm packages. infernus add openmultiplayer/open.mp samp-incognito/samp-streamer-plugin@^2.9.6 # install a component dependency infernus add katursis/Pawn.RakNet@^1.6.0-omp --component # production mode install deps (not copy inc files) infernus add samp-incognito/samp-streamer-plugin@^2.9.6 -p ``` -------------------------------- ### Configure Pawn Main Scripts Source: https://dockfries.github.io/infernus/quick-start.html Modify the 'pawn.main_scripts' section in 'config.json' to specify the main scripts for your Pawn gamemode, especially when using raknet. ```json { "pawn": { "main_scripts": ["polyfill_raknet 1"], }, } ``` -------------------------------- ### Configure GitHub Token with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Set a GitHub token to resolve API rate limit issues. This can be done globally via the config command or through an environment variable. ```sh # Set a GitHub token to resolve API rate limit issues (on-demand). # Note: environment variable gh_token will take precedence over the global config. infernus config gh_token ``` -------------------------------- ### Async Support for Player Command Events Source: https://dockfries.github.io/infernus/essentials/events.html Handles player commands asynchronously using async/await or Promises. The async/await syntax is recommended for cleaner code. ```typescript import { Player, PlayerEvent } from "@infernus/core"; // In order to demonstrate the false async const fakePromise = () => { return new Promise((resolve) => { setTimeout(() => { resolve(); }, 1000); }); }; // You can use async grammar sugar, which is also the recommended grammar PlayerEvent.onCommandText("async", async ({ player, next }) => { await fakePromise(); player.sendClientMessage("#fff", "Send a message after a delay of 1 second."); return next(); }); // Promise is OK, but it is not recommended PlayerEvent.onCommandText("promise", ({ player, next }) => { return new Promise((resolve) => { fakePromise().then(() => { player.sendClientMessage( "#fff", "Send a message after a delay of 1 second." ); resolve(); return next(); }); }); }); ``` -------------------------------- ### Modify Configuration File Source: https://dockfries.github.io/infernus/quick-start.html After cloning the repository, navigate to the project directory and modify the 'config.json' file to set parameters like the rcon password. ```sh # enter the project root directory. cd infernus-starter # modify the rcon password in config.json. vim config.json # you don't necessarily need to use vim, any editor is fine. # "rcon": { ``` -------------------------------- ### Defining and Using Custom Events Source: https://dockfries.github.io/infernus/essentials/events.html Create custom events using `defineEvent` to extend functionality. These events can be triggered and handled like built-in events. ```APIDOC ## defineEvent and Custom Event Middleware ### Description Allows the creation of custom events that can be triggered and managed through middleware, extending the event system beyond built-in events. ### Method `defineEvent(options)` ### Parameters - `options` (object) - Configuration for the custom event. - `isNative` (boolean) - Required. Set to `false` for custom events. - `name` (string) - Required. A unique name for the event (e.g., `OnPlayerDanger`). - `defaultValue` (any) - Optional. The default return value for middleware. - `beforeEach` (function) - Optional. A function executed before all middleware to enhance parameters or perform initial setup. Must return an object. - Parameters depend on the event definition. - `afterEach` (function) - Optional. A function executed after all middleware has completed. - Parameters depend on the event definition. ### Usage Example ```typescript import type { Player } from "@infernus/core"; import { defineEvent, PlayerEvent } from "@infernus/core"; const healthDangerSet = new Set(); const [onPlayerDanger, trigger] = defineEvent({ isNative: false, name: "OnPlayerDanger", defaultValue: true, beforeEach(player: Player, health: number) { return { player, health }; }, afterEach({ player, health }) {} }); PlayerEvent.onUpdate(({ player, next }) => { const isDanger = healthDangerSet.has(player); const health = player.getHealth(); if (!isDanger && health <= 10) { healthDangerSet.add(player); const ret = trigger(player, health); if (!ret) return false; } if (isDanger && health > 10) { healthDangerSet.delete(player); } return next(); }); onPlayerDanger(({ player, health, next }) => { player.sendClientMessage( "#ff0", `DANGER! Your health is only ${health}, and the system will automatically return blood for you after 3 seconds.`, ); setTimeout(() => { player.setHealth(100); }, 3000); return next(); }); ``` ``` -------------------------------- ### Middleware Pattern for Player Connect Events Source: https://dockfries.github.io/infernus/essentials/events.html Demonstrates the middleware pattern for PlayerEvent.onConnect. Forgetting to call next() will prevent subsequent middleware from executing. ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onConnect(({ player, next }) => { console.log("player connected 1"); // return next(); Suppose you forget to call the }); PlayerEvent.onConnect(({ player, next }) => { console.log("player connected 2"); // This middleware will not be executed return next(); }); ``` -------------------------------- ### Registering Commands with Case Sensitivity Option Source: https://dockfries.github.io/infernus/essentials/events.html Register a command with the `PlayerEvent.onCommandText` method, allowing you to specify if it should be case-sensitive. ```APIDOC ## PlayerEvent.onCommandText ### Description Registers a command handler for player-issued commands. Allows specifying case sensitivity. ### Method `PlayerEvent.onCommandText(options)` ### Parameters - `options` (object) - Configuration for the command handler. - `caseSensitive` (boolean) - Optional. Specifies if the command is case-sensitive. Defaults to global setting. - `command` (string) - Required. The command text to register. - `run` (function) - Required. The callback function to execute when the command is triggered. - `player` (Player) - The player who issued the command. - `subcommand` (string) - The subcommand, if any. - `next` (function) - Function to call to proceed to the next middleware or handler. ### Request Example ```typescript PlayerEvent.onCommandText({ caseSensitive: false, command: "foo", run({ player, subcommand, next }) { return next(); }, }); ``` ``` -------------------------------- ### Display and Delete Global Configuration Source: https://dockfries.github.io/infernus/quick-start.html View the current global configuration settings using 'infernus config -l' or remove a specific configuration item, such as the GitHub token. ```sh # Display global configuration information infernus config -l # Delete a global configuration infernus config gh_token ``` -------------------------------- ### Before Guard for Command Execution Source: https://dockfries.github.io/infernus/essentials/events.html Implement a `onCommandReceived` guard to execute logic before a command is processed by `onCommandText`. Returning `false` will trigger the error guard. ```APIDOC ## PlayerEvent.onCommandReceived ### Description Executes a middleware function before a player command is processed. Useful for pre-command validation or modification. ### Method `PlayerEvent.onCommandReceived(callback)` ### Parameters - `callback` (function) - The function to execute before command processing. - `player` (Player) - The player who issued the command. - `command` (string) - The command text. - `next` (function) - Function to call to proceed to the next middleware or handler. ### Request Example ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onCommandReceived(({ player, command, next }) => { return next(); }); ``` ``` -------------------------------- ### Reloading a Registered Script with a Command Source: https://dockfries.github.io/infernus/essentials/use.html Shows how to use PlayerEvent.onCommandText to trigger GameMode.reloadUseScript. Ensure the script name matches the registered script. ```typescript import { GameMode, PlayerEvent } from "@infernus/core"; PlayerEvent.onCommandText("reloadMyScript", ({ next }) => { GameMode.reloadUseScript("my_script"); return next(); }); ``` -------------------------------- ### Player Internationalization Attributes Source: https://dockfries.github.io/infernus/essentials/i18n.html Illustrates the default charset and locale attributes on a Player instance, which control internationalization settings. ```typescript class Player { charset = "ISO-8859-1"; locale = "en_US"; } ``` -------------------------------- ### Enable Command Case Sensitivity Source: https://dockfries.github.io/infernus/essentials/events.html Enable case sensitivity for all subsequently registered player commands. This means commands must be typed with the exact casing. ```typescript import { GameMode } from "@infernus/core"; GameMode.enableCmdCaseSensitive(); // Enable case sensitivity for commands ``` -------------------------------- ### Define Player Commands Source: https://dockfries.github.io/infernus/essentials/events.html Define player commands with simple names, hierarchical subcommands, or multiple aliases. The handler function receives player context and a subcommand array. ```typescript import { Player, PlayerEvent } from "@infernus/core"; // Define a first-level command PlayerEvent.onCommandText("help", ({ player, next }) => { console.log(`player ${player.getName()}, hello`); return next(); }); // Define a second-level command PlayerEvent.onCommandText("help teleport", ({ player, next }) => { console.log( `player ${player.getName()} want to get help information related to teleport` ); return next(); }); // Define a command that can be triggered by /msg or /message PlayerEvent.onCommandText( ["msg", "message"], ({ player, subcommand, next }) => { console.log( `player ${player.getName()} entered this command, and may also have entered a subcommand ${subcommand.toString()}` ); // It is equivalent to the player entering / message global or / msg global if (subcommand[0] === "global") { // Extra logic return next(); } else { next(); // Thought to be an invalid command, will trigger the rear guard return false; } }, ); ``` -------------------------------- ### Translate Text Using Player Locale Source: https://dockfries.github.io/infernus/essentials/i18n.html Demonstrates how to use the $t function with a player's specific locale to fetch translated strings. ```typescript // Suppose you have an instance of player console.log( $t("server.incoming", ["127.0.0.1", "8080", "123456"], player.locale), ); ``` -------------------------------- ### Close Player Dialog - TypeScript Source: https://dockfries.github.io/infernus/essentials/dialogs.html Shows how to implement a command to close a dialog for a specified player. It includes input validation, player lookup, and the use of the static `Dialog.close()` method. Remember to convert player IDs from strings to numbers. ```typescript import { PlayerEvent, Player, Dialog } from "@infernus/core"; PlayerEvent.onCommandText("closeDialog", ({ player, subcommand, next }) => { const [playerId] = subcommand; if (!playerId) { player.sendClientMessage( "#f00", "Please enter the dialog for which player you want to close" ); return next(); } // The commands entered by the player are all strings, so you need to convert the type to a numeric type. const closePlayer = Player.getInstance(+playerId); if (!closePlayer) { player.sendClientMessage("#f00", "The player is not online."); } else { // Dialog static method Dialog.close(closePlayer); player.sendClientMessage("#ff0", "You closed the player's dialog."); } return next(); }); ``` -------------------------------- ### Initialize I18n Instance and Translate Text Source: https://dockfries.github.io/infernus/essentials/i18n.html Initializes the I18n instance with default locale and language packs. Use the $t function to retrieve translated strings, optionally providing placeholders and a specific locale. ```typescript import { I18n } from "@infernus/core"; // Internationalized json language Pack import zh_CN from "./locales/zh_CN.json"; import en_US from "./locales/en_US.json"; const locales = { zh_CN, en_US, }; export const { $t } = new I18n("en_US", locales); console.log($t("server.running")); console.log($t("server.connection", ["127.0.0.1", "8080", "123456"])); console.log($t("server.connection", ["127.0.0.1", "8080", "123456"], "zh_CN")); ``` -------------------------------- ### Enable Support for All Nickname Characters Source: https://dockfries.github.io/infernus/essentials/i18n.html Enables the game server to accept all international usernames, including characters like Chinese characters, by utilizing a new API. This is typically called during game mode initialization. ```typescript import { GameMode } from "@infernus/core"; GameMode.onInit(({ next }) => { GameMode.supportAllNickname(); return next(); }); ``` -------------------------------- ### Managing Event Listeners in Load/Unload Functions Source: https://dockfries.github.io/infernus/essentials/use.html Illustrates how to properly manage event listeners within the load and unload functions of a script. Returning an array of off-functions from load prevents memory leaks. ```typescript const MyScript = { name: 'my_script', load(...args) { const off1 = PlayerEvent.onCommandText("foo", ({ player, next }) => { return next(); }); const off2 = PlayerEvent.onConnect(({ player, next }) => { return next(); }); return [off1, off2]; }, unload() { } } GameMode.use(MyScript); ``` -------------------------------- ### Check Command Case Sensitivity Status Source: https://dockfries.github.io/infernus/essentials/events.html Check if command registration is currently case sensitive. This setting affects how player commands are matched. ```typescript import { GameMode } from "@infernus/core"; console.log(GameMode.isCmdCaseSensitive()); ``` -------------------------------- ### Implementing a Before Guard for Commands Source: https://dockfries.github.io/infernus/essentials/events.html Use onCommandReceived to add logic before a command is processed. Returning false will trigger the error guard. ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onCommandReceived(({ player, command, next }) => { return next(); }); ``` -------------------------------- ### Define English Language Pack Source: https://dockfries.github.io/infernus/essentials/i18n.html Defines an English language pack using a JSON structure with nested keys. Supports '%s' as placeholders for dynamic data. ```json { "server": { "running": "Successfully running an omp server powered by node.js", "connection": "connection information: %s - %s : %s" } } ``` -------------------------------- ### Define Player Class Hooks Source: https://dockfries.github.io/infernus/essentials/hooks.html Use `defineHooks` to create hooks for the Player class. The `setPlayerHook` function allows you to define custom logic for methods like `setArmour`. Remember to call original methods using `orig_playerMethods` to avoid infinite loops. ```typescript import { defineHooks, Player } from "@infernus/core"; // Destructure to get all original methods and the method to set hooks. export const [orig_playerMethods, setPlayerHook] = defineHooks(Player); // This demonstrates hooking the Player class. Most entity classes can be passed in, such as Vehicle, TextDraw... // The first parameter is the name of the hookable method, which will have TS type hints. // The return value is the second parameter you passed in. export const my_setPlayerArmour = setPlayerHook( "setArmour", function (armour: number) { // Here, `this` refers to the current player const flag = true; // Assume true for this example if (flag) { console.log("my hook"); // Call the original setArmour method, but we intentionally subtract 1 and return the original call result return orig_playerMethods.setArmour.call(this, armour - 1); // Never directly use this.setArmour(armour), as it will cause an infinite loop // Inside the hook function body, you can only call all original functions via orig_playerMethods. } }, ); /* setPlayerHook( "setArmour", function (armour: number) { // You can only hook a method once within the same defineHooks group // Never hook the same method again. // If you need to hook multiple times, use the defineHooks function multiple times and split files or define different variable names. }, ); */ ``` -------------------------------- ### After Guard for Command Execution Source: https://dockfries.github.io/infernus/essentials/events.html Utilize the `onCommandPerformed` guard to run logic after a command has been executed by `onCommandText`. Returning `false` will trigger the error guard. ```APIDOC ## PlayerEvent.onCommandPerformed ### Description Executes a middleware function after a player command has been performed. Useful for post-command logging or cleanup. ### Method `PlayerEvent.onCommandPerformed(callback)` ### Parameters - `callback` (function) - The function to execute after command performance. - `player` (Player) - The player who issued the command. - `command` (string) - The command text. - `next` (function) - Function to call to proceed to the next middleware or handler. ### Request Example ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onCommandPerformed(({ player, command, next }) => { return next(); }); ``` ``` -------------------------------- ### Define and Cancel One-Time Command Source: https://dockfries.github.io/infernus/essentials/events.html Define an event listener for a command that should only execute once. The returned 'off' function must be called after `next()` to ensure the listener is removed. ```typescript const off = PlayerEvent.onCommandText("once", ({ player, next }) => { console.log( "This command is only executed once, and the next execution will not exist." ); const ret = next(); off(); // next function should be executed before the off function return ret; }); ``` -------------------------------- ### Registering a Case-Insensitive Command Source: https://dockfries.github.io/infernus/essentials/events.html Register a command that is not case-sensitive, overriding the global setting. This is useful for commands where case should not matter. ```typescript PlayerEvent.onCommandText({ caseSensitive: false, // Specify if the command is case sensitive command: "foo", // Your command run({ player, subcommand, next }) { return next(); }, }); ``` -------------------------------- ### Remove Dependencies with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Uninstall one or more dependencies from your project using the 'infernus remove' command followed by the package names. ```sh infernus remove openmultiplayer/open.mp samp-incognito/samp-streamer-plugin infernus remove katursis/Pawn.RakNet ``` -------------------------------- ### Define Chinese Language Pack Source: https://dockfries.github.io/infernus/essentials/i18n.html Defines a Chinese language pack using a JSON structure with nested keys. Supports '%s' as placeholders for dynamic data. ```json { "server": { "running": "成功运行由 node.js 强力驱动的 omp 服务器", "connection": "连接信息: %s - %s : %s" } } ``` -------------------------------- ### Update Dependencies with Infernus CLI Source: https://dockfries.github.io/infernus/quick-start.html Update a specific dependency to its latest version or to a specified version using the 'infernus update' command. ```sh # Update a dependency (update global cache and apply to current directory) infernus update openmultiplayer/open.mp # Update a dependency to a specific version infernus update openmultiplayer/open.mp@^1.2.0.2670 ``` -------------------------------- ### Implementing an After Guard for Commands Source: https://dockfries.github.io/infernus/essentials/events.html Use onCommandPerformed to add logic after a command has been executed. Returning false will trigger the error guard. ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onCommandPerformed(({ player, command, next }) => { return next(); }); ``` -------------------------------- ### Handling Command Errors Source: https://dockfries.github.io/infernus/essentials/events.html Implement onCommandError to catch command failures from guards or undefined commands. Returning true prevents default error handling. ```typescript PlayerEvent.onCommandError(({ player, command, error, next }) => { player.sendClientMessage( "#f00", `player ${player.id} command ${command} with error ${error.code}, ${error.msg}`, ); next(); // If there are other onCommandError middleware, execute return true; // Returning true indicates that the error has been handled and the default event is no longer triggered }); ``` -------------------------------- ### Conditional Command Case Sensitivity Source: https://dockfries.github.io/infernus/essentials/events.html Register commands with different case sensitivity settings by enabling or disabling command case sensitivity before each registration. Strict matching (case-sensitive) takes precedence over non-strict matching. ```typescript import { GameMode, PlayerEvent } from "@infernus/core"; GameMode.disableCmdCaseSensitive(); // Commands registered at this point are not case sensitive, // allowing players to use commands like help, HeLP, etc. PlayerEvent.onCommandText("help", ({ player, next }) => { player.sendClientMessage(-1, "help command (not case sensitive)"); return next(); }); GameMode.enableCmdCaseSensitive(); // Commands registered at this point are case sensitive, // requiring players to use Help only. PlayerEvent.onCommandText("Help", ({ player, next }) => { player.sendClientMessage(-1, "help command (case sensitive)"); return next(); }); ``` -------------------------------- ### Clear Infernus Cache Source: https://dockfries.github.io/infernus/quick-start.html Manage the global dependency cache using 'infernus cache clean'. You can clear specific versions, all versions of a package, or the entire cache. ```sh # Clear the lowest matching version of a single global dependency infernus cache clean samp-incognito/samp-streamer-plugin@^2.9.6 # Clear all versions of a single global dependency infernus cache clean samp-incognito/samp-streamer-plugin # Clear all global cache dependencies infernus cache clean -a ``` -------------------------------- ### Set PowerShell/cmd Charset to UTF-8 Source: https://dockfries.github.io/infernus/essentials/i18n.html For PowerShell users, this command sets the input and output encoding to UTF-8 for the current session. Add it to your $PROFILE for permanent changes. For cmd users, this command changes the charset to UTF-8 before running the omp server. ```powershell $OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding ``` ```sh cmd /c "chcp 65001 > nul & omp-server" ``` -------------------------------- ### Disable Command Case Sensitivity Source: https://dockfries.github.io/infernus/essentials/events.html Disable case sensitivity for all subsequently registered player commands. Players can use commands with any casing. ```typescript import { GameMode } from "@infernus/core"; GameMode.disableCmdCaseSensitive(); // Disable case sensitivity for commands ``` -------------------------------- ### Error Guard for Command Handling Source: https://dockfries.github.io/infernus/essentials/events.html The `onCommandError` guard catches errors during command processing, including refusals from before/after guards or undefined commands. Returning `true` prevents default error handling. ```APIDOC ## PlayerEvent.onCommandError ### Description Handles errors that occur during player command processing, such as guard refusals or undefined commands. Allows for custom error reporting or handling. ### Method `PlayerEvent.onCommandError(callback)` ### Parameters - `callback` (function) - The function to execute when a command error occurs. - `player` (Player) - The player associated with the command error. - `command` (string) - The command that caused the error. - `error` (object) - An object containing error details. - `code` (number) - The error code. - `msg` (string) - The error message. - `next` (function) - Function to call to proceed to the next middleware or handler. ### Request Example ```typescript PlayerEvent.onCommandError(({ player, command, error, next }) => { player.sendClientMessage( "#f00", `player ${player.id} command ${command} with error ${error.code}, ${error.msg}`, ); next(); // If there are other onCommandError middleware, execute return true; // Returning true indicates that the error has been handled and the default event is no longer triggered }); ``` ``` -------------------------------- ### Handling Player Text Events with Default Behavior Source: https://dockfries.github.io/infernus/essentials/events.html The PlayerEvent.onText event allows you to intercept player text input. Returning true or 1 continues the default chat message display. ```typescript import { PlayerEvent } from "@infernus/core"; PlayerEvent.onText(({ player, next }) => { return true; }); ``` -------------------------------- ### TypeScript Interface for FilterScript Source: https://dockfries.github.io/infernus/essentials/use.html Defines the structure for filterscripts, including name, load, and unload functions. It also allows for additional properties. ```typescript interface IFilterScript { name: string; load: (...args: Array) => Array<() => void> | Promise void>>; unload: () => any; [propName: string | number | symbol]: any; } type Use = (plugin: IFilterScript, ...options: Array) => GameMode; ``` -------------------------------- ### Async Return Value Behavior in Events Source: https://dockfries.github.io/infernus/essentials/events.html The return value of async event handlers is ignored due to underlying logic. The default behavior of the event is always returned, regardless of the async function's explicit return. ```typescript import { Player, PlayerEvent } from "@infernus/core"; PlayerEvent.onText(({ player, next }) => { return next(); // 1 }); PlayerEvent.onText(({ player, next }) => { return next(); // 1 }); PlayerEvent.onText(async ({ player, next }) => { // because it is async, // the specific return value depends on the default return value of // the event defined by the underlying defineEvent of the source code. // // does not depend on what the async function returns. // onText defaults to true, and the underlying layer will be converted to int, that is, 1 const ret = next(); // the function after execution return ret; // convert false to int = 0 }); // The synchronous return value defined after the async function also makes no sense, // and the default value has been returned when an async function is encountered PlayerEvent.onText(({ player, next }) => { return false; }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.