{ "version": 3, "sources": ["../../server/room-battle-bestof.ts"], "sourcesContent": ["import { Utils } from '../lib';\nimport { RoomGamePlayer, RoomGame } from \"./room-game\";\nimport type { RoomBattlePlayerOptions, RoomBattleOptions } from './room-battle';\nimport type { PrivacySetting, RoomSettings } from './rooms';\n\nconst BEST_OF_IN_BETWEEN_TIME = 40;\n\nexport class BestOfPlayer extends RoomGamePlayer {\n\twins = 0;\n\tready: boolean | null = null;\n\toptions: Omit & { user: null };\n\tdcAutoloseTime: number | null = null;\n\tconstructor(user: User | null, game: BestOfGame, num: number, options: RoomBattlePlayerOptions) {\n\t\tsuper(user, game, num);\n\t\tthis.options = { ...options, user: null };\n\t}\n\tavatar() {\n\t\tlet avatar = Users.get(this.id)?.avatar;\n\t\tif (!avatar || typeof avatar === 'number') avatar = 'unknownf';\n\t\tconst url = Chat.plugins.avatars?.Avatars.src(avatar) ||\n\t\t\t`https://${Config.routes.client}/sprites/trainers/${avatar}.png`;\n\t\treturn url;\n\t}\n\tupdateReadyButton() {\n\t\tconst user = this.getUser();\n\t\tif (!user?.connected) return;\n\n\t\tthis.dcAutoloseTime = null;\n\t\tconst room = this.game.room;\n\t\tconst battleRoom = this.game.games[this.game.games.length - 1]?.room as Room | undefined;\n\t\tconst gameNum = this.game.games.length + 1;\n\n\t\tif (this.ready === false) {\n\t\t\tconst notification = `|tempnotify|choice|Next game|It's time for game ${gameNum} in your best-of-${this.game.bestOf}!`;\n\t\t\tif (battleRoom && user.inRooms.has(battleRoom.roomid)) {\n\t\t\t\tbattleRoom.send(notification);\n\t\t\t} else {\n\t\t\t\tthis.sendRoom(notification);\n\t\t\t}\n\t\t} else {\n\t\t\tconst notification = `|tempnotifyoff|choice`;\n\t\t\tbattleRoom?.sendUser(user, notification);\n\t\t\tthis.sendRoom(notification);\n\t\t}\n\n\t\tif (this.ready === null) {\n\t\t\tconst button = `|c|~|/uhtml controls,`;\n\t\t\tthis.sendRoom(button);\n\t\t\tbattleRoom?.sendUser(user, button);\n\t\t\treturn;\n\t\t}\n\n\t\tconst cmd = `/msgroom ${room.roomid},/confirmready`;\n\t\tconst button = `|c|~|/uhtml controls,

Are you ready for game ${gameNum}, ${this.name}?

` +\n\t\t\t(this.ready ?\n\t\t\t\t` – waiting for opponent...` :\n\t\t\t\t``\n\t\t\t) +\n\t\t\t`

`;\n\t\tthis.sendRoom(button);\n\t\tbattleRoom?.sendUser(user, button);\n\t}\n}\n\nexport class BestOfGame extends RoomGame {\n\toverride readonly gameid = 'bestof' as ID;\n\toverride allowRenames = false;\n\toverride room!: GameRoom;\n\tbestOf: number;\n\tformat: Format;\n\twinThreshold: number;\n\toptions: Omit & { parent: Room, players: null };\n\tforcedSettings: { modchat?: string | null, privacy?: string | null } = {};\n\tties = 0;\n\tgames: { room: GameRoom, winner: BestOfPlayer | null | undefined, rated: number }[] = [];\n\tplayerNum = 0;\n\t/** null = tie, undefined = not ended */\n\twinner: BestOfPlayer | null | undefined = undefined;\n\t/** when waiting between battles, this is the just-ended battle room, the one with the |tempnotify| */\n\twaitingBattle: GameRoom | null = null;\n\tnextBattleTimerEnd: number | null = null;\n\tnextBattleTimer: NodeJS.Timeout | null = null;\n\t/** Does NOT control bestof's own timer, which is always-on. Controls timers in sub-battles. */\n\tneedsTimer = false;\n\tscore: number[] | null = null;\n\tconstructor(room: GameRoom, options: RoomBattleOptions) {\n\t\tsuper(room);\n\t\tthis.gameid = 'bestof' as ID;\n\t\tthis.format = Dex.formats.get(options.format);\n\t\tthis.bestOf = Number(Dex.formats.getRuleTable(this.format).valueRules.get('bestof'))!;\n\t\tthis.winThreshold = Math.floor(this.bestOf / 2) + 1;\n\t\tthis.title = this.format.name;\n\t\tif (!toID(this.title).includes('bestof')) {\n\t\t\tthis.title += ` (Best-of-${this.bestOf})`;\n\t\t}\n\t\tthis.room.bestOf = this;\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\tisBestOfSubBattle: true,\n\t\t\tparent: this.room,\n\t\t\tallowRenames: false,\n\t\t\tplayers: null,\n\t\t};\n\t\tfor (const playerOpts of options.players) {\n\t\t\tthis.addPlayer(playerOpts.user, playerOpts);\n\t\t}\n\t\tprocess.nextTick(() => this.nextGame());\n\t}\n\toverride onConnect(user: User) {\n\t\tconst player = this.playerTable[user.id];\n\t\tplayer?.sendRoom('|cantleave|');\n\t\tplayer?.updateReadyButton();\n\t}\n\toverride makePlayer(user: User | null, options: RoomBattlePlayerOptions): BestOfPlayer {\n\t\treturn new BestOfPlayer(user, this, ++this.playerNum, options);\n\t}\n\toverride addPlayer(user: User, options: RoomBattlePlayerOptions) {\n\t\tconst player = super.addPlayer(user, options);\n\t\tif (!player) throw new Error(`Failed to make player ${user} in ${this.roomid}`);\n\t\tthis.room.auth.set(user.id, Users.PLAYER_SYMBOL);\n\t\treturn player;\n\t}\n\tcheckPrivacySettings(options: RoomBattleOptions & Partial) {\n\t\tlet inviteOnly = false;\n\t\tconst privacySetter = new Set([]);\n\t\tfor (const p of options.players) {\n\t\t\tif (p.user) {\n\t\t\t\tif (p.inviteOnly) {\n\t\t\t\t\tinviteOnly = true;\n\t\t\t\t\tprivacySetter.add(p.user.id);\n\t\t\t\t} else if (p.hidden) {\n\t\t\t\t\tprivacySetter.add(p.user.id);\n\t\t\t\t}\n\t\t\t\tthis.checkForcedUserSettings(p.user);\n\t\t\t}\n\t\t}\n\n\t\tif (privacySetter.size) {\n\t\t\tconst room = this.room;\n\t\t\tif (this.forcedSettings.privacy) {\n\t\t\t\troom.setPrivate(false);\n\t\t\t\troom.settings.modjoin = null;\n\t\t\t\troom.add(`|raw|
This best-of set is required to be public due to a player having a name starting with '${this.forcedSettings.privacy}'.
`);\n\t\t\t} else if (!options.tour || (room.tour?.allowModjoin)) {\n\t\t\t\troom.setPrivate('hidden');\n\t\t\t\tif (inviteOnly) room.settings.modjoin = '%';\n\t\t\t\troom.privacySetter = privacySetter;\n\t\t\t\tif (inviteOnly) {\n\t\t\t\t\troom.settings.modjoin = '%';\n\t\t\t\t\troom.add(`|raw|
This best-of set is invite-only!
Users must be invited with /invite (or be staff) to join
`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tcheckForcedUserSettings(user: User) {\n\t\tthis.forcedSettings = {\n\t\t\tmodchat: this.forcedSettings.modchat || Rooms.RoomBattle.battleForcedSetting(user, 'modchat'),\n\t\t\tprivacy: this.forcedSettings.privacy || Rooms.RoomBattle.battleForcedSetting(user, 'privacy'),\n\t\t};\n\t\tif (\n\t\t\tthis.players.some(p => p.getUser()?.battleSettings.special) ||\n\t\t\t(this.options.rated && this.forcedSettings.modchat)\n\t\t) {\n\t\t\tthis.room.settings.modchat = '\\u2606';\n\t\t}\n\t}\n\tsetPrivacyOfGames(privacy: PrivacySetting) {\n\t\tfor (let i = 0; i < this.games.length; i++) {\n\t\t\tconst room = this.games[i].room;\n\t\t\tconst prevRoom = this.games[i - 1]?.room;\n\t\t\tconst gameNum = i + 1;\n\n\t\t\troom.setPrivate(privacy);\n\t\t\tthis.room.add(`|uhtmlchange|game${gameNum}|${room.title}`);\n\t\t\troom.add(`|uhtmlchange|bestof|

Game ${gameNum} of a best-of-${this.bestOf}

`).update();\n\t\t\tif (prevRoom) {\n\t\t\t\tprevRoom.add(`|uhtmlchange|next|Next: Game ${gameNum} of ${this.bestOf}`).update();\n\t\t\t}\n\t\t}\n\t\tthis.updateDisplay();\n\t}\n\tclearWaiting() {\n\t\tthis.waitingBattle = null;\n\t\tfor (const player of this.players) {\n\t\t\tplayer.ready = null;\n\t\t\tplayer.updateReadyButton();\n\t\t}\n\t\tif (this.nextBattleTimer) {\n\t\t\tclearInterval(this.nextBattleTimer);\n\t\t\tthis.nextBattleTimerEnd = null;\n\t\t}\n\t\tthis.nextBattleTimerEnd = null;\n\t\tthis.nextBattleTimer = null;\n\t}\n\tgetOptions(): RoomBattleOptions | null {\n\t\tconst players = this.players.map(player => ({\n\t\t\t...player.options,\n\t\t\tuser: player.getUser()!,\n\t\t}));\n\t\tif (players.some(p => !p.user)) {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\t...this.options,\n\t\t\tplayers,\n\t\t};\n\t}\n\tnextGame() {\n\t\tconst prevBattleRoom = this.waitingBattle;\n\t\tif (!prevBattleRoom && this.games.length) return; // should never happen\n\t\tthis.clearWaiting();\n\n\t\tconst options = this.getOptions();\n\t\tif (!options) {\n\t\t\tfor (const p of this.players) {\n\t\t\t\tif (!p.getUser()) {\n\t\t\t\t\t// tbc this isn't just being offline, it's changing name or being offline for 15 minutes\n\t\t\t\t\tthis.forfeitPlayer(p, ` lost by being unavailable at the start of a game.`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new Error(`Failed to get options for ${this.roomid}`);\n\t\t}\n\t\tconst battleRoom = Rooms.createBattle(options);\n\t\t// shouldn't happen even in lockdown\n\t\tif (!battleRoom) throw new Error(\"Failed to create battle for \" + this.title);\n\t\tthis.games.push({\n\t\t\troom: battleRoom,\n\t\t\twinner: undefined,\n\t\t\trated: battleRoom.rated,\n\t\t});\n\t\t// the absolute result is what counts for rating\n\t\tbattleRoom.rated = 0;\n\t\tif (this.needsTimer) {\n\t\t\tbattleRoom.battle?.timer.start();\n\t\t}\n\t\tconst gameNum = this.games.length;\n\t\tconst p1 = this.players[0];\n\t\tconst p2 = this.players[1];\n\t\tbattleRoom.add(\n\t\t\tUtils.html`|html|` +\n\t\t\t`
${p1.name}${p2.name}
${this.renderWins(p1)}${this.renderWins(p2)}
`\n\t\t);\n\t\tbattleRoom.add(\n\t\t\t`|uhtml|bestof|

Game ${gameNum} of a best-of-${this.bestOf}

`\n\t\t).update();\n\n\t\tthis.room.add(`|html|

Game ${gameNum}

`);\n\t\tthis.room.add(Utils.html`|uhtml|game${gameNum}|${battleRoom.title}`);\n\t\tthis.updateDisplay();\n\n\t\tprevBattleRoom?.add(\n\t\t\t`|uhtml|next|Next: Game ${gameNum} of ${this.bestOf}`\n\t\t).update();\n\t}\n\trenderWins(player: BestOfPlayer) {\n\t\tconst wins = this.games.filter(game => game.winner === player).length;\n\t\tconst winBuf = ` `.repeat(wins);\n\t\tconst restBuf = ` `.repeat(this.winThreshold - wins);\n\t\treturn player.num === 1 ? winBuf + restBuf : restBuf + winBuf;\n\t}\n\tupdateDisplay() {\n\t\tconst p1name = this.players[0].name;\n\t\tconst p2name = this.players[1].name;\n\t\tlet buf = Utils.html`
${p1name} and ${p2name}'s Best-of-${this.bestOf} progress:
`;\n\t\tbuf += '';\n\t\tfor (const p of this.players) {\n\t\t\tbuf += Utils.html``;\n\t\t}\n\t\tbuf += `
${p.name}: `;\n\t\t\tfor (let i = 0; i < this.bestOf; i++) {\n\t\t\t\tif (this.games[i]?.winner === p) {\n\t\t\t\t\tbuf += ``;\n\t\t\t\t} else {\n\t\t\t\t\tbuf += ``;\n\t\t\t\t}\n\t\t\t\tif (i !== this.bestOf - 1) {\n\t\t\t\t\tbuf += ` `;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuf += `


`;\n\t\tbuf += ``;\n\n\t\tfor (const i of [0, null, 1]) {\n\t\t\tif (i === null) {\n\t\t\t\tbuf += ``;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbuf += Utils.html``;\n\t\t}\n\n\t\tbuf += ``;\n\n\t\tfor (const i of [0, null, 1]) {\n\t\t\tif (i === null) {\n\t\t\t\tbuf += ``;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst p = this.players[i];\n\t\t\tconst mirrorLeftPlayer = !i ? ' style=\"transform: scaleX(-1)\"' : \"\";\n\t\t\tbuf += ``;\n\t\t}\n\n\t\tbuf += ``;\n\n\t\tfor (const i of [0, null, 1]) {\n\t\t\tif (i === null) {\n\t\t\t\tbuf += ``;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst team = Teams.unpack(this.players[i].options.team || \"\");\n\t\t\tif (!team || !Dex.formats.getRuleTable(this.format).has('teampreview')) {\n\t\t\t\tbuf += ``;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst mirrorLeftPlayer = !i ? ' style=\"transform: scaleX(-1)\"' : \"\";\n\t\t\tbuf += ``;\n\t\t}\n\t\tbuf += `
${this.players[i].name}
`;\n\t\t\tbuf += ``;\n\t\t\tbuf += `
vs `;\n\t\t\t\tbuf += ` `.repeat(3);\n\t\t\t\tbuf += `
`;\n\t\t\t\tbuf += ` `.repeat(3);\n\t\t\t\tbuf += `
`;\n\t\t\tfor (const [j, set] of team.entries()) {\n\t\t\t\tif (j % 3 === 0 && j > 1) buf += `
`;\n\t\t\t\tbuf += ``;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\tthis.room.add(`|fieldhtml|
${buf}
`);\n\n\t\tbuf = this.games.map(({ room, winner }, index) => {\n\t\t\tlet progress = `being played`;\n\t\t\tif (winner) progress = Utils.html`won by ${winner.name}`;\n\t\t\tif (winner === null) progress = `tied`;\n\t\t\treturn Utils.html`

Game ${index + 1}: ${progress}

`;\n\t\t}).join('');\n\t\tif (this.winner) {\n\t\t\tbuf += Utils.html`

${this.winner.name} won!

`;\n\t\t} else if (this.winner === null) {\n\t\t\tbuf += `

The battle was tied.

`;\n\t\t}\n\t\tthis.room.add(`|controlshtml|
${buf}
`);\n\t\tthis.room.update();\n\t}\n\n\toverride startTimer() {\n\t\tthis.needsTimer = true;\n\t\tfor (const { room } of this.games) {\n\t\t\troom.battle?.timer.start();\n\t\t}\n\t}\n\n\tonBattleWin(room: Room, winnerid: ID) {\n\t\tif (this.ended) return; // can happen if the bo3 is destroyed fsr\n\n\t\tconst winner = winnerid ? this.playerTable[winnerid] : null;\n\t\tthis.games[this.games.length - 1].winner = winner;\n\t\tif (winner) {\n\t\t\twinner.wins++;\n\t\t\tconst loserPlayer = room.battle!.players.find(p => p.num !== winner.num);\n\t\t\tif (loserPlayer && loserPlayer.dcSecondsLeft <= 0) { // disconnection means opp wins the set\n\t\t\t\treturn this.forfeit(loserPlayer.name, ` lost the series due to inactivity.`);\n\t\t\t}\n\t\t\tthis.room.add(Utils.html`|html|${winner.name} won game ${this.games.length}!`).update();\n\t\t\tif (winner.wins >= this.winThreshold) {\n\t\t\t\treturn this.end(winner.id);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ties++;\n\t\t\tthis.winThreshold = Math.floor((this.bestOf - this.ties) / 2) + 1;\n\t\t\tthis.room.add(`|html|Game ${this.games.length} was a tie.`).update();\n\t\t}\n\t\tif (this.games.length >= this.bestOf) {\n\t\t\treturn this.end(''); // overall tie\n\t\t}\n\n\t\t// no one has won, skip onwards\n\t\tthis.promptNextGame(room);\n\t}\n\tpromptNextGame(room: Room) {\n\t\tif (!room.battle || this.winner) return; // ???\n\t\tthis.updateDisplay();\n\t\tthis.waitingBattle = room;\n\t\tconst now = Date.now();\n\t\tthis.nextBattleTimerEnd = now + BEST_OF_IN_BETWEEN_TIME * 1000;\n\t\tfor (const player of this.players) {\n\t\t\tplayer.ready = false;\n\t\t\tconst dcAutoloseTime = now + room.battle.players[player.num - 1].dcSecondsLeft * 1000;\n\t\t\tif (dcAutoloseTime < this.nextBattleTimerEnd) {\n\t\t\t\tplayer.dcAutoloseTime = dcAutoloseTime;\n\t\t\t}\n\t\t\tplayer.updateReadyButton();\n\t\t}\n\t\tthis.nextBattleTimer = setInterval(() => this.pokeNextBattleTimer(), 10000);\n\t}\n\tpokeNextBattleTimer() {\n\t\tif (!this.nextBattleTimerEnd || !this.nextBattleTimer) return; // ??\n\t\tif (Date.now() >= this.nextBattleTimerEnd) {\n\t\t\treturn this.nextGame();\n\t\t}\n\t\tfor (const p of this.players) {\n\t\t\tif (!p.ready) {\n\t\t\t\tconst now = Date.now() - 100; // fudge to make rounding work better\n\t\t\t\tif (p.dcAutoloseTime && now > p.dcAutoloseTime) {\n\t\t\t\t\treturn this.forfeit(p.name, ` lost the series due to inactivity.`);\n\t\t\t\t}\n\t\t\t\tconst message = (p.dcAutoloseTime ?\n\t\t\t\t\t`|inactive|${p.name} has ${Chat.toDurationString(p.dcAutoloseTime - now)} to reconnect!` :\n\t\t\t\t\t`|inactive|${p.name} has ${Chat.toDurationString(this.nextBattleTimerEnd - now)} to confirm battle start!`\n\t\t\t\t);\n\t\t\t\tthis.waitingBattle?.add(message);\n\t\t\t\tthis.room.add(message);\n\t\t\t}\n\t\t}\n\t\tthis.waitingBattle?.update();\n\t\tthis.room.update();\n\t}\n\tconfirmReady(user: User) {\n\t\tconst player = this.playerTable[user.id];\n\t\tif (!player) {\n\t\t\tthrow new Chat.ErrorMessage(\"You aren't a player in this best-of set.\");\n\t\t}\n\t\tif (!this.waitingBattle) {\n\t\t\tthrow new Chat.ErrorMessage(\"The battle is not currently waiting for ready confirmation.\");\n\t\t}\n\n\t\tplayer.ready = true;\n\t\tplayer.updateReadyButton();\n\t\tconst readyMsg = `||${player.name} is ready for game ${this.games.length + 1}.`;\n\t\tthis.waitingBattle.add(readyMsg).update();\n\t\tthis.room.add(readyMsg).update();\n\t\tif (this.players.every(p => p.ready)) {\n\t\t\tthis.nextGame();\n\t\t}\n\t}\n\toverride setEnded() {\n\t\tthis.clearWaiting();\n\t\tsuper.setEnded();\n\t}\n\tend(winnerid: ID) {\n\t\tif (this.ended) return;\n\t\tthis.setEnded();\n\t\tthis.room.add(`|allowleave|`).update();\n\t\tconst winner = winnerid ? this.playerTable[winnerid] : null;\n\t\tthis.winner = winner;\n\t\tif (winner) {\n\t\t\tthis.room.add(`|win|${winner.name}`);\n\t\t} else {\n\t\t\tthis.room.add(`|tie`);\n\t\t}\n\t\tthis.updateDisplay();\n\t\tthis.room.update();\n\t\tconst p1 = this.players[0];\n\t\tconst p2 = this.players[1];\n\t\tthis.score = this.players.map(p => p.wins);\n\t\tthis.room.parent?.game?.onBattleWin?.(this.room, winnerid);\n\t\t// run elo stuff here\n\t\tlet p1score = 0.5;\n\t\tif (winner === p1) {\n\t\t\tp1score = 1;\n\t\t} else if (winner === p2) {\n\t\t\tp1score = 0;\n\t\t}\n\n\t\tconst { rated, room } = this.games[this.games.length - 1];\n\t\tif (rated) {\n\t\t\tvoid room.battle?.updateLadder(p1score, winnerid);\n\t\t}\n\t}\n\toverride forfeit(user: User | string, message = '') {\n\t\tconst userid = (typeof user !== 'string') ? user.id : toID(user);\n\n\t\tconst loser = this.playerTable[userid];\n\t\tif (loser) this.forfeitPlayer(loser, message);\n\t}\n\tforfeitPlayer(loser: BestOfPlayer, message = '') {\n\t\tif (this.ended || this.winner) return false;\n\n\t\tthis.winner = this.players.find(p => p !== loser)!;\n\t\tthis.room.add(`||${loser.name}${message || ' forfeited.'}`);\n\t\tthis.end(this.winner.id);\n\n\t\tconst lastBattle = this.games[this.games.length - 1].room.battle;\n\t\tif (lastBattle && !lastBattle.ended) lastBattle.forfeit(loser.id, message);\n\t\treturn true;\n\t}\n\toverride destroy() {\n\t\tthis.setEnded();\n\t\tfor (const { room } of this.games) room.expire();\n\t\tthis.games = [];\n\t\tfor (const p of this.players) p.destroy();\n\t\tthis.players = [];\n\t\tthis.playerTable = {};\n\t\tthis.winner = null;\n\t}\n}\n"], "mappings": "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", "names": ["button"] }