UNPKG

mc-server-management

Version:

A library for the Minecraft server management protocol added in 25w35a

1 lines 113 kB
{"version":3,"file":"index.mjs","names":["#connection","#assertBoolean","#assertString","#assertNumber","#connection","#items","bans: IPBan[]","bans: UserBan[]","ops: Operator[]","#connection","#onConnectionEvent","Notifications","#getByNameOrPos","#operatorList","#allowlist","#ipBanList","#banList","#gameRules","#state","Notifications","players: Player[]"],"sources":["../src/error/InvalidResponseError.ts","../src/error/IncorrectTypeError.ts","../src/server/ServerSettings.ts","../src/error/MissingPropertyError.ts","../src/schemas/player/Player.ts","../src/player-list/PlayerList.ts","../src/util.ts","../src/player-list/AllowList.ts","../src/schemas/player/ban/Ban.ts","../src/schemas/player/ban/IncomingIPBan.ts","../src/schemas/player/ban/IPBan.ts","../src/player-list/IPBanList.ts","../src/schemas/player/ban/UserBan.ts","../src/player-list/BanList.ts","../src/schemas/player/KickPlayer.ts","../src/schemas/player/Operator.ts","../src/player-list/OperatorList.ts","../src/schemas/message/Message.ts","../src/schemas/message/SystemMessage.ts","../src/schemas/gamerule/GameRule.ts","../src/schemas/gamerule/UntypedGameRule.ts","../src/server/MinecraftServer.ts","../src/server/Notifications.ts","../src/error/JsonRPCError.ts","../src/connection/Connection.ts","../src/connection/WebSocketConnection.ts","../src/schemas/gamerule/GameRuleType.ts","../src/schemas/gamerule/TypedGameRule.ts","../src/schemas/server/Version.ts","../src/schemas/server/ServerState.ts","../src/schemas/server/Difficulty.ts","../src/schemas/server/GameMode.ts"],"sourcesContent":["export default abstract class InvalidResponseError extends Error {\n /**\n * The full response received from the server.\n */\n readonly response: unknown;\n /**\n * The path in the response that was invalid.\n */\n readonly path: string[];\n\n protected constructor(message: string, response: unknown, path: string[]) {\n super(\"Invalid response from server at '\" + path.join(\".\") + \"'. \" + message);\n this.response = response;\n this.path = path;\n }\n}\n","import InvalidResponseError from \"./InvalidResponseError.js\";\n\nexport default class IncorrectTypeError extends InvalidResponseError {\n /**\n * The expected type of the response.\n */\n readonly expectedType: string;\n /**\n * The actual type of the response.\n */\n readonly foundType: string;\n\n /**\n * Creates a new InvalidResponseError.\n * @param path The path in the response that was invalid.\n * @param expectedType The expected type of the response.\n * @param foundType The actual type of the response.\n * @param response The full response received from the server.\n * @internal\n */\n constructor(expectedType: string, foundType: string, response: unknown, ...path: string[]) {\n super(\"Expected \" + expectedType + \", received \" + foundType + \".\", response, path);\n this.expectedType = expectedType;\n this.foundType = foundType;\n }\n}\n","import Connection from \"../connection/Connection\";\nimport IncorrectTypeError from \"../error/IncorrectTypeError\";\nimport Difficulty from \"../schemas/server/Difficulty\";\nimport GameMode from \"../schemas/server/GameMode\";\n\n/**\n * An API wrapper for the settings of the Minecraft server.\n */\nexport default class ServerSettings {\n #connection: Connection;\n\n /**\n * Create an API wrapper for the server settings. Use {@link MinecraftServer.settings}.\n * @param connection\n * @internal\n */\n constructor(connection: Connection) {\n this.#connection = connection;\n }\n\n /**\n * Get whether the server automatically saves the world periodically.\n * @returns {Promise<boolean>} True if the server automatically saves the world, false otherwise.\n */\n async getAutoSave(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/autosave', []),\n );\n }\n\n /**\n * Set whether the server automatically saves the world periodically.\n * @param value True to enable auto-saving, false to disable it.\n */\n async setAutoSave(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/autosave/set', [value]));\n }\n\n /**\n * Get the current difficulty level of the server.\n * @returns {Promise<Difficulty>} The current difficulty level.\n */\n async getDifficulty(): Promise<Difficulty> {\n return this.#assertString(\n await this.#connection.call('minecraft:serversettings/difficulty', []),\n \"Difficulty\"\n ) as Difficulty;\n }\n\n /**\n * Set the difficulty level of the server.\n * @param value The difficulty level to set.\n */\n async setDifficulty(value: Difficulty): Promise<void> {\n this.#assertString(await this.#connection.call('minecraft:serversettings/difficulty/set', [value]))\n }\n\n /**\n * Get whether the server immediately kicks players when they are removed from the allowlist.\n * @returns {Promise<boolean>} If true, players are kicked when removed from the allowlist.\n */\n async getEnforceAllowList(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/enforce_allowlist', []),\n );\n }\n\n /**\n * Set whether the server immediately kicks players when they are removed from the allowlist.\n * @param value True to enable enforcement, false to disable it.\n */\n async setEnforceAllowList(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/enforce_allowlist/set', [value]));\n }\n\n /**\n * Get whether the server uses the allow list.\n * @returns {Promise<boolean>} True if the server uses the allow list, false otherwise.\n */\n async getUseAllowList(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/use_allowlist', []),\n );\n }\n\n /**\n * Set whether the server uses the allow list.\n * @param value True to enable the allow list, false to disable it.\n */\n async setUseAllowList(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/use_allowlist/set', [value]));\n }\n\n /**\n * Get the maximum number of players that can join the server.\n * @returns {Promise<number>} The maximum number of players.\n */\n async getMaxPlayers(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/max_players', [])\n );\n }\n\n /**\n * Set the maximum number of players that can join the server.\n * @param value The maximum number of players.\n */\n async setMaxPlayers(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/max_players/set', [value]));\n }\n\n /**\n * Get the number of seconds the server waits before pausing when no players are online.\n * A non-positive value means the server never pauses.\n * @returns {Promise<number>} The number of seconds before pausing when empty.\n */\n async getPauseWhenEmptySeconds(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/pause_when_empty_seconds', [])\n );\n }\n\n /**\n * Set the number of seconds the server waits before pausing when no players are online.\n * A non-positive value means the server never pauses.\n * @param value The number of seconds before pausing when empty.\n */\n async setPauseWhenEmptySeconds(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/pause_when_empty_seconds/set', [value]));\n }\n\n /**\n * Get the number of minutes a player can be idle before being kicked.\n * Value 0 means players are never kicked for idling.\n * @returns {Promise<number>} The number of minutes before kicking idle players.\n */\n async getPlayerIdleTimeout(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/player_idle_timeout', [])\n );\n }\n\n /**\n * Set the number of minutes a player can be idle before being kicked.\n * Value 0 means players are never kicked for idling.\n * @param value The number of minutes before kicking idle players.\n */\n async setPlayerIdleTimeout(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/player_idle_timeout/set', [value]));\n }\n\n /**\n * Get whether players are allowed to fly on the server. This only changes the flight detection, it does not\n * enable flight for players in survival mode without a hacked client.\n * @returns {Promise<boolean>} True if players are allowed to fly, false otherwise.\n */\n async getAllowFlight(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/allow_flight', []),\n );\n }\n\n /**\n * Set whether players are allowed to fly on the server. This only changes the flight detection, it does not\n * enable flight for players in survival mode without a hacked client.\n * @param value True to allow flying, false to disable it.\n */\n async setAllowFlight(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/allow_flight/set', [value]));\n }\n\n /**\n * Get the message of the day (MOTD) of the server.\n * @returns {Promise<string>} The MOTD of the server.\n */\n async getMOTD(): Promise<string> {\n return this.#assertString(\n await this.#connection.call('minecraft:serversettings/motd', [])\n );\n }\n\n /**\n * Set the message of the day (MOTD) of the server.\n * @param value The MOTD to set.\n */\n async setMOTD(value: string): Promise<void> {\n this.#assertString(await this.#connection.call('minecraft:serversettings/motd/set', [value]));\n }\n\n /**\n * Get the radius around the world spawn point that is protected from non-operator players.\n * @returns {Promise<number>} The spawn protection radius.\n */\n async getSpawnProtectionRadius(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/spawn_protection_radius', [])\n );\n }\n\n /**\n * Set the radius around the world spawn point that is protected from non-operator players.\n * @param value The spawn protection radius.\n */\n async setSpawnProtectionRadius(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/spawn_protection_radius/set', [value]));\n }\n\n /**\n * Get whether players are forced to use the server's game mode when they join.\n * @returns {Promise<boolean>} True if players are forced to use the server's game mode, false otherwise.\n */\n async getForceGameMode(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/force_game_mode', []),\n );\n }\n\n /**\n * Set whether players are forced to use the server's game mode when they join.\n * @param value True to force the server's game mode, false to allow players to use their own.\n */\n async setForceGameMode(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/force_game_mode/set', [value]));\n }\n\n /**\n * Get the default game mode for players when they join the server for the first time. If force game mode is\n * enabled the game mode will be applied to all players when they join, not just new ones.\n * @returns {Promise<GameMode>} The default game mode.\n */\n async getGameMode(): Promise<GameMode> {\n return this.#assertString(\n await this.#connection.call('minecraft:serversettings/game_mode', []),\n \"GameMode\"\n ) as GameMode;\n }\n\n /**\n * Set the default game mode for players when they join the server for the first time. If force game mode is\n * enabled the game mode will be applied to all players when they join, not just new ones.\n * @param value The default game mode.\n */\n async setGameMode(value: GameMode): Promise<void> {\n this.#assertString(await this.#connection.call('minecraft:serversettings/game_mode/set', [value]));\n }\n\n /**\n * Get the view distance of the server, in chunks.\n * This is the distance in chunks that the server sends to players around them.\n * @returns {Promise<number>} The view distance in chunks.\n */\n async getViewDistance(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/view_distance', [])\n );\n }\n\n /**\n * Set the view distance of the server, in chunks.\n * This is the distance in chunks that the server sends to players around them.\n * @param value The view distance in chunks.\n */\n async setViewDistance(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/view_distance/set', [value]));\n }\n\n /**\n * Get the simulation distance of the server, in chunks.\n * This is the distance in chunks that the server simulates around each player.\n * @returns {Promise<number>} The simulation distance in chunks.\n */\n async getSimulationDistance(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/simulation_distance', [])\n );\n }\n\n /**\n * Set the simulation distance of the server, in chunks.\n * This is the distance in chunks that the server simulates around each player.\n * @param value The simulation distance in chunks.\n */\n async setSimulationDistance(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/simulation_distance/set', [value]));\n }\n\n /**\n * Get whether the server accepts players transferred from other servers.\n * @returns {Promise<boolean>} True if the server accepts transferred players, false otherwise.\n */\n async getAcceptTransfers(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/accept_transfers', []),\n );\n }\n\n /**\n * Set whether the server accepts players transferred from other servers.\n * @param value True to accept transferred players, false to reject them.\n */\n async setAcceptTransfers(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/accept_transfers/set', [value]));\n }\n\n /**\n * Get the interval in seconds between status heartbeats sent to server management clients.\n * A value of 0 means no heartbeats are sent.\n * @returns {Promise<number>} The status heartbeat interval in seconds.\n */\n async getStatusHeartbeatInterval(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/status_heartbeat_interval', [])\n );\n }\n\n /**\n * Set the interval in seconds between status heartbeats sent to server management clients.\n * A value of 0 means no heartbeats are sent.\n * @param value The status heartbeat interval in seconds.\n */\n async setStatusHeartbeatInterval(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/status_heartbeat_interval/set', [value]));\n }\n\n /**\n * Get the permission level granted to new operators.\n * Levels are from 1 to 4, with 4 being the highest.\n * @returns {Promise<number>} The operator user permission level.\n */\n async getOperatorUserPermissionLevel(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/operator_user_permission_level', [])\n );\n }\n\n /**\n * Set the permission level granted to new operators.\n * Levels are from 1 to 4, with 4 being the highest.\n * @param value The operator user permission level.\n */\n async setOperatorUserPermissionLevel(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/operator_user_permission_level/set', [value]));\n }\n\n /**\n * Get whether the server hides the list of online players from the server list.\n * @returns {Promise<boolean>} True if the server hides the list of online players, false otherwise.\n */\n async getHideOnlinePlayers(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/hide_online_players', []),\n );\n }\n\n /**\n * Set whether the server hides the list of online players from the server list.\n * @param value True to hide the list of online players, false to show it.\n */\n async setHideOnlinePlayers(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/hide_online_players/set', [value]));\n }\n\n /**\n * Get whether the server responds to status requests in the multiplayer server list.\n * @returns {Promise<boolean>} True if the server responds to status requests, false otherwise.\n */\n async getStatusReplies(): Promise<boolean> {\n return this.#assertBoolean(\n await this.#connection.call('minecraft:serversettings/status_replies', []),\n );\n }\n\n /**\n * Set whether the server responds to status requests in the multiplayer server list.\n * @param value True to respond to status requests, false to ignore them.\n */\n async setStatusReplies(value: boolean): Promise<void> {\n this.#assertBoolean(await this.#connection.call('minecraft:serversettings/status_replies/set', [value]));\n }\n\n /**\n * Get the range in chunks around each player in which entities are updated to the player. This is a percentage\n * value (100 => 100%) of the default value. Min: 10%, Max: 1000%\n * @returns {Promise<number>} The entity broadcast range percentage.\n */\n async getEntityBroadcastRange(): Promise<number> {\n return this.#assertNumber(\n await this.#connection.call('minecraft:serversettings/entity_broadcast_range', [])\n );\n }\n\n /**\n * Set the range in chunks around each player in which entities are updated to the player. This is a percentage\n * value (100 => 100%) of the default value. Min: 10%, Max: 1000%\n * @param value The entity broadcast range percentage.\n */\n async setEntityBroadcastRange(value: number): Promise<void> {\n this.#assertNumber(await this.#connection.call('minecraft:serversettings/entity_broadcast_range/set', [value]));\n }\n\n #assertBoolean(value: unknown): boolean {\n if (typeof value !== 'boolean') {\n throw new IncorrectTypeError(\"boolean\", typeof value, value);\n }\n return value;\n }\n\n #assertString(value: unknown, expected?: string): string {\n if (typeof value !== 'string') {\n throw new IncorrectTypeError(expected ?? \"string\", typeof value, value);\n }\n return value;\n }\n\n #assertNumber(value: unknown): number {\n if (typeof value !== 'number') {\n throw new IncorrectTypeError(\"number\", typeof value, value);\n }\n return value;\n }\n}\n","import InvalidResponseError from \"./InvalidResponseError.js\";\n\nexport default class MissingPropertyError extends InvalidResponseError {\n /**\n * Name of the missing property.\n */\n readonly property: string;\n\n /**\n * Creates a new MissingPropertyError.\n * @param property Name of the missing property.\n * @param response The full response received from the server.\n * @param path The path in the response that was invalid.\n * @internal\n */\n constructor(property: string, response: unknown = null, ...path: string[]) {\n super(`Missing required property '${property}'.`, response, path.concat(property));\n this.property = property;\n }\n}\n","import IncorrectTypeError from \"../../error/IncorrectTypeError\";\nimport MissingPropertyError from \"../../error/MissingPropertyError\";\n\n/**\n * A player object or a player's username.\n */\nexport type PlayerInput = string | Player;\n\nexport default class Player {\n /**\n * Unique identifier of the player (UUID format).\n */\n id?: string;\n /**\n * Username of the player.\n */\n name?: string;\n\n /**\n * Creates a Player instance with the specified UUID.\n * @param id\n */\n static withId(id: string): Player {\n return new Player().setId(id);\n }\n\n /**\n * Creates a Player instance with the specified username.\n * @param name\n */\n static withName(name: string): Player {\n return new Player().setName(name);\n }\n\n /**\n * Parse a Player instance from a PlayerInput.\n * @param input\n * @internal\n */\n static fromInput(input: PlayerInput): Player {\n if (typeof input === \"string\") {\n return Player.withName(input);\n }\n\n return input;\n }\n\n /**\n * Parse a list of Player instances from a raw array.\n * @param data\n * @param response\n * @param path\n * @internal\n */\n static parseList(data: unknown, response: unknown = data, ...path: string[]): Player[] {\n if (!Array.isArray(data)) {\n throw new IncorrectTypeError(\"array\", typeof data, response, ...path);\n }\n\n const players = [];\n for (const [index, entry] of data.entries()) {\n players.push(Player.parse(entry, response, ...path, index.toString()))\n }\n\n return players;\n }\n\n /**\n * Parse a Player instance from a raw object.\n * @param data Raw object to parse.\n * @param response Full response received from the server, used for errors.\n * @param path Path to the data in the original response, used for errors.\n * @returns Parsed Player instance.\n * @throws {IncorrectTypeError} If the data is not a valid Player object.\n * @internal\n */\n static parse(data: unknown, response: unknown = data, ...path: string[]): Player {\n if (typeof data !== 'object' || data === null) {\n throw new IncorrectTypeError(\"object\", typeof data, response, ...path);\n }\n\n if (!(\"id\" in data)) {\n throw new MissingPropertyError(\"id\", response, ...path);\n }\n\n if (!(\"name\" in data)) {\n throw new MissingPropertyError(\"name\", response, ...path);\n }\n\n if (typeof data.id !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.id, response, ...path, 'id');\n }\n\n if (typeof data.name !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.name, response, ...path, 'name');\n }\n\n return new Player(data.id, data.name);\n }\n\n /**\n * @param id Unique identifier of the player (UUID format).\n * @param name Username of the player.\n * @internal Use static methods {@link withId} or {@link withName} to create instances.\n */\n constructor(id?: string, name?: string) {\n this.id = id;\n this.name = name;\n }\n\n /**\n * Sets the unique identifier of the player.\n * @param id\n */\n setId(id?: string): this {\n this.id = id;\n return this;\n }\n\n /**\n * Sets the username of the player.\n * @param name\n */\n setName(name?: string): this {\n this.name = name;\n return this;\n }\n}\n\n","import type Connection from \"../connection/Connection.js\";\nimport IncorrectTypeError from \"../error/IncorrectTypeError.js\";\n\nexport default abstract class PlayerList<ItemType> {\n #connection: Connection;\n #items?: ItemType[];\n\n /**\n * Create a player list API wrapper. Use {@link MinecraftServer.allowlist} or similar methods instead.\n * @param connection\n * @internal\n */\n constructor(connection: Connection) {\n this.#connection = connection;\n }\n\n /**\n * Get the items on the list. If the list is already fetched and force is false, the cached list is returned.\n * @param force Always request the list from the server, even if it was already fetched.\n */\n public async get(force: boolean = false): Promise<ItemType[]> {\n if (!this.#items || force) {\n await this.callAndParse();\n }\n if (!this.#items) {\n throw new Error(\"Invalid player list.\");\n }\n return this.#items;\n }\n\n /**\n * Clear the list.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n */\n public async clear(): Promise<this> {\n return this.callAndParse('clear', []);\n }\n\n /**\n * Add an item to the cached list. Does not update the server.\n * @param item\n * @internal\n */\n public addItem(item: ItemType): this {\n this.#items?.push(item);\n return this;\n }\n\n /**\n * Remove all items matching this callback from the cached list. Does not update the server.\n * If the cached list is not available, this method does nothing.\n * @param filter\n * @internal\n */\n public removeMatching(filter: (item: ItemType) => boolean): this {\n if (!this.#items) {\n return this;\n }\n\n this.#items = this.#items.filter(item => !filter(item));\n return this;\n }\n\n /**\n * Call a method on the player list and return the raw response.\n * @param action Method to call (e.g., 'set', 'add', 'remove', 'clear').\n * @param params Parameters to pass to the method.\n * @returns This PlayerList instance.\n * @protected\n */\n protected async call(action?: string, params: unknown[] = []): Promise<unknown> {\n let method = this.getName();\n if (action) {\n method += \"/\" + action\n }\n return await this.#connection.call(method, params);\n }\n\n /**\n * Call a method on the player list. Updates the cached list with the resulting list from the server and returns this.\n * @param action Method to call (e.g., 'set', 'add', 'remove', 'clear').\n * @param params Parameters to pass to the method.\n * @returns This PlayerList instance.\n * @protected\n */\n protected async callAndParse(action?: string, params: unknown[] = []): Promise<this> {\n const result = await this.call(action, params);\n if (!Array.isArray(result)) {\n throw new IncorrectTypeError(\"array\", typeof result, result);\n }\n\n this.#items = this.parseResult(result);\n return this;\n }\n\n /**\n * Get the name of the player list for use in API calls.\n * E.g., 'minecraft:allowlist' or 'minecraft:ip_bans'.\n * @protected\n */\n protected abstract getName(): string;\n\n /**\n * Parse the result from the server.\n * @param result\n * @protected\n */\n protected abstract parseResult(result: unknown[]): ItemType[];\n}\n","export type ItemOrArray<T> = T | T[];\n\n/**\n * Parse an optional value. If the input is `undefined` or `null`, `undefined` is returned.\n * Otherwise, the input is parsed using the provided function.\n * @param parse\n * @param input\n * @internal\n */\nexport function optional<Input, Output>(\n parse: (input: Input) => Output,\n input: Input | undefined | null,\n): Output|undefined {\n if (input === undefined || input === null) {\n return undefined;\n }\n\n return parse(input);\n}\n\n/**\n * Ensure the input is an array. If the input is already an array, it is returned as-is.\n * @param item\n * @internal\n */\nexport function fromItemOrArray<T>(item: ItemOrArray<T>): T[] {\n if (Array.isArray(item)) {\n return item;\n }\n\n return [item];\n}\n","import Player, {PlayerInput} from \"../schemas/player/Player\";\nimport PlayerList from \"./PlayerList\";\nimport {fromItemOrArray, ItemOrArray} from \"../util\";\n\nexport default class AllowList extends PlayerList<Player> {\n /**\n * Overwrite the existing allowlist with a set of players.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names) or Player objects\n */\n async set(items: PlayerInput[]): Promise<this> {\n return this.callAndParse('set', [fromItemOrArray(items).map(Player.fromInput)]);\n }\n\n /**\n * Add players to the allowlist.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names) or Player objects\n */\n async add(items: ItemOrArray<PlayerInput>): Promise<this> {\n return this.callAndParse('add', [fromItemOrArray(items).map(Player.fromInput)]);\n }\n\n /**\n * Remove players from the allowlist.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names) or Player objects\n */\n async remove(items: ItemOrArray<PlayerInput>): Promise<this> {\n return this.callAndParse('remove', [fromItemOrArray(items).map(Player.fromInput)]);\n }\n\n protected getName(): string {\n return 'minecraft:allowlist';\n }\n\n protected parseResult(result: unknown[]): Player[] {\n return Player.parseList(result);\n }\n}\n","import IncorrectTypeError from \"../../../error/IncorrectTypeError\";\n\nexport type BanExpiryInput = Date | string | null;\n\n/**\n * Base class for all ban related classes.\n */\nexport default class Ban {\n /**\n * Reason for the ban.\n */\n reason: string | null;\n /**\n * Source of the ban (effectively a comment field).\n */\n source: string | null;\n /**\n * Expiration date of the ban in ISO 8601 format. If omitted, the ban is permanent.\n * Use {@link setExpires} to set this field using a Date or bigint.\n */\n expires: string | null = null;\n\n /**\n * @param reason reason for the ban\n * @param source source of the ban\n * @param expires expiration date of the ban as a Date or string in ISO 8601 format. If omitted, the ban is permanent.\n */\n constructor(\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ) {\n this.reason = reason;\n this.source = source;\n this.setExpires(expires);\n }\n\n /**\n * Sets the reason for the ban.\n * @param reason\n */\n setReason(reason: string | null = null): this {\n this.reason = reason;\n return this;\n }\n\n /**\n * Sets the source of the ban.\n * @param source\n */\n setSource(source: string | null = null): this {\n this.source = source;\n return this;\n }\n\n /**\n * Sets the expiration date of the ban.\n * @param expires The expiration date as a Date or string in ISO 8601 format.\n */\n setExpires(expires: BanExpiryInput): this {\n if (expires instanceof Date) {\n if (isNaN(expires.getTime())) {\n throw new Error(\"Invalid date.\");\n }\n\n expires = expires.toISOString();\n }\n\n if (typeof expires != \"string\" && expires !== null) {\n throw new Error(\"Expires must be a Date, string in ISO 8601 format or null.\");\n }\n\n this.expires = expires?.toString() ?? null;\n return this;\n }\n\n /**\n * Gets the expiration date of the ban as a Date object.\n * @returns The expiration date as a Date object, or null if the ban is permanent or the date is invalid.\n */\n getExpiresAsDate(): Date | null {\n if (!this.expires) {\n return null;\n }\n\n const date = new Date(this.expires);\n if (isNaN(date.getTime())) {\n return null;\n }\n\n return date;\n }\n\n /**\n * Parse and apply options from a raw response object.\n * @param data Raw object to parse.\n * @param path Path to the data in the original response, used for errors.\n * @param result The original response object, used for errors.\n * @returns The current UserBan instance.\n * @throws {IncorrectTypeError} If the data is not a valid options object.\n * @internal\n */\n parseAndApplyOptions(data: object, result: unknown, ...path: string[]): this {\n if (\"reason\" in data) {\n if (typeof data.reason !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.reason, result, ...path, 'reason');\n }\n this.reason = data.reason;\n }\n\n if (\"source\" in data) {\n if (typeof data.source !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.source, result, ...path, 'source');\n }\n this.source = data.source;\n }\n\n if (\"expires\" in data) {\n if (typeof data.expires !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.expires, result, ...path, 'expires');\n }\n this.expires = data.expires;\n }\n\n return this;\n }\n}\n\n","import Player from \"../Player\";\nimport Ban, {BanExpiryInput} from \"./Ban\";\n\n/**\n * A IncomingIPBan object or an IP address or a connected Player.\n */\nexport type IncomingIPBanInput = IncomingIPBan | string | Player;\n\n/**\n * Request to ban a player by their IP address.\n */\nexport default class IncomingIPBan extends Ban {\n /**\n * IP address to ban.\n */\n ip: string | null = null;\n /**\n * Connected player who should be banned by their IP address.\n */\n player: Player | null = null;\n\n /**\n * Creates a new IncomingIPBan instance with the specified IP address.\n * @param ip\n */\n static withIp(ip: string): IncomingIPBan {\n return new IncomingIPBan(ip);\n }\n\n /**\n * Creates a new IncomingIPBan instance for the specified player.\n * If the player is not currently connected to the server, they can't be banned by their IP address.\n * @param player\n */\n static withConnectedPlayer(player: Player): IncomingIPBan {\n return new IncomingIPBan(undefined, player);\n }\n\n /**\n * Creates a IncomingIPBan instance from a IPBanInput.\n * @param input\n * @param reason Default reason if input is not an IncomingIPBan\n * @param source Default source if input is not an IncomingIPBan\n * @param expires Default expiry if input is not an IncomingIPBan\n * @internal\n */\n static fromInput(\n input: IncomingIPBanInput,\n reason: string | null,\n source: string | null,\n expires: BanExpiryInput,\n ): IncomingIPBan {\n if (input instanceof IncomingIPBan) {\n return input;\n }\n\n return (typeof input === \"string\" ? IncomingIPBan.withIp(input) : IncomingIPBan.withConnectedPlayer(input))\n .setReason(reason)\n .setSource(source)\n .setExpires(expires);\n }\n\n /**\n * @param ip IP address to ban\n * @param player connected player who should be banned by their IP address\n * @param reason reason for the ban\n * @param source source of the ban\n * @param expires expiration date of the ban as a Date or string in ISO 8601 format. If omitted, the ban is permanent.\n * @internal Use {@link withIp} or {@link withConnectedPlayer} and setters instead.\n */\n constructor(\n ip: string | null = null,\n player: Player | null = null,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ) {\n super(reason, source, expires);\n this.ip = ip;\n this.player = player;\n }\n\n /**\n * Sets the IP address to ban.\n * @param ip\n */\n setIp(ip: string | null = null): this {\n this.ip = ip;\n return this;\n }\n\n /**\n * Sets the connected player who should be banned by their IP address.\n * @param player\n */\n setPlayer(player: Player | null = null): this {\n this.player = player;\n return this;\n }\n}\n","import IncorrectTypeError from \"../../../error/IncorrectTypeError\";\nimport MissingPropertyError from \"../../../error/MissingPropertyError\";\nimport Ban, {BanExpiryInput} from \"./Ban\";\n\nexport type IPBanInput = IPBan | string;\n\n/**\n * Entry on the IP ban list\n */\nexport default class IPBan extends Ban {\n /**\n * Banned ip address.\n */\n ip: string;\n\n /**\n * Creates a IPBan instance from a IPBanInput.\n * @param input\n * @param reason Default reason if input is not an IPBan\n * @param source Default source if input is not an IPBan\n * @param expires Default expiry if input is not an IPBan\n * @internal\n */\n static fromInput(\n input: IPBanInput,\n reason: string | null,\n source: string | null,\n expires: BanExpiryInput,\n ): IPBan {\n if (input instanceof IPBan) {\n return input;\n }\n\n return new IPBan(input, reason, source, expires);\n }\n\n /**\n * Parse an IPBan instance from a raw object.\n * @param data Raw object to parse.\n * @param response Full response received from the server, used for errors.\n * @param path Path to the data in the original response, used for errors.\n * @returns Parsed IPBan instance.\n * @throws {IncorrectTypeError} If the data is not a valid IPBan object.\n * @internal\n */\n static parse(data: unknown, response: unknown = data, ...path: string[]): IPBan {\n if (typeof data !== 'object' || data === null) {\n throw new IncorrectTypeError(\"object\", typeof data, response, ...path);\n }\n\n if (!(\"ip\" in data)) {\n throw new MissingPropertyError(\"ip\", response, ...path);\n }\n\n if (typeof data.ip !== 'string') {\n throw new IncorrectTypeError(\"string\", typeof data.ip, response, ...path, `ip`);\n }\n\n return new IPBan(data.ip).parseAndApplyOptions(data, response, ...path);\n }\n\n /**\n * @param ip banned IP address\n * @param reason reason for the ban\n * @param source source of the ban\n * @param expires expiration date of the ban as a Date or string in ISO 8601 format. If omitted, the ban is permanent.\n */\n constructor(\n ip: string,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ) {\n super(reason, source, expires);\n this.ip = ip;\n }\n\n /**\n * Sets the banned IP address.\n * @param ip\n */\n setIp(ip: string): this {\n this.ip = ip;\n return this;\n }\n}\n","import IncomingIPBan, {IncomingIPBanInput} from \"../schemas/player/ban/IncomingIPBan\";\nimport IPBan, {IPBanInput} from \"../schemas/player/ban/IPBan\";\nimport {fromItemOrArray, ItemOrArray} from \"../util\";\nimport PlayerList from \"./PlayerList\";\nimport {BanExpiryInput} from \"../schemas/player/ban/Ban\";\n\nexport default class IPBanList extends PlayerList<IPBan> {\n /**\n * Overwrite the existing list with a set of entries.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items\n * @param reason Default reason if input is not an IPBan\n * @param source Default source if input is not an IPBan\n * @param expires Default expiry if input is not an IPBan\n */\n public set(\n items: IPBanInput[],\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ): Promise<this> {\n return this.callAndParse('set', [\n items.map((input) => IPBan.fromInput(input, reason, source, expires))\n ]);\n }\n\n /**\n * Ban IP addresses.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of ip addresses as strings, IncomingIPBan objects or Player objects of connected players\n * @param reason Default reason if input is not an IncomingIPBan\n * @param source Default source if input is not an IncomingIPBan\n * @param expires Default expiry if input is not an IncomingIPBan\n */\n public add(\n items: ItemOrArray<IncomingIPBanInput>,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ): Promise<this> {\n return this.callAndParse('add', [fromItemOrArray(items).map(i => IncomingIPBan.fromInput(i, reason, source, expires))]);\n }\n\n /**\n * Unban IP addresses.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param ips list of IP addresses as strings\n */\n public remove(ips: ItemOrArray<string>): Promise<this> {\n return this.callAndParse('remove', [fromItemOrArray(ips)]);\n }\n\n protected getName(): string {\n return 'minecraft:ip_bans';\n }\n\n protected parseResult(result: unknown[]): IPBan[] {\n const bans: IPBan[] = [];\n for (const [index, entry] of result.entries()) {\n bans.push(IPBan.parse(entry, result, index.toString()))\n }\n return bans;\n }\n}\n","import Player, {PlayerInput} from \"../Player\";\nimport IncorrectTypeError from \"../../../error/IncorrectTypeError\";\nimport MissingPropertyError from \"../../../error/MissingPropertyError\";\nimport Ban, {BanExpiryInput} from \"./Ban\";\n\n/**\n * Input type for UserBan. Can be either a UserBan instance or a PlayerInput.\n */\nexport type UserBanInput = UserBan | PlayerInput;\n\nexport default class UserBan extends Ban {\n /**\n * Player who should be banned.\n */\n player: Player;\n\n /**\n * Creates a UserBan instance from a UserBanInput.\n * @param input\n * @param reason Default reason if input is not a UserBan\n * @param source Default source if input is not a UserBan\n * @param expires Default expiry if input is not a UserBan\n * @internal\n */\n static fromInput(\n input: UserBanInput,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ): UserBan {\n if (input instanceof UserBan) {\n return input;\n }\n\n return new UserBan(input, reason, source, expires);\n }\n\n /**\n * Parse an UserBan instance from a raw object.\n * @param data Raw object to parse.\n * @param response Full response received from the server, used for errors.\n * @param path Path to the data in the original response, used for errors.\n * @returns Parsed UserBan instance.\n * @throws {IncorrectTypeError} If the data is not a valid UserBan object.\n * @internal\n */\n static parse(data: unknown, response: unknown = data, ...path: string[]): UserBan {\n if (typeof data !== 'object' || data === null) {\n throw new IncorrectTypeError(\"object\", typeof data, response, ...path);\n }\n\n if (!(\"player\" in data)) {\n throw new MissingPropertyError(\"player\", response, ...path);\n }\n\n const ban = new UserBan(Player.parse(data.player, response, ...path, \"player\"));\n return ban.parseAndApplyOptions(data, response, ...path);\n }\n\n /**\n * @param player the player to ban\n * @param reason reason for the ban\n * @param source source of the ban\n * @param expires expiration date of the ban as a Date or string in ISO 8601 format. If omitted, the ban is permanent.\n */\n constructor(\n player: PlayerInput,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ) {\n super(reason, source, expires);\n this.player = Player.fromInput(player);\n }\n\n /**\n * Sets the player to ban.\n * @param player\n */\n setPlayer(player: Player): this {\n this.player = player;\n return this;\n }\n}\n","import Player, {PlayerInput} from \"../schemas/player/Player\";\nimport UserBan, {UserBanInput} from \"../schemas/player/ban/UserBan\";\nimport {fromItemOrArray, ItemOrArray} from \"../util\";\nimport PlayerList from \"./PlayerList\";\nimport {BanExpiryInput} from \"../schemas/player/ban/Ban\";\n\nexport default class BanList extends PlayerList<UserBan> {\n /**\n * Overwrite the existing list with a set of entries.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names), Player objects or UserBan objects\n * @param reason Default reason if input is not a UserBan\n * @param source Default source if input is not a UserBan\n * @param expires Default expiry if input is not a UserBan\n */\n public set(\n items: UserBanInput[],\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ): Promise<this> {\n return this.callAndParse('set', [this.fromInputs(items, reason, source, expires)]);\n }\n\n /**\n * Add items to the list.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names), Player objects or UserBan objects\n * @param reason Default reason if input is not a UserBan\n * @param source Default source if input is not a UserBan\n * @param expires Default expiry if input is not a UserBan\n */\n public add(\n items: ItemOrArray<UserBanInput>,\n reason: string | null = null,\n source: string | null = null,\n expires: BanExpiryInput = null,\n ): Promise<this> {\n return this.callAndParse('add', [this.fromInputs(items, reason, source, expires)]);\n }\n\n /**\n * Remove items from the list.\n * This method updates the cached with the resulting list from the server. Use `get()` to retrieve it.\n * @param items list of strings (player names) or Player objects\n */\n public remove(items: ItemOrArray<PlayerInput>): Promise<this> {\n return this.callAndParse('remove', [fromItemOrArray(items).map(Player.fromInput)]);\n }\n\n protected getName(): string {\n return 'minecraft:bans';\n }\n\n protected parseResult(result: unknown[]): UserBan[] {\n const bans: UserBan[] = [];\n for (const [index, entry] of result.entries()) {\n bans.push(UserBan.parse(entry, result, index.toString()));\n }\n return bans;\n }\n\n /**\n * Convert input list or item to UserBan instances.\n * @param inputs input list or item\n * @param reason Default reason if input is not a UserBan\n * @param source Default source if input is not a UserBan\n * @param expires Default expiry if input is not a UserBan\n * @protected\n */\n protected fromInputs(\n inputs: ItemOrArray<UserBanInput>,\n reason: string | null,\n source: string | null,\n expires: BanExpiryInput,\n ): UserBan[] {\n return fromItemOrArray(inputs).map((input) => UserBan.fromInput(input, reason, source, expires));\n }\n}\n","import Player from \"./Player\";\nimport Message from \"../message/Message\";\n\n/**\n * Request to kick a player\n */\nexport default class KickPlayer {\n /**\n * Players to kick.\n */\n player: Player;\n /**\n * Message displayed to the player when they are kicked.\n */\n message?: Message;\n\n /**\n * @param player players to kick\n * @param message message displayed to the player when they are kicked\n */\n constructor(player: Player, message?: Message) {\n this.player = player;\n this.message = message;\n }\n}\n","import IncorrectTypeError from \"../../error/IncorrectTypeError\";\nimport MissingPropertyError from \"../../error/MissingPropertyError\";\nimport Player, {PlayerInput} from \"./Player\";\n\n/**\n * Input type for Operator. Can be either an Operator instance or a PlayerInput.\n */\nexport type OperatorInput = Operator | PlayerInpu