|
1 | 1 | import mongoose, { type HydratedDocument } from 'mongoose'; |
| 2 | +import { pokedex } from 'ps-client/data'; |
2 | 3 |
|
3 | 4 | import { IS_ENABLED } from '@/enabled'; |
| 5 | +import { ScrabbleMods } from '@/ps/games/scrabble/constants'; |
| 6 | +import { GamesList } from '@/ps/games/types'; |
| 7 | +import { toId } from '@/tools'; |
4 | 8 |
|
| 9 | +import type { Log as ScrabbleLog } from '@/ps/games/scrabble/logs'; |
| 10 | +import type { WinCtx as ScrabbleWinCtx } from '@/ps/games/scrabble/types'; |
5 | 11 | import type { Player } from '@/ps/games/types'; |
6 | 12 |
|
7 | 13 | const schema = new mongoose.Schema({ |
@@ -80,3 +86,44 @@ export async function getGameById(gameType: string, gameId: string): Promise<Hyd |
80 | 86 | if (!game) throw new Error(`Unable to find a game of ${gameType} with ID ${id}.`); |
81 | 87 | return game; |
82 | 88 | } |
| 89 | + |
| 90 | +type ScrabbleDexEntry = { |
| 91 | + pokemon: string; |
| 92 | + pokemonName: string; |
| 93 | + num: number; |
| 94 | + by: string; |
| 95 | + at: Date; |
| 96 | + gameId: string; |
| 97 | + mod: string; |
| 98 | + won: boolean; |
| 99 | +}; |
| 100 | +export async function getScrabbleDex(): Promise<ScrabbleDexEntry[] | null> { |
| 101 | + if (!IS_ENABLED.DB) return null; |
| 102 | + const scrabbleGames = await model.find({ game: GamesList.Scrabble, mod: [ScrabbleMods.CRAZYMONS, ScrabbleMods.POKEMON] }).lean(); |
| 103 | + return scrabbleGames.flatMap(game => { |
| 104 | + const baseCtx = { gameId: game.id, mod: game.mod! }; |
| 105 | + const winCtx = game.winCtx as ScrabbleWinCtx | undefined; |
| 106 | + const winners = winCtx?.type === 'win' ? winCtx.winnerIds : []; |
| 107 | + const logs = game.log.map<ScrabbleLog>(log => JSON.parse(log)); |
| 108 | + return logs |
| 109 | + .filterMap<ScrabbleDexEntry[]>(log => { |
| 110 | + if (log.action !== 'play') return; |
| 111 | + const words = Object.keys(log.ctx.words).map(toId).unique(); |
| 112 | + return words.filterMap<ScrabbleDexEntry>(word => { |
| 113 | + if (!(word in pokedex)) return; |
| 114 | + const mon = pokedex[word]; |
| 115 | + if (mon.num <= 0) return; |
| 116 | + return { |
| 117 | + ...baseCtx, |
| 118 | + pokemon: word, |
| 119 | + pokemonName: mon.name, |
| 120 | + num: mon.num, |
| 121 | + by: log.turn, |
| 122 | + at: log.time, |
| 123 | + won: winners.includes(log.turn), |
| 124 | + }; |
| 125 | + }); |
| 126 | + }) |
| 127 | + .flat(); |
| 128 | + }); |
| 129 | +} |
0 commit comments