@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
1 lines • 16.7 kB
Source Map (JSON)
{"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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"}