@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
1 lines • 34.9 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/classes/game/index.ts"],"sourcesContent":["import { Engine } from \"../../engine\";\nimport type { Events, Game as GameTypes } from \"../../types\";\nimport type { BotWrapper } from \"../../utils/bot-wrapper\";\nimport { Client } from \"../client\";\nimport { getFullFrame } from \"./utils\";\n\nimport chalk from \"chalk\";\n\nconst moveElementToFirst = <T>(arr: T[], n: number) => [\n arr[n],\n ...arr.slice(0, n),\n ...arr.slice(n + 1)\n];\n\nexport class Game {\n private client: Client;\n private listeners: Parameters<typeof this.client.on>[] = [];\n private frameQueue: GameTypes.Replay.Frame[] = [];\n private incomingGarbage: (GameTypes.Replay.Frames.IGE & { frame: number })[] =\n [];\n private timeout: NodeJS.Timeout | null = null;\n private messageQueue: GameTypes.Client.Events[] = [];\n private startTime: number | null = null;\n #target: GameTypes.Target = { strategy: \"even\" };\n private tick?: GameTypes.Tick.Func;\n // @ts-expect-error\n private isPractice = false;\n #pauseIGEs = false;\n #forcePauseIGEs = false;\n #igeQueue: GameTypes.IGE[] = [];\n #slowTickWarning = false;\n\n /** The client's engine */\n public engine!: Engine;\n /** Data on all players in game, including the client */\n public players: {\n name: string;\n gameid: number;\n userid: string;\n engine: Engine;\n queue: GameTypes.Replay.Frame[];\n }[] = [];\n public get opponents() {\n return this.players.filter((p) => p.gameid !== this.gameid);\n }\n /** The client's `gameid` set by the server */\n public gameid: number;\n /** The raw game config sent by TETR.IO */\n public options: GameTypes.ReadyOptions;\n /** The raw game config for all players, including the client's own game config */\n public readyData: GameTypes.Ready;\n /** The targets set by the server */\n public serverTargets: number[] = [];\n /** The gameids of the users targeting the client */\n public enemies: number[] = [];\n /** The keys the client has queued to press (allows for pressing keys in the future) */\n public keyQueue: NonNullable<GameTypes.Tick.Out[\"keys\"]> = [];\n /** Whether or not targeting is allowed (changed by server). Setting target while this is `false` will throw an error. */\n public canTarget = true;\n /** Whether or not the client's game is over (topped out), and no longer ticking. */\n public over = false;\n /** The BotWrapper in use. When a BotWrapper is set, `tick` will not be called. */\n public botWrapper?: BotWrapper;\n\t/** The last time IGEs were flushed */\n\tpublic lastIGEFlush: number = performance.now();\n\n /** The Frames Per Second of the TETR.IO engine */\n static fps = 60;\n\t/** The maximum amount of time before all IGEs are force-flushed */\n\tstatic maxIGETimeout = 30000;\n /** Frames per message */\n private static fpm = 12;\n\n /** @hideconstructor */\n constructor(client: Client, ready: GameTypes.Ready) {\n this.client = client;\n\n const self = ready.players.find((p) => p.userid === client.user.id);\n\n if (!self) throw new Error(\"User not in game\");\n this.gameid = self.gameid;\n this.options = self.options;\n this.readyData = ready;\n\n try {\n this.engine = this.createEngine(this.options, this.gameid);\n } catch (e) {\n console.error(e);\n throw e;\n }\n\n // including ourself means we get our own replay data\n ready.players.forEach((player) =>\n this.client.emit(\"game.scope.start\", player.gameid)\n );\n\n this.init();\n }\n\n #log(\n msg: string,\n { level = \"info\" }: { level: \"info\" | \"warning\" | \"error\" } = {\n level: \"info\"\n }\n ) {\n const func =\n level === \"info\"\n ? chalk.blue\n : level === \"warning\"\n ? chalk.yellow\n : chalk.red;\n console.log(`${func(\"[🎀\\u2009Triangle.JS]\")}: ${msg}`);\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 /** Kill the game. This is called automatically by the Room class when a game ends/is aborted, you don't need to use this. */\n destroy(): undefined {\n if (!this.over) this.stop();\n\n this.listeners.forEach((l) => this.client.off(l[0], l[1]));\n\n this.players.forEach((engine) => engine.engine.events.removeAllListeners());\n\n delete this.client.game;\n }\n\n /**\n * Stops the client's gameplay, when it dies. Does not destroy the game.\n */\n stop() {\n this.listeners.forEach(\n (l) => l[0] !== \"game.replay\" && this.client.off(l[0], l[1])\n );\n this.listeners = this.listeners.filter((l) => l[0] === \"game.replay\");\n\n if (this.timeout)\n this.timeout = (clearTimeout(this.timeout) as any) || null;\n\n this.engine.events.removeAllListeners();\n this.over = true;\n this.client.ribbon.fasterPing = false;\n }\n\n private init() {\n this.client.ribbon.fasterPing = true;\n\n this.listen(\"game.match\", (_data) => {});\n this.listen(\n \"game.start\",\n () => {\n this.timeout = setTimeout(\n () => {\n this.start();\n },\n this.options.countdown_count * this.options.countdown_interval +\n this.options.precountdown +\n this.options.prestart\n );\n this.listen(\"game.abort\", () => clearTimeout(this.timeout!), true);\n },\n true\n );\n\n const p = this.readyData.players;\n // TODO: Add support for choosing who to spectate\n // const players = p.filter((p) => p.gameid !== this.gameid);\n const players = p;\n this.players = players.map((o) => ({\n name: o.options.username,\n userid: o.userid,\n gameid: o.gameid,\n engine: this.createEngine(o.options, o.gameid),\n queue: []\n }));\n\n // this.listen(\"game.replay.ige\", (data) => this.addIGE(data));\n this.listen(\"game.replay.ige\", (data) => this.#handleIGE(data));\n this.listen(\"game.replay\", ({ gameid, frames }) => {\n const game = this.players.find((player) => player.gameid === gameid);\n if (!game || game.engine.toppedOut) return false;\n\n game.queue.push(...frames);\n while (game.queue.some((f) => f.frame > game.engine.frame)) {\n const frames: GameTypes.Replay.Frame[] = [];\n while (\n game.queue.length > 0 &&\n game.queue[0].frame <= game.engine.frame\n ) {\n frames.push(game.queue.shift()!);\n }\n game.engine.tick(frames);\n }\n });\n }\n\n private start() {\n this.pipe(\n {\n type: \"start\",\n frame: 0,\n data: {}\n },\n getFullFrame(this.options)\n );\n\n this.startTime = performance.now();\n try {\n this.target = this.target;\n } catch {}\n\n this.client.emit(\"client.game.round.start\", [\n (f) => {\n this.tick = f;\n },\n this.engine,\n [\n ...this.players.map((player) => ({\n name: player.name,\n gameid: player.gameid,\n engine: player.engine\n }))\n ]\n ]);\n\n this.timeout = setTimeout(this.tickGame.bind(this), 0);\n }\n\n createEngine(options: GameTypes.ReadyOptions, gameid: number) {\n return new Engine({\n multiplayer: {\n opponents: this.readyData.players\n .map((o) => o.gameid)\n .filter((id) => id !== gameid),\n passthrough: options.passthrough\n },\n board: {\n width: options.boardwidth,\n height: options.boardheight,\n buffer: 20 // there is always a buffer of 20 over the visible board\n },\n kickTable: options.kickset as any,\n options: {\n comboTable: options.combotable as any,\n garbageBlocking: options.garbageblocking as any,\n clutch: options.clutch,\n garbageTargetBonus: options.garbagetargetbonus,\n spinBonuses: options.spinbonuses\n },\n queue: {\n minLength: 31,\n seed: options.seed,\n type: options.bagtype as any\n },\n\n garbage: {\n cap: {\n absolute: options.garbageabsolutecap,\n increase: options.garbagecapincrease,\n max: options.garbagecapmax,\n value: options.garbagecap,\n marginTime: options.garbagecapmargin\n },\n multiplier: {\n value: options.garbagemultiplier,\n increase: options.garbageincrease,\n marginTime: options.garbagemargin\n },\n boardWidth: options.boardwidth,\n garbage: {\n speed: options.garbagespeed,\n holeSize: options.garbageholesize\n },\n messiness: {\n change: options.messiness_change,\n nosame: options.messiness_nosame,\n timeout: options.messiness_timeout,\n within: options.messiness_inner,\n center: options.messiness_center ?? false\n },\n\n bombs: options.usebombs,\n\n seed: options.seed,\n rounding: options.roundmode,\n openerPhase: options.openerphase,\n specialBonus: options.garbagespecialbonus\n },\n pc: options.allclears\n ? {\n garbage: options.allclear_garbage,\n b2b: options.allclear_b2b\n }\n : false,\n b2b: {\n chaining: options.b2bchaining,\n charging: options.b2bcharging\n ? { at: options.b2bcharge_at, base: options.b2bcharge_base }\n : false\n },\n gravity: {\n value: options.g,\n increase: options.gincrease,\n marginTime: options.gmargin\n },\n misc: {\n movement: {\n infinite: options.infinite_movement,\n lockResets: options.lockresets,\n lockTime: options.locktime,\n may20G: options.gravitymay20g\n },\n allowed: {\n spin180: options.allow180,\n hardDrop: options.allow_harddrop,\n hold: options.display_hold\n },\n infiniteHold: options.infinite_hold,\n username: options.username,\n date: new Date()\n },\n handling: options.handling\n });\n }\n\n private flushFrames() {\n let returnFrames = this.frameQueue.filter((f) => f.frame <= this.frame);\n this.frameQueue = this.frameQueue.filter((f) => f.frame > this.frame);\n if (!this.canTarget)\n returnFrames = returnFrames.filter(\n (f) => f.type !== \"strategy\" && f.type !== \"manual_target\"\n );\n if (!this.options.manual_allowed)\n returnFrames = returnFrames.filter((f) => f.type !== \"manual_target\");\n\n // move the full frame to the front as a precaution\n const fullFrameIndex = returnFrames.findIndex(\n (frame) => frame.type === \"full\"\n );\n if (fullFrameIndex >= 0) {\n returnFrames = moveElementToFirst(returnFrames, fullFrameIndex);\n }\n\n // move start frame to front (start -> full at the end)\n const startFrameIndex = returnFrames.findIndex(\n (frame) => frame.type === \"start\"\n );\n if (startFrameIndex >= 0) {\n returnFrames = moveElementToFirst(returnFrames, startFrameIndex);\n }\n return returnFrames;\n }\n\n private async tickGame(): Promise<void> {\n if (this.over) return;\n let runAfter: GameTypes.Tick.Out[\"runAfter\"] = [];\n if (this.tick) {\n try {\n const res = await this.tick({\n gameid: this.gameid,\n frame: this.frame,\n events: this.messageQueue.splice(0, this.messageQueue.length),\n engine: this.engine!\n });\n\n const isValidObject = (obj: any) =>\n typeof obj === \"object\" && obj !== null;\n if (res.keys)\n this.keyQueue.push(\n ...res.keys.filter((k, idx) => {\n if (\n !isValidObject(k) ||\n !(k.type === \"keydown\" || k.type === \"keyup\") ||\n typeof k.frame !== \"number\" ||\n isNaN(k.frame) ||\n k.frame < this.frame ||\n !isValidObject(k.data) ||\n !(\n [\n \"moveLeft\",\n \"moveRight\",\n \"hardDrop\",\n \"hold\",\n \"softDrop\",\n \"rotateCW\",\n \"rotate180\",\n \"rotateCCW\"\n ] satisfies GameTypes.Tick.Keypress[\"data\"][\"key\"][]\n ).includes(k.data.key) ||\n typeof k.data.subframe !== \"number\" ||\n isNaN(k.data.subframe) ||\n k.data.subframe < 0\n ) {\n this.#log(\n `Invalid key event at index ${idx} passed on frame ${this.frame}:\\n${JSON.stringify(k, null, 2)}`,\n {\n level: \"error\"\n }\n );\n return false;\n }\n return true;\n })\n );\n if (res.runAfter)\n runAfter.push(\n ...res.runAfter.filter((ra, idx) => {\n if (typeof ra !== \"function\") {\n this.#log(\n `Invalid runAfter callback at index ${idx} passed on frame ${this.frame}.`,\n {\n level: \"warning\"\n }\n );\n return false;\n }\n return true;\n })\n );\n } catch (e) {\n if (this.over) return;\n throw e;\n }\n }\n if (this.over) return;\n\n // ideally, iges get flushed here\n this.#flushIGEs();\n\n const keys: typeof this.keyQueue = [];\n\n for (let i = this.keyQueue.length - 1; i >= 0; i--) {\n const key = this.keyQueue[i];\n if (Math.floor(key.frame) === this.frame) {\n keys.push(key);\n this.keyQueue.splice(i, 1);\n }\n }\n\n keys.splice(0, keys.length, ...keys.reverse());\n\n try {\n const { garbage } = this.engine.tick([\n ...this.incomingGarbage.splice(0, this.incomingGarbage.length),\n ...keys\n ]);\n\n this.messageQueue.push(\n ...garbage.received.map((g) => ({\n type: \"garbage\" as const,\n ...g\n }))\n );\n\n this.pipe(...keys);\n\n if (this.frame !== 0 && this.frame % Game.fpm === 0) {\n const frames = this.flushFrames();\n this.client.emit(\"game.replay\", {\n gameid: this.gameid,\n provisioned: this.frame,\n frames\n });\n\n this.messageQueue.push({\n type: \"frameset\",\n provisioned: this.frame,\n frames\n });\n }\n\n runAfter.forEach((f) => f());\n\n // flush at the time `keyQueue` is most likely to be empty (so that continuous playing doesn't cause an ige backup). Garbage might be a frame late.\n this.#flushIGEs();\n\n const target =\n ((this.frame + 1) / Game.fps) * 1000 -\n (performance.now() - this.startTime!);\n\n if (target <= -2000 && !this.#slowTickWarning) {\n console.log(\n `${chalk.red(\"[Triangle.js]\")} Triangle.js is lagging behind by more than 2 seconds! Your \\`tick\\` function is likely taking too long to execute.`\n );\n this.#slowTickWarning = true;\n }\n\n // Every half second, use timeout even if we lag to ensure the websocket can send frames\n if (target <= 0 && (this.engine.frame % Game.fps) / 2 !== 0) {\n return this.tickGame();\n }\n\n this.timeout = setTimeout(this.tickGame.bind(this), Math.max(0, target));\n } catch (e) {\n console.error(e);\n throw e;\n }\n }\n\n /**\n * Send raw frames to TETR.IO -\n * Not recommended for normal use.\n */\n pipe(...frames: GameTypes.Replay.Frame[]) {\n this.frameQueue.push(...frames);\n }\n\n #handleIGE(data: Events.in.Game[\"game.replay.ige\"]) {\n this.#igeQueue.push(...data.iges);\n this.#flushIGEs();\n }\n\n #flushIGEs() {\n if (this.igesPaused && this.lastIGEFlush + Game.maxIGETimeout > performance.now()) return;\n this.#igeQueue\n .splice(0, this.#igeQueue.length)\n .forEach((ige) => this.#__internal_handleIGE(ige));\n\t\tthis.lastIGEFlush = performance.now();\n }\n\n #__internal_handleIGE(ige: GameTypes.IGE) {\n const frame: GameTypes.Replay.Frame = {\n frame: this.frame,\n type: \"ige\",\n data: ige\n };\n\n this.pipe(frame);\n this.incomingGarbage.push({ ...frame });\n\n if (ige.type === \"interaction_confirm\") {\n if (ige.data.type === \"targeted\") {\n // TODO: implement\n }\n } else if (ige.type === \"target\") {\n this.serverTargets = ige.data.targets;\n } else if (ige.type === \"allow_targeting\") {\n this.canTarget = ige.data.value;\n }\n }\n\n /**\n * The current targeting strategy. Setting a targeting strategy throws error if targeting is not allowed.\n */\n get target() {\n return this.#target;\n }\n\n set target(t: GameTypes.Target) {\n if (!this.canTarget) throw new Error(\"Targeting not allowed.\");\n const strategyMap = {\n even: 0,\n elims: 1,\n random: 2,\n payback: 3,\n manual: 4\n } as const;\n\n const frame = this.frame;\n if (t.strategy === \"manual\") {\n this.pipe({\n frame,\n type: \"manual_target\",\n data: t.target\n });\n } else {\n this.pipe({\n frame,\n type: \"strategy\",\n data: strategyMap[t.strategy]\n });\n }\n\n this.#target = t;\n }\n\n /**\n * The game's current frame\n */\n public get frame() {\n return this.engine ? this.engine.frame : 0;\n }\n\n private set frame(newFrame: number) {\n this.engine.frame = newFrame;\n }\n\n /** Pauses accepting IGEs (garbage events) when the `keyQueue` has items, when `pauseIGEs` is set to true. */\n public get pauseIGEs() {\n return this.#pauseIGEs;\n }\n\n public set pauseIGEs(value: boolean) {\n this.#pauseIGEs = value;\n this.#flushIGEs();\n }\n\n /** Force stops the processing of all IGEs (garbage, etc). If left `true` for too long (~30s), IGEs will be automatically flushed to avoid a forced disconnect. Use sparingly. */\n public get forcePauseIGEs() {\n return this.#forcePauseIGEs;\n }\n\n public set forcePauseIGEs(value: boolean) {\n this.#forcePauseIGEs = value;\n this.#flushIGEs();\n }\n\n /** Whether or not the `Game` is currently allowed to process IGEs. */\n public get igesPaused() {\n return (\n this.#forcePauseIGEs || (this.#pauseIGEs && this.keyQueue.length > 0)\n );\n }\n}\n"],"names":["Engine","getFullFrame","chalk","moveElementToFirst","arr","n","slice","Game","client","listeners","frameQueue","incomingGarbage","timeout","messageQueue","startTime","strategy","tick","isPractice","engine","players","opponents","filter","p","gameid","options","readyData","serverTargets","enemies","keyQueue","canTarget","over","botWrapper","lastIGEFlush","performance","now","fps","maxIGETimeout","fpm","ready","self","find","userid","user","id","Error","createEngine","e","console","error","forEach","player","emit","init","msg","level","func","blue","yellow","red","log","listen","event","cb","once","push","on","destroy","stop","l","off","events","removeAllListeners","game","clearTimeout","ribbon","fasterPing","_data","setTimeout","start","countdown_count","countdown_interval","precountdown","prestart","map","o","name","username","queue","data","frames","toppedOut","some","f","frame","length","shift","pipe","type","target","tickGame","bind","multiplayer","passthrough","board","width","boardwidth","height","boardheight","buffer","kickTable","kickset","comboTable","combotable","garbageBlocking","garbageblocking","clutch","garbageTargetBonus","garbagetargetbonus","spinBonuses","spinbonuses","minLength","seed","bagtype","garbage","cap","absolute","garbageabsolutecap","increase","garbagecapincrease","max","garbagecapmax","value","garbagecap","marginTime","garbagecapmargin","multiplier","garbagemultiplier","garbageincrease","garbagemargin","boardWidth","speed","garbagespeed","holeSize","garbageholesize","messiness","change","messiness_change","nosame","messiness_nosame","messiness_timeout","within","messiness_inner","center","messiness_center","bombs","usebombs","rounding","roundmode","openerPhase","openerphase","specialBonus","garbagespecialbonus","pc","allclears","allclear_garbage","b2b","allclear_b2b","chaining","b2bchaining","charging","b2bcharging","at","b2bcharge_at","base","b2bcharge_base","gravity","g","gincrease","gmargin","misc","movement","infinite","infinite_movement","lockResets","lockresets","lockTime","locktime","may20G","gravitymay20g","allowed","spin180","allow180","hardDrop","allow_harddrop","hold","display_hold","infiniteHold","infinite_hold","date","Date","handling","flushFrames","returnFrames","manual_allowed","fullFrameIndex","findIndex","startFrameIndex","runAfter","res","splice","isValidObject","obj","keys","k","idx","isNaN","includes","key","subframe","JSON","stringify","ra","i","Math","floor","reverse","received","provisioned","iges","igesPaused","ige","targets","t","strategyMap","even","elims","random","payback","manual","newFrame","pauseIGEs","forcePauseIGEs"],"mappings":"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"}