{"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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"}