@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
1 lines • 20.7 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/classes/room/index.ts"],"sourcesContent":["import type {\n Events,\n Game as GameTypes,\n Room as RoomTypes,\n Utils\n} from \"../../types\";\nimport { Client } from \"../client\";\nimport { Game } from \"../game\";\nimport { roomConfigPresets } from \"./presets\";\nimport { ReplayManager } from \"./replayManager\";\n\nexport class Room {\n private client: Client;\n private listeners: Parameters<typeof this.client.on>[] = [];\n\n /** the ID of the room */\n public id!: string;\n /** Whether or not the room is public */\n public public!: boolean;\n /** The type of the room (public | private) */\n public type!: RoomTypes.Type;\n /** Name of the room */\n public name!: string;\n /** Safe Name of the room */\n public name_safe!: string;\n /** UID of the host */\n public owner!: string;\n /** UID of the room creator (this person can reclaim host) */\n public creator!: string;\n /** The autostart state of the room */\n public autostart!: RoomTypes.Autostart;\n /** The match config for the room */\n public match!: RoomTypes.Match;\n /** The maxiumum number of players that can play in the room (override by moving as host) */\n public userLimit!: number;\n /** The players in the room */\n public players!: RoomTypes.Player[];\n /** The room config */\n public options!: GameTypes.Options;\n /** The current state of the room (ingame | lobby) */\n public state!: RoomTypes.State;\n /** The time the last game started */\n public gameStart: number | null = null;\n /** The replay data for the last played game */\n public replay: ReplayManager | null = null;\n\n /** Room chat history */\n public chats: Events.in.Room[\"room.chat\"][] = [];\n\n /** @hideconstructor */\n constructor(client: Client, data: Events.in.Room[\"room.update\"]) {\n this.client = client;\n\n this.handleUpdate(data);\n\n this.init();\n }\n\n private handleUpdate(data: Events.in.Room[\"room.update\"]) {\n this.id = data.id;\n this.autostart = data.auto;\n\n [\n \"public\",\n \"type\",\n \"name\",\n \"name_safe\",\n \"owner\",\n \"creator\",\n \"state\",\n \"match\",\n \"players\",\n \"userLimit\"\n ].forEach((key) =>\n Object.assign(this, { [key]: data[key as keyof typeof data] })\n );\n\n this.options = data.options;\n }\n\n private listen<T extends keyof Events.in.all>(\n event: T,\n cb: (data: Events.in.all[T]) => void,\n once = false\n ) {\n this.listeners.push([event, cb] as any);\n if (once) {\n this.client.once(event, cb);\n } else {\n this.client.on(event, cb);\n }\n }\n\n private init() {\n const emitPlayers = () =>\n this.client.emit(\"client.room.players\", this.players);\n let abortTimeout: NodeJS.Timeout | null = null;\n this.listen(\"room.update.host\", (data) => {\n this.owner = data;\n });\n\n this.listen(\"room.update.bracket\", (data) => {\n const idx = this.players.findIndex((p) => p._id === data.uid);\n if (idx >= 0) this.players[idx].bracket = data.bracket;\n emitPlayers();\n });\n\n this.listen(\"room.update.auto\", (auto) => {\n this.autostart = auto;\n });\n\n this.listen(\"room.update\", this.handleUpdate.bind(this));\n\n this.listen(\"room.player.add\", (data) => {\n this.players.push(data);\n emitPlayers();\n });\n\n this.listen(\"room.player.remove\", (data) => {\n this.players = this.players.filter((p) => p._id !== data);\n emitPlayers();\n });\n\n this.listen(\"game.ready\", (data) => {\n try {\n this.client.game = new Game(this.client, data);\n } catch {\n return; // not in room, don't do anything\n }\n if (data.isNew) {\n this.gameStart = performance.now();\n this.replay = new ReplayManager(data.players, this.players);\n\n this.client.emit(\"client.game.start\", {\n multi: this.match.ft > 1 || this.match.wb > 1,\n ft: this.match.ft,\n wb: this.match.wb,\n\n players: data.players.map((p) => ({\n id: p.userid,\n name: p.options.username,\n points: 0 as const\n }))\n });\n }\n\n this.replay?.addRound(data.players);\n });\n\n this.listen(\"game.replay\", (event) => this.replay?.pipe(event));\n\n this.listen(\"game.replay.end\", async ({ gameid, data }) => {\n this.replay?.die({ gameid, data, game: this.client.game });\n if (!this.client.game || this.client.game.gameid !== gameid) return;\n this.client.game.stop();\n this.client.emit(\"client.game.over\", { reason: \"finish\", data });\n });\n\n this.listen(\"game.advance\", () => {\n this.replay?.endRound({ game: this.client.game });\n if (this.client.game) {\n this.client.game = this.client.game.destroy();\n this.client.emit(\"client.game.over\", { reason: \"end\" });\n }\n });\n\n this.listen(\"game.score\", (data) => {\n if (this.client.game) {\n this.client.game = this.client.game.destroy();\n this.client.emit(\"client.game.over\", { reason: \"end\" });\n }\n\n this.client.emit(\"client.game.round.end\", data.victor);\n });\n\n this.listen(\"game.abort\", () => {\n if (abortTimeout) return;\n\n abortTimeout = setTimeout(() => {\n abortTimeout = null;\n }, 50);\n\n this.client.emit(\"client.game.abort\");\n\n if (!this.client.game) return;\n this.client.game = this.client.game.destroy();\n this.client.emit(\"client.game.over\", { reason: \"abort\" });\n });\n\n this.listen(\"game.end\", (data) => {\n this.client.emit(\"client.game.round.end\", data.leaderboard[0].id);\n\n const maxWins = data.leaderboard.reduce(\n (max, item) => Math.max(max, item.wins),\n 0\n );\n this.client.emit(\"client.game.end\", {\n duration: performance.now() - (this.gameStart ?? 0),\n players: data.leaderboard.map(\n (item) =>\n ({\n id: item.id,\n name: item.username,\n points: item.wins,\n won: item.wins === maxWins,\n raw: item\n }) satisfies Events.in.Client[\"client.game.end\"][\"players\"][number]\n )\n });\n\n if (!this.client.game) return;\n this.client.game = this.client.game.destroy();\n this.client.emit(\"client.game.over\", { reason: \"end\" });\n });\n\n this.listen(\"client.game.end\", () =>\n this.replay?.end({ self: this.client.user.id })\n );\n\n // chat\n this.listen(\"room.chat\", (item) => this.chats.push(item));\n\n // get booted\n this.listen(\"room.kick\", () => this.destroy());\n this.listen(\"room.leave\", () => this.destroy());\n }\n\n /** Whether or not the client is the host */\n get isHost() {\n return this.client.user.id === this.owner;\n }\n\n private destroy() {\n this.listeners.forEach((l) => this.client.off(l[0], l[1]));\n if (this.client.game) {\n this.client.game.destroy();\n this.client.emit(\"client.game.over\", { reason: \"leave\" });\n }\n\n delete this.client.room;\n }\n\n /**\n * Leave the current room\n * @example\n * await client.room!.leave();\n */\n async leave() {\n await this.client.wrap(\"room.leave\", undefined, \"room.leave\");\n this.destroy();\n }\n\n /**\n * Kick a user from the room for a specified duration (if host)\n * @param id - id of user to kick\n * @param duration - duration to kick the user, in seconds\n * @example\n * await client.room!.kick('646f633d276f42a80ba44304', 100);\n */\n async kick(id: string, duration = 900) {\n return await this.client.wrap(\n \"room.kick\",\n { uid: id, duration },\n \"room.player.remove\"\n );\n }\n\n /**\n * Unban a user from the room\n * @example\n * client.room!.unban('halp');\n */\n unban(username: string) {\n return this.client.emit(\"room.unban\", username);\n }\n\n /**\n * Send a public message to the room's chat.\n * The `pinned` parameter is the same as using the `/announce` command in TETR.IO\n * The `pinned` parameter being true will result in an error if the client is not host.\n * @example\n * await client.room!.chat('hi!');\n * @example\n * await client.room!.chat('Important info:', true);\n */\n async chat(message: string, pinned = false) {\n return await this.client.wrap(\n \"room.chat.send\",\n { content: message, pinned },\n \"room.chat\"\n );\n }\n\n /**\n * Clears the chat\n */\n async clearChat() {\n return await this.client.wrap(\n \"room.chat.clear\",\n undefined,\n \"room.chat.clear\"\n );\n }\n\n /**\n * Sets the room id (only works for supporter accounts)\n * @example\n * client.room!.setID('TEST');\n */\n async setID(id: string) {\n return await this.client.wrap(\n \"room.setid\",\n id.toUpperCase(),\n \"room.update\"\n );\n }\n\n /**\n * Update the room's config, similar to using the /set command in tetr.io\n * await client.room!.update({ index: 'name', value: 'test room'});\n * @returns\n */\n async update<T extends Utils.DeepKeys<RoomTypes.SetConfig>>(\n ...options: {\n index: T;\n value: Utils.DeepKeyValue<RoomTypes.SetConfig, T>;\n }[]\n ) {\n return await this.client.wrap(\n \"room.setconfig\",\n options.map((opt) =>\n typeof opt.value === \"number\"\n ? { index: opt.index, value: opt.value.toString() }\n : opt\n ),\n \"room.update\"\n );\n }\n\n /**\n * Sets the room's preset\n * @example\n * await client.room!.usePreset('tetra league (season 1)');\n */\n async usePreset(preset: GameTypes.Preset) {\n return await this.update(...roomConfigPresets[preset]);\n }\n\n /**\n * Start the game\n */\n async start() {\n return await this.client.wrap(\"room.start\", undefined, \"game.ready\");\n }\n\n /**\n * Abort the game\n */\n async abort() {\n return await this.client.wrap(\"room.abort\", undefined, \"game.abort\");\n }\n\n /**\n * Give the host to someone else\n * @example\n * await client.room!.transferHost(await client.social.resolve('halp'));\n */\n async transferHost(player: string) {\n return await this.client.wrap(\n \"room.owner.transfer\",\n player,\n \"room.update.host\"\n );\n }\n\n /** Take host if you created the room */\n async takeHost() {\n return await this.client.wrap(\n \"room.owner.revoke\",\n undefined,\n \"room.update.host\"\n );\n }\n\n /**\n * Switch bracket\n * @example\n * await client.room!.switch('player');\n */\n async switch(bracket: \"player\" | \"spectator\") {\n if (\n this.players.some(\n (p) => p._id === this.client.user.id && p.bracket === bracket\n )\n )\n return;\n\n return await this.client.wrap(\n \"room.bracket.switch\",\n bracket,\n \"room.update.bracket\"\n );\n }\n\n /**\n * Move someone's bracket\n * @example\n * await client.room!.move('646f633d276f42a80ba44304', 'spectator');\n */\n async move(uid: string, bracket: \"player\" | \"spectator\") {\n const player = this.players.find((p) => p._id === uid);\n if (!player) {\n throw new Error(`Player with UID ${uid} not found in room.`);\n }\n\n if (player.bracket === bracket) return;\n\n return await this.client.wrap(\n \"room.bracket.move\",\n { uid, bracket },\n \"room.update.bracket\"\n );\n }\n}\n\nexport { ReplayManager } from \"./replayManager\";\n"],"names":["Game","roomConfigPresets","ReplayManager","Room","client","listeners","id","public","type","name","name_safe","owner","creator","autostart","match","userLimit","players","options","state","gameStart","replay","chats","data","handleUpdate","init","auto","forEach","key","Object","assign","listen","event","cb","once","push","on","emitPlayers","emit","abortTimeout","idx","findIndex","p","_id","uid","bracket","bind","filter","game","isNew","performance","now","multi","ft","wb","map","userid","username","points","addRound","pipe","gameid","die","stop","reason","endRound","destroy","victor","setTimeout","leaderboard","maxWins","reduce","max","item","Math","wins","duration","won","raw","end","self","user","isHost","l","off","room","leave","wrap","undefined","kick","unban","chat","message","pinned","content","clearChat","setID","toUpperCase","update","opt","value","index","toString","usePreset","preset","start","abort","transferHost","player","takeHost","switch","some","move","find","Error"],"mappings":"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"}