import type PWApiClient from "../api/PWApiClient.js"; import type { GameClientSettings, WorldJoinData, Hook, ISendablePacket, Sendable } from "../types/game.js"; import type { CustomBotEvents, MergedEvents, WorldEvents } from "../types/events.js"; import Queue from "../util/Queue.js"; import type { CleanProtoMessage, Promisable } from "../types/misc.js"; type SafeCheck> = State extends CustomBotEvents ? never : State[K]; export default class PWGameClient = {}> { settings: GameClientSettings; api?: PWApiClient; socket?: WebSocket; private prevWorldId?; protected totalBucket: Queue; protected chatBucket: Queue; protected connectAttempts: { time: number; count: number; }; /** * NOTE: After constructing, you must then run .init() to connect the API IF you're using email/password. */ constructor(api: PWApiClient, settings?: Partial); constructor(settings?: Partial); get connected(): boolean; /** * This will connect to the world. * * (This returns itself for chaining) */ joinWorld(roomId: string, joinData?: WorldJoinData): Promise; /** * INTERNAL */ private createSocket; /** * This is a more direct route if you already have a join key acquired via Pixelwalker's API. * * Useful for those wary of security. */ static joinWorld(joinKey: string, obj?: { joinData?: WorldJoinData; gameSettings?: Partial; }, EndpointURL?: string): Promise; /** * For faster performance (even if it seems insignificant), * direct functions are used instead of events which are also inconsistent with browsers/nodejs etc. * * NOTE: the "this" won't be the client itself. You will need to bind yourself if you want to keep this. */ protected callbacks: Partial<{ [K in keyof MergedEvents]: Array<(data: MergedEvents[K], states?: SafeCheck) => Promisable>; }>; /** * Poorly documented because I cba */ private hooks; /** * This is different to addCallback as all hooks (regardless of the type) will execute first before the callbacks, each hook may modify something or do something in the background * and may pass it to callbacks (via the second parameter in callbacks). If an error occurs while executing one of the hooks, * the hooks after that and the callbacks will not run. * * NOTE: This is permanent, if a hook is added, it can't be removed. */ addHook, keyof WorldEvents>>(hook: Hook): PWGameClient; /** * Adds listeners to the end of the chain for that event type, it can even be a promise too. * * If the callback returns a specific string "STOP", it will prevent further listeners from being invoked. */ addCallback(type: Event, ...cbs: Array<(data: MergedEvents[Event]) => Promisable>): this; addCallback(type: Event, ...cbs: Array<(data: MergedEvents[Event], states?: SafeCheck) => Promisable>): this; /** * Inserts listeners at the start of the chain for that event type, it can even be a promise too. * * If the callback returns a specific string "STOP", it will prevent further listeners from being invoked. */ prependCallback(type: Event, ...cbs: Array<(data: MergedEvents[Event]) => Promisable>): this; prependCallback(type: Event, ...cbs: Array<(data: MergedEvents[Event], states?: SafeCheck) => Promisable>): this; /** * @param type The type of the event * @param cb It can be the function itself (to remove that specific function). If undefined, it will remove ALL functions from that list, it will return undefined. */ removeCallback(type: Event, cb?: (data: MergedEvents[Event], states: SafeCheck) => Promisable): undefined | ((data: MergedEvents[Event], states: SafeCheck) => Promisable); /** * INTERNAL. Invokes all functions of a callback type, unless one of them prohibits in transit. */ protected invoke(type: Event, data: MergedEvents[Event]): Promise<{ count: number; stopped: boolean; }>; protected invoke(type: Event, data: MergedEvents[Event], states: SafeCheck): Promise<{ count: number; stopped: boolean; }>; /** * Sends a packet to the game server. * * @param type Type of the packet. * @param value Value of the packet to send along with, note that some properties are optional. * @param direct If it should skip queue. */ send(type: Event, value?: CleanProtoMessage>, direct?: boolean): void; /** * Difference between this and send is that you can include the packet type in sendRange * for each argument. This means you can pass in list of block and label packets for example. */ sendRange(...packets: ISendablePacket[]): void; /** * By default this will set the game client settings reconnectable to false. * * If reconnect is true, an additionl parameter can be passed which is the amount of time to wait before it attempts to reconnect (DEFAULT: none) */ disconnect(reconnect?: number | boolean): boolean; } export {};