From a046fceb4c302d5b0e03e3857a8b7760d40757cb Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:05:19 +0000 Subject: [PATCH] checkpoint: 16 --- .eslintrc | 3 +- bot/src/utils/misc.ts | 12 +++--- bot/src/utils/returnTypes.ts | 2 +- client/src/types/api-returns.ts | 40 +++++++++---------- client/src/types/seeds.ts | 4 +- client/src/types/tables.ts | 22 +++++----- client/src/util/asserts.ts | 2 +- client/src/util/data.ts | 4 +- client/src/util/grade-deltas.ts | 6 +-- client/src/util/misc.ts | 4 +- client/src/util/tables/create-search.ts | 20 +++++----- client/src/util/tierlist.ts | 26 ++++++------ common/src/lib/schemas.ts | 14 +++---- common/src/types/game-config.ts | 4 ++ .../scripts/test/table-default.test.ts | 14 +++---- server/src/lib/jobs/bms-table-sync.ts | 6 +-- server/src/lib/orphan-queue/orphan-queue.ts | 28 ++++++------- .../calculated-data/calculated-data.ts | 2 +- .../framework/pb/create-pb-doc.test.ts | 4 +- .../framework/pb/create-pb-doc.ts | 8 ++-- .../score-importing/score-id.test.ts | 4 +- .../framework/score-importing/score-id.ts | 2 +- .../score-importing/score-import-main.ts | 2 +- .../framework/sessions/sessions.ts | 4 +- .../import-types/ir/beatoraja/converter.ts | 8 ++-- .../ir/kshook-sv6c-static/converter.ts | 7 +--- .../lib/score-mutation/delete-scores.test.ts | 2 +- .../lib/score-mutation/update-score.test.ts | 2 +- server/src/lib/score-mutation/update-score.ts | 2 +- server/src/lib/targets/goals.ts | 2 +- .../router/api/v1/scores/_scoreID/router.ts | 4 +- .../api/v1/sessions/_sessionID/router.ts | 31 +++++--------- .../games/@gameSpecificRoutes/iidx/router.ts | 9 ++--- .../_userID/games/_game/_playtype/router.ts | 12 ++++-- .../games/_game/_playtype/sessions/router.ts | 4 +- .../api/v1/users/_userID/router.test.ts | 2 +- .../router/api/v1/users/_userID/router.ts | 11 +++-- .../router/ir/usc/_playtype/router.test.ts | 6 +-- server/src/test-utils/resets.ts | 4 +- server/src/test-utils/test-data.ts | 2 +- .../src/utils/calculations/recalc-scores.ts | 2 +- server/src/utils/folder.ts | 20 +++++----- server/src/utils/queries/charts.ts | 6 +-- server/src/utils/string-checks.ts | 24 ++++++----- 44 files changed, 200 insertions(+), 197 deletions(-) diff --git a/.eslintrc b/.eslintrc index 98363f8e7..d39773ad2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,7 +22,8 @@ "@typescript-eslint/no-unsafe-argument": "off", "@typescript-eslint/no-unsafe-member-access": "off", "@typescript-eslint/no-unsafe-property-computation": "off", - "@typescript-eslint/no-unsafe-call": "off" + "@typescript-eslint/no-unsafe-call": "off", + "@typescript-eslint/strict-boolean-expressions": "off" } }, { diff --git a/bot/src/utils/misc.ts b/bot/src/utils/misc.ts index f3b116356..a7ec71be5 100644 --- a/bot/src/utils/misc.ts +++ b/bot/src/utils/misc.ts @@ -152,14 +152,14 @@ export function CreateChartLink(chart: ChartDocument, game: Game) { return `${BotConfig.TACHI_SERVER_LOCATION}/games/${game}/${chart.playtype}/songs/${chart.songID}/${chart.chartID}`; } -type ScOrPBDoc = PBScoreDocument | ScoreDocument; +type ScOrPBDoc = PBScoreDocument | ScoreDocument; -export function FormatScoreData(score: ScOrPBDoc) { +export function FormatScoreData(score: ScOrPBDoc) { const game = score.game; let lampStr: string = score.scoreData.lamp; let scoreStr = `${score.scoreData.score.toLocaleString()} (${ - score.scoreData.grade + score.scoreData.grade.string }, ${score.scoreData.percent.toFixed(2)}%)`; if (game === "iidx" || game === "bms" || game === "pms") { @@ -176,7 +176,7 @@ export function FormatScoreData(score: ScOrPBDo score.playtype, score.scoreData.score, score.scoreData.percent, - score.scoreData.grade + score.scoreData.grade.string ); scoreStr = `${closer === "lower" ? lower : upper} (${ @@ -190,7 +190,7 @@ export function FormatScoreData(score: ScOrPBDo /** * Util for getting a games' grade for a given percent. */ -function GetGradeFromPercent( +function GetGradeFromPercent( game: Game, playtype: Playtype, percent: number @@ -229,7 +229,7 @@ function FormatIIDXEXScore(exscore: integer, notecount: integer, playtype: Playt return `${closer === "lower" ? lower : upper} (${exscore}, ${percent.toFixed(2)}%)`; } -export function GetChartPertinentInfo(game: Game, chart: ChartDocument) { +export function GetChartPertinentInfo(game: Game, chart: ChartDocument) { if (game === "iidx") { const ch = chart as ChartDocument<"iidx:DP" | "iidx:SP">; diff --git a/bot/src/utils/returnTypes.ts b/bot/src/utils/returnTypes.ts index 4645c4afe..1c087b0ab 100644 --- a/bot/src/utils/returnTypes.ts +++ b/bot/src/utils/returnTypes.ts @@ -45,7 +45,7 @@ export type ImportPollStatus = }; }; -export interface UGPTStats { +export interface UGPTStats { gameStats: UserGameStats; firstScore: ScoreDocument; mostRecentScore: ScoreDocument; diff --git a/client/src/types/api-returns.ts b/client/src/types/api-returns.ts index 4a133c085..3d0db9219 100644 --- a/client/src/types/api-returns.ts +++ b/client/src/types/api-returns.ts @@ -9,7 +9,7 @@ import { GoalSubscriptionDocument, Grades, GPTString, - IDStringToGame, + GPTStringToGame, ImportDocument, ImportTrackerFailed, integer, @@ -31,7 +31,7 @@ import { SessionScoreInfo, } from "tachi-common"; -export interface UGPTStatsReturn { +export interface UGPTStatsReturn { gameStats: UserGameStats; firstScore: ScoreDocument; mostRecentScore: ScoreDocument; @@ -78,31 +78,31 @@ export type UGPTPreferenceStatsReturn = export type UGPTHistory = Omit[]; -export interface SessionReturns { +export interface SessionReturns { session: SessionDocument; scores: ScoreDocument[]; scoreInfo: Array; - songs: SongDocument[]; + songs: SongDocument[]; charts: ChartDocument[]; user: UserDocument; } -export interface UGPTChartPBComposition { +export interface UGPTChartPBComposition { scores: ScoreDocument[]; chart: ChartDocument; pb: PBScoreDocument; } -export type UGSWithRankingData = UserGameStats & { +export type UGSWithRankingData = UserGameStats & { __rankingData: Record; }; -export interface SongChartsSearch { - songs: SongDocument[]; +export interface SongChartsSearch { + songs: SongDocument[]; charts: ChartDocument[]; } -export interface FolderStatsInfo { +export interface FolderStatsInfo { grades: Record; lamps: Record; folderID: string; @@ -120,16 +120,16 @@ export interface UGPTTableReturns { table: TableDocument; } -export interface UGPTFolderReturns { +export interface UGPTFolderReturns { folder: FolderDocument; - songs: SongDocument[]; + songs: SongDocument[]; charts: ChartDocument[]; pbs: PBScoreDocument[]; } -export interface GPTFolderReturns { +export interface GPTFolderReturns { folder: FolderDocument; - songs: SongDocument[]; + songs: SongDocument[]; charts: ChartDocument[]; } @@ -145,31 +145,31 @@ export interface RecentClassesReturn { users: UserDocument[]; } -export interface SongsReturn { - song: SongDocument; +export interface SongsReturn { + song: SongDocument; charts: ChartDocument[]; } -export interface ChartPBLeaderboardReturn { +export interface ChartPBLeaderboardReturn { users: UserDocument[]; pbs: PBScoreDocument[]; } -export interface UGPTChartLeaderboardAdjacent { +export interface UGPTChartLeaderboardAdjacent { users: UserDocument[]; pb: PBScoreDocument; adjacentAbove: PBScoreDocument[]; adjacentBelow: PBScoreDocument[]; } -export interface ScoreLeaderboardReturns { +export interface ScoreLeaderboardReturns { users: UserDocument[]; - songs: SongDocument[]; + songs: SongDocument[]; charts: ChartDocument[]; pbs: PBScoreDocument[]; } -export interface UserLeaderboardReturns { +export interface UserLeaderboardReturns { users: UserDocument[]; gameStats: UserGameStats[]; } diff --git a/client/src/types/seeds.ts b/client/src/types/seeds.ts index 36277f49d..d9c27bbc1 100644 --- a/client/src/types/seeds.ts +++ b/client/src/types/seeds.ts @@ -10,7 +10,7 @@ import { GoalDocumentMulti, GoalDocumentSingle, GPTString, - IDStringToGame, + GPTStringToGame, QuestDocument, QuestlineDocument, SongDocument, @@ -61,7 +61,7 @@ export type QuestWithRelated = QuestDocument & { export type ChartWithRelated = ChartDocument & { __related: { - song: SongDocument | undefined; + song: SongDocument | undefined; }; }; diff --git a/client/src/types/tables.ts b/client/src/types/tables.ts index 7dc1fe7a1..b0a725613 100644 --- a/client/src/types/tables.ts +++ b/client/src/types/tables.ts @@ -1,7 +1,7 @@ import { ChartDocument, GPTString, - IDStringToGame, + GPTStringToGame, ImportDocument, ImportTrackerFailed, integer, @@ -15,54 +15,54 @@ import { QuestDocument, } from "tachi-common"; -export type PBDataset = (PBScoreDocument & { +export type PBDataset = (PBScoreDocument & { __related: { chart: ChartDocument; - song: SongDocument; + song: SongDocument; index: integer; user?: UserDocument; }; __playcount?: integer; })[]; -export type ScoreDataset = (ScoreDocument & { +export type ScoreDataset = (ScoreDocument & { __related: { chart: ChartDocument; - song: SongDocument; + song: SongDocument; index: integer; user: UserDocument; }; })[]; -export type FolderDataset = (ChartDocument & { +export type FolderDataset = (ChartDocument & { __related: { pb: PBScoreDocument | null; - song: SongDocument; + song: SongDocument; user: UserDocument; }; })[]; -export type ChartLeaderboardDataset = (PBScoreDocument & { +export type ChartLeaderboardDataset = (PBScoreDocument & { __related: { user: UserDocument; }; })[]; -export type UGSDataset = (UserGameStats & { +export type UGSDataset = (UserGameStats & { __related: { user: UserDocument; index: integer; }; })[]; -export type RivalChartDataset = (UserDocument & { +export type RivalChartDataset = (UserDocument & { __related: { pb: PBScoreDocument | null; index: number; }; })[]; -export type ComparePBsDataset = Array<{ +export type ComparePBsDataset = Array<{ base: PBScoreDocument | null; compare: PBScoreDocument | null; chart: ChartDocument; diff --git a/client/src/util/asserts.ts b/client/src/util/asserts.ts index ad876f3dc..b056c8333 100644 --- a/client/src/util/asserts.ts +++ b/client/src/util/asserts.ts @@ -21,7 +21,7 @@ export function IsSupportedPlaytype( return gameConfig.playtypes.includes(str as unknown as Playtypes[G]); } -export function IsScore( +export function IsScore( pbOrScore: PBScoreDocument | ScoreDocument ): pbOrScore is ScoreDocument { // @ts-expect-error thats the test... diff --git a/client/src/util/data.ts b/client/src/util/data.ts index 186558c26..9b81b2d77 100644 --- a/client/src/util/data.ts +++ b/client/src/util/data.ts @@ -56,7 +56,7 @@ export function CreateChartIDMap(arr: T[]): Map(charts: ChartDocument[]) { +export function CreateChartMap(charts: ChartDocument[]) { const chartMap = new Map>(); for (const chart of charts) { @@ -66,7 +66,7 @@ export function CreateChartMap(charts: ChartDoc return chartMap; } -export function CreateScoreIDMap(scores: ScoreDocument[]) { +export function CreateScoreIDMap(scores: ScoreDocument[]) { const scoreMap = new Map>(); for (const score of scores) { diff --git a/client/src/util/grade-deltas.ts b/client/src/util/grade-deltas.ts index 302dc4502..20c91508b 100644 --- a/client/src/util/grade-deltas.ts +++ b/client/src/util/grade-deltas.ts @@ -1,6 +1,6 @@ import { Game, GetGamePTConfig, Grades, GPTString, integer, Playtypes } from "tachi-common"; -export function AbsoluteGradeDelta( +export function AbsoluteGradeDelta( game: Game, playtype: Playtypes[Game], score: number, @@ -23,7 +23,7 @@ export function AbsoluteGradeDelta( return score - gradeScore; } -export function RelativeGradeDelta( +export function RelativeGradeDelta( game: Game, playtype: Playtypes[Game], score: number, @@ -53,7 +53,7 @@ function WrapGrade(grade: string) { return grade; } -export function GenericFormatGradeDelta( +export function GenericFormatGradeDelta( game: Game, playtype: Playtypes[Game], score: number, diff --git a/client/src/util/misc.ts b/client/src/util/misc.ts index ae637762b..e83906831 100644 --- a/client/src/util/misc.ts +++ b/client/src/util/misc.ts @@ -197,7 +197,7 @@ export function SelectRightChart( return chart; } } - } else if (gptConfig.idString === "itg:Stamina") { + } else if (gptConfig.gptString === "itg:Stamina") { for (const chart of charts) { if ( (chart as ChartDocument<"itg:Stamina">).data.hashGSV3 === chartID && @@ -315,7 +315,7 @@ export function FormatSessionRating( return formatter(value); } -export function GetGradeFromPercent( +export function GetGradeFromPercent( game: Game, playtype: Playtype, percent: number diff --git a/client/src/util/tables/create-search.ts b/client/src/util/tables/create-search.ts index a7b152e69..95e852415 100644 --- a/client/src/util/tables/create-search.ts +++ b/client/src/util/tables/create-search.ts @@ -21,7 +21,7 @@ function GetBMSTableVal(chart: ChartDocument<"bms:7K" | "bms:14K">, key: string) return null; } -export function CreateDefaultScoreSearchParams( +export function CreateDefaultScoreSearchParams( game: Game, playtype: Playtype ) { @@ -36,11 +36,11 @@ export function CreateDefaultScoreSearchParams( percent: (x) => x.scoreData.percent, highlight: (x) => !!x.highlight, lamp: { - valueGetter: (x) => [x.scoreData.lamp, x.scoreData.lampIndex], + valueGetter: (x) => [x.scoreData.lamp, x.scoreData.lamp.index], strToNum: HumanFriendlyStrToLampIndex(game, playtype), }, grade: { - valueGetter: (x) => [x.scoreData.grade, x.scoreData.gradeIndex], + valueGetter: (x) => [x.scoreData.grade.string, x.scoreData.grade.string], strToNum: HumanFriendlyStrToGradeIndex(game, playtype), }, ...CreateCalcDataSearchFns(gptConfig), @@ -53,7 +53,7 @@ export function CreateDefaultScoreSearchParams( return searchFunctions; } -export function CreateDefaultPBSearchParams( +export function CreateDefaultPBSearchParams( game: Game, playtype: Playtype ) { @@ -71,11 +71,11 @@ export function CreateDefaultPBSearchParams( highlight: (x) => !!x.highlight, username: (x) => x.__related.user?.username ?? null, lamp: { - valueGetter: (x) => [x.scoreData.lamp, x.scoreData.lampIndex], + valueGetter: (x) => [x.scoreData.lamp, x.scoreData.lamp.index], strToNum: HumanFriendlyStrToLampIndex(game, playtype), }, grade: { - valueGetter: (x) => [x.scoreData.grade, x.scoreData.gradeIndex], + valueGetter: (x) => [x.scoreData.grade.string, x.scoreData.grade.string], strToNum: HumanFriendlyStrToGradeIndex(game, playtype), }, ...CreateCalcDataSearchFns(gptConfig), @@ -88,7 +88,7 @@ export function CreateDefaultPBSearchParams( return searchFunctions; } -export function CreatePBCompareSearchParams( +export function CreatePBCompareSearchParams( game: Game, playtype: Playtype ) { @@ -106,7 +106,7 @@ export function CreatePBCompareSearchParams( return searchFunctions; } -export function CreateDefaultFolderSearchParams( +export function CreateDefaultFolderSearchParams( game: Game, playtype: Playtype ) { @@ -126,14 +126,14 @@ export function CreateDefaultFolderSearchParams lamp: { valueGetter: (x) => x.__related.pb - ? [x.__related.pb.scoreData.lamp, x.__related.pb.scoreData.lampIndex] + ? [x.__related.pb.scoreData.lamp, x.__related.pb.scoreData.lamp.index] : null, strToNum: HumanFriendlyStrToLampIndex(game, playtype), }, grade: { valueGetter: (x) => x.__related.pb - ? [x.__related.pb.scoreData.grade, x.__related.pb.scoreData.gradeIndex] + ? [x.__related.pb.scoreData.grade.string, x.__related.pb.scoreData.grade.string] : null, strToNum: HumanFriendlyStrToGradeIndex(game, playtype), }, diff --git a/client/src/util/tierlist.ts b/client/src/util/tierlist.ts index 143e0c9da..05d7ef3bd 100644 --- a/client/src/util/tierlist.ts +++ b/client/src/util/tierlist.ts @@ -16,38 +16,38 @@ type ScaleAchievedFns = { const ScaleNameAchievedFns: ScaleAchievedFns = { "bms:14K": { - "sgl-EC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.EASY_CLEAR, - "sgl-HC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.HARD_CLEAR, + "sgl-EC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.EASY_CLEAR, + "sgl-HC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.HARD_CLEAR, }, "bms:7K": { - "sgl-EC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.EASY_CLEAR, - "sgl-HC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.HARD_CLEAR, + "sgl-EC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.EASY_CLEAR, + "sgl-HC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.HARD_CLEAR, }, "pms:Controller": { - "sgl-EC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.EASY_CLEAR, - "sgl-HC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.HARD_CLEAR, + "sgl-EC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.EASY_CLEAR, + "sgl-HC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.HARD_CLEAR, }, "pms:Keyboard": { - "sgl-EC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.EASY_CLEAR, - "sgl-HC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.HARD_CLEAR, + "sgl-EC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.EASY_CLEAR, + "sgl-HC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.HARD_CLEAR, }, "chunithm:Single": {}, "gitadora:Dora": {}, "gitadora:Gita": {}, "iidx:DP": { - "dp-tier": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.CLEAR, + "dp-tier": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.CLEAR, }, "iidx:SP": { - "kt-NC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.CLEAR, - "kt-HC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.HARD_CLEAR, - "kt-EXHC": (k) => k.scoreData.lampIndex >= IIDX_LAMPS.EX_HARD_CLEAR, + "kt-NC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.CLEAR, + "kt-HC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.HARD_CLEAR, + "kt-EXHC": (k) => k.scoreData.lamp.index >= IIDX_LAMPS.EX_HARD_CLEAR, }, "maimaidx:Single": {}, "museca:Single": { "tachi-score": null, }, "sdvx:Single": { - clear: (k) => k.scoreData.lampIndex >= SDVX_LAMPS.CLEAR, + clear: (k) => k.scoreData.lamp.index >= SDVX_LAMPS.CLEAR, }, "usc:Controller": {}, "usc:Keyboard": {}, diff --git a/common/src/lib/schemas.ts b/common/src/lib/schemas.ts index ef68e2299..ab78accab 100644 --- a/common/src/lib/schemas.ts +++ b/common/src/lib/schemas.ts @@ -64,20 +64,20 @@ const extractGPTIDString = (self: unknown) => { const s = self as Record; - if (typeof s.idString !== "string") { - throw new Error(`Expected a string where self.idString is. Got ${s.idString}`); + if (typeof s.gptString !== "string") { + throw new Error(`Expected a string where self.gptString is. Got ${s.gptString}`); } // if there's no ":" in the string, this returns only one element. - const [game, playtype] = s.idString.split(":") as [string, string | undefined]; + const [game, playtype] = s.gptString.split(":") as [string, string | undefined]; if (!IsValidGame(game)) { - throw new Error(`Expected valid game -- got ${game} from idString ${s.idString}.`); + throw new Error(`Expected valid game -- got ${game} from gptString ${s.gptString}.`); } // Playtype might be undefined in the case where the string contains no colon. if (playtype === undefined || !IsValidPlaytype(game, playtype)) { - throw new Error(`Expected valid playtype -- got ${playtype} from idString ${s.idString}.`); + throw new Error(`Expected valid playtype -- got ${playtype} from gptString ${s.gptString}.`); } return { game, playtype }; @@ -475,7 +475,7 @@ const PRE_SCHEMAS = { userID: p.isPositiveNonZeroInteger, timeStarted: p.isPositive, timeFinished: p.isPositive, - idStrings: [p.isIn(allGPTStrings)], + gptStrings: [p.isIn(allGPTStrings)], importID: "string", scoreIDs: ["string"], game: p.isIn(games), @@ -688,7 +688,7 @@ const PRE_SCHEMAS = { const { game } = extractGPTIDString(self); return prSchemaFnWrap({ - idString: p.isIn(allGPTStrings), + gptString: p.isIn(allGPTStrings), chartDoc: PR_CHART_DOCUMENT(game), songDoc: PR_SONG_DOCUMENT(game), userIDs: [p.isPositiveNonZeroInteger], diff --git a/common/src/types/game-config.ts b/common/src/types/game-config.ts index 2617787b8..347540bfc 100644 --- a/common/src/types/game-config.ts +++ b/common/src/types/game-config.ts @@ -126,6 +126,10 @@ export type ProfileRatingAlgorithms = { [G in GPTString]: keyof typeof GAME_PT_CONFIGS[G]["profileRatingAlgs"]; }; +export type AnyScoreRatingAlg = ScoreRatingAlgorithms[GPTString]; +export type AnySessionRatingAlg = SessionRatingAlgorithms[GPTString]; +export type AnyProfileRatingAlg = ProfileRatingAlgorithms[GPTString]; + export type ConfProvidedMetrics = { [G in GPTString]: typeof GAME_PT_CONFIGS[G]["providedMetrics"]; }; diff --git a/database-seeds/scripts/test/table-default.test.ts b/database-seeds/scripts/test/table-default.test.ts index 4fa57ac9e..cc3a9026c 100644 --- a/database-seeds/scripts/test/table-default.test.ts +++ b/database-seeds/scripts/test/table-default.test.ts @@ -3,7 +3,7 @@ import { FormatGame, TableDocument } from "tachi-common"; import { allGPTString } from "tachi-common/config/static-config"; import { ReadCollection } from "../util"; -const idStringMap = {}; +const gptStringMap = {}; const tables: Array = ReadCollection("tables.json"); @@ -22,8 +22,8 @@ for (const t of tables) { } if (t.default) { - const idString = `${t.game}:${t.playtype}`; - if (idStringMap[idString]) { + const gptString = `${t.game}:${t.playtype}`; + if (gptStringMap[gptString]) { console.log( chalk.red( `[TABLE-DEFAULT] There are multiple default tables for ${FormatGame( @@ -34,13 +34,13 @@ for (const t of tables) { ); } - idStringMap[idString] = true; + gptStringMap[gptString] = true; } } -for (const idString of allGPTString) { - if (!idStringMap[idString]) { - console.log(chalk.red(`[TABLE-DEFAULT] There is no default table for ${idString}.`)); +for (const gptString of allGPTString) { + if (!gptStringMap[gptString]) { + console.log(chalk.red(`[TABLE-DEFAULT] There is no default table for ${gptString}.`)); errs += 1; } } diff --git a/server/src/lib/jobs/bms-table-sync.ts b/server/src/lib/jobs/bms-table-sync.ts index 823a457f5..60da853de 100644 --- a/server/src/lib/jobs/bms-table-sync.ts +++ b/server/src/lib/jobs/bms-table-sync.ts @@ -118,7 +118,7 @@ async function ImportTableLevels( ); for (const td of tableEntries) { - let query: FilterQuery; + let query: FilterQuery>; switch (td.checksum.type) { case "md5": { @@ -132,9 +132,7 @@ async function ImportTableLevels( } } - let chart = (await db.charts.bms.findOne(query)) as ChartDocument< - "bms:7K" | "bms:14K" - > | null; + let chart: ChartDocument<"bms:7K" | "bms:14K"> | null = await db.charts.bms.findOne(query); if (!chart) { // didn't find it in the DB? diff --git a/server/src/lib/orphan-queue/orphan-queue.ts b/server/src/lib/orphan-queue/orphan-queue.ts index e1575ed60..96431fc39 100644 --- a/server/src/lib/orphan-queue/orphan-queue.ts +++ b/server/src/lib/orphan-queue/orphan-queue.ts @@ -7,9 +7,9 @@ import type { WithID } from "monk"; import type { ChartDocument, GPTString, - IDStringToGame, + GPTStringToGame, integer, - OrphanChart, + OrphanChartDocument, SongDocument, } from "tachi-common"; @@ -27,12 +27,12 @@ const logger = CreateLogCtx(__filename); * If the chart has been seen before, and has >= N unique players who have * played it, unorphan the chart, and return it. */ -export async function HandleOrphanQueue( - idString: I, - game: IDStringToGame[I], +export async function HandleOrphanQueue( + gptString: I, + game: GPTStringToGame[I], chartDoc: ChartDocument, - songDoc: SongDocument, - orphanMatchCriteria: FilterQuery>, + songDoc: SongDocument, + orphanMatchCriteria: FilterQuery>, queueSize: integer, userID: integer, chartName: string @@ -40,7 +40,7 @@ export async function HandleOrphanQueue( logger.debug(`Received orphanqueue request for ${chartName}.`); const orphanChart = await db["orphan-chart-queue"].findOne( - { idString, ...orphanMatchCriteria }, + { gptString, ...orphanMatchCriteria }, { projectID: true, } @@ -50,7 +50,7 @@ export async function HandleOrphanQueue( logger.verbose(`Received unknown chart ${chartName}, orphaning.`); await db["orphan-chart-queue"].insert({ - idString, + gptString, chartDoc, songDoc, userIDs: [userID], @@ -111,13 +111,13 @@ export async function HandleOrphanQueue( * Useful for something like BMS-Table-Sync, where we want to load anything in a table * regardless of how many people have played the chart. */ -export async function DeorphanIfInQueue( - idString: I, - game: IDStringToGame[I], - orphanMatchCriteria: FilterQuery> +export async function DeorphanIfInQueue( + gptString: I, + game: GPTStringToGame[I], + orphanMatchCriteria: FilterQuery> ): Promise | null> { const orphanChart = await db["orphan-chart-queue"].findOne( - { idString, ...orphanMatchCriteria }, + { gptString, ...orphanMatchCriteria }, { projectID: true, } diff --git a/server/src/lib/score-import/framework/calculated-data/calculated-data.ts b/server/src/lib/score-import/framework/calculated-data/calculated-data.ts index f020e5484..7e0711271 100644 --- a/server/src/lib/score-import/framework/calculated-data/calculated-data.ts +++ b/server/src/lib/score-import/framework/calculated-data/calculated-data.ts @@ -87,7 +87,7 @@ export async function CalculateDataForGamePT( return CalculatedDataFunctions[`${game}:${playtype}` as GPTString](dryScore, chart, logger); } -type CalculatedData = Required["calculatedData"]>; +type CalculatedData = Required["calculatedData"]>; function CalculateDataIIDX( dryScore: DryScore, diff --git a/server/src/lib/score-import/framework/pb/create-pb-doc.test.ts b/server/src/lib/score-import/framework/pb/create-pb-doc.test.ts index 58377c34f..0b97c7535 100644 --- a/server/src/lib/score-import/framework/pb/create-pb-doc.test.ts +++ b/server/src/lib/score-import/framework/pb/create-pb-doc.test.ts @@ -40,8 +40,8 @@ t.test("#CreatePBDoc", (t) => { score: IIDXScore.scoreData.score, percent: IIDXScore.scoreData.percent, esd: IIDXScore.scoreData.esd, - grade: IIDXScore.scoreData.grade, - gradeIndex: IIDXScore.scoreData.gradeIndex, + grade: IIDXScore.scoreData.grade.string, + gradeIndex: IIDXScore.scoreData.grade.string, judgements: IIDXScore.scoreData.judgements, lamp: "FULL COMBO", lampIndex: lamps.indexOf("FULL COMBO"), diff --git a/server/src/lib/score-import/framework/pb/create-pb-doc.ts b/server/src/lib/score-import/framework/pb/create-pb-doc.ts index 2c125ba48..8e12b5389 100644 --- a/server/src/lib/score-import/framework/pb/create-pb-doc.ts +++ b/server/src/lib/score-import/framework/pb/create-pb-doc.ts @@ -19,7 +19,7 @@ import type { ScoreDocument, } from "tachi-common"; -export type PBScoreDocumentNoRank = Omit< +export type PBScoreDocumentNoRank = Omit< PBScoreDocument, "rankingData" >; @@ -183,10 +183,10 @@ async function MergeScoreLampIntoPB( score: scorePB.scoreData.score, percent: scorePB.scoreData.percent, esd: scorePB.scoreData.esd, - grade: scorePB.scoreData.grade, - gradeIndex: scorePB.scoreData.gradeIndex, + grade: scorePB.scoreData.grade.string, + gradeIndex: scorePB.scoreData.grade.string, lamp: lampPB.scoreData.lamp, - lampIndex: lampPB.scoreData.lampIndex, + lampIndex: lampPB.scoreData.lamp.index, judgements: scorePB.scoreData.judgements, // this will probably be overrode by game-specific fns diff --git a/server/src/lib/score-import/framework/score-importing/score-id.test.ts b/server/src/lib/score-import/framework/score-importing/score-id.test.ts index 306c9cef8..57cf9845d 100644 --- a/server/src/lib/score-import/framework/score-importing/score-id.test.ts +++ b/server/src/lib/score-import/framework/score-importing/score-id.test.ts @@ -44,7 +44,7 @@ t.test("#CreateScoreID", (t) => { scoreData: { percent: TestingIIDXSPDryScore.scoreData.percent, score: TestingIIDXSPDryScore.scoreData.score, - grade: TestingIIDXSPDryScore.scoreData.grade, + grade: TestingIIDXSPDryScore.scoreData.grade.string, lamp: TestingIIDXSPDryScore.scoreData.lamp, }, }; @@ -82,7 +82,7 @@ t.test("#CreateScoreID", (t) => { ); minimalScore.scoreData.lamp = TestingIIDXSPDryScore.scoreData.lamp; - minimalScore.scoreData.grade = "F"; + minimalScore.scoreData.grade.string = "F"; t.not( scoreID, diff --git a/server/src/lib/score-import/framework/score-importing/score-id.ts b/server/src/lib/score-import/framework/score-importing/score-id.ts index 43bb41642..70266888f 100644 --- a/server/src/lib/score-import/framework/score-importing/score-id.ts +++ b/server/src/lib/score-import/framework/score-importing/score-id.ts @@ -19,7 +19,7 @@ function HashScoreIDString(scoreIDString: string) { */ export function CreateScoreID(userID: integer, dryScore: DryScore, chartID: string) { const hash = HashScoreIDString( - `${userID}|${chartID}|${dryScore.scoreData.lamp}|${dryScore.scoreData.grade}|${dryScore.scoreData.score}|${dryScore.scoreData.percent}` + `${userID}|${chartID}|${dryScore.scoreData.lamp}|${dryScore.scoreData.grade.string}|${dryScore.scoreData.score}|${dryScore.scoreData.percent}` ); return `R${hash}`; diff --git a/server/src/lib/score-import/framework/score-importing/score-import-main.ts b/server/src/lib/score-import/framework/score-importing/score-import-main.ts index 6b029f0da..94f2700d2 100644 --- a/server/src/lib/score-import/framework/score-importing/score-import-main.ts +++ b/server/src/lib/score-import/framework/score-importing/score-import-main.ts @@ -187,7 +187,7 @@ export default async function ScoreImportMain( // Create and Save an import document to the database, and finish everything up! const ImportDocument: ImportDocument = { importType, - idStrings: playtypes.map((e) => `${game}:${e}`) as Array, + gptStrings: playtypes.map((e) => `${game}:${e}`) as Array, scoreIDs, playtypes, game, diff --git a/server/src/lib/score-import/framework/sessions/sessions.ts b/server/src/lib/score-import/framework/sessions/sessions.ts index 0fd663f75..c1cc6bc4e 100644 --- a/server/src/lib/score-import/framework/sessions/sessions.ts +++ b/server/src/lib/score-import/framework/sessions/sessions.ts @@ -67,8 +67,8 @@ function ScoreToSessionScoreInfo( return { scoreID: score.scoreID, isNewScore: false, - gradeDelta: score.scoreData.gradeIndex - previousPB.scoreData.gradeIndex, - lampDelta: score.scoreData.lampIndex - previousPB.scoreData.lampIndex, + gradeDelta: score.scoreData.grade.string - previousPB.scoreData.grade.string, + lampDelta: score.scoreData.lamp.index - previousPB.scoreData.lamp.index, percentDelta: score.scoreData.percent - previousPB.scoreData.percent, scoreDelta: score.scoreData.score - previousPB.scoreData.score, }; diff --git a/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts b/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts index cce510dce..292c17880 100644 --- a/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts +++ b/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts @@ -64,7 +64,7 @@ async function HandleOrphanChartProcess( "chartDoc.data.hashSHA256": context.chart.sha256, }; - const idString = context.chart.mode === "BEAT_7K" ? "bms:7K" : "bms:14K"; + const gptString = context.chart.mode === "BEAT_7K" ? "bms:7K" : "bms:14K"; const { chartDoc, songDoc } = ConvertBeatorajaChartToTachi( context.chart, @@ -72,7 +72,7 @@ async function HandleOrphanChartProcess( ); chart = await HandleOrphanQueue( - idString, + gptString, "bms", chartDoc, songDoc, @@ -89,12 +89,12 @@ async function HandleOrphanChartProcess( playtype, }; - const idString = playtype === "Controller" ? "pms:Controller" : "pms:Keyboard"; + const gptString = playtype === "Controller" ? "pms:Controller" : "pms:Keyboard"; const { chartDoc, songDoc } = ConvertBeatorajaChartToTachi(context.chart, playtype); chart = await HandleOrphanQueue( - idString, + gptString, "pms", chartDoc, songDoc, diff --git a/server/src/lib/score-import/import-types/ir/kshook-sv6c-static/converter.ts b/server/src/lib/score-import/import-types/ir/kshook-sv6c-static/converter.ts index 02a190722..d33a17b9f 100644 --- a/server/src/lib/score-import/import-types/ir/kshook-sv6c-static/converter.ts +++ b/server/src/lib/score-import/import-types/ir/kshook-sv6c-static/converter.ts @@ -3,7 +3,6 @@ import { InternalFailure, SongOrChartNotFoundFailure, } from "lib/score-import/framework/common/converter-failures"; -import { GenericGetGradeAndPercent } from "lib/score-import/framework/common/score-utils"; import { FindSDVXChartOnInGameIDVersion } from "utils/queries/charts"; import { FindSongOnID } from "utils/queries/songs"; import type { ConverterFunction } from "../../common/types"; @@ -17,7 +16,7 @@ export const ConverterKsHookSV6CStatic: ConverterFunction< > = async (data, context, importType, logger) => { const diff = SV6CConvertDifficulty(data.difficulty); - const chart = await FindSDVXChartOnInGameIDVersion(data.music_id, diff, "konaste"); + const chart = await FindSDVXChartOnInGameIDVersion(data.music_id, diff, "Konaste"); if (!chart) { throw new SongOrChartNotFoundFailure( @@ -35,8 +34,6 @@ export const ConverterKsHookSV6CStatic: ConverterFunction< throw new InternalFailure(`Song ${chart.songID} (sdvx) has no parent song?`); } - const { percent, grade } = GenericGetGradeAndPercent("sdvx", data.score, chart); - const dryScore: DryScore<"sdvx:Single"> = { game: "sdvx", service: "kshook SV6C Static", @@ -45,8 +42,6 @@ export const ConverterKsHookSV6CStatic: ConverterFunction< timeAchieved: data.timestamp * 1000, scoreData: { score: data.score, - percent, - grade, lamp: SV6CConvertLamp(data.clear), judgements: {}, optional: { diff --git a/server/src/lib/score-mutation/delete-scores.test.ts b/server/src/lib/score-mutation/delete-scores.test.ts index 7babcdd5b..d877b97a4 100644 --- a/server/src/lib/score-mutation/delete-scores.test.ts +++ b/server/src/lib/score-mutation/delete-scores.test.ts @@ -18,7 +18,7 @@ const mockImportDocument: ImportDocument = { createdSessions: [], errors: [], goalInfo: [], - idStrings: [], + gptStrings: [], importID: "mockImportID", importType: "file/batch-manual", questInfo: [], diff --git a/server/src/lib/score-mutation/update-score.test.ts b/server/src/lib/score-mutation/update-score.test.ts index e4d299c7f..300b3b055 100644 --- a/server/src/lib/score-mutation/update-score.test.ts +++ b/server/src/lib/score-mutation/update-score.test.ts @@ -14,7 +14,7 @@ const mockImportDocument: ImportDocument = { createdSessions: [], errors: [], goalInfo: [], - idStrings: [], + gptStrings: [], importID: "mockImportID", importType: "file/batch-manual", questInfo: [], diff --git a/server/src/lib/score-mutation/update-score.ts b/server/src/lib/score-mutation/update-score.ts index 83b3c0410..11e831f68 100644 --- a/server/src/lib/score-mutation/update-score.ts +++ b/server/src/lib/score-mutation/update-score.ts @@ -35,7 +35,7 @@ export default async function UpdateScore( const chartID = newScore.chartID; - const chart = await db.charts[oldScore.game].findOne({ + const chart = await db.anyCharts[oldScore.game].findOne({ chartID, }); diff --git a/server/src/lib/targets/goals.ts b/server/src/lib/targets/goals.ts index d35b6db69..c7f20426a 100644 --- a/server/src/lib/targets/goals.ts +++ b/server/src/lib/targets/goals.ts @@ -248,7 +248,7 @@ export function HumaniseGoalProgress( playtype, userPB.scoreData.score, userPB.scoreData.percent, - userPB.scoreData.grade, + userPB.scoreData.grade.string, fmtFn ); diff --git a/server/src/server/router/api/v1/scores/_scoreID/router.ts b/server/src/server/router/api/v1/scores/_scoreID/router.ts index ecd619eb3..2a7f67264 100644 --- a/server/src/server/router/api/v1/scores/_scoreID/router.ts +++ b/server/src/server/router/api/v1/scores/_scoreID/router.ts @@ -28,8 +28,8 @@ router.get("/", async (req, res) => { if (req.query.getRelated !== undefined) { const [user, chart, song] = await Promise.all([ GetUserWithID(score.userID), - db.charts[score.game].findOne({ chartID: score.chartID }), - db.songs[score.game].findOne({ id: score.songID }), + db.anyCharts[score.game].findOne({ chartID: score.chartID }), + db.anySongs[score.game].findOne({ id: score.songID }), ]); if (!user || !chart || !song) { diff --git a/server/src/server/router/api/v1/sessions/_sessionID/router.ts b/server/src/server/router/api/v1/sessions/_sessionID/router.ts index b6e410678..3163fac02 100644 --- a/server/src/server/router/api/v1/sessions/_sessionID/router.ts +++ b/server/src/server/router/api/v1/sessions/_sessionID/router.ts @@ -11,14 +11,7 @@ import { AddToSetInRecord } from "utils/misc"; import { optNull } from "utils/prudence"; import { GetTachiData } from "utils/req-tachi-data"; import { GetUserWithID } from "utils/user"; -import type { - FolderDocument, - Grades, - GPTString, - Lamps, - ScoreDocument, - integer, -} from "tachi-common"; +import type { FolderDocument, GPTString, ScoreDocument, integer } from "tachi-common"; const router: Router = Router({ mergeParams: true }); @@ -37,10 +30,10 @@ router.get("/", async (req, res) => { }); const [songs, charts, user, scoreInfo] = await Promise.all([ - db.songs[session.game].find({ + db.anySongs[session.game].find({ id: { $in: scores.map((e) => e.songID) }, }), - db.charts[session.game].find({ + db.anyCharts[session.game].find({ chartID: { $in: scores.map((e) => e.chartID) }, }), GetUserWithID(session.userID), @@ -166,14 +159,14 @@ router.get("/folder-raises", async (req, res) => { // new scores may also be grade raises for (const score of [...gradeRaises, ...newRaises]) { // skip things that aren't good enough - if (score.scoreData.gradeIndex < clearGradeIndex) { + if (score.scoreData.grade.string < clearGradeIndex) { continue; } const exists = gradeRaiseMap.get(score.chartID); if (exists) { - if (exists.scoreData.gradeIndex < score.scoreData.gradeIndex) { + if (exists.scoreData.grade.string < score.scoreData.grade.string) { // this one is more important gradeRaiseMap.set(score.chartID, score); } @@ -187,14 +180,14 @@ router.get("/folder-raises", async (req, res) => { for (const score of [...lampRaises, ...newRaises]) { // skip things that aren't good enough - if (score.scoreData.lampIndex < clearLampIndex) { + if (score.scoreData.lamp.index < clearLampIndex) { continue; } const exists = lampRaiseMap.get(score.chartID); if (exists) { - if (exists.scoreData.lampIndex < score.scoreData.lampIndex) { + if (exists.scoreData.lamp.index < score.scoreData.lamp.index) { // this one is more important lampRaiseMap.set(score.chartID, score); } @@ -264,7 +257,7 @@ router.get("/folder-raises", async (req, res) => { // and EX HARD CLEAR, so // we want ["HARD CLEAR", "EX HARD CLEAR"]. const originalGradeIndex = - gradeRaise.scoreData.gradeIndex - + gradeRaise.scoreData.grade.string - (gradeDeltas[gradeRaise.scoreID] ?? Infinity) + 1; @@ -274,7 +267,7 @@ router.get("/folder-raises", async (req, res) => { for (const grade of gptConfig.grades.slice( minimumGrade, - gradeRaise.scoreData.gradeIndex + 1 + gradeRaise.scoreData.grade.string + 1 )) { AddToSetInRecord(grade, raiseGradeDist, gradeRaise.chartID); } @@ -283,7 +276,7 @@ router.get("/folder-raises", async (req, res) => { if (lampRaise) { // see previous gradeRaise handler for explanation const originalLampIndex = - lampRaise.scoreData.lampIndex - + lampRaise.scoreData.lamp.index - (lampDeltas[lampRaise.scoreID] ?? Infinity) + 1; @@ -291,7 +284,7 @@ router.get("/folder-raises", async (req, res) => { for (const lamp of gptConfig.lamps.slice( minimumLamp, - lampRaise.scoreData.lampIndex + 1 + lampRaise.scoreData.lamp.index + 1 )) { AddToSetInRecord(lamp, raiseLampDist, lampRaise.chartID); } @@ -320,8 +313,6 @@ router.get("/folder-raises", async (req, res) => { raiseInfo.push({ folder, - // @ts-expect-error this is definitely a valid retrieval. be quiet. - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment previousCount: lampDist[lamp] ?? 0, raisedCharts: Array.from(raisedCharts), diff --git a/server/src/server/router/api/v1/users/_userID/games/@gameSpecificRoutes/iidx/router.ts b/server/src/server/router/api/v1/users/_userID/games/@gameSpecificRoutes/iidx/router.ts index b7e589939..b9a007b28 100644 --- a/server/src/server/router/api/v1/users/_userID/games/@gameSpecificRoutes/iidx/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/@gameSpecificRoutes/iidx/router.ts @@ -8,13 +8,12 @@ import { GetUser } from "utils/req-tachi-data"; import type { TachiIIDXPlaylist } from "lib/game-specific/iidx-playlists"; import type { ChartDocument, - Grades, - Lamps, PBScoreDocument, Playtypes, SongDocument, integer, } from "tachi-common"; +import type { GetEnumValue } from "tachi-common/types/metrics"; const router: Router = Router({ mergeParams: true }); @@ -90,7 +89,7 @@ router.get( // get all relevant charts const charts = await db.charts.iidx.find({ songID: { $in: pbData.map((e) => e.song.id) }, - difficulty: { $in: ["BEGINNER", "NORMAL", "HYPER", "ANOTHER", "LEGGENDARIA"] }, + difficulty: { $in: ["NORMAL", "HYPER", "ANOTHER", "LEGGENDARIA"] }, }); // get a lookup table for songID + difficulty -> chart. @@ -144,8 +143,8 @@ router.get( pb.scoreData.judgements.pgreat?.toString() ?? "0", // pgreat pb.scoreData.judgements.great?.toString() ?? "0", // great pb.scoreData.optional.bp?.toString() ?? "0", // BP - ConvertEamLamp(pb.scoreData.lamp), // lamp - ConvertEamGrade(pb.scoreData.grade) // grade + ConvertEamLamp(pb.scoreData.lamp.string), // lamp + ConvertEamGrade(pb.scoreData.grade.string) // grade ); if (pb.timeAchieved !== null && lastPlayed < pb.timeAchieved) { diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts index e7832b695..64563f6a1 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts @@ -30,7 +30,13 @@ import { GetUsersRankingAndOutOf, GetUsersWithIDs, } from "utils/user"; -import type { integer, PBScoreDocument, UserGameStatsSnapshotDocument } from "tachi-common"; +import type { + integer, + PBScoreDocument, + UserGameStatsSnapshotDocument, + GPTString, + ProfileRatingAlgorithms, +} from "tachi-common"; const logger = CreateLogCtx(__filename); @@ -260,7 +266,7 @@ router.get("/leaderboard-adjacent", async (req, res) => { const gptConfig = GetGamePTConfig(game, playtype); - let alg = gptConfig.defaultProfileRatingAlg; + let alg = gptConfig.defaultProfileRatingAlg as ProfileRatingAlgorithms[GPTString]; if (IsString(req.query.alg)) { const temp = CheckStrProfileAlg(game, playtype, req.query.alg); @@ -270,7 +276,7 @@ router.get("/leaderboard-adjacent", async (req, res) => { success: false, description: `Invalid value of ${ req.query.alg - } for alg. Expected one of ${gptConfig.profileRatingAlgs.join(", ")}`, + } for alg. Expected one of ${Object.keys(gptConfig.profileRatingAlgs).join(", ")}`, }); } diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts index 364bf6315..38cd96cb1 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts @@ -55,7 +55,9 @@ router.get("/best", async (req, res) => { success: false, description: `Invalid algorithm '${ req.query.alg - }' provided. Expected any of ${gptConfig.sessionRatingAlgs.join(", ")}.`, + }' provided. Expected any of ${Object.keys(gptConfig.sessionRatingAlgs).join( + ", " + )}.`, }); } diff --git a/server/src/server/router/api/v1/users/_userID/router.test.ts b/server/src/server/router/api/v1/users/_userID/router.test.ts index cd372ea59..c878b1361 100644 --- a/server/src/server/router/api/v1/users/_userID/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/router.test.ts @@ -402,7 +402,7 @@ t.test("GET /api/v1/users/:userID/recent-imports", (t) => { importType, importID: Random20Hex(), goalInfo: [], - idStrings: [], + gptStrings: [], questInfo: [], playtypes: [], scoreIDs: [], diff --git a/server/src/server/router/api/v1/users/_userID/router.ts b/server/src/server/router/api/v1/users/_userID/router.ts index 33259b46b..d462bf82f 100644 --- a/server/src/server/router/api/v1/users/_userID/router.ts +++ b/server/src/server/router/api/v1/users/_userID/router.ts @@ -29,8 +29,13 @@ import { } from "utils/queries/summary"; import { GetUser } from "utils/req-tachi-data"; import { FormatUserDoc, GetAllRankings, GetUserWithID } from "utils/user"; -import type { GPTString, ImportTypes, UserGameStats, integer } from "tachi-common"; -import type { ProfileRatingAlgs } from "utils/string-checks"; +import type { + AnyProfileRatingAlg, + GPTString, + ImportTypes, + UserGameStats, + integer, +} from "tachi-common"; const logger = CreateLogCtx(__filename); @@ -213,7 +218,7 @@ router.get("/game-stats", async (req, res) => { // a user has played a game if and only if they have stats for it. const stats: Array< UserGameStats & { - __rankingData?: Record; + __rankingData?: Record; } > = await db["game-stats"].find({ userID: user.id }); diff --git a/server/src/server/router/ir/usc/_playtype/router.test.ts b/server/src/server/router/ir/usc/_playtype/router.test.ts index 5a636b236..9c6b7b52b 100644 --- a/server/src/server/router/ir/usc/_playtype/router.test.ts +++ b/server/src/server/router/ir/usc/_playtype/router.test.ts @@ -811,7 +811,7 @@ t.test("POST /scores", (t) => { const orphanData = await db["orphan-chart-queue"].findOne({ "chartDoc.data.hashSHA1": "NEW_CHART", - idString: "usc:Controller", + gptString: "usc:Controller", }); t.strictSame(orphanData?.userIDs, [1, 2]); @@ -831,7 +831,7 @@ t.test("POST /scores", (t) => { const orphanData2 = await db["orphan-chart-queue"].findOne({ "chartDoc.data.hashSHA1": "NEW_CHART", - idString: "usc:Controller", + gptString: "usc:Controller", }); t.strictSame( @@ -855,7 +855,7 @@ t.test("POST /scores", (t) => { const orphanData3 = await db["orphan-chart-queue"].findOne({ "chartDoc.data.hashSHA1": "NEW_CHART", - idString: "usc:Controller", + gptString: "usc:Controller", }); t.equal(orphanData3, null, "Should have removed the orphan chart from the database."); diff --git a/server/src/test-utils/resets.ts b/server/src/test-utils/resets.ts index e28896abb..df32becd8 100644 --- a/server/src/test-utils/resets.ts +++ b/server/src/test-utils/resets.ts @@ -42,9 +42,9 @@ function GetAndCache( let collection: ICollection; if (filename.startsWith("songs-")) { - collection = db.songs[filename.split("-")[1] as Game]; + collection = db.anySongs[filename.split("-")[1] as Game]; } else if (filename.startsWith("charts-")) { - collection = db.charts[filename.split("-")[1] as Game]; + collection = db.anyCharts[filename.split("-")[1] as Game]; } else if (filename in db) { collection = db[filename as StaticDatabases]; } else { diff --git a/server/src/test-utils/test-data.ts b/server/src/test-utils/test-data.ts index 88f860182..8aa1717a2 100644 --- a/server/src/test-utils/test-data.ts +++ b/server/src/test-utils/test-data.ts @@ -866,7 +866,7 @@ export const FakeImport: ImportDocument = { errors: [], game: "iidx", goalInfo: [], - idStrings: ["iidx:SP"], + gptStrings: ["iidx:SP"], importID: "fake_import", importType: "ir/direct-manual", questInfo: [], diff --git a/server/src/utils/calculations/recalc-scores.ts b/server/src/utils/calculations/recalc-scores.ts index e277014a1..164dd667e 100644 --- a/server/src/utils/calculations/recalc-scores.ts +++ b/server/src/utils/calculations/recalc-scores.ts @@ -25,7 +25,7 @@ export async function RecalcAllScores(filter = {}) { await EfficientDBIterate( db.scores, async (c) => { - const chart = await db.charts[c.game].findOne({ chartID: c.chartID }); + const chart = await db.anyCharts[c.game].findOne({ chartID: c.chartID }); if (!chart) { logger.error(`Can't find chartID ${c.chartID} ${c.scoreID} (${c.game})`, { diff --git a/server/src/utils/folder.ts b/server/src/utils/folder.ts index fce34687a..4e6eed3b7 100644 --- a/server/src/utils/folder.ts +++ b/server/src/utils/folder.ts @@ -45,7 +45,7 @@ export async function ResolveFolderToCharts( switch (folder.type) { case "static": { - charts = await db.charts[folder.game].find( + charts = await db.anyCharts[folder.game].find( deepmerge(filter, { // Specifying playtype is mandatory, don't want to catch other charts. playtype: folder.playtype, @@ -56,9 +56,9 @@ export async function ResolveFolderToCharts( } case "songs": { - songs = await db.songs[folder.game].find(folder.data); + songs = await db.anySongs[folder.game].find(folder.data); - charts = await db.charts[folder.game].find( + charts = await db.anyCharts[folder.game].find( deepmerge(filter, { playtype: folder.playtype, songID: { $in: songs.map((e) => e.id) }, @@ -77,7 +77,7 @@ export async function ResolveFolderToCharts( const fx = deepmerge.all([filter, { playtype: folder.playtype }, folderDataTransposed]); - charts = await db.charts[folder.game].find(fx); + charts = await db.anyCharts[folder.game].find(fx); break; } @@ -98,7 +98,7 @@ export async function ResolveFolderToCharts( return { songs, charts }; } - songs = await db.songs[folder.game].find({ + songs = await db.anySongs[folder.game].find({ id: { $in: charts.map((e) => e.songID) }, }); @@ -150,12 +150,12 @@ export async function GetFolderCharts( ): Promise<{ songs?: Array; charts: Array }> { const chartIDs = await GetFolderChartIDs(folder.folderID); - const charts = await db.charts[folder.game].find( + const charts = await db.anyCharts[folder.game].find( deepmerge.all([{ playtype: folder.playtype }, { chartID: { $in: chartIDs } }, filter]) ); if (getSongs) { - const songs = await db.songs[folder.game].find({ + const songs = await db.anySongs[folder.game].find({ id: { $in: charts.map((e) => e.songID) }, }); @@ -324,10 +324,10 @@ export function CalculateGradeDistribution(pbs: Array) { const gradeDist: Partial> = {}; for (const pb of pbs) { - if (gradeDist[pb.scoreData.grade] !== undefined) { - gradeDist[pb.scoreData.grade]!++; + if (gradeDist[pb.scoreData.grade.string] !== undefined) { + gradeDist[pb.scoreData.grade.string]!++; } else { - gradeDist[pb.scoreData.grade] = 1; + gradeDist[pb.scoreData.grade.string] = 1; } } diff --git a/server/src/utils/queries/charts.ts b/server/src/utils/queries/charts.ts index 1ca8a0e08..5c4eee2c4 100644 --- a/server/src/utils/queries/charts.ts +++ b/server/src/utils/queries/charts.ts @@ -23,7 +23,7 @@ export function FindChartWithChartID(game: Game, chartID: string) { export function FindChartWithPTDF< G extends Game = Game, P extends Playtypes[G] = Playtypes[G], - I extends GPTString = GPTString + GPT extends GPTString = GPTString >(game: G, songID: integer, playtype: P, difficulty: Difficulties[I]) { return db.anyCharts[game].findOne({ songID, @@ -40,7 +40,7 @@ export function FindChartWithPTDF< export function FindChartWithPTDFVersion< G extends Game = Game, P extends Playtypes[G] = Playtypes[G], - I extends GPTString = GPTString + GPT extends GPTString = GPTString >(game: G, songID: integer, playtype: P, difficulty: Difficulties[I], version: Versions[I]) { return db.anyCharts[game].findOne({ songID, @@ -126,7 +126,7 @@ export function FindIIDXChartOnInGameIDVersion( /** * Find a chart on its in-game-ID, playtype, difficulty and version. */ -export function FindChartOnInGameIDVersion( +export function FindChartOnInGameIDVersion( game: Game, inGameID: number, playtype: Playtype, diff --git a/server/src/utils/string-checks.ts b/server/src/utils/string-checks.ts index 5e775825e..7b2fcf497 100644 --- a/server/src/utils/string-checks.ts +++ b/server/src/utils/string-checks.ts @@ -1,6 +1,12 @@ import { IsString } from "./misc"; import { GetGamePTConfig } from "tachi-common"; -import type { Game, GamePTConfig, Playtype } from "tachi-common"; +import type { + AnyProfileRatingAlg, + AnyScoreRatingAlg, + AnySessionRatingAlg, + Game, + Playtype, +} from "tachi-common"; const isIntegerRegex = /^-?\d+$/u; @@ -44,39 +50,35 @@ export function ParseStrPositiveNonZeroInt(val: unknown) { return v; } -export type ProfileRatingAlgs = GamePTConfig["defaultProfileRatingAlg"]; -export type ScoreRatingAlgs = GamePTConfig["defaultScoreRatingAlg"]; -export type SessionRatingAlgs = GamePTConfig["defaultSessionRatingAlg"]; - export function CheckStrProfileAlg(game: Game, playtype: Playtype, strVal: string) { const gptConfig = GetGamePTConfig(game, playtype); // @hack - if (!gptConfig.profileRatingAlgs.includes(strVal as ProfileRatingAlgs)) { + if (!Object.keys(gptConfig.profileRatingAlgs).includes(strVal as AnyProfileRatingAlg)) { return null; } - return strVal as ProfileRatingAlgs; + return strVal as AnyProfileRatingAlg; } export function CheckStrScoreAlg(game: Game, playtype: Playtype, strVal: string) { const gptConfig = GetGamePTConfig(game, playtype); // @hack - if (!gptConfig.scoreRatingAlgs.includes(strVal as ScoreRatingAlgs)) { + if (!Object.keys(gptConfig.scoreRatingAlgs).includes(strVal as AnyScoreRatingAlg)) { return null; } - return strVal as ScoreRatingAlgs; + return strVal as AnyScoreRatingAlg; } export function CheckStrSessionAlg(game: Game, playtype: Playtype, strVal: string) { const gptConfig = GetGamePTConfig(game, playtype); // @hack - if (!gptConfig.sessionRatingAlgs.includes(strVal as SessionRatingAlgs)) { + if (!Object.keys(gptConfig.sessionRatingAlgs).includes(strVal as AnySessionRatingAlg)) { return null; } - return strVal as SessionRatingAlgs; + return strVal as AnySessionRatingAlg; }