{"version":3,"sources":["../../../src/classes/room/replayManager.ts"],"sourcesContent":["import { Room } from \".\";\nimport { Events, type Game, type VersusReplay } from \"../../types\";\nimport { Game as GameClass } from \"../game\";\n\nexport class ReplayManager {\n  #replay: VersusReplay;\n  constructor(\n    readyPlayers: Game.Ready[\"players\"],\n    roomPlayers: Room[\"players\"]\n  ) {\n    this.#replay = {\n      gamemode: null,\n      id: null,\n      ts: new Date().toString(),\n      version: 1,\n      users: readyPlayers\n        .map((p) => roomPlayers.find((pl) => pl._id === p.userid)!)\n        .map(\n          (p) =>\n            ({\n              id: p._id,\n              username: p.username,\n              avatar_revision: 0,\n              banner_revision: 0,\n              flags: 0,\n              country: p.country\n            }) satisfies VersusReplay[\"users\"][number]\n        ),\n      replay: {\n        leaderboard: readyPlayers.map(\n          (p) =>\n            ({\n              id: p.userid,\n              username: p.options.username,\n              wins: 0,\n              active: true,\n              shadowedBy: [null, null],\n              shadows: [],\n              naturalorder: p.naturalorder,\n              stats: {\n                apm: 0,\n                pps: 0,\n                vsscore: 0,\n                garbagesent: 0,\n                garbagereceived: 0,\n                kills: 0,\n                altitude: 0,\n                rank: 0,\n                targetingfactor: 0,\n                targetinggrace: 0,\n                btb: 0,\n                revives: 0,\n                escapeartist: null,\n                blockrationing_app: null,\n                blockrationing_final: null\n              }\n            }) satisfies VersusReplay[\"replay\"][\"leaderboard\"][number]\n        ),\n        rounds: []\n      }\n    };\n  }\n\n  addRound(players: Game.Ready[\"players\"]) {\n    this.#replay.replay.rounds.push(\n      players.map((p) => ({\n        active: true,\n        alive: true,\n        naturalorder: p.naturalorder,\n        id: p.userid,\n        lifetime: 0,\n        shadows: [],\n        shadowedBy: [null, null],\n        stats: {\n          apm: 0,\n          pps: 0,\n          vsscore: 0,\n          garbagesent: 0,\n          garbagereceived: 0,\n          kills: 0,\n          altitude: 0,\n          rank: 0,\n          targetingfactor: 0,\n          targetinggrace: 0,\n          btb: 0,\n          revives: 0\n        },\n        replay: {\n          frames: 0,\n          events: [],\n          options: {\n            ...p.options,\n            gameid: p.gameid\n          },\n          results: {\n            aggregatestats: {\n              apm: 0,\n              pps: 0,\n              vsscore: 0\n            },\n            stats: {\n              lines: 0,\n              level_lines: 0,\n              level_lines_needed: 0,\n              inputs: 0,\n              holds: 0,\n              score: 0,\n              zenlevel: 0,\n              zenprogress: 0,\n              level: 0,\n              combo: 0,\n              topcombo: 0,\n              combopower: 0,\n              btb: 0,\n              topbtb: 0,\n              btbpower: 0,\n              tspins: 0,\n              piecesplaced: 0,\n              clears: {\n                singles: 0,\n                doubles: 0,\n                triples: 0,\n                quads: 0,\n                pentas: 0,\n                realtspins: 0,\n                minitspins: 0,\n                minitspinsingles: 0,\n                tspinsingles: 0,\n                minitspindoubles: 0,\n                tspindoubles: 0,\n                minitspintriples: 0,\n                tspintriples: 0,\n                minitspinquads: 0,\n                tspinquads: 0,\n                tspinpentas: 0,\n                allclear: 0\n              },\n              garbage: {\n                sent: 0,\n                sent_nomult: 0,\n                maxspike: 0,\n                maxspike_nomult: 0,\n                received: 0,\n                attack: 0,\n                cleared: 0\n              },\n              kills: 0,\n              finesse: {\n                combo: 0,\n                faults: 0,\n                perfectpieces: 0\n              },\n              zenith: {\n                altitude: 0,\n                rank: 0,\n                peakrank: 0,\n                avgrankpts: 0,\n                floor: 0,\n                targetingfactor: 0,\n                targetinggrace: 0,\n                totalbonus: 0,\n                revives: 0,\n                revivesTotal: 0,\n                revivesMaxOfBoth: 0,\n                speedrun: false,\n                speedrun_seen: false,\n                splits: [0, 0, 0, 0, 0, 0, 0, 0, 0]\n              },\n              finaltime: 0\n            },\n            gameoverreason: \"x\" as any\n          }\n        }\n      }))\n    );\n  }\n\n  pipe({ gameid, frames }: { gameid: number; frames: Game.Replay.Frame[] }) {\n    const p = this.#replay.replay.rounds\n      .at(-1)!\n      .find((p) => p.replay.options.gameid === gameid);\n    if (!p) return;\n    p.replay.frames = frames.reduce(\n      (acc, frame) => Math.max(acc, frame.frame),\n      p.replay.frames\n    );\n    p.replay.events.push(...frames);\n  }\n\n  die({\n    gameid,\n    data,\n    game\n  }: {\n    gameid: number;\n    data?: Events.in.Game[\"game.replay.end\"][\"data\"];\n    game?: GameClass;\n  }) {\n    const p = this.#replay.replay.rounds\n      .at(-1)!\n      .find((p) => p.replay.options.gameid === gameid);\n    if (p && p.replay.results.gameoverreason === (\"x\" as any)) {\n      p.replay.results.gameoverreason = data?.gameoverreason ?? \"winner\";\n      p.alive = (data?.gameoverreason ?? \"winner\") === \"winner\";\n      p.active = true;\n      p.lifetime = (p.replay.frames * 1000) / GameClass.fps;\n      if (game) {\n        const e = game.players.find((p) => p.gameid === gameid)?.engine;\n        if (e) {\n          p.stats.apm = e.dynamicStats.apm;\n          p.stats.pps = e.dynamicStats.pps;\n          p.stats.vsscore = e.dynamicStats.vs;\n          p.stats.garbagesent = e.stats.garbage.sent;\n          p.stats.garbagereceived = e.stats.garbage.receive;\n          p.replay.results.aggregatestats = {\n            apm: e.dynamicStats.apm,\n            pps: e.dynamicStats.pps,\n            vsscore: e.dynamicStats.vs\n          };\n        }\n      }\n\n      if (!p.replay.events.find((f) => f.type === \"end\")) {\n        p.replay.events.push({\n          type: \"end\",\n          frame: p.replay.frames,\n          // TODO: put real data here\n          data: {}\n        });\n      }\n    }\n  }\n\n  endRound({ game }: { game?: GameClass }) {\n    if (!game) return;\n    for (const p of game.players) {\n      this.die({\n        gameid: p.gameid,\n        game\n      });\n    }\n  }\n\n  end({ self }: { self: string }) {\n    this.#replay.ts = new Date().toString();\n    this.#replay.replay.leaderboard.forEach((user) => {\n      const rounds = this.#replay.replay.rounds\n        .map((r) => r.find((p) => p.id === user.id)!)\n        .filter((r) => r);\n      user.stats.apm =\n        rounds.reduce((acc, r) => acc + r.stats.apm, 0) / rounds.length;\n      user.stats.pps =\n        rounds.reduce((acc, r) => acc + r.stats.pps, 0) / rounds.length;\n      user.stats.vsscore =\n        rounds.reduce((acc, r) => acc + r.stats.vsscore, 0) / rounds.length;\n      user.stats.garbagesent = rounds.reduce(\n        (acc, r) => acc + r.stats.garbagesent,\n        0\n      );\n      user.stats.garbagereceived = rounds.reduce(\n        (acc, r) => acc + r.stats.garbagereceived,\n        0\n      );\n      user.stats.kills = rounds.reduce((acc, r) => acc + r.stats.kills, 0);\n      user.wins = rounds.reduce((acc, r) => acc + (r.alive ? 1 : 0), 0);\n    });\n    // sort: self uesr id needs first in naturalorder\n    this.#replay.replay.leaderboard = this.#replay.replay.leaderboard\n      .toSorted((a, b) => {\n        if (a.id === self) return -1;\n        if (b.id === self) return 1;\n        return a.naturalorder - b.naturalorder;\n      })\n      .map((user, i) => {\n        user.naturalorder = i;\n        return user;\n      });\n\n    this.#replay.replay.rounds = this.#replay.replay.rounds.map((round) =>\n      round\n        .toSorted((a, b) => {\n          if (a.id === self) return -1;\n          if (b.id === self) return 1;\n          return a.naturalorder - b.naturalorder;\n        })\n        .map((user, i) => {\n          user.naturalorder = i;\n          return user;\n        })\n    );\n  }\n\n  export() {\n    return this.#replay;\n  }\n}\n"],"names":["Game","GameClass","ReplayManager","readyPlayers","roomPlayers","gamemode","id","ts","Date","toString","version","users","map","p","find","pl","_id","userid","username","avatar_revision","banner_revision","flags","country","replay","leaderboard","options","wins","active","shadowedBy","shadows","naturalorder","stats","apm","pps","vsscore","garbagesent","garbagereceived","kills","altitude","rank","targetingfactor","targetinggrace","btb","revives","escapeartist","blockrationing_app","blockrationing_final","rounds","addRound","players","push","alive","lifetime","frames","events","gameid","results","aggregatestats","lines","level_lines","level_lines_needed","inputs","holds","score","zenlevel","zenprogress","level","combo","topcombo","combopower","topbtb","btbpower","tspins","piecesplaced","clears","singles","doubles","triples","quads","pentas","realtspins","minitspins","minitspinsingles","tspinsingles","minitspindoubles","tspindoubles","minitspintriples","tspintriples","minitspinquads","tspinquads","tspinpentas","allclear","garbage","sent","sent_nomult","maxspike","maxspike_nomult","received","attack","cleared","finesse","faults","perfectpieces","zenith","peakrank","avgrankpts","floor","totalbonus","revivesTotal","revivesMaxOfBoth","speedrun","speedrun_seen","splits","finaltime","gameoverreason","pipe","at","reduce","acc","frame","Math","max","die","data","game","fps","e","engine","dynamicStats","vs","receive","f","type","endRound","end","self","forEach","user","r","filter","length","toSorted","a","b","i","round","export"],"mappings":"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"}