@shaunlwm/pickle.ts 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -10
- package/dist/index.d.ts +550 -69
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection-profile.ts","../src/adapters/base-adapter.ts","../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/cplegacy-adapter.ts","../src/adapters/cpzero-adapter.ts","../src/adapters/newcp-adapter.ts","../src/adapters/penguinorigins-adapter.ts","../src/adapters/index.ts","../src/games/card-jitsu.ts"],"sourcesContent":["export type ConnectionProfilePreset = \"chrome\" | \"node\";\n\nexport type HeaderValue = string | number | boolean | null | undefined;\n\nexport type HeaderBag = Record<string, HeaderValue>;\n\nexport type ConnectionProfile = {\n preset?: ConnectionProfilePreset;\n userAgent?: string;\n acceptLanguage?: string;\n origin?: string;\n referer?: string;\n headers?: HeaderBag;\n};\n\nexport type ConnectionProfileInput =\n | ConnectionProfilePreset\n | ConnectionProfile;\n\nexport type NormalizedConnectionProfile = {\n preset: ConnectionProfilePreset;\n userAgent?: string;\n acceptLanguage?: string;\n origin?: string;\n referer?: string;\n headers: HeaderBag;\n};\n\nconst CHROME_USER_AGENT =\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36\";\n\nconst CHROME_ACCEPT_LANGUAGE = \"en-US,en;q=0.9\";\n\nconst RESTRICTED_HEADERS = new Set([\n \"connection\",\n \"content-length\",\n \"host\",\n \"transfer-encoding\",\n \"upgrade\",\n]);\n\nexport function resolveConnectionProfile(\n input: ConnectionProfileInput = \"chrome\",\n): NormalizedConnectionProfile {\n if (typeof input === \"string\") {\n return { preset: input, headers: {} };\n }\n\n const preset = input.preset ?? \"chrome\";\n\n return {\n preset,\n userAgent: input.userAgent,\n acceptLanguage: input.acceptLanguage,\n origin: input.origin,\n referer: input.referer,\n headers: input.headers ?? {},\n };\n}\n\nexport function defaultOriginForUrl(urlOrOrigin: string): string {\n const input = urlOrOrigin.match(/^[a-z][a-z0-9+.-]*:\\/\\//i)\n ? urlOrOrigin\n : `https://${urlOrOrigin}`;\n\n try {\n const url = new URL(input);\n const protocol =\n url.protocol === \"wss:\"\n ? \"https:\"\n : url.protocol === \"ws:\"\n ? \"http:\"\n : url.protocol;\n\n return `${protocol}//${url.host}`;\n } catch {\n return urlOrOrigin.replace(/\\/+$/, \"\");\n }\n}\n\nexport function resolveConnectionOrigin(\n profile: NormalizedConnectionProfile,\n defaultUrlOrOrigin: string,\n): string | undefined {\n if (profile.origin) return profile.origin;\n if (profile.preset === \"node\") return undefined;\n return defaultOriginForUrl(defaultUrlOrOrigin);\n}\n\nexport function buildConnectionHeaders(\n profile: NormalizedConnectionProfile,\n options: {\n defaultOrigin: string;\n headers?: HeaderBag;\n },\n): Record<string, string> {\n const headers: HeaderBag = {};\n const origin = resolveConnectionOrigin(profile, options.defaultOrigin);\n const referer =\n profile.referer ??\n (profile.preset === \"node\" || !origin ? undefined : `${origin}/`);\n\n if (profile.preset !== \"node\") {\n headers[\"User-Agent\"] = profile.userAgent ?? CHROME_USER_AGENT;\n headers[\"Accept-Language\"] =\n profile.acceptLanguage ?? CHROME_ACCEPT_LANGUAGE;\n }\n\n if (origin) headers.Origin = origin;\n if (referer) headers.Referer = referer;\n\n return sanitizeHeaders({\n ...headers,\n ...profile.headers,\n ...options.headers,\n });\n}\n\nexport function sanitizeHeaders(headers: HeaderBag): Record<string, string> {\n const sanitized: Record<string, string> = {};\n\n for (const [name, value] of Object.entries(headers)) {\n if (value === null || value === undefined) continue;\n if (isRestrictedHeader(name)) continue;\n sanitized[name] = String(value);\n }\n\n return sanitized;\n}\n\nfunction isRestrictedHeader(name: string): boolean {\n const normalized = name.toLowerCase();\n return (\n RESTRICTED_HEADERS.has(normalized) ||\n normalized.startsWith(\"sec-websocket-\")\n );\n}\n","import type { ManagerOptions, Socket, SocketOptions } from \"socket.io-client\";\nimport {\n buildConnectionHeaders,\n type HeaderBag,\n type NormalizedConnectionProfile,\n resolveConnectionOrigin,\n resolveConnectionProfile,\n} from \"../connection-profile.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type {\n PlayerAppearance,\n PlayerData,\n RoomUser,\n} from \"../types/player-types.js\";\n\ntype SocketIoConnectionOptions = Partial<ManagerOptions & SocketOptions> & {\n extraHeaders?: Record<string, string>;\n origin?: string;\n};\n\nexport type ConnectOptions = {\n onQueueUpdate?: (update: QueueUpdate) => void;\n};\n\nexport abstract class BaseAdapter {\n abstract readonly id: string;\n protected socket: Socket | null = null;\n loginMessage: string | null = null;\n loginStatus: \"active\" | \"banned\" = \"active\";\n\n constructor(\n protected readonly connectionProfile: NormalizedConnectionProfile = resolveConnectionProfile(),\n ) {}\n\n abstract login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<LoginResult>;\n abstract connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket>;\n abstract disconnect(): void;\n abstract send(action: string, args: Record<string, unknown>): void;\n\n protected socketIoOptions(\n defaultUrlOrOrigin: string,\n ): SocketIoConnectionOptions {\n const headers = this.connectionHeaders(defaultUrlOrOrigin);\n const origin = this.connectionOrigin(defaultUrlOrOrigin);\n const options: SocketIoConnectionOptions = {};\n\n if (Object.keys(headers).length > 0) options.extraHeaders = headers;\n if (origin) options.origin = origin;\n if (this.connectionProfile.preset !== \"node\" || origin) {\n options.withCredentials = true;\n }\n\n return options;\n }\n\n protected webSocketOptions(defaultUrlOrOrigin: string): {\n headers?: Record<string, string>;\n origin?: string;\n } {\n const headers = this.connectionHeaders(defaultUrlOrOrigin);\n const origin = this.connectionOrigin(defaultUrlOrOrigin);\n return {\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(origin ? { origin } : {}),\n };\n }\n\n protected connectionHeaders(\n defaultUrlOrOrigin: string,\n headers?: HeaderBag,\n ): Record<string, string> {\n return buildConnectionHeaders(this.connectionProfile, {\n defaultOrigin: defaultUrlOrOrigin,\n headers,\n });\n }\n\n protected connectionOrigin(defaultUrlOrOrigin: string): string | undefined {\n return resolveConnectionOrigin(this.connectionProfile, defaultUrlOrOrigin);\n }\n\n normalizeUser(_raw: Record<string, unknown>): RoomUser {\n throw new Error(\"Not implemented: normalizeUser\");\n }\n\n normalizePlayer(_raw: Record<string, unknown>): PlayerData {\n throw new Error(\"Not implemented: normalizePlayer\");\n }\n\n protected extractAppearance(raw: Record<string, unknown>): PlayerAppearance {\n return {\n color: (raw.color as number) ?? 0,\n head: (raw.head as number) ?? 0,\n face: (raw.face as number) ?? 0,\n neck: (raw.neck as number) ?? 0,\n body: (raw.body as number) ?? 0,\n hand: (raw.hand as number) ?? 0,\n feet: (raw.feet as number) ?? 0,\n flag: (raw.flag as number) ?? 0,\n photo: (raw.photo as number) ?? 0,\n };\n }\n\n sendMessage(_message: string): void {\n throw new Error(\"Not implemented: sendMessage\");\n }\n\n sendEmote(_emote: number): void {\n throw new Error(\"Not implemented: sendEmote\");\n }\n\n sendSafe(_safe: number): void {\n throw new Error(\"Not implemented: sendSafe\");\n }\n\n walk(_x: number, _y: number): void {\n throw new Error(\"Not implemented: walk\");\n }\n\n sendFrame(_frame: number, _set?: boolean): void {\n throw new Error(\"Not implemented: sendFrame\");\n }\n\n snowball(_x: number, _y: number): void {\n throw new Error(\"Not implemented: snowball\");\n }\n\n joinRoom(_room: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinRoom\");\n }\n\n addItem(_item: number): void {\n throw new Error(\"Not implemented: addItem\");\n }\n\n equipColor(_item: number): void {\n throw new Error(\"Not implemented: equipColor\");\n }\n\n equipHead(_item: number): void {\n throw new Error(\"Not implemented: equipHead\");\n }\n\n equipFace(_item: number): void {\n throw new Error(\"Not implemented: equipFace\");\n }\n\n equipNeck(_item: number): void {\n throw new Error(\"Not implemented: equipNeck\");\n }\n\n equipBody(_item: number): void {\n throw new Error(\"Not implemented: equipBody\");\n }\n\n equipHand(_item: number): void {\n throw new Error(\"Not implemented: equipHand\");\n }\n\n equipFeet(_item: number): void {\n throw new Error(\"Not implemented: equipFeet\");\n }\n\n equipFlag(_item: number): void {\n throw new Error(\"Not implemented: equipFlag\");\n }\n\n equipPhoto(_item: number): void {\n throw new Error(\"Not implemented: equipPhoto\");\n }\n\n buddyRequest(_id: number): void {\n throw new Error(\"Not implemented: buddyRequest\");\n }\n\n buddyAccept(_id: number): void {\n throw new Error(\"Not implemented: buddyAccept\");\n }\n\n buddyReject(_id: number): void {\n throw new Error(\"Not implemented: buddyReject\");\n }\n\n buddyRequestSeen(_id: number): void {\n throw new Error(\"Not implemented: buddyRequestSeen\");\n }\n\n getBuddy(_id: number, _type: \"buddies\" | \"buddyRequests\"): void {\n throw new Error(\"Not implemented: getBuddy\");\n }\n\n removeBuddy(_id: number): void {\n throw new Error(\"Not implemented: removeBuddy\");\n }\n\n addIgnore(_id: number): void {\n throw new Error(\"Not implemented: addIgnore\");\n }\n\n removeIgnore(_id: number): void {\n throw new Error(\"Not implemented: removeIgnore\");\n }\n\n getPlayer(_id: number): void {\n throw new Error(\"Not implemented: getPlayer\");\n }\n\n getAllSlots(): void {\n throw new Error(\"Not implemented: getAllSlots\");\n }\n\n getMascots(): void {\n throw new Error(\"Not implemented: getMascots\");\n }\n\n sendPostcard(_userId: number, _cardId: string): void {\n throw new Error(\"Not implemented: sendPostcard\");\n }\n\n getStamps(_userId: number): void {\n throw new Error(\"Not implemented: getStamps\");\n }\n\n getPostcards(): void {\n throw new Error(\"Not implemented: getPostcards\");\n }\n\n getIglooOpen(_igloo: number): void {\n throw new Error(\"Not implemented: getIglooOpen\");\n }\n\n getIgloos(): void {\n throw new Error(\"Not implemented: getIgloos\");\n }\n\n getPuffles(_userId: number): void {\n throw new Error(\"Not implemented: getPuffles\");\n }\n\n adoptPuffle(_type: number, _name: string): void {\n throw new Error(\"Not implemented: adoptPuffle\");\n }\n\n getIglooLikes(): void {\n throw new Error(\"Not implemented: getIglooLikes\");\n }\n\n checkPuffleSprite(_puffleSprite: boolean): void {\n throw new Error(\"Not implemented: checkPuffleSprite\");\n }\n\n joinIgloo(_igloo: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinIgloo\");\n }\n\n gameOver(_coins: number): void {\n throw new Error(\"Not implemented: gameOver\");\n }\n\n collectStamp(_stamp: number): void {\n throw new Error(\"Not implemented: collectStamp\");\n }\n\n /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */\n getNinja(): void {\n throw new Error(\"Not implemented: getNinja\");\n }\n\n /** Fetch state of all Dojo mats. Listen for `get_waddles` event. */\n getMats(): void {\n throw new Error(\"Not implemented: getMats\");\n }\n\n /** Join Sensei matchmaking queue. Listen for `tick_matchmaking` events. */\n joinMatchmaking(): void {\n throw new Error(\"Not implemented: joinMatchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n throw new Error(\"Not implemented: leaveMatchmaking\");\n }\n\n /** Start a Card-Jitsu match after entering a game room. Listen for `start_game` event. */\n startGame(): void {\n throw new Error(\"Not implemented: startGame\");\n }\n\n /** Play a card from your hand by slot index. Listen for `move_my_card` event. */\n selectCard(_slot: number): void {\n throw new Error(\"Not implemented: selectCard\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(_animation: string): void {\n throw new Error(\"Not implemented: loadAnimation\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(_waddle: number): void {\n throw new Error(\"Not implemented: joinMat\");\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport type { BaseAdapter, ConnectOptions } from \"./adapters/base-adapter.js\";\nimport { type AdapterName, createAdapter } from \"./adapters/index.js\";\nimport type { ConnectionProfileInput } from \"./connection-profile.js\";\nimport { CardJitsu } from \"./games/card-jitsu.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"./types/adapter-types.js\";\nimport type { ServerMessages } from \"./types/message-types.js\";\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\";\n\n/** Actions with explicit switch-case handling or typed in ServerMessages — not truly unknown. */\nconst KNOWN_ACTIONS = new Set<string>([\n // Handled in switch\n \"load_player\",\n \"join_room\",\n \"add_player\",\n \"remove_player\",\n \"send_position\",\n \"send_frame\",\n \"update_player\",\n \"kick\",\n \"close_with_error\",\n // Typed passthrough (emitted as-is, no state updates needed)\n \"send_message\",\n \"send_emote\",\n \"cpj_ping\",\n \"open_sprite\",\n \"close_sprite\",\n \"set_weather\",\n \"server_error\",\n \"error\",\n \"stamp_earned\",\n \"game_over\",\n \"join_game_room\",\n \"get_ninja\",\n \"get_waddles\",\n \"update_waddle\",\n \"join_matchmaking\",\n \"tick_matchmaking\",\n \"start_game\",\n \"set_cards\",\n \"add_enemy_cards\",\n \"start_round\",\n \"enable_cards\",\n \"remove_card\",\n \"move_my_card\",\n \"card_effect\",\n \"round_over\",\n \"play_animation\",\n \"game_won\",\n \"get_player\",\n \"buddy_request\",\n \"buddy_accept\",\n \"buddy_reject\",\n \"buddy_request_seen\",\n \"get_buddy\",\n \"send_postcard\",\n \"stamps_result\",\n \"ignore_add\",\n \"ignore_remove\",\n \"add_item\",\n \"get_postcards\",\n \"get_igloo_open\",\n \"get_igloos\",\n \"get_igloo_likes\",\n \"join_igloo\",\n \"get_puffles\",\n \"get_mascots\",\n \"wait_queue_update\",\n \"slot\",\n \"snowball\",\n \"send_safe\",\n \"stop_walking\",\n \"update_table\",\n \"transform_player\",\n \"adopt_puffle\",\n \"info\",\n \"queue_server_join\",\n \"disconnect\",\n \"unknown_packet\",\n]);\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (\n args: ServerMessages[K],\n) => void;\n\nexport type LogFn = (message: string, ...args: unknown[]) => void;\n\nexport type ClientOptions = {\n debug?: boolean | LogFn;\n connectionProfile?: ConnectionProfileInput;\n};\n\ntype MessagePayload = {\n action: string;\n args: Record<string, unknown>;\n};\n\nfunction isMessagePayload(msg: unknown): msg is MessagePayload {\n return (\n typeof msg === \"object\" && msg !== null && \"action\" in msg && \"args\" in msg\n );\n}\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null;\n room: number | null = null;\n users: Map<number, RoomUser> = new Map();\n connected = false;\n\n private adapter: BaseAdapter;\n private loginResult: LoginResult | null = null;\n private log: LogFn | null = null;\n private _cardJitsu: CardJitsu | null = null;\n\n get loginMessage(): string | null {\n return this.adapter.loginMessage;\n }\n\n get loginStatus(): \"active\" | \"banned\" {\n return this.adapter.loginStatus;\n }\n\n get cardJitsu(): CardJitsu {\n if (!this._cardJitsu)\n this._cardJitsu = new CardJitsu(this.adapter, this.waitFor.bind(this));\n return this._cardJitsu;\n }\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super();\n this.adapter = createAdapter(server, options?.connectionProfile);\n\n if (options?.debug) {\n this.log =\n typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console);\n }\n }\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username);\n this.loginResult = await this.adapter.login(options);\n this.log?.(\"[login] success —\", this.loginResult.servers.length, \"servers\");\n return this.loginResult.servers;\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\");\n\n this.log?.(\"[connect] joining\", serverName);\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`);\n this.emit(\"wait_queue_update\", update);\n options?.onQueueUpdate?.(update);\n },\n };\n\n const socket = await this.adapter.connect(\n serverName,\n this.loginResult,\n connectOptions,\n );\n\n socket.on(\"message\", (msg: unknown) => {\n if (!isMessagePayload(msg)) return;\n this.handleMessage(msg);\n });\n\n socket.on(\"disconnect\", () => {\n this.log?.(\"[disconnect] connection lost\");\n this.cleanup();\n this.emit(\"disconnect\");\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Waiting for load_player timed out\"));\n }, 10_000);\n\n let playerLoaded = false;\n let roomJoined = false;\n\n const checkReady = (): void => {\n if (playerLoaded && roomJoined) {\n clearTimeout(timeout);\n this.connected = true;\n resolve();\n }\n };\n\n const onMessage = (msg: unknown): void => {\n if (!isMessagePayload(msg)) return;\n switch (msg.action) {\n case \"load_player\":\n playerLoaded = true;\n checkReady();\n break;\n case \"join_room\":\n roomJoined = true;\n checkReady();\n break;\n case \"kick\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { reason?: string }).reason ?? \"unknown\"}`,\n ),\n );\n break;\n case \"close_with_error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { error?: string }).error ?? \"unknown\"}`,\n ),\n );\n break;\n case \"error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Server error: ${(msg.args as { error?: string | number }).error ?? \"unknown\"}`,\n ),\n );\n break;\n }\n };\n\n const onDisconnect = (): void => {\n if (!playerLoaded || !roomJoined) {\n clearTimeout(timeout);\n reject(new Error(\"Disconnected before fully loaded\"));\n }\n };\n\n socket.on(\"message\", onMessage);\n socket.once(\"disconnect\", onDisconnect);\n });\n }\n\n on<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n on(event: string, listener: (...args: unknown[]) => void): this;\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n off(event: string, listener: (...args: unknown[]) => void): this;\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n once(event: string, listener: (...args: unknown[]) => void): this;\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener);\n }\n\n emit<K extends keyof ServerMessages>(\n event: K,\n args: ServerMessages[K],\n ): boolean;\n emit(event: string, ...args: unknown[]): boolean;\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args);\n }\n\n /** Wait for a server event. Resolves with the event payload. Optional timeout in ms. Rejects on disconnect. */\n waitFor<K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n ): Promise<ServerMessages[K]> {\n return new Promise<ServerMessages[K]>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const cleanup = (): void => {\n if (timer) clearTimeout(timer);\n this.off(event, handler as unknown as (...args: unknown[]) => void);\n this.off(\"disconnect\", onDisconnect);\n };\n\n const handler = ((args: ServerMessages[K]) => {\n cleanup();\n resolve(args);\n }) as ServerMessageHandler<K>;\n\n const onDisconnect = (): void => {\n cleanup();\n reject(new Error(`Disconnected while waiting for ${String(event)}`));\n };\n\n if (timeout !== undefined) {\n timer = setTimeout(() => {\n cleanup();\n reject(new Error(`Timed out waiting for ${String(event)}`));\n }, timeout);\n }\n\n this.once(event, handler);\n this.once(\"disconnect\", onDisconnect);\n });\n }\n\n sendMessage(message: string): void {\n this.adapter.sendMessage(message);\n }\n sendEmote(emote: number): void {\n this.adapter.sendEmote(emote);\n }\n sendSafe(safe: number): void {\n this.adapter.sendSafe(safe);\n }\n walk(x: number, y: number): void {\n this.adapter.walk(x, y);\n }\n sendFrame(frame: number, set?: boolean): void {\n this.adapter.sendFrame(frame, set);\n }\n snowball(x: number, y: number): void {\n this.adapter.snowball(x, y);\n }\n joinRoom(\n room: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_room\"]> {\n this.adapter.joinRoom(room, x, y);\n return this.waitFor(\"join_room\");\n }\n addItem(item: number): Promise<ServerMessages[\"add_item\"]> {\n this.adapter.addItem(item);\n return this.waitFor(\"add_item\");\n }\n equipColor(item: number): void {\n this.adapter.equipColor(item);\n }\n equipHead(item: number): void {\n this.adapter.equipHead(item);\n }\n equipFace(item: number): void {\n this.adapter.equipFace(item);\n }\n equipNeck(item: number): void {\n this.adapter.equipNeck(item);\n }\n equipBody(item: number): void {\n this.adapter.equipBody(item);\n }\n equipHand(item: number): void {\n this.adapter.equipHand(item);\n }\n equipFeet(item: number): void {\n this.adapter.equipFeet(item);\n }\n equipFlag(item: number): void {\n this.adapter.equipFlag(item);\n }\n equipPhoto(item: number): void {\n this.adapter.equipPhoto(item);\n }\n buddyRequest(id: number): void {\n this.adapter.buddyRequest(id);\n }\n buddyAccept(id: number): Promise<ServerMessages[\"buddy_accept\"]> {\n this.adapter.buddyAccept(id);\n return this.waitFor(\"buddy_accept\");\n }\n buddyReject(id: number): Promise<ServerMessages[\"buddy_reject\"]> {\n this.adapter.buddyReject(id);\n return this.waitFor(\"buddy_reject\");\n }\n buddyRequestSeen(id: number): Promise<ServerMessages[\"buddy_request_seen\"]> {\n this.adapter.buddyRequestSeen(id);\n return this.waitFor(\"buddy_request_seen\");\n }\n getBuddy(\n id: number,\n type: \"buddies\" | \"buddyRequests\",\n ): Promise<ServerMessages[\"get_buddy\"]> {\n this.adapter.getBuddy(id, type);\n return this.waitFor(\"get_buddy\");\n }\n removeBuddy(id: number): void {\n this.adapter.removeBuddy(id);\n }\n addIgnore(id: number): Promise<ServerMessages[\"ignore_add\"]> {\n this.adapter.addIgnore(id);\n return this.waitFor(\"ignore_add\");\n }\n removeIgnore(id: number): Promise<ServerMessages[\"ignore_remove\"]> {\n this.adapter.removeIgnore(id);\n return this.waitFor(\"ignore_remove\");\n }\n getPlayer(id: number): Promise<ServerMessages[\"get_player\"]> {\n this.adapter.getPlayer(id);\n return this.waitFor(\"get_player\");\n }\n getAllSlots(): Promise<ServerMessages[\"slot\"]> {\n this.adapter.getAllSlots();\n return this.waitFor(\"slot\");\n }\n getMascots(): Promise<ServerMessages[\"get_mascots\"]> {\n this.adapter.getMascots();\n return this.waitFor(\"get_mascots\");\n }\n sendPostcard(\n userId: number,\n cardId: string,\n ): Promise<ServerMessages[\"send_postcard\"]> {\n this.adapter.sendPostcard(userId, cardId);\n return this.waitFor(\"send_postcard\");\n }\n getStamps(userId: number): Promise<ServerMessages[\"stamps_result\"]> {\n this.adapter.getStamps(userId);\n return this.waitFor(\"stamps_result\");\n }\n getPostcards(): Promise<ServerMessages[\"get_postcards\"]> {\n this.adapter.getPostcards();\n return this.waitFor(\"get_postcards\");\n }\n getIglooOpen(igloo: number): Promise<ServerMessages[\"get_igloo_open\"]> {\n this.adapter.getIglooOpen(igloo);\n return this.waitFor(\"get_igloo_open\");\n }\n getIgloos(): Promise<ServerMessages[\"get_igloos\"]> {\n this.adapter.getIgloos();\n return this.waitFor(\"get_igloos\");\n }\n getPuffles(userId: number): Promise<ServerMessages[\"get_puffles\"]> {\n this.adapter.getPuffles(userId);\n return this.waitFor(\"get_puffles\");\n }\n adoptPuffle(\n type: number,\n name: string,\n ): Promise<ServerMessages[\"adopt_puffle\"]> {\n this.adapter.adoptPuffle(type, name);\n return this.waitFor(\"adopt_puffle\");\n }\n getIglooLikes(): Promise<ServerMessages[\"get_igloo_likes\"]> {\n this.adapter.getIglooLikes();\n return this.waitFor(\"get_igloo_likes\");\n }\n checkPuffleSprite(puffleSprite: boolean): void {\n this.adapter.checkPuffleSprite(puffleSprite);\n }\n joinIgloo(\n igloo: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_igloo\"]> {\n this.adapter.joinIgloo(igloo, x, y);\n return this.waitFor(\"join_igloo\");\n }\n gameOver(coins: number): Promise<ServerMessages[\"game_over\"]> {\n this.adapter.gameOver(coins);\n return this.waitFor(\"game_over\");\n }\n collectStamp(stamp: number): Promise<ServerMessages[\"stamp_earned\"]> {\n this.adapter.collectStamp(stamp);\n return this.waitFor(\"stamp_earned\");\n }\n\n sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\");\n this.adapter.disconnect();\n this.cleanup();\n }\n\n private cleanup(): void {\n this.connected = false;\n this.player = null;\n this.room = null;\n this.users.clear();\n }\n\n private handleMessage(msg: MessagePayload): void {\n const { action, args } = msg;\n let emitArgs: unknown = args;\n\n switch (action) {\n case \"load_player\": {\n const player = this.adapter.normalizePlayer(args);\n this.player = player;\n emitArgs = { user: player };\n this.log?.(\n \"[load_player]\",\n player.username,\n `id=${player.id}`,\n `coins=${player.coins}`,\n `inventory=${player.inventory.length}`,\n );\n break;\n }\n case \"join_room\": {\n const room = args.room as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = room;\n this.users.clear();\n const users: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n users.push(user);\n }\n emitArgs = { room, users };\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`);\n break;\n }\n case \"add_player\": {\n const user = this.adapter.normalizeUser(\n args.user as Record<string, unknown>,\n );\n this.users.set(user.id, user);\n emitArgs = { user };\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`);\n break;\n }\n case \"remove_player\": {\n const id = args.user as number;\n this.users.delete(id);\n this.log?.(\"[remove_player]\", `id=${id}`);\n break;\n }\n case \"send_position\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.x = args.x as number;\n user.y = args.y as number;\n }\n break;\n }\n case \"send_frame\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.frame = args.frame as number;\n }\n break;\n }\n case \"join_igloo\": {\n const igloo = args.igloo as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = igloo;\n this.users.clear();\n const iglooUsers: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n iglooUsers.push(user);\n }\n emitArgs = { ...args, users: iglooUsers };\n this.log?.(\n \"[join_igloo]\",\n `igloo=${igloo}`,\n `users=${iglooUsers.length}`,\n );\n break;\n }\n case \"update_player\": {\n const id = args.id as number;\n const slot = args.slot as string;\n const item = args.item as number;\n const user = this.users.get(id);\n if (user && slot in user) {\n (user as Record<string, unknown>)[slot] = item;\n }\n break;\n }\n case \"kick\": {\n const reason = (args as { reason?: string }).reason ?? \"unknown\";\n this.log?.(\"[kick]\", reason);\n this.cleanup();\n break;\n }\n case \"close_with_error\": {\n const error = (args as { error?: string }).error ?? \"unknown\";\n this.log?.(\"[kick]\", error);\n this.cleanup();\n break;\n }\n default: {\n if (!KNOWN_ACTIONS.has(action)) {\n this.log?.(`[unknown_packet]`, action, JSON.stringify(args));\n this.emit(\"unknown_packet\", { action, args });\n }\n break;\n }\n }\n\n const eventName = action === \"error\" ? \"server_error\" : action;\n this.emit(eventName, emitArgs);\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"wss://play.cpjourney.net\";\nconst DEFAULT_SECRET = \"skip\";\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const secret = options.secret ?? DEFAULT_SECRET;\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : {\n username: options.username,\n password: options.password,\n secret,\n };\n\n loginSocket.emit(\"message\", { action: \"login\", args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n if (response.message?.startsWith(\"Banned:\")) {\n this.loginStatus = \"banned\";\n }\n reject(\n new Error(response.message ?? \"Login failed\"),\n );\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n // Queue step on a fresh login socket (matches browser flow).\n // The original login socket is dead — server disconnects after login response.\n await this.queueForServer(serverName, options);\n\n // Connect game socket — still needs game_auth in Node.js\n // (browser uses cookies from HTTP polling, not available cross-Manager)\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n private async queueForServer(\n serverName: string,\n options?: ConnectOptions,\n ): Promise<void> {\n const queueSocket = this.createSocket(\"/world/login/\");\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n queueSocket.disconnect();\n reject(new Error(\"Queue timed out\"));\n }, 60_000);\n\n queueSocket.on(\"connect\", () => {\n queueSocket.emit(\"message\", {\n action: \"queue_server_join\",\n args: { server: serverName },\n });\n });\n\n queueSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\":\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n case \"queue_server_join\":\n clearTimeout(timeout);\n queueSocket.disconnect();\n resolve();\n break;\n }\n });\n\n queueSocket.once(\"disconnect\", () => {\n clearTimeout(timeout);\n resolve();\n });\n\n queueSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n queueSocket.disconnect();\n reject(new Error(`Queue connection failed: ${err.message}`));\n });\n });\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n const {\n id,\n username,\n displayName,\n joinTime,\n x,\n y,\n frame,\n walking,\n color,\n head,\n face,\n neck,\n body,\n hand,\n feet,\n flag,\n photo,\n ...rest\n } = raw;\n return {\n ...this.extractAppearance(raw),\n id: id as number,\n username: username as string,\n displayName: displayName as string | undefined,\n joinTime: joinTime as string | undefined,\n x: (x as number) ?? 0,\n y: (y as number) ?? 0,\n frame: (frame as number) ?? 0,\n walking: walking as number | undefined,\n meta: rest,\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n const {\n user: _user,\n coins,\n rank,\n inventory,\n furniture,\n flooring,\n buddies,\n buddyRequests,\n ignores,\n igloos,\n ...rest\n } = raw;\n return {\n ...normalized,\n _raw: raw,\n coins: (coins as number) ?? 0,\n rank: (rank as number) ?? 0,\n inventory: (inventory as number[]) ?? [],\n furniture: (furniture as unknown[]) ?? [],\n flooring: (flooring as unknown[]) ?? [],\n buddies: (user.buddies as Buddy[]) ?? [],\n buddyRequests: (user.buddyRequests as number[]) ?? [],\n ignores: (user.ignores as number[]) ?? [],\n igloos: (igloos as unknown[]) ?? [],\n meta: { ...normalized.meta, ...rest },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override buddyRequestSeen(id: number): void {\n this.send(\"buddy_request_seen\", { id });\n }\n\n override getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void {\n this.send(\"get_buddy\", { id, type });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getAllSlots(): void {\n this.send(\"get_all_slots\", {});\n }\n\n override getMascots(): void {\n this.send(\"get_mascots\", {});\n }\n\n override sendPostcard(userId: number, cardId: string): void {\n this.send(\"send_postcard\", { userId, cardId });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override getIgloos(): void {\n this.send(\"get_igloos\", {});\n }\n\n override getPuffles(userId: number): void {\n this.send(\"get_puffles\", { userId });\n }\n\n override adoptPuffle(type: number, name: string): void {\n this.send(\"adopt_puffle\", { type, name });\n }\n\n override getIglooLikes(): void {\n this.send(\"get_igloo_likes\", {});\n }\n\n override checkPuffleSprite(puffleSprite: boolean): void {\n this.send(\"check_puffle_sprite\", { puffleSprite });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n override getNinja(): void {\n this.send(\"get_ninja\", {});\n }\n\n override getMats(): void {\n this.send(\"get_waddles\", {});\n }\n\n override joinMatchmaking(): void {\n this.send(\"join_matchmaking\", {});\n }\n\n override leaveMatchmaking(): void {\n this.send(\"leave_matchmaking\", {});\n }\n\n override startGame(): void {\n this.send(\"start_game\", {});\n }\n\n override selectCard(slot: number): void {\n this.send(\"select_card\", { slot });\n }\n\n override loadAnimation(animation: string): void {\n this.send(\"load_animation\", { animation });\n }\n\n override joinMat(waddle: number): void {\n this.send(\"join_waddle\", { waddle });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n ...this.socketIoOptions(BASE_URL),\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_URL = \"https://api.cplegacy.com/login\";\nconst TOKEN_LOGIN_URL = \"https://api.cplegacy.com/token_login\";\nconst BROWSER_ORIGIN = \"https://play.cplegacy.com\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n requires2FA: boolean;\n message?: string;\n wantedVersion?: string;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n};\n\n/**\n * Wraps a CPLegacy socket to normalize its positional message format\n * `(\"message\", action, args)` into the `{ action, args }` envelope\n * that the Client class expects.\n */\nfunction wrapSocket(raw: Socket): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (action: unknown, args: unknown) => {\n listener({ action, args: args ?? {} });\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class CplegacyAdapter extends BaseAdapter {\n readonly id = \"CPLegacy\";\n private version = \"\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const url = \"token\" in options ? TOKEN_LOGIN_URL : LOGIN_URL;\n const body: Record<string, unknown> =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : {\n username: options.username,\n password: options.password,\n version: this.version,\n };\n\n let data = await this.postLogin(url, body);\n\n // Version negotiation: server returns wantedVersion when ours is stale/empty\n if (!data.success && data.wantedVersion) {\n this.version = data.wantedVersion;\n body.version = this.version;\n data = await this.postLogin(url, body);\n }\n\n if (!data.success) {\n this.loginMessage = data.message ?? null;\n throw new Error(`Login failed: ${data.message ?? \"unknown error\"}`);\n }\n\n const servers: ServerInfo[] = Object.entries(data.populations ?? {}).map(\n ([name, population]) => ({ name, population }),\n );\n\n return {\n servers,\n key: data.key,\n username: data.username,\n moderator: false,\n buddyWorlds: [],\n };\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const wsUrl = `wss://${serverName.toLowerCase()}.server.cplegacy.com`;\n const rawSocket = io(wsUrl, {\n ...this.socketIoOptions(BROWSER_ORIGIN),\n path: \"/socket.io/\",\n parser: msgpackParser,\n transports: [\"websocket\"],\n reconnection: false,\n });\n this.socket = rawSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n rawSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n rawSocket.on(\"connect\", () => {\n rawSocket.emit(\"message\", \"game_auth\", {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n token: \"\",\n });\n });\n\n rawSocket.on(\n \"message\",\n (action: string, args: Record<string, unknown>) => {\n switch (action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n // CPLegacy requires explicitly requesting load_player before join_server\n rawSocket.emit(\"message\", \"load_player\", {});\n rawSocket.emit(\"message\", \"join_server\", {});\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n },\n );\n\n rawSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n // Return wrapped socket so Client receives normalized { action, args } messages\n return wrapSocket(rawSocket);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", action, args);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.realUsername as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n walking: (raw.walking as number) ?? undefined,\n meta: {\n internalUsername: raw.username as string,\n approved: raw.approved,\n emailVerified: raw.emailVerified,\n safeChat: raw.safeChat,\n tutorial: raw.tutorial,\n loginStreak: raw.loginStreak,\n walkingColor: raw.walkingColor,\n stampbookColor: raw.stampbookColor,\n stampbookClasp: raw.stampbookClasp,\n stampbookPattern: raw.stampbookPattern,\n ninjaPoints: raw.ninjaPoints,\n highestNinjaRank: raw.highestNinjaRank,\n character: raw.character,\n transformed: raw.transformed,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (user.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n buddies: [],\n buddyRequests:\n (raw.pending as Buddy[] | undefined)?.map((b) => b.id) ?? [],\n ignores: [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n private async postLogin(\n url: string,\n body: Record<string, unknown>,\n ): Promise<LoginResponse> {\n const resp = await fetch(url, {\n method: \"POST\",\n headers: this.connectionHeaders(BROWSER_ORIGIN, {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n body: JSON.stringify(body),\n });\n\n return resp.json() as Promise<LoginResponse>;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\nimport type {\n LoginOptions,\n LoginResult,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_WS_URL = \"wss://server.cpzero.net/login\";\nconst GAME_WS_URL = \"wss://server.cpzero.net/sub_zero\";\nconst SERVERS_XML_URL = \"https://play.cpzero.net/servers.xml\";\nconst API_VERSION = \"253\";\nconst LOGIN_ZONE = \"w1\";\nconst NUL = \"\\0\";\n\n/**\n * CPZero user string field indices.\n * Extended Houdini format with 15 clothing slots (indices 3–17).\n */\nconst U = {\n ID: 0,\n USERNAME: 1,\n // 2 = agent/approval\n COLOR: 3,\n HEAD: 4,\n FACE: 5,\n NECK: 6,\n BODY: 7,\n HAND: 8,\n BACK: 9,\n BODY2: 10,\n HAND2: 11,\n BEAK: 12,\n HAIR: 13,\n FEET: 14,\n MOUNT: 15,\n FLAG: 16,\n PHOTO: 17,\n X: 18,\n Y: 19,\n FRAME: 20,\n // 21 = member\n RANK: 22,\n} as const;\n\nfunction md5(input: string): string {\n return createHash(\"md5\").update(input).digest(\"hex\");\n}\n\n/** MD5 then swap the two 16-char halves — classic Houdini password hash. */\nfunction swapMD5(input: string): string {\n const hash = md5(input);\n return hash.substring(16, 32) + hash.substring(0, 16);\n}\n\nfunction int(v: string | undefined): number {\n const n = Number(v);\n return Number.isNaN(n) ? 0 : n;\n}\n\n/**\n * Parse a pipe-delimited user string into a keyed object.\n * Example: `32924|kingofxiaomi|1|15|674|0|0|...|x|y|frame|...`\n */\nfunction parseUserString(str: string): Record<string, unknown> {\n const f = str.split(\"|\");\n return {\n id: int(f[U.ID]),\n username: f[U.USERNAME] ?? \"\",\n color: int(f[U.COLOR]),\n head: int(f[U.HEAD]),\n face: int(f[U.FACE]),\n neck: int(f[U.NECK]),\n body: int(f[U.BODY]),\n hand: int(f[U.HAND]),\n back: int(f[U.BACK]),\n body2: int(f[U.BODY2]),\n hand2: int(f[U.HAND2]),\n beak: int(f[U.BEAK]),\n hair: int(f[U.HAIR]),\n feet: int(f[U.FEET]),\n mount: int(f[U.MOUNT]),\n flag: int(f[U.FLAG]),\n photo: int(f[U.PHOTO]),\n x: int(f[U.X]),\n y: int(f[U.Y]),\n frame: int(f[U.FRAME]),\n rank: int(f[U.RANK]),\n };\n}\n\n/**\n * Minimal Socket-like wrapper around a raw WebSocket.\n * Emits `\"message\"` with `{ action, args }` payloads so the Client class\n * can consume CPZero messages identically to Socket.IO adapters.\n */\nclass SmartFoxSocket extends EventEmitter {\n private ws: WebSocket;\n private _closed = false;\n private _buffering = true;\n private _buffer: { action: string; args: Record<string, unknown> }[] = [];\n\n constructor(ws: WebSocket) {\n super();\n this.ws = ws;\n\n ws.on(\"close\", () => {\n this._closed = true;\n this.emit(\"disconnect\");\n });\n\n ws.on(\"error\", (err) => {\n this.emit(\"connect_error\", err);\n });\n }\n\n /** Emit a `\"message\"` event with the standard `{ action, args }` shape. */\n dispatchMessage(action: string, args: Record<string, unknown>): void {\n if (this._buffering) {\n this._buffer.push({ action, args });\n }\n this.emit(\"message\", { action, args });\n }\n\n /**\n * Stop buffering and replay all buffered messages on the next microtask.\n * This gives the Client time to attach its `socket.on(\"message\", ...)` listener\n * after `connect()` resolves.\n */\n flush(): void {\n this._buffering = false;\n const buffered = this._buffer;\n this._buffer = [];\n setTimeout(() => {\n for (const msg of buffered) {\n this.emit(\"message\", msg);\n }\n }, 0);\n }\n\n send(data: string): void {\n if (!this._closed) this.ws.send(data + NUL);\n }\n\n disconnect(): void {\n if (!this._closed) {\n this._closed = true;\n this.ws.close();\n }\n }\n\n get connected(): boolean {\n return !this._closed && this.ws.readyState === WebSocket.OPEN;\n }\n}\n\n/**\n * Map `%xt%` command names to the normalized action + args shape\n * that the Client class expects.\n */\nfunction translateXt(\n cmd: string,\n parts: string[],\n): { action: string; args: Record<string, unknown> } | null {\n switch (cmd) {\n case \"lp\": {\n // load_player: parts[0] = user string, parts[1..] = extra fields\n const user = parseUserString(parts[0] ?? \"\");\n const coins = int(parts[1]);\n const rank = user.rank as number;\n return {\n action: \"load_player\",\n args: { user, coins, rank },\n };\n }\n\n case \"jr\": {\n // join_room: parts[0] = roomId, parts[1..] = user strings\n const room = int(parts[0]);\n const users = parts.slice(1).filter(Boolean).map(parseUserString);\n return { action: \"join_room\", args: { room, users } };\n }\n\n case \"ap\": {\n // add_player: single user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"add_player\", args: { user } };\n }\n\n case \"rp\": {\n // remove_player: user id\n return { action: \"remove_player\", args: { user: int(parts[0]) } };\n }\n\n case \"sp\": {\n // send_position: userId, x, y\n return {\n action: \"send_position\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"sf\": {\n // send_frame: userId, frame\n return {\n action: \"send_frame\",\n args: { id: int(parts[0]), frame: int(parts[1]) },\n };\n }\n\n case \"sm\": {\n // send_message: userId, message\n return {\n action: \"send_message\",\n args: { id: int(parts[0]), message: parts[1] ?? \"\" },\n };\n }\n\n case \"se\": {\n // send_emote: userId, emote\n return {\n action: \"send_emote\",\n args: { id: int(parts[0]), emote: int(parts[1]) },\n };\n }\n\n case \"sa\": {\n // send_action (safe chat): userId, action\n return {\n action: \"send_safe\",\n args: { id: int(parts[0]), safe: int(parts[1]) },\n };\n }\n\n case \"sb\": {\n // snowball: userId, x, y\n return {\n action: \"snowball\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"gp\": {\n // get_player response: user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"get_player\", args: { user } };\n }\n\n // Equip updates: userId, itemId\n case \"upc\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"color\" },\n };\n case \"uph\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"head\" },\n };\n case \"upf\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"face\" },\n };\n case \"upn\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"neck\" },\n };\n case \"upb\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"body\" },\n };\n case \"upa\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"hand\" },\n };\n case \"upe\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"feet\" },\n };\n case \"upl\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"flag\" },\n };\n case \"upp\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"photo\" },\n };\n case \"upba\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"back\" },\n };\n case \"upm\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"mount\" },\n };\n\n case \"ai\": {\n // add_item response: itemId, coins remaining\n return {\n action: \"add_item\",\n args: { item: int(parts[0]), coins: int(parts[1]) },\n };\n }\n\n case \"jg\": {\n // join_game_room\n return { action: \"join_game_room\", args: { game: int(parts[0]) } };\n }\n\n case \"e\": {\n // error\n return { action: \"error\", args: { error: parts[0] ?? \"unknown\" } };\n }\n\n default:\n return null;\n }\n}\n\nexport class CpzeroAdapter extends BaseAdapter {\n readonly id = \"CPZero\";\n private sfs: SmartFoxSocket | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (\"token\" in options) {\n throw new Error(\"CPZero does not support token login\");\n }\n\n const loginHash = options.secret;\n if (!loginHash) {\n throw new Error(\n \"CPZero requires a pre-computed login hash in options.secret\",\n );\n }\n\n // Fetch server name mapping in parallel with the WS login handshake\n const serverNameMapPromise = fetchServerNameMap();\n\n const ws = new WebSocket(LOGIN_WS_URL, this.webSocketOptions(LOGIN_WS_URL));\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n ws.on(\"open\", () => {\n ws.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`) + NUL);\n });\n\n ws.on(\"message\", async (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n ws.send(xmlMsg(\"rndK\", \"-1\", \"\") + NUL);\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n const loginXml = xmlLogin(options.username, loginHash);\n ws.send(loginXml + NUL);\n continue;\n }\n\n if (msg.startsWith(\"%xt%l%\")) {\n // Split without filtering to preserve empty segments from %%\n // Format: %xt%l%-1%<nick>%<confirmKey>%%<populations>%%<email>%\n const rawParts = msg.split(\"%\");\n // rawParts: [\"\", \"xt\", \"l\", \"-1\", nick, confirmKey, \"\", popData, \"\", email, \"\"]\n const nickString = rawParts[4] ?? \"\";\n const confirmationKey = rawParts[5] ?? \"\";\n const popDataRaw = rawParts[7] ?? \"\";\n const nickFields = nickString.split(\"|\");\n\n clearTimeout(timeout);\n ws.close();\n\n const serverNameMap = await serverNameMapPromise;\n const servers = parseServerPopulations(popDataRaw, serverNameMap);\n\n const userId = int(nickFields[0]);\n const username = nickFields[2] ?? options.username;\n resolve({\n servers,\n key: `${userId}|${nickString}|${confirmationKey}`,\n username,\n moderator: false,\n buddyWorlds: [],\n });\n return;\n }\n\n if (msg.startsWith(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Login failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n ws.close();\n reject(new Error(`Login WS error: ${(err as Error).message}`));\n });\n\n ws.on(\"close\", () => {\n clearTimeout(timeout);\n });\n });\n\n return result;\n }\n\n async connect(\n _serverName: string,\n loginResult: LoginResult,\n _options?: ConnectOptions,\n ): Promise<import(\"socket.io-client\").Socket> {\n // loginResult.key = \"userId|nickString|confirmationKey\"\n const keyParts = loginResult.key.split(\"|\");\n const userId = keyParts[0] ?? \"\";\n const nickString = keyParts.slice(1, -1).join(\"|\");\n const confirmationKey = keyParts[keyParts.length - 1] ?? \"\";\n const loginKey = nickString.split(\"|\")[3] ?? \"\";\n\n const ws = new WebSocket(GAME_WS_URL, this.webSocketOptions(GAME_WS_URL));\n const sfs = new SmartFoxSocket(ws);\n this.sfs = sfs;\n // Store as unknown since SmartFoxSocket is not a Socket.IO Socket\n this.socket = sfs as unknown as import(\"socket.io-client\").Socket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n ws.on(\"open\", () => {\n sfs.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`));\n });\n\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n // XML phase\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n sfs.send(xmlMsg(\"rndK\", \"-1\", \"\"));\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n const rndK = kMatch[1];\n const gamePword = `${swapMD5(loginKey + rndK)}${loginKey}#${confirmationKey}`;\n sfs.send(xmlGameLogin(nickString, gamePword));\n continue;\n }\n\n // xt phase — may contain multiple messages concatenated\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n\n // Detect login success and send join_server\n if (msg.includes(\"%xt%l%\")) {\n sfs.send(`%xt%s%j#js%-1%${userId}%${loginKey}%en%`);\n }\n\n // Resolve once we get load_player + join_room\n if (msg.includes(\"%xt%jr%\")) {\n clearTimeout(timeout);\n resolve();\n }\n }\n\n if (msg.includes(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Game auth failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new Error(`Game WS error: ${(err as Error).message}`));\n });\n });\n\n // Wire up ongoing message handling\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n }\n }\n });\n\n // Replay buffered load_player/join_room messages after the Client attaches its listener\n sfs.flush();\n\n // Cast to Socket — Client only uses .on(\"message\") / .on(\"disconnect\") / .off()\n return sfs as unknown as import(\"socket.io-client\").Socket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const xt = actionToXt(action, args);\n if (xt) this.sfs.send(xt);\n }\n\n disconnect(): void {\n this.sfs?.disconnect();\n this.sfs = null;\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n back: raw.back,\n body2: raw.body2,\n hand2: raw.hand2,\n beak: raw.beak,\n hair: raw.hair,\n mount: raw.mount,\n rank: raw.rank,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: [],\n buddies: [],\n ignores: [],\n };\n }\n\n override sendMessage(message: string): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const userId = 0; // Server ignores the sent userId for own messages\n this.sfs.send(`%xt%s%m#sm%-1%${userId}%${message}%`);\n }\n\n override sendEmote(emote: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#se%-1%${emote}%`);\n }\n\n override sendSafe(safe: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sa%-1%${safe}%`);\n }\n\n override walk(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sp%-1%${x}%${y}%`);\n }\n\n override sendFrame(frame: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sf%-1%${frame}%`);\n }\n\n override snowball(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sb%-1%${x}%${y}%`);\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jr%-1%${room}%${x ?? 0}%${y ?? 0}%`);\n }\n\n override addItem(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%i#ai%-1%${item}%`);\n }\n\n override equipColor(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upc%-1%${item}%`);\n }\n\n override equipHead(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#uph%-1%${item}%`);\n }\n\n override equipFace(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upf%-1%${item}%`);\n }\n\n override equipNeck(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upn%-1%${item}%`);\n }\n\n override equipBody(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upb%-1%${item}%`);\n }\n\n override equipHand(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upa%-1%${item}%`);\n }\n\n override equipFeet(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upe%-1%${item}%`);\n }\n\n override equipFlag(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upl%-1%${item}%`);\n }\n\n override equipPhoto(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upp%-1%${item}%`);\n }\n\n override getPlayer(id: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#gp%-1%${id}%`);\n }\n\n override joinIgloo(igloo: number, _x?: number, _y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jp%-1%${igloo}%igloo%`);\n }\n\n /**\n * Process a batch of `%xt%` messages that may be concatenated in a single\n * WebSocket frame (separated by \\0 already split, but multiple %xt% in one string).\n */\n private processXtBatch(raw: string, sfs: SmartFoxSocket): void {\n // Split concatenated xt messages: \" %xt%cmd1%...% %xt%cmd2%...%\"\n const xtMessages = raw\n .split(/(?=%xt%)/)\n .map((s) => s.trim())\n .filter(Boolean);\n\n for (const xt of xtMessages) {\n const parts = xt.split(\"%\").filter(Boolean);\n // parts: [\"xt\", cmd, roomId, ...args]\n if (parts[0] !== \"xt\" || parts.length < 3) continue;\n\n const cmd = parts[1];\n const xtArgs = parts.slice(3); // skip \"xt\", cmd, roomId\n\n const translated = translateXt(cmd, xtArgs);\n if (translated) {\n sfs.dispatchMessage(translated.action, translated.args);\n }\n }\n }\n}\n\n// ── XML helpers ──\n\nfunction xmlMsg(action: string, r: string, body: string): string {\n return `<msg t='sys'><body action='${action}' r='${r}'>${body}</body></msg>`;\n}\n\nfunction xmlLogin(username: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${username}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\nfunction xmlGameLogin(nick: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${nick}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\n/**\n * Convert a normalized Client action to the raw `%xt%` send format.\n * Only used when called via the generic `send()` method.\n */\nfunction actionToXt(\n action: string,\n args: Record<string, unknown>,\n): string | null {\n switch (action) {\n case \"send_position\":\n return `%xt%s%u#sp%-1%${args.x}%${args.y}%`;\n case \"send_frame\":\n return `%xt%s%u#sf%-1%${args.frame}%`;\n case \"send_message\":\n return `%xt%s%m#sm%-1%0%${args.message}%`;\n case \"send_emote\":\n return `%xt%s%u#se%-1%${args.emote}%`;\n case \"send_safe\":\n return `%xt%s%u#sa%-1%${args.safe}%`;\n case \"snowball\":\n return `%xt%s%u#sb%-1%${args.x}%${args.y}%`;\n case \"join_room\":\n return `%xt%s%j#jr%-1%${args.room}%${args.x ?? 0}%${args.y ?? 0}%`;\n case \"add_item\":\n return `%xt%s%i#ai%-1%${args.item}%`;\n case \"get_player\":\n return `%xt%s%u#gp%-1%${args.id}%`;\n default:\n return null;\n }\n}\n\n/**\n * Fetch server ID → name mapping from the CPZero servers.xml endpoint.\n * Returns an empty map on failure so login can still proceed with fallback names.\n */\nasync function fetchServerNameMap(): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n try {\n const resp = await fetch(SERVERS_XML_URL);\n if (!resp.ok) return map;\n const xml = await resp.text();\n // Only parse servers under <language locale=\"en\">\n const enBlock = xml.match(\n /<language\\s+locale=\"en\">([\\s\\S]*?)<\\/language>/,\n )?.[1];\n if (!enBlock) return map;\n for (const m of enBlock.matchAll(/<server\\s([^>]+)>/g)) {\n const attrs = m[1];\n const id = attrs.match(/id=\"(\\d+)\"/)?.[1];\n const name = attrs.match(/name=\"([^\"]+)\"/)?.[1];\n if (id && name) map.set(id, name);\n }\n } catch {\n // Non-fatal — server names will fall back to \"Server {id}\"\n }\n return map;\n}\n\n/**\n * Parse the population segment from the login response.\n * Format: \"3100,0|3101,0|3103,7|3102,0|3104,7\"\n */\nfunction parseServerPopulations(\n raw: string,\n nameMap: Map<string, string>,\n): ServerInfo[] {\n if (!raw) return [];\n return raw\n .split(\"|\")\n .filter(Boolean)\n .map((entry) => {\n const [id, pop] = entry.split(\",\");\n return {\n name: nameMap.get(id) ?? `Server ${id}`,\n population: int(pop),\n };\n });\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { io, type Socket } from \"socket.io-client\";\nimport nacl from \"tweetnacl\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst CRUMBS_URL =\n \"https://media8.newcp.net/assets/media/crumbs/en/crumbs.json\";\n\ntype WorldConfig = {\n id?: number;\n host: string;\n path: string;\n login?: boolean;\n};\n\ntype CrumbsWorlds = Record<string, WorldConfig>;\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\nclass Encryptor {\n private aesKey: Buffer | null = null;\n private keypair = nacl.box.keyPair();\n\n get publicKey(): string {\n return Buffer.from(this.keypair.publicKey).toString(\"base64\");\n }\n\n get encrypted(): boolean {\n return this.aesKey !== null;\n }\n\n acquireKey(encryptedB64: string, serverPubKeyB64: string): string | null {\n const data = Buffer.from(encryptedB64, \"base64\");\n const serverPubKey = Buffer.from(serverPubKeyB64, \"base64\");\n const nonce = data.subarray(0, nacl.box.nonceLength);\n const ciphertext = data.subarray(nacl.box.nonceLength);\n const plaintext = nacl.box.open(\n new Uint8Array(ciphertext),\n new Uint8Array(nonce),\n new Uint8Array(serverPubKey),\n this.keypair.secretKey,\n );\n return plaintext ? new TextDecoder().decode(plaintext) : null;\n }\n\n setKey(keyString: string): void {\n this.aesKey = Buffer.from(keyString, \"utf-8\");\n }\n\n encrypt(plaintext: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const iv = randomBytes(16);\n const cipher = createCipheriv(\"aes-256-cbc\", this.aesKey, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf-8\"),\n cipher.final(),\n ]);\n const result = Buffer.concat([iv, encrypted]);\n return result.toString(\"base64\");\n }\n\n decrypt(data: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const buf = Buffer.from(data, \"base64\");\n const iv = buf.subarray(0, 16);\n const ciphertext = buf.subarray(16);\n const decipher = createDecipheriv(\"aes-256-cbc\", this.aesKey, iv);\n return Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf-8\");\n }\n\n encode(data: Record<string, unknown>): string {\n return this.encrypted\n ? this.encrypt(JSON.stringify(data))\n : JSON.stringify(data);\n }\n\n decode(data: unknown): Record<string, unknown> {\n if (this.encrypted && typeof data === \"string\") {\n return JSON.parse(this.decrypt(data)) as Record<string, unknown>;\n }\n return typeof data === \"string\"\n ? (JSON.parse(data) as Record<string, unknown>)\n : (data as Record<string, unknown>);\n }\n}\n\nfunction performHandshake(socket: Socket, encryptor: Encryptor): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Handshake timed out\"));\n }, 10_000);\n\n socket.once(\n \"handshake\",\n (encryptedKey: string, serverPubKeyB64: string) => {\n clearTimeout(timeout);\n const raw = encryptor.acquireKey(encryptedKey, serverPubKeyB64);\n if (!raw) {\n reject(new Error(\"Failed to decrypt handshake key\"));\n return;\n }\n\n const parsed = JSON.parse(raw) as { key: string; time?: number };\n if (\n parsed.time &&\n typeof parsed.time === \"number\" &&\n Math.abs(Date.now() - parsed.time) > 300_000\n ) {\n reject(new Error(\"Server time desync\"));\n return;\n }\n\n encryptor.setKey(parsed.key);\n resolve();\n },\n );\n\n socket.emit(\"handshake\", encryptor.publicKey);\n });\n}\n\n/**\n * Wraps a NewCP socket to decrypt incoming messages into the\n * `{ action, args }` envelope that the Client class expects.\n */\nfunction wrapSocket(raw: Socket, encryptor: Encryptor): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (msg: unknown) => {\n try {\n const decoded = encryptor.decode(msg);\n listener({ action: decoded.action, args: decoded.args ?? {} });\n } catch {\n // Skip malformed messages\n }\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class NewcpAdapter extends BaseAdapter {\n readonly id = \"NewCP\";\n private encryptor = new Encryptor();\n private worlds: CrumbsWorlds | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const loginWorld = Object.values(this.worlds ?? {}).find((w) => w.login);\n if (!loginWorld) throw new Error(\"Login world not found in crumbs\");\n\n const loginSocket = this.createSocket(loginWorld.host, loginWorld.path);\n this.encryptor = new Encryptor();\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n loginSocket.on(\"connect\", async () => {\n try {\n await performHandshake(loginSocket, this.encryptor);\n\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n const encrypted = this.encryptor.encode({ action: \"login\", args });\n loginSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n if (decoded.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = decoded.args as unknown as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n reject(new Error(response.message ?? \"Login failed\"));\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(\n response.populations ?? {},\n ).map(([name, population]) => ({ name, population }));\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator ?? false,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const worldConfig = this.worlds?.[serverName];\n if (!worldConfig)\n throw new Error(`World config not found for: ${serverName}`);\n\n this.encryptor = new Encryptor();\n const gameSocket = this.createSocket(worldConfig.host, worldConfig.path);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n gameSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n gameSocket.on(\"connect\", async () => {\n try {\n await performHandshake(gameSocket, this.encryptor);\n\n const encrypted = this.encryptor.encode({\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n },\n });\n gameSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(err);\n }\n });\n\n gameSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n\n switch (decoded.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(decoded.args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = decoded.args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n const joinEncrypted = this.encryptor.encode({\n action: \"join_server\",\n args: {},\n });\n gameSocket.emit(\"message\", joinEncrypted);\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n } catch {\n // Ignore decode errors during auth phase\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return wrapSocket(gameSocket, this.encryptor);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n const encrypted = this.encryptor.encode({ action, args });\n this.socket.emit(\"message\", encrypted);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: raw.nickname as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n nickname: raw.nickname,\n registrationDate: raw.registrationDate,\n customNameColor: raw.customNameColor,\n customBubbleColor: raw.customBubbleColor,\n customBubbleTextColor: raw.customBubbleTextColor,\n wallHacks: raw.wallHacks,\n moderator: raw.moderator,\n character: raw.character,\n approved: raw.approved,\n walking: raw.walking,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n buddies: (raw.buddies as Buddy[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n flooring: (raw.floorings as unknown[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n private createSocket(host: string, path: string): Socket {\n return io(host, {\n ...this.socketIoOptions(host),\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n\n private async loadWorlds(): Promise<void> {\n const resp = await fetch(CRUMBS_URL, {\n headers: this.connectionHeaders(CRUMBS_URL),\n });\n if (!resp.ok) throw new Error(`Failed to fetch crumbs: ${resp.status}`);\n const crumbs = (await resp.json()) as { worlds: CrumbsWorlds };\n this.worlds = crumbs.worlds;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"https://play.penguinorigins.online\";\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class PenguinoriginsAdapter extends BaseAdapter {\n readonly id = \"PenguinOrigins\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const action = \"token\" in options ? \"token_login\" : \"login\";\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n loginSocket.emit(\"message\", { action, args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n reject(new Error(response.message ?? \"Login failed\"));\n return;\n }\n\n const servers = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: false,\n buddyWorlds: [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: true,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.nickname as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n toy: raw.toy,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n return {\n ...normalized,\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: (raw.furniture as unknown[]) ?? [],\n flooring: (raw.flooring as unknown[]) ?? [],\n buddies: (raw.buddies as PlayerData[\"buddies\"]) ?? [],\n buddyRequests: (raw.buddyRequests as number[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n meta: {\n ...normalized.meta,\n postcards: raw.postcards,\n mascots: raw.mascots,\n pets: raw.pets,\n },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set: set ?? false });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n ...this.socketIoOptions(BASE_URL),\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import {\n type ConnectionProfileInput,\n resolveConnectionProfile,\n} from \"../connection-profile.js\";\nimport type { BaseAdapter } from \"./base-adapter.js\";\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\";\nimport { CplegacyAdapter } from \"./cplegacy-adapter.js\";\nimport { CpzeroAdapter } from \"./cpzero-adapter.js\";\nimport { NewcpAdapter } from \"./newcp-adapter.js\";\nimport { PenguinoriginsAdapter } from \"./penguinorigins-adapter.js\";\n\nconst ADAPTERS = {\n CPJourney: CpjourneyAdapter,\n CPLegacy: CplegacyAdapter,\n CPZero: CpzeroAdapter,\n NewCP: NewcpAdapter,\n PenguinOrigins: PenguinoriginsAdapter,\n} as const;\n\nexport type AdapterName = keyof typeof ADAPTERS;\n\nexport function createAdapter(\n name: AdapterName,\n connectionProfile?: ConnectionProfileInput,\n): BaseAdapter {\n return new ADAPTERS[name](resolveConnectionProfile(connectionProfile));\n}\n","import type { BaseAdapter } from \"../adapters/base-adapter.js\";\nimport type { ServerMessages } from \"../types/message-types.js\";\n\ntype WaitForFn = <K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n) => Promise<ServerMessages[K]>;\n\nexport class CardJitsu {\n constructor(\n private adapter: BaseAdapter,\n private waitFor: WaitForFn,\n ) {}\n\n /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */\n getNinja(): Promise<ServerMessages[\"get_ninja\"]> {\n this.adapter.getNinja();\n return this.waitFor(\"get_ninja\");\n }\n\n /** Fetch state of all Dojo mats. Resolves with mat state. */\n getMats(): Promise<ServerMessages[\"get_waddles\"]> {\n this.adapter.getMats();\n return this.waitFor(\"get_waddles\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(waddle: number): void {\n this.adapter.joinMat(waddle);\n }\n\n /** Join Sensei matchmaking queue. Resolves when server acknowledges. */\n joinMatchmaking(): Promise<ServerMessages[\"join_matchmaking\"]> {\n this.adapter.joinMatchmaking();\n return this.waitFor(\"join_matchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n this.adapter.leaveMatchmaking();\n }\n\n /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */\n startGame(): Promise<ServerMessages[\"start_game\"]> {\n this.adapter.startGame();\n return this.waitFor(\"start_game\");\n }\n\n /** Play a card from your hand by slot index. Resolves when server acknowledges. */\n selectCard(slot: number): Promise<ServerMessages[\"move_my_card\"]> {\n this.adapter.selectCard(slot);\n return this.waitFor(\"move_my_card\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(animation: string): void {\n this.adapter.loadAnimation(animation);\n }\n}\n"],"mappings":"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","names":["CHROME_USER_AGENT","CHROME_ACCEPT_LANGUAGE","RESTRICTED_HEADERS","resolveConnectionProfile","input","defaultOriginForUrl","urlOrOrigin","url","resolveConnectionOrigin","profile","defaultUrlOrOrigin","buildConnectionHeaders","options","headers","origin","referer","sanitizeHeaders","sanitized","name","value","isRestrictedHeader","normalized","BaseAdapter","connectionProfile","resolveConnectionProfile","defaultUrlOrOrigin","headers","origin","options","buildConnectionHeaders","resolveConnectionOrigin","_raw","raw","_message","_emote","_safe","_x","_y","_frame","_set","_room","_item","_id","_type","_userId","_cardId","_igloo","_name","_puffleSprite","_coins","_stamp","_slot","_animation","_waddle","EventEmitter","io","msgpackParser","BASE_URL","DEFAULT_SECRET","CpjourneyAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","secret","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","queueSocket","action","raw","id","username","displayName","joinTime","x","y","frame","walking","color","head","face","neck","body","hand","feet","flag","photo","rest","user","normalized","_user","coins","rank","inventory","furniture","flooring","buddies","buddyRequests","ignores","igloos","message","emote","safe","set","room","item","type","userId","cardId","igloo","puffleSprite","stamp","slot","animation","waddle","path","io","msgpackParser","io","msgpackParser","LOGIN_URL","TOKEN_LOGIN_URL","BROWSER_ORIGIN","wrapSocket","raw","original","event","listener","action","args","CplegacyAdapter","BaseAdapter","options","url","body","data","name","population","serverName","loginResult","wsUrl","rawSocket","io","msgpackParser","resolve","reject","timeout","err","user","b","message","emote","safe","x","y","frame","set","room","item","id","userId","igloo","coins","stamp","createHash","EventEmitter","WebSocket","LOGIN_WS_URL","GAME_WS_URL","SERVERS_XML_URL","API_VERSION","LOGIN_ZONE","NUL","U","md5","input","createHash","swapMD5","hash","int","v","n","parseUserString","str","f","SmartFoxSocket","EventEmitter","ws","err","action","args","buffered","msg","data","WebSocket","translateXt","cmd","parts","user","coins","rank","room","users","CpzeroAdapter","BaseAdapter","options","loginHash","serverNameMapPromise","fetchServerNameMap","resolve","reject","timeout","xmlMsg","raw","messages","loginXml","xmlLogin","rawParts","nickString","confirmationKey","popDataRaw","nickFields","serverNameMap","servers","parseServerPopulations","userId","username","errParts","_serverName","loginResult","_options","keyParts","loginKey","sfs","kMatch","rndK","gamePword","xmlGameLogin","xt","actionToXt","message","emote","safe","x","y","frame","item","id","igloo","_x","_y","xtMessages","s","xtArgs","translated","r","body","pword","nick","map","resp","enBlock","m","attrs","name","nameMap","entry","pop","createCipheriv","createDecipheriv","randomBytes","io","nacl","CRUMBS_URL","Encryptor","nacl","encryptedB64","serverPubKeyB64","data","serverPubKey","nonce","ciphertext","plaintext","keyString","iv","randomBytes","cipher","createCipheriv","encrypted","buf","decipher","createDecipheriv","performHandshake","socket","encryptor","resolve","reject","timeout","encryptedKey","raw","parsed","wrapSocket","original","event","listener","msg","decoded","NewcpAdapter","BaseAdapter","options","loginWorld","w","loginSocket","args","err","response","servers","name","population","serverName","loginResult","worldConfig","gameSocket","joinEncrypted","action","user","message","emote","safe","x","y","frame","set","room","item","id","igloo","host","path","io","resp","crumbs","io","BASE_URL","PenguinoriginsAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","action","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","raw","user","normalized","message","emote","safe","x","y","frame","set","room","item","id","igloo","coins","path","io","ADAPTERS","CpjourneyAdapter","CplegacyAdapter","CpzeroAdapter","NewcpAdapter","PenguinoriginsAdapter","createAdapter","name","connectionProfile","resolveConnectionProfile","CardJitsu","adapter","waitFor","waddle","slot","animation","KNOWN_ACTIONS","isMessagePayload","msg","Client","EventEmitter","CardJitsu","server","options","createAdapter","serverName","connectOptions","update","socket","resolve","reject","timeout","playerLoaded","roomJoined","checkReady","onMessage","onDisconnect","event","listener","args","timer","cleanup","handler","message","emote","safe","x","y","frame","set","room","item","id","type","userId","cardId","igloo","name","puffleSprite","coins","stamp","ms","action","emitArgs","player","rawUsers","users","rawUser","user","iglooUsers","slot","reason","error","eventName"]}
|
|
1
|
+
{"version":3,"sources":["../src/connection-profile.ts","../src/errors.ts","../src/lifecycle.ts","../src/adapters/base-adapter.ts","../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/cplegacy-adapter.ts","../src/adapters/cpps-lol-adapter.ts","../src/adapters/cpps-lol-packet-signer.ts","../src/adapters/newcp-adapter.ts","../src/adapters/penguinorigins-adapter.ts","../src/adapters/index.ts","../src/games/card-jitsu.ts","../src/games/cpps-lol.ts"],"sourcesContent":["export type ConnectionProfilePreset = \"chrome\" | \"node\";\n\nexport type HeaderValue = string | number | boolean | null | undefined;\n\nexport type HeaderBag = Record<string, HeaderValue>;\n\nexport type ConnectionProfile = {\n preset?: ConnectionProfilePreset;\n userAgent?: string;\n acceptLanguage?: string;\n origin?: string;\n referer?: string;\n headers?: HeaderBag;\n};\n\nexport type ConnectionProfileInput =\n | ConnectionProfilePreset\n | ConnectionProfile;\n\nexport type NormalizedConnectionProfile = {\n preset: ConnectionProfilePreset;\n userAgent?: string;\n acceptLanguage?: string;\n origin?: string;\n referer?: string;\n headers: HeaderBag;\n};\n\nconst CHROME_USER_AGENT =\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36\";\n\nconst CHROME_ACCEPT_LANGUAGE = \"en-US,en;q=0.9\";\n\nconst RESTRICTED_HEADERS = new Set([\n \"connection\",\n \"content-length\",\n \"host\",\n \"transfer-encoding\",\n \"upgrade\",\n]);\n\nexport function resolveConnectionProfile(\n input: ConnectionProfileInput = \"chrome\",\n): NormalizedConnectionProfile {\n if (typeof input === \"string\") {\n return { preset: input, headers: {} };\n }\n\n const preset = input.preset ?? \"chrome\";\n\n return {\n preset,\n userAgent: input.userAgent,\n acceptLanguage: input.acceptLanguage,\n origin: input.origin,\n referer: input.referer,\n headers: input.headers ?? {},\n };\n}\n\nexport function defaultOriginForUrl(urlOrOrigin: string): string {\n const input = urlOrOrigin.match(/^[a-z][a-z0-9+.-]*:\\/\\//i)\n ? urlOrOrigin\n : `https://${urlOrOrigin}`;\n\n try {\n const url = new URL(input);\n const protocol =\n url.protocol === \"wss:\"\n ? \"https:\"\n : url.protocol === \"ws:\"\n ? \"http:\"\n : url.protocol;\n\n return `${protocol}//${url.host}`;\n } catch {\n return urlOrOrigin.replace(/\\/+$/, \"\");\n }\n}\n\nexport function resolveConnectionOrigin(\n profile: NormalizedConnectionProfile,\n defaultUrlOrOrigin: string,\n): string | undefined {\n if (profile.origin) return profile.origin;\n if (profile.preset === \"node\") return undefined;\n return defaultOriginForUrl(defaultUrlOrOrigin);\n}\n\nexport function buildConnectionHeaders(\n profile: NormalizedConnectionProfile,\n options: {\n defaultOrigin: string;\n headers?: HeaderBag;\n },\n): Record<string, string> {\n const headers: HeaderBag = {};\n const origin = resolveConnectionOrigin(profile, options.defaultOrigin);\n const referer =\n profile.referer ??\n (profile.preset === \"node\" || !origin ? undefined : `${origin}/`);\n\n if (profile.preset !== \"node\") {\n headers[\"User-Agent\"] = profile.userAgent ?? CHROME_USER_AGENT;\n headers[\"Accept-Language\"] =\n profile.acceptLanguage ?? CHROME_ACCEPT_LANGUAGE;\n }\n\n if (origin) headers.Origin = origin;\n if (referer) headers.Referer = referer;\n\n return sanitizeHeaders({\n ...headers,\n ...profile.headers,\n ...options.headers,\n });\n}\n\nexport function sanitizeHeaders(headers: HeaderBag): Record<string, string> {\n const sanitized: Record<string, string> = {};\n\n for (const [name, value] of Object.entries(headers)) {\n if (value === null || value === undefined) continue;\n if (isRestrictedHeader(name)) continue;\n sanitized[name] = String(value);\n }\n\n return sanitized;\n}\n\nfunction isRestrictedHeader(name: string): boolean {\n const normalized = name.toLowerCase();\n return (\n RESTRICTED_HEADERS.has(normalized) ||\n normalized.startsWith(\"sec-websocket-\")\n );\n}\n","import type { ClientLifecyclePhase } from \"./lifecycle.js\";\n\nexport type ClientOperationErrorCategory =\n | \"login_timeout\"\n | \"login_rejected\"\n | \"invalid_credentials\"\n | \"account_banned\"\n | \"queue_timeout\"\n | \"transport_error\"\n | \"auth_timeout\"\n | \"auth_failed\"\n | \"initial_state_timeout\"\n | \"operation_timeout\"\n | \"unsupported_operation\"\n | \"aborted\"\n | \"disconnected\"\n | \"kicked\"\n | \"server_error\";\n\nexport type ClientOperationErrorOptions = {\n category: ClientOperationErrorCategory;\n phase: ClientLifecyclePhase;\n retryable: boolean;\n message: string;\n cause?: unknown;\n};\n\nconst MAX_PUBLIC_MESSAGE_LENGTH = 500;\nconst QUOTED_SECRET_FIELD =\n /\\b(password|token|login[_-]?key|confirmation[_-]?key|secret)([\"']?\\s*[:=]\\s*)([\"'])([^\"']*)\\3/gi;\nconst BARE_SECRET_FIELD =\n /\\b(password|token|login[_-]?key|confirmation[_-]?key|secret)(\\s*[:=]\\s*)([^\\s&,;]+)/gi;\nconst URL_CREDENTIALS = /\\b([a-z][a-z\\d+.-]*:\\/\\/)([^\\s/@]+)@/gi;\n\nexport function sanitizeClientErrorMessage(message: string): string {\n return message\n .replace(URL_CREDENTIALS, \"$1[REDACTED]@\")\n .replace(QUOTED_SECRET_FIELD, \"$1$2$3[REDACTED]$3\")\n .replace(BARE_SECRET_FIELD, \"$1$2[REDACTED]\")\n .slice(0, MAX_PUBLIC_MESSAGE_LENGTH);\n}\n\nexport class ClientOperationError extends Error {\n readonly category: ClientOperationErrorCategory;\n readonly phase: ClientLifecyclePhase;\n readonly retryable: boolean;\n\n constructor(options: ClientOperationErrorOptions) {\n super(sanitizeClientErrorMessage(options.message), {\n cause: options.cause,\n });\n this.name = \"ClientOperationError\";\n this.category = options.category;\n this.phase = options.phase;\n this.retryable = options.retryable;\n }\n}\n","import type { QueueUpdate } from \"./types/adapter-types.js\";\n\nexport type ClientLifecyclePhase =\n | \"transport_connecting\"\n | \"queueing\"\n | \"authenticating\"\n | \"joining_session\"\n | \"awaiting_initial_state\"\n | \"ready\"\n | \"disconnecting\"\n | \"disconnected\";\n\nexport type ClientLifecycleUpdate = {\n phase: ClientLifecyclePhase;\n occurredAt: number;\n queue?: QueueUpdate;\n};\n\nexport type ClientOperationOptions = {\n signal?: AbortSignal;\n timeoutMs?: number;\n};\n\nexport type ClientConnectionTimeouts = {\n loginMs: number;\n transportMs: number;\n /** Maximum silence between queue updates, not total time spent queued. */\n queueMs: number;\n authenticationMs: number;\n initialStateMs: number;\n requestMs: number;\n};\n\nexport const DEFAULT_CLIENT_CONNECTION_TIMEOUTS = {\n loginMs: 20_000,\n transportMs: 20_000,\n queueMs: 300_000,\n authenticationMs: 20_000,\n initialStateMs: 15_000,\n requestMs: 15_000,\n} as const satisfies ClientConnectionTimeouts;\n\nexport type ClientDisconnectInfo = {\n intentional: boolean;\n reason: string | null;\n occurredAt: number;\n};\n","import type { ManagerOptions, Socket, SocketOptions } from \"socket.io-client\";\nimport {\n buildConnectionHeaders,\n type HeaderBag,\n type NormalizedConnectionProfile,\n resolveConnectionOrigin,\n resolveConnectionProfile,\n} from \"../connection-profile.js\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientConnectionTimeouts,\n type ClientLifecyclePhase,\n type ClientLifecycleUpdate,\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type {\n PlayerAppearance,\n PlayerData,\n RoomUser,\n} from \"../types/player-types.js\";\n\ntype SocketIoConnectionOptions = Partial<ManagerOptions & SocketOptions> & {\n extraHeaders?: Record<string, string>;\n origin?: string;\n};\n\nexport type AdapterMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport type ConnectOptions = {\n signal?: AbortSignal;\n timeouts?: Partial<ClientConnectionTimeouts>;\n onQueueUpdate?: (update: QueueUpdate) => void;\n onLifecycleUpdate?: (update: ClientLifecycleUpdate) => void;\n /** @internal Normalized message delivery installed before session join. */\n onMessage?: (message: AdapterMessage) => void;\n /** @internal Transport disconnect delivery installed before session join. */\n onDisconnect?: (reason: string | null) => void;\n};\n\nexport abstract class BaseAdapter {\n abstract readonly id: string;\n protected socket: Socket | null = null;\n loginMessage: string | null = null;\n loginStatus: \"active\" | \"banned\" = \"active\";\n\n constructor(\n protected readonly connectionProfile: NormalizedConnectionProfile = resolveConnectionProfile(),\n ) {}\n\n abstract login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult>;\n abstract connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket>;\n abstract disconnect(): void;\n abstract send(action: string, args: Record<string, unknown>): void;\n\n protected connectionTimeouts(\n options?: ConnectOptions,\n ): ClientConnectionTimeouts {\n return {\n ...DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n ...options?.timeouts,\n };\n }\n\n protected reportLifecycle(\n options: ConnectOptions | undefined,\n phase: ClientLifecyclePhase,\n queue?: QueueUpdate,\n ): void {\n options?.onLifecycleUpdate?.({\n phase,\n occurredAt: Date.now(),\n ...(queue ? { queue } : {}),\n });\n }\n\n protected resetLoginState(): void {\n this.loginMessage = null;\n this.loginStatus = \"active\";\n }\n\n protected unsupportedOperation(operation: string): ClientOperationError {\n return new ClientOperationError({\n category: \"unsupported_operation\",\n phase: \"ready\",\n retryable: false,\n message: `${this.id} does not support ${operation}`,\n });\n }\n\n protected socketIoOptions(\n defaultUrlOrOrigin: string,\n ): SocketIoConnectionOptions {\n const headers = this.connectionHeaders(defaultUrlOrOrigin);\n const origin = this.connectionOrigin(defaultUrlOrOrigin);\n const options: SocketIoConnectionOptions = {};\n\n if (Object.keys(headers).length > 0) options.extraHeaders = headers;\n if (origin) options.origin = origin;\n if (this.connectionProfile.preset !== \"node\" || origin) {\n options.withCredentials = true;\n }\n\n return options;\n }\n\n protected webSocketOptions(defaultUrlOrOrigin: string): {\n headers?: Record<string, string>;\n origin?: string;\n } {\n const headers = this.connectionHeaders(defaultUrlOrOrigin);\n const origin = this.connectionOrigin(defaultUrlOrOrigin);\n return {\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(origin ? { origin } : {}),\n };\n }\n\n protected connectionHeaders(\n defaultUrlOrOrigin: string,\n headers?: HeaderBag,\n ): Record<string, string> {\n return buildConnectionHeaders(this.connectionProfile, {\n defaultOrigin: defaultUrlOrOrigin,\n headers,\n });\n }\n\n protected connectionOrigin(defaultUrlOrOrigin: string): string | undefined {\n return resolveConnectionOrigin(this.connectionProfile, defaultUrlOrOrigin);\n }\n\n normalizeUser(_raw: Record<string, unknown>): RoomUser {\n throw this.unsupportedOperation(\"normalizeUser\");\n }\n\n normalizePlayer(_raw: Record<string, unknown>): PlayerData {\n throw this.unsupportedOperation(\"normalizePlayer\");\n }\n\n protected extractAppearance(raw: Record<string, unknown>): PlayerAppearance {\n return {\n color: (raw.color as number) ?? 0,\n head: (raw.head as number) ?? 0,\n face: (raw.face as number) ?? 0,\n neck: (raw.neck as number) ?? 0,\n body: (raw.body as number) ?? 0,\n hand: (raw.hand as number) ?? 0,\n feet: (raw.feet as number) ?? 0,\n flag: (raw.flag as number) ?? 0,\n photo: (raw.photo as number) ?? 0,\n };\n }\n\n sendMessage(_message: string): void {\n throw this.unsupportedOperation(\"sendMessage\");\n }\n\n sendEmote(_emote: number): void {\n throw this.unsupportedOperation(\"sendEmote\");\n }\n\n sendSafe(_safe: number): void {\n throw this.unsupportedOperation(\"sendSafe\");\n }\n\n walk(_x: number, _y: number): void {\n throw this.unsupportedOperation(\"walk\");\n }\n\n sendFrame(_frame: number, _set?: boolean): void {\n throw this.unsupportedOperation(\"sendFrame\");\n }\n\n snowball(_x: number, _y: number): void {\n throw this.unsupportedOperation(\"snowball\");\n }\n\n joinRoom(_room: number, _x?: number, _y?: number): void {\n throw this.unsupportedOperation(\"joinRoom\");\n }\n\n addItem(_item: number): void {\n throw this.unsupportedOperation(\"addItem\");\n }\n\n equipColor(_item: number): void {\n throw this.unsupportedOperation(\"equipColor\");\n }\n\n equipHead(_item: number): void {\n throw this.unsupportedOperation(\"equipHead\");\n }\n\n equipFace(_item: number): void {\n throw this.unsupportedOperation(\"equipFace\");\n }\n\n equipNeck(_item: number): void {\n throw this.unsupportedOperation(\"equipNeck\");\n }\n\n equipBody(_item: number): void {\n throw this.unsupportedOperation(\"equipBody\");\n }\n\n equipHand(_item: number): void {\n throw this.unsupportedOperation(\"equipHand\");\n }\n\n equipFeet(_item: number): void {\n throw this.unsupportedOperation(\"equipFeet\");\n }\n\n equipFlag(_item: number): void {\n throw this.unsupportedOperation(\"equipFlag\");\n }\n\n equipPhoto(_item: number): void {\n throw this.unsupportedOperation(\"equipPhoto\");\n }\n\n buddyRequest(_id: number): void {\n throw this.unsupportedOperation(\"buddyRequest\");\n }\n\n buddyAccept(_id: number): void {\n throw this.unsupportedOperation(\"buddyAccept\");\n }\n\n buddyReject(_id: number): void {\n throw this.unsupportedOperation(\"buddyReject\");\n }\n\n buddyRequestSeen(_id: number): void {\n throw this.unsupportedOperation(\"buddyRequestSeen\");\n }\n\n getBuddy(_id: number, _type: \"buddies\" | \"buddyRequests\"): void {\n throw this.unsupportedOperation(\"getBuddy\");\n }\n\n findBuddy(_id: number): void {\n throw this.unsupportedOperation(\"findBuddy\");\n }\n\n removeBuddy(_id: number): void {\n throw this.unsupportedOperation(\"removeBuddy\");\n }\n\n addIgnore(_id: number): void {\n throw this.unsupportedOperation(\"addIgnore\");\n }\n\n removeIgnore(_id: number): void {\n throw this.unsupportedOperation(\"removeIgnore\");\n }\n\n getPlayer(_id: number): void {\n throw this.unsupportedOperation(\"getPlayer\");\n }\n\n getAllSlots(): void {\n throw this.unsupportedOperation(\"getAllSlots\");\n }\n\n getMascots(): void {\n throw this.unsupportedOperation(\"getMascots\");\n }\n\n sendPostcard(_userId: number, _cardId: string): void {\n throw this.unsupportedOperation(\"sendPostcard\");\n }\n\n getStamps(_userId: number): void {\n throw this.unsupportedOperation(\"getStamps\");\n }\n\n getPostcards(): void {\n throw this.unsupportedOperation(\"getPostcards\");\n }\n\n getIglooOpen(_igloo: number): void {\n throw this.unsupportedOperation(\"getIglooOpen\");\n }\n\n getIgloos(): void {\n throw this.unsupportedOperation(\"getIgloos\");\n }\n\n getPuffles(_userId: number, _isBackyard?: boolean): void {\n throw this.unsupportedOperation(\"getPuffles\");\n }\n\n getAllPuffles(): void {\n throw this.unsupportedOperation(\"getAllPuffles\");\n }\n\n getPuffleWellbeing(_puffle: number): void {\n throw this.unsupportedOperation(\"getPuffleWellbeing\");\n }\n\n playPuffle(_puffle: number): void {\n throw this.unsupportedOperation(\"playPuffle\");\n }\n\n restPuffle(_puffle: number): void {\n throw this.unsupportedOperation(\"restPuffle\");\n }\n\n buyPuffleItem(_puffleId: number, _item: number): void {\n throw this.unsupportedOperation(\"buyPuffleItem\");\n }\n\n walkPuffle(_puffle: number): void {\n throw this.unsupportedOperation(\"walkPuffle\");\n }\n\n initializePuffleTower(): void {\n throw this.unsupportedOperation(\"initializePuffleTower\");\n }\n\n getBackyardSupplies(): void {\n throw this.unsupportedOperation(\"getBackyardSupplies\");\n }\n\n adoptPuffle(_type: number, _name: string): void {\n throw this.unsupportedOperation(\"adoptPuffle\");\n }\n\n getIglooLikes(): void {\n throw this.unsupportedOperation(\"getIglooLikes\");\n }\n\n checkPuffleSprite(_puffleSprite: boolean): void {\n throw this.unsupportedOperation(\"checkPuffleSprite\");\n }\n\n joinIgloo(_igloo: number, _x?: number, _y?: number): void {\n throw this.unsupportedOperation(\"joinIgloo\");\n }\n\n getStoreMusic(): void {\n throw this.unsupportedOperation(\"getStoreMusic\");\n }\n\n buyMusic(_music: string): void {\n throw this.unsupportedOperation(\"buyMusic\");\n }\n\n getIglooStoreItems(): void {\n throw this.unsupportedOperation(\"getIglooStoreItems\");\n }\n\n buyFurniture(_furniture: string, _amount: number): void {\n throw this.unsupportedOperation(\"buyFurniture\");\n }\n\n updateIglooMusic(_music: string): void {\n throw this.unsupportedOperation(\"updateIglooMusic\");\n }\n\n updateIglooFurniture(\n _furniture: Array<{\n furnitureId: number;\n x: number;\n y: number;\n rotation: number;\n frame: number;\n depth: number;\n slot?: number;\n }>,\n ): void {\n throw this.unsupportedOperation(\"updateIglooFurniture\");\n }\n\n autoUpdateIglooFurniture(\n _furniture: Array<{\n furnitureId: number;\n x: number;\n y: number;\n rotation: number;\n frame: number;\n depth: number;\n slot?: number;\n }>,\n ): void {\n throw this.unsupportedOperation(\"autoUpdateIglooFurniture\");\n }\n\n updateIglooType(_type: number): void {\n throw this.unsupportedOperation(\"updateIglooType\");\n }\n\n openIgloo(): void {\n throw this.unsupportedOperation(\"openIgloo\");\n }\n\n closeIglooBounds(): void {\n throw this.unsupportedOperation(\"closeIglooBounds\");\n }\n\n likeIgloo(): void {\n throw this.unsupportedOperation(\"likeIgloo\");\n }\n\n openIglooEditor(): void {\n throw this.unsupportedOperation(\"openIglooEditor\");\n }\n\n closeIglooEditor(): void {\n throw this.unsupportedOperation(\"closeIglooEditor\");\n }\n\n gameOver(_coins: number): void {\n throw this.unsupportedOperation(\"gameOver\");\n }\n\n collectStamp(_stamp: number): void {\n throw this.unsupportedOperation(\"collectStamp\");\n }\n\n /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */\n getNinja(): void {\n throw this.unsupportedOperation(\"getNinja\");\n }\n\n /** Fetch state of all Dojo mats. Listen for `get_waddles` event. */\n getMats(): void {\n throw this.unsupportedOperation(\"getMats\");\n }\n\n /** Join Sensei matchmaking queue. Listen for `tick_matchmaking` events. */\n joinMatchmaking(): void {\n throw this.unsupportedOperation(\"joinMatchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n throw this.unsupportedOperation(\"leaveMatchmaking\");\n }\n\n /** Start a Card-Jitsu match after entering a game room. Listen for `start_game` event. */\n startGame(): void {\n throw this.unsupportedOperation(\"startGame\");\n }\n\n /** Play a card from your hand by slot index. Listen for `move_my_card` event. */\n selectCard(_slot: number): void {\n throw this.unsupportedOperation(\"selectCard\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(_animation: string): void {\n throw this.unsupportedOperation(\"loadAnimation\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(_waddle: number): void {\n throw this.unsupportedOperation(\"joinMat\");\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport type {\n AdapterMessage,\n BaseAdapter,\n ConnectOptions,\n} from \"./adapters/base-adapter.js\";\nimport { type AdapterName, createAdapter } from \"./adapters/index.js\";\nimport type { ConnectionProfileInput } from \"./connection-profile.js\";\nimport { ClientOperationError } from \"./errors.js\";\nimport { CardJitsu } from \"./games/card-jitsu.js\";\nimport { Cppslol } from \"./games/cpps-lol.js\";\nimport {\n type ClientDisconnectInfo,\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"./lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"./types/adapter-types.js\";\nimport type { ClientMessages, ServerMessages } from \"./types/message-types.js\";\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\";\n\n/** Actions with explicit switch-case handling or typed in ServerMessages — not truly unknown. */\nconst KNOWN_ACTIONS = new Set<string>([\n // Handled in switch\n \"load_player\",\n \"join_room\",\n \"add_player\",\n \"remove_player\",\n \"send_position\",\n \"send_frame\",\n \"update_player\",\n \"kick\",\n \"close_with_error\",\n // Typed passthrough (emitted as-is, no state updates needed)\n \"send_message\",\n \"send_emote\",\n \"cpj_ping\",\n \"open_sprite\",\n \"close_sprite\",\n \"set_weather\",\n \"server_error\",\n \"error\",\n \"stamp_earned\",\n \"game_over\",\n \"join_game_room\",\n \"get_ninja\",\n \"get_waddles\",\n \"update_waddle\",\n \"join_matchmaking\",\n \"tick_matchmaking\",\n \"start_game\",\n \"set_cards\",\n \"add_enemy_cards\",\n \"start_round\",\n \"enable_cards\",\n \"remove_card\",\n \"move_my_card\",\n \"card_effect\",\n \"round_over\",\n \"play_animation\",\n \"game_won\",\n \"get_player\",\n \"buddy_request\",\n \"buddy_accept\",\n \"buddy_reject\",\n \"buddy_request_seen\",\n \"get_buddy\",\n \"buddy_find\",\n \"send_postcard\",\n \"stamps_result\",\n \"ignore_add\",\n \"ignore_remove\",\n \"add_item\",\n \"get_postcards\",\n \"get_igloo_open\",\n \"get_igloos\",\n \"get_igloo_likes\",\n \"join_igloo\",\n \"get_puffles\",\n \"get_all_puffles\",\n \"get_wellbeing\",\n \"get_walking_puffle\",\n \"update_wellbeing\",\n \"puffle_levelup\",\n \"puffle_popup\",\n \"buy_puffle_item\",\n \"walk_puffle\",\n \"backyard_supplies\",\n \"receive_postcard\",\n \"get_store_music\",\n \"add_music\",\n \"get_igloostore_items\",\n \"add_furniture\",\n \"update_music\",\n \"igloo_open_status\",\n \"igloo_bounds_status\",\n \"igloo_liked\",\n \"get_mascots\",\n \"wait_queue_update\",\n \"slot\",\n \"snowball\",\n \"send_safe\",\n \"stop_walking\",\n \"update_table\",\n \"transform_player\",\n \"adopt_puffle\",\n \"info\",\n \"queue_server_join\",\n \"disconnect\",\n \"unknown_packet\",\n \"remove_inventory\",\n \"snowflake_state\",\n \"get_pets\",\n \"igloo_contest\",\n \"igloo_likes\",\n \"marry_request\",\n]);\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (\n args: ServerMessages[K],\n) => void;\n\ntype ServerMessageMatcher<K extends keyof ServerMessages> = (\n args: ServerMessages[K],\n) => boolean;\n\nexport type LogFn = (message: string, ...args: unknown[]) => void;\n\nexport type ClientOptions = {\n debug?: boolean | LogFn;\n connectionProfile?: ConnectionProfileInput;\n};\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null;\n room: number | null = null;\n users: Map<number, RoomUser> = new Map();\n connected = false;\n\n private adapter: BaseAdapter;\n private loginResult: LoginResult | null = null;\n private log: LogFn | null = null;\n private _cardJitsu: CardJitsu | null = null;\n private _cppslol: Cppslol | null = null;\n private intentionalDisconnect = false;\n private disconnectNotified = false;\n private connectionFailure: ClientOperationError | null = null;\n private lifecycleReporter: ConnectOptions[\"onLifecycleUpdate\"];\n private requestTails = new Map<keyof ServerMessages, Promise<void>>();\n private disconnectEpoch = 0;\n private lastDisconnectInfo: ClientDisconnectInfo | null = null;\n\n get loginMessage(): string | null {\n return this.adapter.loginMessage;\n }\n\n get loginStatus(): \"active\" | \"banned\" {\n return this.adapter.loginStatus;\n }\n\n get cardJitsu(): CardJitsu {\n if (!this._cardJitsu)\n this._cardJitsu = new CardJitsu(this.adapter, this.request.bind(this));\n return this._cardJitsu;\n }\n\n get cppslol(): Cppslol {\n if (!this._cppslol)\n this._cppslol = new Cppslol(this.adapter, this.request.bind(this));\n return this._cppslol;\n }\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super();\n this.adapter = createAdapter(server, options?.connectionProfile);\n\n if (options?.debug) {\n this.log =\n typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console);\n }\n }\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username);\n this.loginResult = null;\n const loginResult = await this.adapter.login(options, operationOptions);\n this.loginResult = loginResult;\n this.log?.(\"[login] success —\", loginResult.servers.length, \"servers\");\n return loginResult.servers;\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\");\n\n this.log?.(\"[connect] joining\", serverName);\n this.intentionalDisconnect = false;\n this.disconnectNotified = false;\n this.connectionFailure = null;\n this.lastDisconnectInfo = null;\n this.lifecycleReporter = options?.onLifecycleUpdate;\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`);\n this.emit(\"wait_queue_update\", update);\n options?.onQueueUpdate?.(update);\n },\n onMessage: (message: AdapterMessage) => {\n this.handleMessage(message);\n },\n onDisconnect: (reason) => {\n this.handleAdapterDisconnect(reason);\n },\n };\n\n try {\n await this.adapter.connect(serverName, this.loginResult, connectOptions);\n this.reportLifecycle(\"awaiting_initial_state\");\n await this.waitForInitialState(connectOptions);\n this.connected = true;\n this.connectionFailure = null;\n this.reportLifecycle(\"ready\");\n } catch (cause) {\n const error =\n cause instanceof ClientOperationError\n ? cause\n : new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message:\n cause instanceof Error ? cause.message : \"Connection failed\",\n cause,\n });\n this.intentionalDisconnect = false;\n this.adapter.disconnect();\n this.cleanup();\n if (!this.disconnectNotified) {\n this.disconnectNotified = true;\n this.disconnectEpoch += 1;\n this.lastDisconnectInfo = {\n intentional: false,\n reason: error.message,\n occurredAt: Date.now(),\n };\n this.reportLifecycle(\"disconnected\");\n }\n throw error;\n }\n }\n\n private waitForInitialState(options: ConnectOptions): Promise<void> {\n const timeoutMs =\n options.timeouts?.initialStateMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.initialStateMs;\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const cleanupWait = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n this.off(\"load_player\", onProgress);\n this.off(\"join_room\", onProgress);\n this.off(\"kick\", onKick);\n this.off(\"close_with_error\", onCloseWithError);\n this.off(\"server_error\", onServerError);\n this.off(\"disconnect\", onDisconnect);\n options.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanupWait();\n resolve();\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanupWait();\n reject(error);\n };\n\n const checkReady = (): void => {\n if (this.connectionFailure) {\n fail(this.connectionFailure);\n return;\n }\n if (this.player !== null && this.room !== null) succeed();\n };\n\n const onProgress = (): void => checkReady();\n const onKick = ({ reason }: ServerMessages[\"kick\"]): void => {\n fail(\n new ClientOperationError({\n category: \"kicked\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Kicked before initial state: ${reason ?? \"unknown\"}`,\n }),\n );\n };\n const onCloseWithError = ({\n error,\n }: ServerMessages[\"close_with_error\"]): void => {\n fail(\n new ClientOperationError({\n category: \"kicked\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Connection closed before initial state: ${error ?? \"unknown\"}`,\n }),\n );\n };\n const onServerError = ({\n error,\n }: ServerMessages[\"server_error\"]): void => {\n fail(\n new ClientOperationError({\n category: \"server_error\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Server error before initial state: ${String(error)}`,\n }),\n );\n };\n const onDisconnect = (info: ClientDisconnectInfo): void => {\n fail(\n new ClientOperationError({\n category: \"disconnected\",\n phase: \"awaiting_initial_state\",\n retryable: !info.intentional,\n message: `Disconnected before initial state${info.reason ? `: ${info.reason}` : \"\"}`,\n }),\n );\n };\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: \"Initial state wait cancelled\",\n }),\n );\n };\n\n this.on(\"load_player\", onProgress);\n this.on(\"join_room\", onProgress);\n this.on(\"kick\", onKick);\n this.on(\"close_with_error\", onCloseWithError);\n this.on(\"server_error\", onServerError);\n this.on(\"disconnect\", onDisconnect);\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n if (options.signal?.aborted) {\n onAbort();\n return;\n }\n\n checkReady();\n if (settled) return;\n\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category: \"initial_state_timeout\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: \"Waiting for initial player and room state timed out\",\n }),\n );\n }, timeoutMs);\n });\n }\n\n on<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n on(event: string, listener: (...args: unknown[]) => void): this;\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n off(event: string, listener: (...args: unknown[]) => void): this;\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n once(event: string, listener: (...args: unknown[]) => void): this;\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener);\n }\n\n emit<K extends keyof ServerMessages>(\n event: K,\n args: ServerMessages[K],\n ): boolean;\n emit(event: string, ...args: unknown[]): boolean;\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args);\n }\n\n /** Wait for a server event. Resolves with the event payload and rejects on timeout, abort, or disconnect. */\n waitFor<K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n ): Promise<ServerMessages[K]>;\n waitFor<K extends keyof ServerMessages>(\n event: K,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[K]>;\n waitFor<K extends keyof ServerMessages>(\n event: K,\n optionsOrTimeout?: number | ClientOperationOptions,\n ): Promise<ServerMessages[K]> {\n return this.waitForEvent(event, optionsOrTimeout);\n }\n\n private waitForEvent<K extends keyof ServerMessages>(\n event: K,\n optionsOrTimeout?: number | ClientOperationOptions,\n send?: () => void,\n matches?: ServerMessageMatcher<K>,\n ): Promise<ServerMessages[K]> {\n const options =\n typeof optionsOrTimeout === \"number\"\n ? { timeoutMs: optionsOrTimeout }\n : optionsOrTimeout;\n const timeoutMs =\n options?.timeoutMs ?? DEFAULT_CLIENT_CONNECTION_TIMEOUTS.requestMs;\n\n return new Promise<ServerMessages[K]>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n this.off(event, handler as unknown as (...args: unknown[]) => void);\n this.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const handler = ((args: ServerMessages[K]) => {\n if (settled) return;\n if (matches && !matches(args)) return;\n settled = true;\n cleanup();\n resolve(args);\n }) as ServerMessageHandler<K>;\n\n const rejectWith = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n };\n\n const onDisconnect = (info?: ClientDisconnectInfo): void => {\n rejectWith(\n new ClientOperationError({\n category: \"disconnected\",\n phase: \"ready\",\n retryable: !info?.intentional,\n message: `Disconnected while waiting for ${String(event)}${info?.reason ? `: ${info.reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n rejectWith(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"ready\",\n retryable: true,\n message: `Cancelled while waiting for ${String(event)}`,\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n if (Number.isFinite(timeoutMs)) {\n timer = setTimeout(() => {\n rejectWith(\n new ClientOperationError({\n category: \"operation_timeout\",\n phase: \"ready\",\n retryable: true,\n message: `Timed out waiting for ${String(event)}`,\n }),\n );\n }, timeoutMs);\n }\n\n this.on(event, handler);\n this.once(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n if (send) {\n try {\n send();\n } catch (cause) {\n if (cause instanceof ClientOperationError) {\n rejectWith(cause);\n return;\n }\n rejectWith(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"ready\",\n retryable: true,\n message: `Failed to send request for ${String(event)}`,\n cause,\n }),\n );\n }\n }\n });\n }\n\n private request<K extends keyof ServerMessages>(\n event: K,\n send: () => void,\n options?: ClientOperationOptions,\n matches?: ServerMessageMatcher<K>,\n ): Promise<ServerMessages[K]> {\n const previous = this.requestTails.get(event);\n const disconnectEpoch = this.disconnectEpoch;\n let releaseTurn = (): void => {};\n const turn = new Promise<void>((resolve) => {\n releaseTurn = resolve;\n });\n const tail = previous ? previous.then(() => turn) : turn;\n this.requestTails.set(event, tail);\n\n const operation = previous\n ? this.waitForRequestTurn(\n event,\n previous,\n disconnectEpoch,\n options?.signal,\n ).then(() => this.waitForEvent(event, options, send, matches))\n : this.waitForEvent(event, options, send, matches);\n\n return operation.finally(() => {\n releaseTurn();\n void tail.finally(() => {\n if (this.requestTails.get(event) === tail) {\n this.requestTails.delete(event);\n }\n });\n });\n }\n\n private waitForRequestTurn(\n event: keyof ServerMessages,\n previous: Promise<void>,\n disconnectEpoch: number,\n signal?: AbortSignal,\n ): Promise<void> {\n const aborted = (): ClientOperationError =>\n new ClientOperationError({\n category: \"aborted\",\n phase: \"ready\",\n retryable: true,\n message: `Cancelled before sending request for ${String(event)}`,\n });\n\n if (signal?.aborted) return Promise.reject(aborted());\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const cleanup = (): void => {\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(aborted());\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n void previous.then(() => {\n if (settled) return;\n settled = true;\n cleanup();\n if (this.disconnectEpoch !== disconnectEpoch) {\n const info = this.lastDisconnectInfo;\n reject(\n new ClientOperationError({\n category: \"disconnected\",\n phase: \"ready\",\n retryable: !info?.intentional,\n message: `Disconnected before sending request for ${String(event)}${info?.reason ? `: ${info.reason}` : \"\"}`,\n }),\n );\n return;\n }\n resolve();\n });\n });\n }\n\n sendMessage(message: string): void {\n this.adapter.sendMessage(message);\n }\n sendEmote(emote: number): void {\n this.adapter.sendEmote(emote);\n }\n sendSafe(safe: number): void {\n this.adapter.sendSafe(safe);\n }\n walk(x: number, y: number): void {\n this.adapter.walk(x, y);\n }\n sendFrame(frame: number, set?: boolean): void {\n this.adapter.sendFrame(frame, set);\n }\n snowball(x: number, y: number): void {\n this.adapter.snowball(x, y);\n }\n joinRoom(\n room: number,\n x?: number,\n y?: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"join_room\"]> {\n return this.request(\n \"join_room\",\n () => this.adapter.joinRoom(room, x, y),\n options,\n (response) => response.room === room,\n );\n }\n addItem(\n item: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"add_item\"]> {\n return this.request(\n \"add_item\",\n () => this.adapter.addItem(item),\n options,\n (response) => Number(response.item) === item,\n );\n }\n equipColor(item: number): void {\n this.adapter.equipColor(item);\n }\n equipHead(item: number): void {\n this.adapter.equipHead(item);\n }\n equipFace(item: number): void {\n this.adapter.equipFace(item);\n }\n equipNeck(item: number): void {\n this.adapter.equipNeck(item);\n }\n equipBody(item: number): void {\n this.adapter.equipBody(item);\n }\n equipHand(item: number): void {\n this.adapter.equipHand(item);\n }\n equipFeet(item: number): void {\n this.adapter.equipFeet(item);\n }\n equipFlag(item: number): void {\n this.adapter.equipFlag(item);\n }\n equipPhoto(item: number): void {\n this.adapter.equipPhoto(item);\n }\n buddyRequest(id: number): void {\n this.adapter.buddyRequest(id);\n }\n buddyAccept(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"buddy_accept\"]> {\n return this.request(\n \"buddy_accept\",\n () => this.adapter.buddyAccept(id),\n options,\n (response) => response.id === id,\n );\n }\n buddyReject(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"buddy_reject\"]> {\n return this.request(\n \"buddy_reject\",\n () => this.adapter.buddyReject(id),\n options,\n (response) => response.id === id,\n );\n }\n buddyRequestSeen(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"buddy_request_seen\"]> {\n return this.request(\n \"buddy_request_seen\",\n () => this.adapter.buddyRequestSeen(id),\n options,\n (response) => response.id === id,\n );\n }\n getBuddy(\n id: number,\n type: \"buddies\" | \"buddyRequests\",\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_buddy\"]> {\n return this.request(\n \"get_buddy\",\n () => this.adapter.getBuddy(id, type),\n options,\n (response) => response.id === id && response.type === type,\n );\n }\n findBuddy(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"buddy_find\"]> {\n return this.request(\n \"buddy_find\",\n () => this.adapter.findBuddy(id),\n options,\n );\n }\n removeBuddy(id: number): void {\n this.adapter.removeBuddy(id);\n }\n addIgnore(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"ignore_add\"]> {\n return this.request(\n \"ignore_add\",\n () => this.adapter.addIgnore(id),\n options,\n (response) => response.id === id,\n );\n }\n removeIgnore(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"ignore_remove\"]> {\n return this.request(\n \"ignore_remove\",\n () => this.adapter.removeIgnore(id),\n options,\n (response) => response.id === id,\n );\n }\n getPlayer(\n id: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_player\"]> {\n return this.request(\n \"get_player\",\n () => this.adapter.getPlayer(id),\n options,\n (response) => response.user.id === id,\n );\n }\n getAllSlots(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"slot\"]> {\n return this.request(\"slot\", () => this.adapter.getAllSlots(), options);\n }\n getMascots(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_mascots\"]> {\n return this.request(\n \"get_mascots\",\n () => this.adapter.getMascots(),\n options,\n );\n }\n sendPostcard(\n userId: number,\n cardId: string,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"send_postcard\"]> {\n return this.request(\n \"send_postcard\",\n () => this.adapter.sendPostcard(userId, cardId),\n options,\n );\n }\n getStamps(\n userId: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"stamps_result\"]> {\n return this.request(\n \"stamps_result\",\n () => this.adapter.getStamps(userId),\n options,\n );\n }\n getPostcards(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_postcards\"]> {\n return this.request(\n \"get_postcards\",\n () => this.adapter.getPostcards(),\n options,\n );\n }\n getIglooOpen(\n igloo: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_igloo_open\"]> {\n return this.request(\n \"get_igloo_open\",\n () => this.adapter.getIglooOpen(igloo),\n options,\n );\n }\n getIgloos(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_igloos\"]> {\n return this.request(\"get_igloos\", () => this.adapter.getIgloos(), options);\n }\n getPuffles(\n userId: number,\n options?: ClientOperationOptions & { isBackyard?: boolean },\n ): Promise<ServerMessages[\"get_puffles\"]> {\n return this.request(\n \"get_puffles\",\n () => this.adapter.getPuffles(userId, options?.isBackyard),\n options,\n (response) => response.userId === userId,\n );\n }\n getAllPuffles(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_all_puffles\"]> {\n return this.request(\n \"get_all_puffles\",\n () => this.adapter.getAllPuffles(),\n options,\n );\n }\n getPuffleWellbeing(\n puffle: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_wellbeing\"]> {\n return this.request(\n \"get_wellbeing\",\n () => this.adapter.getPuffleWellbeing(puffle),\n options,\n (response) => response.puffleId === puffle,\n );\n }\n playPuffle(puffle: number): void {\n this.adapter.playPuffle(puffle);\n }\n restPuffle(puffle: number): void {\n this.adapter.restPuffle(puffle);\n }\n buyPuffleItem(\n puffleId: number,\n item: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"buy_puffle_item\"]> {\n return this.request(\n \"buy_puffle_item\",\n () => this.adapter.buyPuffleItem(puffleId, item),\n options,\n (response) => response.puffleId === puffleId && response.item === item,\n );\n }\n walkPuffle(\n puffle: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_walking_puffle\"]> {\n return this.request(\n \"get_walking_puffle\",\n () => this.adapter.walkPuffle(puffle),\n options,\n (response) => response.puffle.id === puffle,\n );\n }\n /** CPJourney sends tower_init after its walking-puffle acknowledgement. */\n initializePuffleTower(): void {\n this.adapter.initializePuffleTower();\n }\n getBackyardSupplies(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"backyard_supplies\"]> {\n return this.request(\n \"backyard_supplies\",\n () => this.adapter.getBackyardSupplies(),\n options,\n );\n }\n adoptPuffle(\n type: number,\n name: string,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"adopt_puffle\"]> {\n return this.request(\n \"adopt_puffle\",\n () => this.adapter.adoptPuffle(type, name),\n options,\n );\n }\n getIglooLikes(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_igloo_likes\"]> {\n return this.request(\n \"get_igloo_likes\",\n () => this.adapter.getIglooLikes(),\n options,\n );\n }\n checkPuffleSprite(puffleSprite: boolean): void {\n this.adapter.checkPuffleSprite(puffleSprite);\n }\n joinIgloo(\n igloo: number,\n x?: number,\n y?: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"join_igloo\"]> {\n return this.request(\n \"join_igloo\",\n () => this.adapter.joinIgloo(igloo, x, y),\n options,\n (response) => response.igloo === igloo,\n );\n }\n getStoreMusic(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_store_music\"]> {\n return this.request(\n \"get_store_music\",\n () => this.adapter.getStoreMusic(),\n options,\n );\n }\n buyMusic(\n music: string,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"add_music\"]> {\n return this.request(\n \"add_music\",\n () => this.adapter.buyMusic(music),\n options,\n (response) => response.music === music,\n );\n }\n getIglooStoreItems(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_igloostore_items\"]> {\n return this.request(\n \"get_igloostore_items\",\n () => this.adapter.getIglooStoreItems(),\n options,\n );\n }\n buyFurniture(\n furniture: string,\n amount = 1,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"add_furniture\"]> {\n return this.request(\n \"add_furniture\",\n () => this.adapter.buyFurniture(furniture, amount),\n options,\n (response) =>\n response.furniture === furniture && response.amount === amount,\n );\n }\n updateIglooMusic(\n music: string,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"update_music\"]> {\n return this.request(\n \"update_music\",\n () => this.adapter.updateIglooMusic(music),\n options,\n (response) => response.music === music,\n );\n }\n updateIglooFurniture(\n furniture: ClientMessages[\"update_furniture\"][\"furniture\"],\n ): void {\n this.adapter.updateIglooFurniture(furniture);\n }\n autoUpdateIglooFurniture(\n furniture: ClientMessages[\"update_furniture_auto\"][\"furniture\"],\n ): void {\n this.adapter.autoUpdateIglooFurniture(furniture);\n }\n updateIglooType(type: number): void {\n this.adapter.updateIglooType(type);\n }\n openIgloo(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_open_status\"]> {\n return this.request(\n \"igloo_open_status\",\n () => this.adapter.openIgloo(),\n options,\n );\n }\n closeIglooBounds(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_bounds_status\"]> {\n return this.request(\n \"igloo_bounds_status\",\n () => this.adapter.closeIglooBounds(),\n options,\n );\n }\n likeIgloo(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_liked\"]> {\n return this.request(\"igloo_liked\", () => this.adapter.likeIgloo(), options);\n }\n openIglooEditor(): void {\n this.adapter.openIglooEditor();\n }\n closeIglooEditor(): void {\n this.adapter.closeIglooEditor();\n }\n gameOver(\n coins: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"game_over\"]> {\n return this.request(\n \"game_over\",\n () => this.adapter.gameOver(coins),\n options,\n );\n }\n collectStamp(\n stamp: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"stamp_earned\"]> {\n return this.request(\n \"stamp_earned\",\n () => this.adapter.collectStamp(stamp),\n options,\n );\n }\n\n sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\");\n this.intentionalDisconnect = true;\n this.reportLifecycle(\"disconnecting\");\n this.adapter.disconnect();\n this.handleAdapterDisconnect(\"client disconnect\");\n }\n\n private reportLifecycle(\n phase: Parameters<\n NonNullable<ConnectOptions[\"onLifecycleUpdate\"]>\n >[0][\"phase\"],\n ): void {\n this.lifecycleReporter?.({ phase, occurredAt: Date.now() });\n }\n\n private handleAdapterDisconnect(reason: string | null): void {\n if (this.disconnectNotified) return;\n this.disconnectNotified = true;\n const info: ClientDisconnectInfo = {\n intentional: this.intentionalDisconnect,\n reason,\n occurredAt: Date.now(),\n };\n this.disconnectEpoch += 1;\n this.lastDisconnectInfo = info;\n if (!info.intentional && !this.connected) {\n this.connectionFailure = new ClientOperationError({\n category: \"disconnected\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Disconnected before initial state${reason ? `: ${reason}` : \"\"}`,\n });\n }\n this.log?.(\n \"[disconnect]\",\n info.intentional ? \"connection closed\" : \"connection lost\",\n reason ?? \"\",\n );\n this.cleanup();\n this.reportLifecycle(\"disconnected\");\n this.emit(\"disconnect\", info);\n }\n\n private cleanup(): void {\n this.connected = false;\n this.player = null;\n this.room = null;\n this.users.clear();\n }\n\n private handleMessage(msg: AdapterMessage): void {\n const { action, args } = msg;\n let emitArgs: unknown = args;\n\n switch (action) {\n case \"load_player\": {\n const player = this.adapter.normalizePlayer(args);\n this.player = player;\n emitArgs = { user: player };\n this.log?.(\n \"[load_player]\",\n player.username,\n `id=${player.id}`,\n `coins=${player.coins}`,\n `inventory=${player.inventory.length}`,\n );\n break;\n }\n case \"join_room\": {\n const room = args.room as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = room;\n this.users.clear();\n const users: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n users.push(user);\n }\n emitArgs = { room, users };\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`);\n break;\n }\n case \"add_player\": {\n const user = this.adapter.normalizeUser(\n args.user as Record<string, unknown>,\n );\n this.users.set(user.id, user);\n emitArgs = { user };\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`);\n break;\n }\n case \"remove_player\": {\n const id = args.user as number;\n this.users.delete(id);\n this.log?.(\"[remove_player]\", `id=${id}`);\n break;\n }\n case \"send_position\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.x = args.x as number;\n user.y = args.y as number;\n }\n break;\n }\n case \"send_frame\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.frame = args.frame as number;\n }\n break;\n }\n case \"join_igloo\": {\n const igloo = args.igloo as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = igloo;\n this.users.clear();\n const iglooUsers: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n iglooUsers.push(user);\n }\n emitArgs = { ...args, users: iglooUsers };\n this.log?.(\n \"[join_igloo]\",\n `igloo=${igloo}`,\n `users=${iglooUsers.length}`,\n );\n break;\n }\n case \"update_player\": {\n const id = args.id as number;\n const slot = args.slot as string;\n const item = Number(args.item);\n const updateSlot = (user: RoomUser): void => {\n if (slot in user) {\n (user as Record<string, unknown>)[slot] = item;\n } else if (slot in user.meta || this.adapter.id === \"CPPS.lol\") {\n user.meta[slot] = item;\n }\n };\n const roomUser = this.users.get(id);\n if (roomUser) updateSlot(roomUser);\n if (this.player?.id === id && this.player !== roomUser) {\n updateSlot(this.player);\n }\n break;\n }\n case \"walk_puffle\": {\n const id = args.user as number;\n const user = this.users.get(id);\n if (user) {\n user.walking = args.puffle as number;\n user.meta.walkingPuffleType = args.type as number;\n }\n break;\n }\n case \"stop_walking\": {\n const id = args.user as number;\n const user = this.users.get(id);\n if (user) {\n user.walking = 0;\n user.meta.walkingPuffleType = undefined;\n }\n break;\n }\n case \"igloo_open_status\": {\n const status = args.status as number;\n if (this.player) {\n this.player.meta.iglooOpen = status;\n const roomUser = this.users.get(this.player.id);\n if (roomUser) roomUser.meta.iglooOpen = status;\n }\n break;\n }\n case \"remove_inventory\": {\n if (this.adapter.id !== \"CPPS.lol\" || !this.player) break;\n const item = Number(args.id);\n if (Number.isFinite(item)) {\n this.player.inventory = this.player.inventory.filter(\n (inventoryItem) => inventoryItem !== item,\n );\n }\n break;\n }\n case \"add_item\": {\n if (this.adapter.id !== \"CPJourney\" && this.adapter.id !== \"CPPS.lol\") {\n break;\n }\n const coins = args.coins;\n if (this.player && typeof coins === \"number\") {\n this.player.coins = coins;\n }\n const item = Number(args.item);\n if (\n this.player &&\n Number.isFinite(item) &&\n !this.player.inventory.includes(item)\n ) {\n this.player.inventory.push(item);\n }\n break;\n }\n case \"add_furniture\":\n case \"add_music\":\n case \"adopt_puffle\":\n case \"buy_puffle_item\":\n case \"game_over\": {\n // These captured coin values are CPJourney totals. Do not impose that\n // interpretation on adapters that reuse an action name differently.\n if (this.adapter.id !== \"CPJourney\") break;\n const coins = args.coins;\n if (this.player && typeof coins === \"number\") {\n this.player.coins = coins;\n }\n break;\n }\n case \"kick\": {\n const reason = (args as { reason?: string }).reason ?? \"unknown\";\n this.log?.(\"[kick]\", reason);\n if (!this.connected) {\n this.connectionFailure = new ClientOperationError({\n category: \"kicked\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Kicked before initial state: ${reason}`,\n });\n }\n this.cleanup();\n break;\n }\n case \"close_with_error\": {\n const error = (args as { error?: string }).error ?? \"unknown\";\n this.log?.(\"[kick]\", error);\n if (!this.connected) {\n this.connectionFailure = new ClientOperationError({\n category: \"kicked\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Connection closed before initial state: ${error}`,\n });\n }\n this.cleanup();\n break;\n }\n case \"error\": {\n const error = (args as { error?: string | number }).error ?? \"unknown\";\n if (!this.connected) {\n this.connectionFailure = new ClientOperationError({\n category: \"server_error\",\n phase: \"awaiting_initial_state\",\n retryable: true,\n message: `Server error before initial state: ${String(error)}`,\n });\n }\n break;\n }\n default: {\n if (!KNOWN_ACTIONS.has(action)) {\n this.log?.(`[unknown_packet]`, action, JSON.stringify(args));\n this.emit(\"unknown_packet\", { action, args });\n }\n break;\n }\n }\n\n const eventName = action === \"error\" ? \"server_error\" : action;\n this.emit(eventName, emitArgs);\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"wss://play.cpjourney.net\";\nconst DEFAULT_SECRET = \"skip\";\nconst INVALID_CREDENTIAL_MESSAGES = new Set([\n \"Penguin not found. Try Again?\",\n \"Incorrect password. NOTE: Passwords are CaSe SeNsiTIVE\",\n]);\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\";\n private gameToken: string | undefined;\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult> {\n this.resetLoginState();\n this.gameToken = \"token\" in options ? options.token : undefined;\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n let settled = false;\n const timeout = setTimeout(() => {\n fail(\n new ClientOperationError({\n category: \"login_timeout\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login timed out\",\n }),\n );\n }, operationOptions?.timeoutMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.loginMs);\n\n const cleanup = (): void => {\n clearTimeout(timeout);\n loginSocket.off(\"connect\", onConnect);\n loginSocket.off(\"message\", onMessage);\n loginSocket.off(\"connect_error\", onConnectError);\n loginSocket.off(\"disconnect\", onDisconnect);\n operationOptions?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket.disconnect();\n reject(error);\n };\n\n const succeed = (value: LoginResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket.disconnect();\n resolve(value);\n };\n\n const onConnect = (): void => {\n const secret = options.secret ?? DEFAULT_SECRET;\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : {\n username: options.username,\n password: options.password,\n secret,\n };\n\n loginSocket.emit(\"message\", { action: \"login\", args });\n };\n\n const onMessage = (msg: ServerMessage): void => {\n if (msg.action !== \"login\") return;\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n const message = response.message ?? \"Login failed\";\n if (response.message?.startsWith(\"Banned:\")) {\n this.loginStatus = \"banned\";\n }\n const invalidCredentials = INVALID_CREDENTIAL_MESSAGES.has(message);\n fail(\n new ClientOperationError({\n category:\n this.loginStatus === \"banned\"\n ? \"account_banned\"\n : invalidCredentials\n ? \"invalid_credentials\"\n : \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message,\n }),\n );\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n succeed({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection closed unexpectedly${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login cancelled\",\n }),\n );\n };\n\n if (operationOptions?.signal?.aborted) {\n onAbort();\n return;\n }\n\n loginSocket.on(\"connect\", onConnect);\n loginSocket.on(\"message\", onMessage);\n loginSocket.on(\"connect_error\", onConnectError);\n loginSocket.on(\"disconnect\", onDisconnect);\n operationOptions?.signal?.addEventListener(\"abort\", onAbort, {\n once: true,\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n this.reportLifecycle(options, \"transport_connecting\");\n await this.queueForServer(serverName, options);\n\n this.reportLifecycle(options, \"transport_connecting\");\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n const timeouts = this.connectionTimeouts(options);\n\n const forwardMessage = (message: ServerMessage): void => {\n if (\n message.action === \"game_auth\" ||\n message.action === \"wait_queue_update\"\n ) {\n return;\n }\n options?.onMessage?.(message);\n };\n const forwardDisconnect = (reason: string): void => {\n options?.onDisconnect?.(reason ?? null);\n };\n gameSocket.on(\"message\", forwardMessage);\n gameSocket.on(\"disconnect\", forwardDisconnect);\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let activePhase: \"transport_connecting\" | \"authenticating\" | \"queueing\" =\n \"transport_connecting\";\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n gameSocket.off(\"connect\", onConnect);\n gameSocket.off(\"message\", onMessage);\n gameSocket.off(\"connect_error\", onConnectError);\n gameSocket.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n gameSocket.off(\"message\", forwardMessage);\n gameSocket.off(\"disconnect\", forwardDisconnect);\n gameSocket.disconnect();\n this.socket = null;\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n\n const startTimer = (\n timeoutMs: number,\n category: \"transport_error\" | \"auth_timeout\" | \"queue_timeout\",\n phase: \"transport_connecting\" | \"authenticating\" | \"queueing\",\n message: string,\n ): void => {\n if (timer !== undefined) clearTimeout(timer);\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category,\n phase,\n retryable: true,\n message,\n }),\n );\n }, timeoutMs);\n };\n\n const onConnect = (): void => {\n activePhase = \"authenticating\";\n this.reportLifecycle(options, \"authenticating\");\n startTimer(\n timeouts.authenticationMs,\n \"auth_timeout\",\n \"authenticating\",\n \"Game authentication timed out\",\n );\n const authArgs: Record<string, unknown> = {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: this.gameToken ?? \"\",\n };\n\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: authArgs,\n });\n };\n\n const onMessage = (msg: ServerMessage): void => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n const update = msg.args as QueueUpdate;\n activePhase = \"queueing\";\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startTimer(\n timeouts.queueMs,\n \"queue_timeout\",\n \"queueing\",\n \"Game server queue stopped responding\",\n );\n break;\n }\n case \"game_auth\": {\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication failed\",\n }),\n );\n return;\n }\n\n this.reportLifecycle(options, \"joining_session\");\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n succeed();\n break;\n }\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Game connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: activePhase,\n retryable: true,\n message: `Disconnected before joining the game${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: activePhase,\n retryable: true,\n message: \"Game connection cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n gameSocket.on(\"connect\", onConnect);\n gameSocket.on(\"message\", onMessage);\n gameSocket.on(\"connect_error\", onConnectError);\n gameSocket.on(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startTimer(\n timeouts.transportMs,\n \"transport_error\",\n \"transport_connecting\",\n \"Game transport connection timed out\",\n );\n });\n\n return gameSocket;\n }\n\n private async queueForServer(\n serverName: string,\n options?: ConnectOptions,\n ): Promise<void> {\n const queueSocket = this.createSocket(\"/world/login/\");\n const timeouts = this.connectionTimeouts(options);\n this.reportLifecycle(options, \"queueing\");\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let completed = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n\n const startQueueIdleTimer = (): void => {\n if (timeout !== undefined) clearTimeout(timeout);\n timeout = setTimeout(() => {\n fail(\n new ClientOperationError({\n category: \"queue_timeout\",\n phase: \"queueing\",\n retryable: true,\n message: \"Server queue stopped responding\",\n }),\n );\n }, timeouts.queueMs);\n };\n\n const cleanup = (): void => {\n if (timeout !== undefined) clearTimeout(timeout);\n queueSocket.off(\"connect\", onConnect);\n queueSocket.off(\"message\", onMessage);\n queueSocket.off(\"disconnect\", onDisconnect);\n queueSocket.off(\"connect_error\", onConnectError);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n queueSocket.disconnect();\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n completed = true;\n cleanup();\n queueSocket.disconnect();\n resolve();\n };\n\n const onConnect = (): void => {\n queueSocket.emit(\"message\", {\n action: \"queue_server_join\",\n args: { server: serverName },\n });\n };\n\n const onMessage = (msg: ServerMessage): void => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n const update = msg.args as QueueUpdate;\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startQueueIdleTimer();\n break;\n }\n case \"queue_server_join\": {\n succeed();\n break;\n }\n }\n };\n\n const onDisconnect = (reason: string): void => {\n if (completed) return;\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"queueing\",\n retryable: true,\n message: `Queue connection closed unexpectedly${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"queueing\",\n retryable: true,\n message: `Queue connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"queueing\",\n retryable: true,\n message: \"Queue wait cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n queueSocket.on(\"connect\", onConnect);\n queueSocket.on(\"message\", onMessage);\n queueSocket.on(\"disconnect\", onDisconnect);\n queueSocket.on(\"connect_error\", onConnectError);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startQueueIdleTimer();\n });\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n const {\n id,\n username,\n displayName,\n joinTime,\n x,\n y,\n frame,\n walking,\n color,\n head,\n face,\n neck,\n body,\n hand,\n feet,\n flag,\n photo,\n ...rest\n } = raw;\n return {\n ...this.extractAppearance(raw),\n id: id as number,\n username: username as string,\n displayName: displayName as string | undefined,\n joinTime: joinTime as string | undefined,\n x: (x as number) ?? 0,\n y: (y as number) ?? 0,\n frame: (frame as number) ?? 0,\n walking: walking as number | undefined,\n meta: rest,\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n const {\n user: _user,\n coins,\n rank,\n inventory,\n furniture,\n flooring,\n buddies,\n buddyRequests,\n ignores,\n igloos,\n ...rest\n } = raw;\n return {\n ...normalized,\n _raw: raw,\n coins: (coins as number) ?? 0,\n rank: (rank as number) ?? 0,\n inventory: (inventory as number[]) ?? [],\n furniture: (furniture as unknown[]) ?? [],\n flooring: (flooring as unknown[]) ?? [],\n buddies: (user.buddies as Buddy[]) ?? [],\n buddyRequests: (user.buddyRequests as number[]) ?? [],\n ignores: (user.ignores as number[]) ?? [],\n igloos: (igloos as unknown[]) ?? [],\n meta: { ...normalized.meta, ...rest },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override buddyRequestSeen(id: number): void {\n this.send(\"buddy_request_seen\", { id });\n }\n\n override getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void {\n this.send(\"get_buddy\", { id, type });\n }\n\n override findBuddy(id: number): void {\n this.send(\"buddy_find\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getAllSlots(): void {\n this.send(\"get_all_slots\", {});\n }\n\n override getMascots(): void {\n this.send(\"get_mascots\", {});\n }\n\n override sendPostcard(userId: number, cardId: string): void {\n this.send(\"send_postcard\", { userId, cardId });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override getIgloos(): void {\n this.send(\"get_igloos\", {});\n }\n\n override getPuffles(userId: number, isBackyard?: boolean): void {\n this.send(\"get_puffles\", {\n userId,\n ...(isBackyard !== undefined ? { isBackyard } : {}),\n });\n }\n\n override getAllPuffles(): void {\n this.send(\"get_all_puffles\", {});\n }\n\n override getPuffleWellbeing(puffle: number): void {\n this.send(\"get_wellbeing\", { puffle });\n }\n\n override playPuffle(puffle: number): void {\n this.send(\"puffle_play\", { puffle });\n }\n\n override restPuffle(puffle: number): void {\n this.send(\"update_puffle_rest\", { puffle });\n }\n\n override buyPuffleItem(puffleId: number, item: number): void {\n this.send(\"puffle_buy_item\", { puffleId, item });\n }\n\n override walkPuffle(puffle: number): void {\n this.send(\"walk_puffle\", { puffle });\n }\n\n override initializePuffleTower(): void {\n this.send(\"tower_init\", {});\n }\n\n override getBackyardSupplies(): void {\n this.send(\"backyard_supplies\", {});\n }\n\n override adoptPuffle(type: number, name: string): void {\n this.send(\"adopt_puffle\", { type, name });\n }\n\n override getIglooLikes(): void {\n this.send(\"get_igloo_likes\", {});\n }\n\n override checkPuffleSprite(puffleSprite: boolean): void {\n this.send(\"check_puffle_sprite\", { puffleSprite });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override getStoreMusic(): void {\n this.send(\"get_store_music\", {});\n }\n\n override buyMusic(music: string): void {\n this.send(\"add_music\", { music });\n }\n\n override getIglooStoreItems(): void {\n this.send(\"get_igloostore_items\", {});\n }\n\n override buyFurniture(furniture: string, amount: number): void {\n this.send(\"add_furniture\", { furniture, amount });\n }\n\n override updateIglooMusic(music: string): void {\n this.send(\"update_music\", { music });\n }\n\n override updateIglooFurniture(\n furniture: Array<{\n furnitureId: number;\n x: number;\n y: number;\n rotation: number;\n frame: number;\n depth: number;\n slot?: number;\n }>,\n ): void {\n this.send(\"update_furniture\", { furniture });\n }\n\n override autoUpdateIglooFurniture(\n furniture: Array<{\n furnitureId: number;\n x: number;\n y: number;\n rotation: number;\n frame: number;\n depth: number;\n slot?: number;\n }>,\n ): void {\n this.send(\"update_furniture_auto\", { furniture });\n }\n\n override updateIglooType(type: number): void {\n this.send(\"update_igloo\", { type });\n }\n\n override openIgloo(): void {\n this.send(\"open_igloo\", {});\n }\n\n override closeIglooBounds(): void {\n this.send(\"close_igloo_bounds\", {});\n }\n\n override likeIgloo(): void {\n this.send(\"like_igloo\", {});\n }\n\n override openIglooEditor(): void {\n this.send(\"igloo_editor_open\", {});\n }\n\n override closeIglooEditor(): void {\n this.send(\"igloo_editor_closed\", {});\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n override getNinja(): void {\n this.send(\"get_ninja\", {});\n }\n\n override getMats(): void {\n this.send(\"get_waddles\", {});\n }\n\n override joinMatchmaking(): void {\n this.send(\"join_matchmaking\", {});\n }\n\n override leaveMatchmaking(): void {\n this.send(\"leave_matchmaking\", {});\n }\n\n override startGame(): void {\n this.send(\"start_game\", {});\n }\n\n override selectCard(slot: number): void {\n this.send(\"select_card\", { slot });\n }\n\n override loadAnimation(animation: string): void {\n this.send(\"load_animation\", { animation });\n }\n\n override joinMat(waddle: number): void {\n this.send(\"join_waddle\", { waddle });\n }\n\n protected createSocket(path: string): Socket {\n return io(BASE_URL, {\n ...this.socketIoOptions(BASE_URL),\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_URL = \"https://api.cplegacy.com/login\";\nconst TOKEN_LOGIN_URL = \"https://api.cplegacy.com/token_login\";\nconst BROWSER_ORIGIN = \"https://play.cplegacy.com\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n requires2FA: boolean;\n message?: string;\n wantedVersion?: string;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n};\n\n/**\n * Wraps a CPLegacy socket to normalize its positional message format\n * `(\"message\", action, args)` into the `{ action, args }` envelope\n * that the Client class expects.\n */\nfunction wrapSocket(raw: Socket): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (action: unknown, args: unknown) => {\n listener({ action, args: args ?? {} });\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class CplegacyAdapter extends BaseAdapter {\n readonly id = \"CPLegacy\";\n private version = \"\";\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult> {\n this.resetLoginState();\n const url = \"token\" in options ? TOKEN_LOGIN_URL : LOGIN_URL;\n const body: Record<string, unknown> =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : {\n username: options.username,\n password: options.password,\n version: this.version,\n };\n\n const controller = new AbortController();\n let timedOut = false;\n const onAbort = (): void => controller.abort();\n if (operationOptions?.signal?.aborted) {\n throw new ClientOperationError({\n category: \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login cancelled\",\n });\n }\n operationOptions?.signal?.addEventListener(\"abort\", onAbort, {\n once: true,\n });\n const timeout = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, operationOptions?.timeoutMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.loginMs);\n\n let data: LoginResponse;\n try {\n data = await this.postLogin(url, body, controller.signal);\n\n if (!data.success && data.wantedVersion) {\n this.version = data.wantedVersion;\n body.version = this.version;\n data = await this.postLogin(url, body, controller.signal);\n }\n } catch (cause) {\n if (controller.signal.aborted) {\n throw new ClientOperationError({\n category: timedOut ? \"login_timeout\" : \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: timedOut ? \"Login timed out\" : \"Login cancelled\",\n cause,\n });\n }\n throw new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message:\n cause instanceof Error\n ? `Login connection failed: ${cause.message}`\n : \"Login connection failed\",\n cause,\n });\n } finally {\n clearTimeout(timeout);\n operationOptions?.signal?.removeEventListener(\"abort\", onAbort);\n }\n\n if (!data.success) {\n this.loginMessage = data.message ?? null;\n const message = data.message ?? \"unknown error\";\n const invalidCredentials =\n /password|credential|incorrect|invalid login/i.test(message);\n throw new ClientOperationError({\n category: invalidCredentials ? \"invalid_credentials\" : \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message: `Login failed: ${message}`,\n });\n }\n\n const servers: ServerInfo[] = Object.entries(data.populations ?? {}).map(\n ([name, population]) => ({ name, population }),\n );\n\n return {\n servers,\n key: data.key,\n username: data.username,\n moderator: false,\n buddyWorlds: [],\n };\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n this.reportLifecycle(options, \"transport_connecting\");\n const rawSocket = this.createSocket(serverName);\n this.socket = rawSocket;\n const timeouts = this.connectionTimeouts(options);\n\n const forwardMessage = (\n action: string,\n args: Record<string, unknown> | undefined,\n ): void => {\n if (action === \"game_auth\" || action === \"wait_queue_update\") return;\n options?.onMessage?.({ action, args: args ?? {} });\n };\n const forwardDisconnect = (reason: string): void => {\n options?.onDisconnect?.(reason ?? null);\n };\n rawSocket.on(\"message\", forwardMessage);\n rawSocket.on(\"disconnect\", forwardDisconnect);\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let activePhase: \"transport_connecting\" | \"authenticating\" | \"queueing\" =\n \"transport_connecting\";\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n rawSocket.off(\"connect\", onConnect);\n rawSocket.off(\"message\", onMessage);\n rawSocket.off(\"connect_error\", onConnectError);\n rawSocket.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n rawSocket.off(\"message\", forwardMessage);\n rawSocket.off(\"disconnect\", forwardDisconnect);\n rawSocket.disconnect();\n this.socket = null;\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n\n const startTimer = (\n timeoutMs: number,\n category: \"transport_error\" | \"auth_timeout\" | \"queue_timeout\",\n phase: \"transport_connecting\" | \"authenticating\" | \"queueing\",\n message: string,\n ): void => {\n if (timer !== undefined) clearTimeout(timer);\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category,\n phase,\n retryable: true,\n message,\n }),\n );\n }, timeoutMs);\n };\n\n const onConnect = (): void => {\n activePhase = \"authenticating\";\n this.reportLifecycle(options, \"authenticating\");\n startTimer(\n timeouts.authenticationMs,\n \"auth_timeout\",\n \"authenticating\",\n \"Game authentication timed out\",\n );\n rawSocket.emit(\"message\", \"game_auth\", {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n token: \"\",\n });\n };\n\n const onMessage = (\n action: string,\n args: Record<string, unknown>,\n ): void => {\n switch (action) {\n case \"wait_queue_update\": {\n const update = args as unknown as QueueUpdate;\n activePhase = \"queueing\";\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startTimer(\n timeouts.queueMs,\n \"queue_timeout\",\n \"queueing\",\n \"Game server queue stopped responding\",\n );\n break;\n }\n case \"game_auth\": {\n const response = args as unknown as GameAuthResponse;\n if (!response.success) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication failed\",\n }),\n );\n return;\n }\n\n this.reportLifecycle(options, \"joining_session\");\n rawSocket.emit(\"message\", \"load_player\", {});\n rawSocket.emit(\"message\", \"join_server\", {});\n succeed();\n break;\n }\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Game connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: activePhase,\n retryable: true,\n message: `Disconnected before game authentication${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: activePhase,\n retryable: true,\n message: \"Game connection cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n rawSocket.on(\"connect\", onConnect);\n rawSocket.on(\"message\", onMessage);\n rawSocket.on(\"connect_error\", onConnectError);\n rawSocket.on(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startTimer(\n timeouts.transportMs,\n \"transport_error\",\n \"transport_connecting\",\n \"Game transport connection timed out\",\n );\n });\n\n // Return wrapped socket so Client receives normalized { action, args } messages\n return wrapSocket(rawSocket);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", action, args);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.realUsername as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n walking: (raw.walking as number) ?? undefined,\n meta: {\n internalUsername: raw.username as string,\n approved: raw.approved,\n emailVerified: raw.emailVerified,\n safeChat: raw.safeChat,\n tutorial: raw.tutorial,\n loginStreak: raw.loginStreak,\n walkingColor: raw.walkingColor,\n stampbookColor: raw.stampbookColor,\n stampbookClasp: raw.stampbookClasp,\n stampbookPattern: raw.stampbookPattern,\n ninjaPoints: raw.ninjaPoints,\n highestNinjaRank: raw.highestNinjaRank,\n character: raw.character,\n transformed: raw.transformed,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (user.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n buddies: [],\n buddyRequests:\n (raw.pending as Buddy[] | undefined)?.map((b) => b.id) ?? [],\n ignores: [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n private async postLogin(\n url: string,\n body: Record<string, unknown>,\n signal: AbortSignal,\n ): Promise<LoginResponse> {\n const resp = await fetch(url, {\n method: \"POST\",\n headers: this.connectionHeaders(BROWSER_ORIGIN, {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n }),\n body: JSON.stringify(body),\n signal,\n });\n\n return resp.json() as Promise<LoginResponse>;\n }\n\n protected createSocket(serverName: string): Socket {\n const wsUrl = `wss://${serverName.toLowerCase()}.server.cplegacy.com`;\n return io(wsUrl, {\n ...this.socketIoOptions(BROWSER_ORIGIN),\n path: \"/socket.io/\",\n parser: msgpackParser,\n transports: [\"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type {\n IglooFurniturePlacement,\n PlayerData,\n RoomUser,\n} from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\nimport { CppslolPacketSigner } from \"./cpps-lol-packet-signer.js\";\n\nconst BASE_URL = \"https://play.cpps.lol\";\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number | { bars: number; users: number }>;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n packetKey?: string;\n serverTime?: number;\n reconnectToken?: string;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class CppslolAdapter extends BaseAdapter {\n readonly id = \"CPPS.lol\";\n private signer: CppslolPacketSigner | null = null;\n private sessionToken = \"\";\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult> {\n this.resetLoginState();\n this.sessionToken = \"\";\n const loginSocket = this.createSocket(\"/world/login/\");\n\n return new Promise<LoginResult>((resolve, reject) => {\n let settled = false;\n const timeout = setTimeout(() => {\n fail(\n new ClientOperationError({\n category: \"login_timeout\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login timed out\",\n }),\n );\n }, operationOptions?.timeoutMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.loginMs);\n\n const cleanup = (): void => {\n clearTimeout(timeout);\n loginSocket.off(\"connect\", onConnect);\n loginSocket.off(\"message\", onMessage);\n loginSocket.off(\"connect_error\", onConnectError);\n loginSocket.off(\"disconnect\", onDisconnect);\n operationOptions?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n this.sessionToken = \"\";\n cleanup();\n loginSocket.disconnect();\n reject(error);\n };\n\n const succeed = (value: LoginResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket.disconnect();\n resolve(value);\n };\n\n const onConnect = (): void => {\n const action = \"token\" in options ? \"token_login\" : \"login\";\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n loginSocket.emit(\"message\", { action, args });\n };\n\n const onMessage = (message: ServerMessage): void => {\n if (message.action !== \"login\") return;\n const response = message.args as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n const errorMessage = response.message ?? \"Login failed\";\n const invalidCredentials =\n /password|credential|incorrect|invalid login/i.test(errorMessage);\n fail(\n new ClientOperationError({\n category: invalidCredentials\n ? \"invalid_credentials\"\n : \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message: errorMessage,\n }),\n );\n return;\n }\n\n // CPPS.lol's population value is the bar count shown in its server browser.\n // `users` is the exact number of penguins online.\n const servers = Object.entries(response.populations).map(\n ([name, population]) =>\n typeof population === \"number\"\n ? { name, population }\n : {\n name,\n population: population.bars,\n users: population.users,\n },\n );\n\n this.sessionToken = \"token\" in options ? options.token : \"\";\n\n succeed({\n servers,\n key: response.key,\n username: response.username,\n moderator: false,\n buddyWorlds: [],\n });\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection closed unexpectedly${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login cancelled\",\n }),\n );\n };\n\n if (operationOptions?.signal?.aborted) {\n onAbort();\n return;\n }\n\n loginSocket.on(\"connect\", onConnect);\n loginSocket.on(\"message\", onMessage);\n loginSocket.on(\"connect_error\", onConnectError);\n loginSocket.on(\"disconnect\", onDisconnect);\n operationOptions?.signal?.addEventListener(\"abort\", onAbort, {\n once: true,\n });\n });\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n this.signer = null;\n this.reportLifecycle(options, \"transport_connecting\");\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n const timeouts = this.connectionTimeouts(options);\n\n const forwardMessage = (message: ServerMessage): void => {\n if (\n message.action === \"game_auth\" ||\n message.action === \"wait_queue_update\"\n ) {\n return;\n }\n options?.onMessage?.(message);\n };\n const forwardDisconnect = (reason: string): void => {\n this.signer = null;\n this.sessionToken = \"\";\n options?.onDisconnect?.(reason ?? null);\n };\n gameSocket.on(\"message\", forwardMessage);\n gameSocket.on(\"disconnect\", forwardDisconnect);\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let activePhase: \"transport_connecting\" | \"authenticating\" | \"queueing\" =\n \"transport_connecting\";\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n gameSocket.off(\"connect\", onConnect);\n gameSocket.off(\"message\", onMessage);\n gameSocket.off(\"connect_error\", onConnectError);\n gameSocket.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n gameSocket.off(\"message\", forwardMessage);\n gameSocket.off(\"disconnect\", forwardDisconnect);\n this.signer = null;\n this.sessionToken = \"\";\n gameSocket.disconnect();\n this.socket = null;\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n\n const startTimer = (\n timeoutMs: number,\n category: \"transport_error\" | \"auth_timeout\" | \"queue_timeout\",\n phase: \"transport_connecting\" | \"authenticating\" | \"queueing\",\n message: string,\n ): void => {\n if (timer !== undefined) clearTimeout(timer);\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category,\n phase,\n retryable: true,\n message,\n }),\n );\n }, timeoutMs);\n };\n\n const onConnect = (): void => {\n activePhase = \"authenticating\";\n this.reportLifecycle(options, \"authenticating\");\n startTimer(\n timeouts.authenticationMs,\n \"auth_timeout\",\n \"authenticating\",\n \"Game authentication timed out\",\n );\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: true,\n token: this.sessionToken,\n },\n });\n };\n\n const onMessage = (message: ServerMessage): void => {\n switch (message.action) {\n case \"wait_queue_update\": {\n const update = message.args as QueueUpdate;\n activePhase = \"queueing\";\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startTimer(\n timeouts.queueMs,\n \"queue_timeout\",\n \"queueing\",\n \"Game server queue stopped responding\",\n );\n break;\n }\n case \"game_auth\": {\n const response = message.args as GameAuthResponse;\n if (\n !response.success ||\n !response.packetKey ||\n typeof response.serverTime !== \"number\"\n ) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication failed\",\n }),\n );\n return;\n }\n\n try {\n this.signer = new CppslolPacketSigner(\n response.packetKey,\n response.serverTime,\n );\n this.sessionToken = response.token ?? this.sessionToken;\n } catch (cause) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication returned invalid signing data\",\n cause,\n }),\n );\n return;\n }\n\n this.reportLifecycle(options, \"joining_session\");\n gameSocket.emit(\"message\", { action: \"join_server\", args: {} });\n succeed();\n break;\n }\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Game connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: activePhase,\n retryable: true,\n message: `Disconnected before game authentication${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: activePhase,\n retryable: true,\n message: \"Game connection cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n gameSocket.on(\"connect\", onConnect);\n gameSocket.on(\"message\", onMessage);\n gameSocket.on(\"connect_error\", onConnectError);\n gameSocket.on(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startTimer(\n timeouts.transportMs,\n \"transport_error\",\n \"transport_connecting\",\n \"Game transport connection timed out\",\n );\n });\n\n return gameSocket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket || !this.signer) {\n throw new Error(\"Not connected or authenticated\");\n }\n this.socket.emit(\"message\", this.signer.sign(action, args));\n }\n\n disconnect(): void {\n this.signer = null;\n this.sessionToken = \"\";\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName:\n (raw.nickname as string) ??\n (raw.displayName as string) ??\n (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n toy: raw.toy,\n headLayer: raw.headLayer,\n headColor: raw.headColor,\n headLayerColor: raw.headLayerColor,\n faceLayer: raw.faceLayer,\n faceColor: raw.faceColor,\n faceLayerColor: raw.faceLayerColor,\n neckLayer: raw.neckLayer,\n neckColor: raw.neckColor,\n neckLayerColor: raw.neckLayerColor,\n bodyLayer: raw.bodyLayer,\n bodyColor: raw.bodyColor,\n bodyLayerColor: raw.bodyLayerColor,\n handLayer: raw.handLayer,\n handColor: raw.handColor,\n handLayerColor: raw.handLayerColor,\n feetLayer: raw.feetLayer,\n feetColor: raw.feetColor,\n feetLayerColor: raw.feetLayerColor,\n flagLayer: raw.flagLayer,\n flagColor: raw.flagColor,\n flagLayerColor: raw.flagLayerColor,\n photoLayer: raw.photoLayer,\n photoColor: raw.photoColor,\n photoLayerColor: raw.photoLayerColor,\n flags: raw.flags,\n isMascot: raw.isMascot,\n invisible: raw.invisible,\n isAfk: raw.isAfk,\n connectionUnstable: raw.connectionUnstable,\n transform: raw.transform,\n playercardMusic: raw.playercardMusic,\n outfits: raw.outfits,\n relationships: raw.relationships,\n likes: raw.likes,\n features: raw.features,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n return {\n ...normalized,\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: (raw.furniture as unknown[]) ?? [],\n flooring: (raw.flooring as unknown[]) ?? [],\n buddies: (raw.buddies as PlayerData[\"buddies\"]) ?? [],\n buddyRequests: (raw.buddyRequests as number[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n meta: {\n ...normalized.meta,\n snowflakes: raw.snowflakes,\n postcards: raw.postcards,\n mascots: raw.mascots,\n pets: raw.pets,\n locations: raw.locations,\n },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.sendPackedEmote(1, emote);\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { set: set ?? true, frame });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.leaveWaddle();\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item: String(item) });\n }\n\n private updatePlayer(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipColor(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipHead(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipFace(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipNeck(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipBody(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipHand(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipFeet(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipFlag(item: number): void {\n this.updatePlayer(item);\n }\n\n override equipPhoto(item: number): void {\n this.updatePlayer(item);\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.leaveWaddle();\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override updateIglooFurniture(furniture: IglooFurniturePlacement[]): void {\n this.send(\"update_furniture\", { furniture });\n }\n\n openIglooRaw(): void {\n this.send(\"open_igloo\", {});\n }\n\n sendPackedEmote(pack: number, emote: number): void {\n this.send(\"send_emote\", { pack, emote });\n }\n\n updateLayeredPlayer(item: number): void {\n this.send(\"update_player\", { item, layer: true });\n }\n\n acceptMature(): void {\n this.send(\"accept_mature\", {});\n }\n\n removeInventory(item: number): void {\n this.send(\"remove_inventory\", { item });\n }\n\n getSnowflakeState(): void {\n this.send(\"get_snowflake_state\", {});\n }\n\n getPets(userId: number): void {\n this.send(\"get_pets\", { userId });\n }\n\n getIglooContest(): void {\n this.send(\"get_igloo_contest\", {});\n }\n\n getIglooLikesFor(iglooId: number): void {\n this.send(\"get_igloo_likes\", { iglooId });\n }\n\n likeIglooById(iglooId: number): void {\n this.send(\"like_igloo\", { iglooId });\n }\n\n sendMail(recipient: number, postcardId: number): void {\n this.send(\"send_mail\", { recipient, postcardId });\n }\n\n marryRequest(id: number): void {\n this.send(\"marry_request\", { id });\n }\n\n leaveWaddle(): void {\n this.send(\"leave_waddle\", {});\n }\n\n protected createSocket(path: string): Socket {\n return io(BASE_URL, {\n ...this.socketIoOptions(BASE_URL),\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { createHmac } from \"node:crypto\";\n\nexport type CppslolSignedPacket = {\n action: string;\n args: Record<string, unknown>;\n seq: number;\n ts: number;\n mac: string;\n};\n\n/** Canonical JSON encoding used by CPPS.lol before calculating a packet MAC. */\nexport function canonicalizeCppslolPacketValue(value: unknown): string {\n if (value === null || typeof value !== \"object\") {\n return JSON.stringify(value) ?? \"null\";\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(canonicalizeCppslolPacketValue).join(\",\")}]`;\n }\n\n const object = value as Record<string, unknown>;\n return `{${Object.keys(object)\n .sort()\n .map(\n (key) =>\n `${JSON.stringify(key)}:${canonicalizeCppslolPacketValue(object[key])}`,\n )\n .join(\",\")}}`;\n}\n\nexport class CppslolPacketSigner {\n private sequence = 0;\n private readonly clockOffsetMs: number;\n private readonly key: Buffer;\n\n constructor(\n packetKey: string,\n serverTime: number,\n private readonly now: () => number = Date.now,\n ) {\n if (!/^(?:[0-9a-fA-F]{2})+$/.test(packetKey)) {\n throw new Error(\"CPPS.lol returned an invalid packet key\");\n }\n if (!Number.isFinite(serverTime)) {\n throw new Error(\"CPPS.lol returned an invalid server time\");\n }\n\n this.key = Buffer.from(packetKey, \"hex\");\n this.clockOffsetMs = serverTime - this.now();\n }\n\n sign(action: string, args: Record<string, unknown>): CppslolSignedPacket {\n const seq = ++this.sequence;\n const ts = this.now() + this.clockOffsetMs;\n const input = `${seq}.${ts}.${action}.${canonicalizeCppslolPacketValue(args)}`;\n const mac = createHmac(\"sha256\", this.key).update(input).digest(\"hex\");\n\n return { action, args, seq, ts, mac };\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { io, type Socket } from \"socket.io-client\";\nimport nacl from \"tweetnacl\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst CRUMBS_URL =\n \"https://media8.newcp.net/assets/media/crumbs/en/crumbs.json\";\n\ntype WorldConfig = {\n id?: number;\n host: string;\n path: string;\n login?: boolean;\n};\n\ntype CrumbsWorlds = Record<string, WorldConfig>;\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\nclass Encryptor {\n private aesKey: Buffer | null = null;\n private keypair = nacl.box.keyPair();\n\n get publicKey(): string {\n return Buffer.from(this.keypair.publicKey).toString(\"base64\");\n }\n\n get encrypted(): boolean {\n return this.aesKey !== null;\n }\n\n acquireKey(encryptedB64: string, serverPubKeyB64: string): string | null {\n const data = Buffer.from(encryptedB64, \"base64\");\n const serverPubKey = Buffer.from(serverPubKeyB64, \"base64\");\n const nonce = data.subarray(0, nacl.box.nonceLength);\n const ciphertext = data.subarray(nacl.box.nonceLength);\n const plaintext = nacl.box.open(\n new Uint8Array(ciphertext),\n new Uint8Array(nonce),\n new Uint8Array(serverPubKey),\n this.keypair.secretKey,\n );\n return plaintext ? new TextDecoder().decode(plaintext) : null;\n }\n\n setKey(keyString: string): void {\n this.aesKey = Buffer.from(keyString, \"utf-8\");\n }\n\n encrypt(plaintext: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const iv = randomBytes(16);\n const cipher = createCipheriv(\"aes-256-cbc\", this.aesKey, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf-8\"),\n cipher.final(),\n ]);\n const result = Buffer.concat([iv, encrypted]);\n return result.toString(\"base64\");\n }\n\n decrypt(data: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const buf = Buffer.from(data, \"base64\");\n const iv = buf.subarray(0, 16);\n const ciphertext = buf.subarray(16);\n const decipher = createDecipheriv(\"aes-256-cbc\", this.aesKey, iv);\n return Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf-8\");\n }\n\n encode(data: Record<string, unknown>): string {\n return this.encrypted\n ? this.encrypt(JSON.stringify(data))\n : JSON.stringify(data);\n }\n\n decode(data: unknown): Record<string, unknown> {\n if (this.encrypted && typeof data === \"string\") {\n return JSON.parse(this.decrypt(data)) as Record<string, unknown>;\n }\n return typeof data === \"string\"\n ? (JSON.parse(data) as Record<string, unknown>)\n : (data as Record<string, unknown>);\n }\n}\n\nfunction performHandshake(\n socket: Socket,\n encryptor: Encryptor,\n signal: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = (): void => {\n socket.off(\"handshake\", onHandshake);\n signal.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: Error): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n };\n\n const onAbort = (): void => {\n fail(new Error(\"Handshake cancelled\"));\n };\n\n const onHandshake = (\n encryptedKey: string,\n serverPubKeyB64: string,\n ): void => {\n try {\n const raw = encryptor.acquireKey(encryptedKey, serverPubKeyB64);\n if (!raw) {\n fail(new Error(\"Failed to decrypt handshake key\"));\n return;\n }\n\n const parsed = JSON.parse(raw) as { key: string; time?: number };\n if (\n parsed.time &&\n typeof parsed.time === \"number\" &&\n Math.abs(Date.now() - parsed.time) > 300_000\n ) {\n fail(new Error(\"Server time desync\"));\n return;\n }\n\n encryptor.setKey(parsed.key);\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n } catch (cause) {\n fail(cause instanceof Error ? cause : new Error(\"Handshake failed\"));\n }\n };\n\n if (signal.aborted) {\n onAbort();\n return;\n }\n\n socket.on(\"handshake\", onHandshake);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n socket.emit(\"handshake\", encryptor.publicKey);\n });\n}\n\n/**\n * Wraps a NewCP socket to decrypt incoming messages into the\n * `{ action, args }` envelope that the Client class expects.\n */\nfunction wrapSocket(raw: Socket, encryptor: Encryptor): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (msg: unknown) => {\n try {\n const decoded = encryptor.decode(msg);\n listener({ action: decoded.action, args: decoded.args ?? {} });\n } catch {\n // Skip malformed messages\n }\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class NewcpAdapter extends BaseAdapter {\n readonly id = \"NewCP\";\n private encryptor = new Encryptor();\n private worlds: CrumbsWorlds | null = null;\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult> {\n this.resetLoginState();\n const controller = new AbortController();\n let timedOut = false;\n const onCallerAbort = (): void => controller.abort();\n if (operationOptions?.signal?.aborted) {\n throw new ClientOperationError({\n category: \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login cancelled\",\n });\n }\n operationOptions?.signal?.addEventListener(\"abort\", onCallerAbort, {\n once: true,\n });\n const timeout = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, operationOptions?.timeoutMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.loginMs);\n\n let loginSocket: Socket | null = null;\n try {\n if (!this.worlds) {\n await this.loadWorlds(controller.signal);\n }\n\n const loginWorld = Object.values(this.worlds ?? {}).find((w) => w.login);\n if (!loginWorld) {\n throw new ClientOperationError({\n category: \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message: \"Login world not found in crumbs\",\n });\n }\n\n loginSocket = this.createSocket(loginWorld.host, loginWorld.path);\n this.encryptor = new Encryptor();\n\n return await new Promise<LoginResult>((resolve, reject) => {\n let settled = false;\n\n const cleanup = (): void => {\n loginSocket?.off(\"connect\", onConnect);\n loginSocket?.off(\"message\", onMessage);\n loginSocket?.off(\"connect_error\", onConnectError);\n loginSocket?.off(\"disconnect\", onDisconnect);\n controller.signal.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket?.disconnect();\n reject(error);\n };\n\n const succeed = (result: LoginResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket?.disconnect();\n resolve(result);\n };\n\n const onConnect = async (): Promise<void> => {\n try {\n if (!loginSocket) return;\n await performHandshake(\n loginSocket,\n this.encryptor,\n controller.signal,\n );\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n const encrypted = this.encryptor.encode({ action: \"login\", args });\n loginSocket.emit(\"message\", encrypted);\n } catch (cause) {\n if (settled) return;\n fail(\n new ClientOperationError({\n category: controller.signal.aborted\n ? timedOut\n ? \"login_timeout\"\n : \"aborted\"\n : \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: controller.signal.aborted\n ? timedOut\n ? \"Login timed out\"\n : \"Login cancelled\"\n : cause instanceof Error\n ? `Login handshake failed: ${cause.message}`\n : \"Login handshake failed\",\n cause,\n }),\n );\n }\n };\n\n const onMessage = (message: unknown): void => {\n try {\n const decoded = this.encryptor.decode(message);\n if (decoded.action !== \"login\") return;\n const response = decoded.args as unknown as LoginResponse;\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n const responseMessage = response.message ?? \"Login failed\";\n const invalidCredentials =\n /password|credential|incorrect|invalid login/i.test(\n responseMessage,\n );\n fail(\n new ClientOperationError({\n category: invalidCredentials\n ? \"invalid_credentials\"\n : \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message: responseMessage,\n }),\n );\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(\n response.populations ?? {},\n ).map(([name, population]) => ({ name, population }));\n succeed({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator ?? false,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n } catch (cause) {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Invalid login response\",\n cause,\n }),\n );\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection closed unexpectedly${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: timedOut ? \"login_timeout\" : \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: timedOut ? \"Login timed out\" : \"Login cancelled\",\n }),\n );\n };\n\n loginSocket?.on(\"connect\", onConnect);\n loginSocket?.on(\"message\", onMessage);\n loginSocket?.on(\"connect_error\", onConnectError);\n loginSocket?.on(\"disconnect\", onDisconnect);\n controller.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n } catch (cause) {\n if (cause instanceof ClientOperationError) throw cause;\n if (controller.signal.aborted) {\n throw new ClientOperationError({\n category: timedOut ? \"login_timeout\" : \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: timedOut ? \"Login timed out\" : \"Login cancelled\",\n cause,\n });\n }\n throw new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: cause instanceof Error ? cause.message : \"Login failed\",\n cause,\n });\n } finally {\n clearTimeout(timeout);\n operationOptions?.signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n if (!this.worlds) {\n await this.loadWorlds(options?.signal);\n }\n\n const worldConfig = this.worlds?.[serverName];\n if (!worldConfig)\n throw new Error(`World config not found for: ${serverName}`);\n\n this.encryptor = new Encryptor();\n this.reportLifecycle(options, \"transport_connecting\");\n const gameSocket = this.createSocket(worldConfig.host, worldConfig.path);\n this.socket = gameSocket;\n const timeouts = this.connectionTimeouts(options);\n const phaseController = new AbortController();\n\n const forwardMessage = (message: unknown): void => {\n try {\n const decoded = this.encryptor.decode(message);\n const action = decoded.action;\n if (typeof action !== \"string\") return;\n if (action === \"game_auth\" || action === \"wait_queue_update\") return;\n options?.onMessage?.({\n action,\n args: (decoded.args as Record<string, unknown> | undefined) ?? {},\n });\n } catch {\n // Malformed messages are ignored by the protocol adapter.\n }\n };\n const forwardDisconnect = (reason: string): void => {\n options?.onDisconnect?.(reason ?? null);\n };\n gameSocket.on(\"message\", forwardMessage);\n gameSocket.on(\"disconnect\", forwardDisconnect);\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let activePhase: \"transport_connecting\" | \"authenticating\" | \"queueing\" =\n \"transport_connecting\";\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n gameSocket.off(\"connect\", onConnect);\n gameSocket.off(\"message\", onMessage);\n gameSocket.off(\"connect_error\", onConnectError);\n gameSocket.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n phaseController.abort();\n gameSocket.off(\"message\", forwardMessage);\n gameSocket.off(\"disconnect\", forwardDisconnect);\n gameSocket.disconnect();\n this.socket = null;\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n\n const startTimer = (\n timeoutMs: number,\n category: \"transport_error\" | \"auth_timeout\" | \"queue_timeout\",\n phase: \"transport_connecting\" | \"authenticating\" | \"queueing\",\n message: string,\n ): void => {\n if (timer !== undefined) clearTimeout(timer);\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category,\n phase,\n retryable: true,\n message,\n }),\n );\n }, timeoutMs);\n };\n\n const onConnect = async (): Promise<void> => {\n activePhase = \"authenticating\";\n this.reportLifecycle(options, \"authenticating\");\n startTimer(\n timeouts.authenticationMs,\n \"auth_timeout\",\n \"authenticating\",\n \"Game authentication timed out\",\n );\n try {\n await performHandshake(\n gameSocket,\n this.encryptor,\n phaseController.signal,\n );\n if (settled) return;\n\n const encrypted = this.encryptor.encode({\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n },\n });\n gameSocket.emit(\"message\", encrypted);\n } catch (cause) {\n if (settled) return;\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"authenticating\",\n retryable: true,\n message:\n cause instanceof Error\n ? `Game handshake failed: ${cause.message}`\n : \"Game handshake failed\",\n cause,\n }),\n );\n }\n };\n\n const onMessage = (message: unknown): void => {\n try {\n const decoded = this.encryptor.decode(message);\n\n switch (decoded.action) {\n case \"wait_queue_update\": {\n const update = decoded.args as unknown as QueueUpdate;\n activePhase = \"queueing\";\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startTimer(\n timeouts.queueMs,\n \"queue_timeout\",\n \"queueing\",\n \"Game server queue stopped responding\",\n );\n break;\n }\n case \"game_auth\": {\n const response = decoded.args as unknown as GameAuthResponse;\n if (!response.success) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication failed\",\n }),\n );\n return;\n }\n\n this.reportLifecycle(options, \"joining_session\");\n const joinEncrypted = this.encryptor.encode({\n action: \"join_server\",\n args: {},\n });\n gameSocket.emit(\"message\", joinEncrypted);\n succeed();\n break;\n }\n }\n } catch {\n // Ignore decode errors during auth phase\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Game connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: activePhase,\n retryable: true,\n message: `Disconnected before game authentication${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: activePhase,\n retryable: true,\n message: \"Game connection cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n gameSocket.on(\"connect\", onConnect);\n gameSocket.on(\"message\", onMessage);\n gameSocket.on(\"connect_error\", onConnectError);\n gameSocket.on(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startTimer(\n timeouts.transportMs,\n \"transport_error\",\n \"transport_connecting\",\n \"Game transport connection timed out\",\n );\n });\n\n return wrapSocket(gameSocket, this.encryptor);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n const encrypted = this.encryptor.encode({ action, args });\n this.socket.emit(\"message\", encrypted);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: raw.nickname as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n nickname: raw.nickname,\n registrationDate: raw.registrationDate,\n customNameColor: raw.customNameColor,\n customBubbleColor: raw.customBubbleColor,\n customBubbleTextColor: raw.customBubbleTextColor,\n wallHacks: raw.wallHacks,\n moderator: raw.moderator,\n character: raw.character,\n approved: raw.approved,\n walking: raw.walking,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n buddies: (raw.buddies as Buddy[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n flooring: (raw.floorings as unknown[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n protected createSocket(host: string, path: string): Socket {\n return io(host, {\n ...this.socketIoOptions(host),\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n\n private async loadWorlds(signal?: AbortSignal): Promise<void> {\n const resp = await fetch(CRUMBS_URL, {\n headers: this.connectionHeaders(CRUMBS_URL),\n signal,\n });\n if (!resp.ok) throw new Error(`Failed to fetch crumbs: ${resp.status}`);\n const crumbs = (await resp.json()) as { worlds: CrumbsWorlds };\n this.worlds = crumbs.worlds;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport { ClientOperationError } from \"../errors.js\";\nimport {\n type ClientOperationOptions,\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS,\n} from \"../lifecycle.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"https://play.penguinorigins.online\";\n\ntype LoginResponse = {\n success: boolean;\n message?: string;\n username: string;\n key: string;\n populations: Record<string, number>;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class PenguinoriginsAdapter extends BaseAdapter {\n readonly id = \"PenguinOrigins\";\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n operationOptions?: ClientOperationOptions,\n ): Promise<LoginResult> {\n this.resetLoginState();\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n let settled = false;\n const timeout = setTimeout(() => {\n fail(\n new ClientOperationError({\n category: \"login_timeout\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login timed out\",\n }),\n );\n }, operationOptions?.timeoutMs ??\n DEFAULT_CLIENT_CONNECTION_TIMEOUTS.loginMs);\n\n const cleanup = (): void => {\n clearTimeout(timeout);\n loginSocket.off(\"connect\", onConnect);\n loginSocket.off(\"message\", onMessage);\n loginSocket.off(\"connect_error\", onConnectError);\n loginSocket.off(\"disconnect\", onDisconnect);\n operationOptions?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket.disconnect();\n reject(error);\n };\n\n const succeed = (value: LoginResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n loginSocket.disconnect();\n resolve(value);\n };\n\n const onConnect = (): void => {\n const action = \"token\" in options ? \"token_login\" : \"login\";\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n loginSocket.emit(\"message\", { action, args });\n };\n\n const onMessage = (msg: ServerMessage): void => {\n if (msg.action !== \"login\") return;\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n this.loginMessage = response.message ?? null;\n const message = response.message ?? \"Login failed\";\n const invalidCredentials =\n /password|credential|incorrect|invalid login/i.test(message);\n fail(\n new ClientOperationError({\n category: invalidCredentials\n ? \"invalid_credentials\"\n : \"login_rejected\",\n phase: \"transport_connecting\",\n retryable: false,\n message,\n }),\n );\n return;\n }\n\n const servers = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n succeed({\n servers,\n key: response.key,\n username: response.username,\n moderator: false,\n buddyWorlds: [],\n });\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Login connection closed unexpectedly${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: \"transport_connecting\",\n retryable: true,\n message: \"Login cancelled\",\n }),\n );\n };\n\n if (operationOptions?.signal?.aborted) {\n onAbort();\n return;\n }\n\n loginSocket.on(\"connect\", onConnect);\n loginSocket.on(\"message\", onMessage);\n loginSocket.on(\"connect_error\", onConnectError);\n loginSocket.on(\"disconnect\", onDisconnect);\n operationOptions?.signal?.addEventListener(\"abort\", onAbort, {\n once: true,\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n this.reportLifecycle(options, \"transport_connecting\");\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n const timeouts = this.connectionTimeouts(options);\n\n const forwardMessage = (message: ServerMessage): void => {\n if (\n message.action === \"game_auth\" ||\n message.action === \"wait_queue_update\"\n ) {\n return;\n }\n options?.onMessage?.(message);\n };\n const forwardDisconnect = (reason: string): void => {\n options?.onDisconnect?.(reason ?? null);\n };\n gameSocket.on(\"message\", forwardMessage);\n gameSocket.on(\"disconnect\", forwardDisconnect);\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let activePhase: \"transport_connecting\" | \"authenticating\" | \"queueing\" =\n \"transport_connecting\";\n\n const cleanup = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n gameSocket.off(\"connect\", onConnect);\n gameSocket.off(\"message\", onMessage);\n gameSocket.off(\"connect_error\", onConnectError);\n gameSocket.off(\"disconnect\", onDisconnect);\n options?.signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const fail = (error: ClientOperationError): void => {\n if (settled) return;\n settled = true;\n cleanup();\n gameSocket.off(\"message\", forwardMessage);\n gameSocket.off(\"disconnect\", forwardDisconnect);\n gameSocket.disconnect();\n this.socket = null;\n reject(error);\n };\n\n const succeed = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n };\n\n const startTimer = (\n timeoutMs: number,\n category: \"transport_error\" | \"auth_timeout\" | \"queue_timeout\",\n phase: \"transport_connecting\" | \"authenticating\" | \"queueing\",\n message: string,\n ): void => {\n if (timer !== undefined) clearTimeout(timer);\n timer = setTimeout(() => {\n fail(\n new ClientOperationError({\n category,\n phase,\n retryable: true,\n message,\n }),\n );\n }, timeoutMs);\n };\n\n const onConnect = (): void => {\n activePhase = \"authenticating\";\n this.reportLifecycle(options, \"authenticating\");\n startTimer(\n timeouts.authenticationMs,\n \"auth_timeout\",\n \"authenticating\",\n \"Game authentication timed out\",\n );\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: true,\n token: \"\",\n },\n });\n };\n\n const onMessage = (msg: ServerMessage): void => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n const update = msg.args as QueueUpdate;\n activePhase = \"queueing\";\n this.reportLifecycle(options, \"queueing\", update);\n options?.onQueueUpdate?.(update);\n startTimer(\n timeouts.queueMs,\n \"queue_timeout\",\n \"queueing\",\n \"Game server queue stopped responding\",\n );\n break;\n }\n case \"game_auth\": {\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n fail(\n new ClientOperationError({\n category: \"auth_failed\",\n phase: \"authenticating\",\n retryable: true,\n message: \"Game authentication failed\",\n }),\n );\n return;\n }\n\n this.reportLifecycle(options, \"joining_session\");\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n succeed();\n break;\n }\n }\n };\n\n const onConnectError = (cause: Error): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: \"transport_connecting\",\n retryable: true,\n message: `Game connection failed: ${cause.message}`,\n cause,\n }),\n );\n };\n\n const onDisconnect = (reason: string): void => {\n fail(\n new ClientOperationError({\n category: \"transport_error\",\n phase: activePhase,\n retryable: true,\n message: `Disconnected before game authentication${reason ? `: ${reason}` : \"\"}`,\n }),\n );\n };\n\n const onAbort = (): void => {\n fail(\n new ClientOperationError({\n category: \"aborted\",\n phase: activePhase,\n retryable: true,\n message: \"Game connection cancelled\",\n }),\n );\n };\n\n if (options?.signal?.aborted) {\n onAbort();\n return;\n }\n\n gameSocket.on(\"connect\", onConnect);\n gameSocket.on(\"message\", onMessage);\n gameSocket.on(\"connect_error\", onConnectError);\n gameSocket.on(\"disconnect\", onDisconnect);\n options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n startTimer(\n timeouts.transportMs,\n \"transport_error\",\n \"transport_connecting\",\n \"Game transport connection timed out\",\n );\n });\n\n return gameSocket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.nickname as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n toy: raw.toy,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n return {\n ...normalized,\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: (raw.furniture as unknown[]) ?? [],\n flooring: (raw.flooring as unknown[]) ?? [],\n buddies: (raw.buddies as PlayerData[\"buddies\"]) ?? [],\n buddyRequests: (raw.buddyRequests as number[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n meta: {\n ...normalized.meta,\n postcards: raw.postcards,\n mascots: raw.mascots,\n pets: raw.pets,\n },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set: set ?? false });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n protected createSocket(path: string): Socket {\n return io(BASE_URL, {\n ...this.socketIoOptions(BASE_URL),\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import {\n type ConnectionProfileInput,\n resolveConnectionProfile,\n} from \"../connection-profile.js\";\nimport type { BaseAdapter } from \"./base-adapter.js\";\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\";\nimport { CplegacyAdapter } from \"./cplegacy-adapter.js\";\nimport { CppslolAdapter } from \"./cpps-lol-adapter.js\";\nimport { NewcpAdapter } from \"./newcp-adapter.js\";\nimport { PenguinoriginsAdapter } from \"./penguinorigins-adapter.js\";\n\nconst ADAPTERS = {\n CPPSlol: CppslolAdapter,\n CPJourney: CpjourneyAdapter,\n CPLegacy: CplegacyAdapter,\n NewCP: NewcpAdapter,\n PenguinOrigins: PenguinoriginsAdapter,\n} as const;\n\nexport type AdapterName = keyof typeof ADAPTERS;\n\nexport function createAdapter(\n name: AdapterName,\n connectionProfile?: ConnectionProfileInput,\n): BaseAdapter {\n return new ADAPTERS[name](resolveConnectionProfile(connectionProfile));\n}\n","import type { BaseAdapter } from \"../adapters/base-adapter.js\";\nimport type { ClientOperationOptions } from \"../lifecycle.js\";\nimport type { ServerMessages } from \"../types/message-types.js\";\n\ntype RequestFn = <K extends keyof ServerMessages>(\n event: K,\n send: () => void,\n options?: ClientOperationOptions,\n matches?: (args: ServerMessages[K]) => boolean,\n) => Promise<ServerMessages[K]>;\n\nexport class CardJitsu {\n constructor(\n private adapter: BaseAdapter,\n private request: RequestFn,\n ) {}\n\n /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */\n getNinja(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_ninja\"]> {\n return this.request(\"get_ninja\", () => this.adapter.getNinja(), options);\n }\n\n /** Fetch state of all Dojo mats. Resolves with mat state. */\n getMats(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_waddles\"]> {\n return this.request(\"get_waddles\", () => this.adapter.getMats(), options);\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(waddle: number): void {\n this.adapter.joinMat(waddle);\n }\n\n /** Join Sensei matchmaking queue. Resolves when server acknowledges. */\n joinMatchmaking(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"join_matchmaking\"]> {\n return this.request(\n \"join_matchmaking\",\n () => this.adapter.joinMatchmaking(),\n options,\n );\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n this.adapter.leaveMatchmaking();\n }\n\n /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */\n startGame(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"start_game\"]> {\n return this.request(\"start_game\", () => this.adapter.startGame(), options);\n }\n\n /** Play a card from your hand by slot index. Resolves when server acknowledges. */\n selectCard(\n slot: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"move_my_card\"]> {\n return this.request(\n \"move_my_card\",\n () => this.adapter.selectCard(slot),\n options,\n (response) => response.slot === slot,\n );\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(animation: string): void {\n this.adapter.loadAnimation(animation);\n }\n}\n","import type { BaseAdapter } from \"../adapters/base-adapter.js\";\nimport { CppslolAdapter } from \"../adapters/cpps-lol-adapter.js\";\nimport { ClientOperationError } from \"../errors.js\";\nimport type { ClientOperationOptions } from \"../lifecycle.js\";\nimport type { ServerMessages } from \"../types/message-types.js\";\n\ntype RequestFn = <K extends keyof ServerMessages>(\n event: K,\n send: () => void,\n options?: ClientOperationOptions,\n matches?: (args: ServerMessages[K]) => boolean,\n) => Promise<ServerMessages[K]>;\n\n/** Operations implemented only by CPPS.lol's captured protocol. */\nexport class Cppslol {\n constructor(\n private readonly baseAdapter: BaseAdapter,\n private readonly request: RequestFn,\n ) {}\n\n private get adapter(): CppslolAdapter {\n if (this.baseAdapter instanceof CppslolAdapter) return this.baseAdapter;\n throw new ClientOperationError({\n category: \"unsupported_operation\",\n phase: \"ready\",\n retryable: false,\n message: `${this.baseAdapter.id} does not support CPPS.lol actions`,\n });\n }\n\n /** Send an emote from a CPPS.lol emote pack. */\n sendPackedEmote(pack: number, emote: number): void {\n this.adapter.sendPackedEmote(pack, emote);\n }\n\n /** Equip an item in CPPS.lol's additional appearance layer. */\n updateLayeredPlayer(item: number): void {\n this.adapter.updateLayeredPlayer(item);\n }\n\n /** Acknowledge the mature-server notice for the current session. */\n acceptMature(): void {\n this.adapter.acceptMature();\n }\n\n removeInventory(\n item: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"remove_inventory\"]> {\n return this.request(\n \"remove_inventory\",\n () => this.adapter.removeInventory(item),\n options,\n (response) => Number(response.id) === item,\n );\n }\n\n getSnowflakeState(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"snowflake_state\"]> {\n return this.request(\n \"snowflake_state\",\n () => this.adapter.getSnowflakeState(),\n options,\n );\n }\n\n getPets(\n userId: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"get_pets\"]> {\n return this.request(\n \"get_pets\",\n () => this.adapter.getPets(userId),\n options,\n (response) => response.userId === undefined || response.userId === userId,\n );\n }\n\n getIglooContest(\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_contest\"]> {\n return this.request(\n \"igloo_contest\",\n () => this.adapter.getIglooContest(),\n options,\n );\n }\n\n getIglooLikes(\n iglooId: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_likes\"]> {\n return this.request(\n \"igloo_likes\",\n () => this.adapter.getIglooLikesFor(iglooId),\n options,\n (response) => response.iglooId === iglooId,\n );\n }\n\n likeIgloo(\n iglooId: number,\n options?: ClientOperationOptions,\n ): Promise<ServerMessages[\"igloo_likes\"]> {\n return this.request(\n \"igloo_likes\",\n () => this.adapter.likeIglooById(iglooId),\n options,\n (response) => response.iglooId === iglooId,\n );\n }\n\n /** CPPS.lol does not acknowledge this action with a dedicated response. */\n openIgloo(): void {\n this.adapter.openIglooRaw();\n }\n\n sendMail(recipient: number, postcardId: number): void {\n this.adapter.sendMail(recipient, postcardId);\n }\n\n marryRequest(id: number): void {\n this.adapter.marryRequest(id);\n }\n\n leaveWaddle(): void {\n this.adapter.leaveWaddle();\n }\n}\n"],"mappings":"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","names":["CHROME_USER_AGENT","CHROME_ACCEPT_LANGUAGE","RESTRICTED_HEADERS","resolveConnectionProfile","input","defaultOriginForUrl","urlOrOrigin","url","resolveConnectionOrigin","profile","defaultUrlOrOrigin","buildConnectionHeaders","options","headers","origin","referer","sanitizeHeaders","sanitized","name","value","isRestrictedHeader","normalized","QUOTED_SECRET_FIELD","BARE_SECRET_FIELD","URL_CREDENTIALS","sanitizeClientErrorMessage","message","ClientOperationError","options","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","BaseAdapter","connectionProfile","resolveConnectionProfile","options","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","phase","queue","operation","ClientOperationError","defaultUrlOrOrigin","headers","origin","buildConnectionHeaders","resolveConnectionOrigin","_raw","raw","_message","_emote","_safe","_x","_y","_frame","_set","_room","_item","_id","_type","_userId","_cardId","_igloo","_isBackyard","_puffle","_puffleId","_name","_puffleSprite","_music","_furniture","_amount","_coins","_stamp","_slot","_animation","_waddle","EventEmitter","io","msgpackParser","BASE_URL","DEFAULT_SECRET","INVALID_CREDENTIAL_MESSAGES","CpjourneyAdapter","BaseAdapter","options","operationOptions","loginSocket","resolve","reject","settled","timeout","fail","ClientOperationError","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","cleanup","onConnect","onMessage","onConnectError","onDisconnect","onAbort","error","succeed","value","secret","args","msg","response","message","invalidCredentials","servers","name","population","cause","reason","serverName","loginResult","gameSocket","timeouts","forwardMessage","forwardDisconnect","timer","activePhase","startTimer","timeoutMs","category","phase","authArgs","update","queueSocket","completed","startQueueIdleTimer","action","raw","id","username","displayName","joinTime","x","y","frame","walking","color","head","face","neck","body","hand","feet","flag","photo","rest","user","normalized","_user","coins","rank","inventory","furniture","flooring","buddies","buddyRequests","ignores","igloos","emote","safe","set","room","item","type","userId","cardId","igloo","isBackyard","puffle","puffleId","puffleSprite","music","amount","stamp","slot","animation","waddle","path","io","msgpackParser","io","msgpackParser","LOGIN_URL","TOKEN_LOGIN_URL","BROWSER_ORIGIN","wrapSocket","raw","original","event","listener","action","args","CplegacyAdapter","BaseAdapter","options","operationOptions","url","body","controller","timedOut","onAbort","ClientOperationError","timeout","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","data","cause","message","invalidCredentials","name","population","serverName","loginResult","rawSocket","timeouts","forwardMessage","forwardDisconnect","reason","resolve","reject","settled","timer","activePhase","cleanup","onConnect","onMessage","onConnectError","onDisconnect","fail","error","succeed","startTimer","timeoutMs","category","phase","update","user","b","emote","safe","x","y","frame","set","room","item","id","userId","igloo","coins","stamp","signal","wsUrl","io","msgpackParser","io","createHmac","canonicalizeCppslolPacketValue","value","object","key","CppslolPacketSigner","packetKey","serverTime","now","action","args","seq","ts","input","mac","BASE_URL","CppslolAdapter","BaseAdapter","options","operationOptions","loginSocket","resolve","reject","settled","timeout","fail","ClientOperationError","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","cleanup","onConnect","onMessage","onConnectError","onDisconnect","onAbort","error","succeed","value","action","args","message","response","errorMessage","invalidCredentials","servers","name","population","cause","reason","serverName","loginResult","gameSocket","timeouts","forwardMessage","forwardDisconnect","timer","activePhase","startTimer","timeoutMs","category","phase","update","CppslolPacketSigner","raw","user","normalized","emote","safe","x","y","frame","set","room","item","igloo","furniture","pack","userId","iglooId","recipient","postcardId","id","path","io","createCipheriv","createDecipheriv","randomBytes","io","nacl","CRUMBS_URL","Encryptor","nacl","encryptedB64","serverPubKeyB64","data","serverPubKey","nonce","ciphertext","plaintext","keyString","iv","randomBytes","cipher","createCipheriv","encrypted","buf","decipher","createDecipheriv","performHandshake","socket","encryptor","signal","resolve","reject","settled","cleanup","onHandshake","onAbort","fail","error","encryptedKey","raw","parsed","cause","wrapSocket","original","event","listener","msg","decoded","NewcpAdapter","BaseAdapter","options","operationOptions","controller","timedOut","onCallerAbort","ClientOperationError","timeout","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","loginSocket","loginWorld","w","onConnect","onMessage","onConnectError","onDisconnect","succeed","result","args","message","response","responseMessage","invalidCredentials","servers","name","population","reason","serverName","loginResult","worldConfig","gameSocket","timeouts","phaseController","forwardMessage","action","forwardDisconnect","timer","activePhase","startTimer","timeoutMs","category","phase","update","joinEncrypted","user","emote","safe","x","y","frame","set","room","item","id","igloo","host","path","io","resp","crumbs","io","BASE_URL","PenguinoriginsAdapter","BaseAdapter","options","operationOptions","loginSocket","resolve","reject","settled","timeout","fail","ClientOperationError","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","cleanup","onConnect","onMessage","onConnectError","onDisconnect","onAbort","error","succeed","value","action","args","msg","response","message","invalidCredentials","servers","name","population","cause","reason","serverName","loginResult","gameSocket","timeouts","forwardMessage","forwardDisconnect","timer","activePhase","startTimer","timeoutMs","category","phase","update","raw","user","normalized","emote","safe","x","y","frame","set","room","item","id","igloo","coins","path","io","ADAPTERS","CppslolAdapter","CpjourneyAdapter","CplegacyAdapter","NewcpAdapter","PenguinoriginsAdapter","createAdapter","name","connectionProfile","resolveConnectionProfile","CardJitsu","adapter","request","options","waddle","slot","response","animation","Cppslol","baseAdapter","request","CppslolAdapter","ClientOperationError","pack","emote","item","options","response","userId","iglooId","recipient","postcardId","id","KNOWN_ACTIONS","Client","EventEmitter","CardJitsu","Cppslol","server","options","createAdapter","operationOptions","loginResult","serverName","connectOptions","update","message","reason","cause","error","ClientOperationError","timeoutMs","DEFAULT_CLIENT_CONNECTION_TIMEOUTS","resolve","reject","settled","timer","cleanupWait","onProgress","onKick","onCloseWithError","onServerError","onDisconnect","onAbort","succeed","fail","checkReady","info","event","listener","args","optionsOrTimeout","send","matches","cleanup","handler","rejectWith","previous","disconnectEpoch","releaseTurn","turn","tail","signal","aborted","emote","safe","x","y","frame","set","room","response","item","id","type","userId","cardId","igloo","puffle","puffleId","name","puffleSprite","music","furniture","amount","coins","stamp","ms","phase","msg","action","emitArgs","player","rawUsers","users","rawUser","user","iglooUsers","slot","updateSlot","roomUser","status","inventoryItem","eventName"]}
|