diff --git a/server/package.json b/server/package.json index 9e3fcfc22..8466ace07 100644 --- a/server/package.json +++ b/server/package.json @@ -82,7 +82,7 @@ "rimraf": "3.0.2", "safe-json-stringify": "1.2.0", "seq-logging": "^1.1.1", - "tachi-common": "0.3.7", + "tachi-common": "0.3.9", "ts-node": "10.0.0", "typescript": "4.3.4", "winston": "3.3.3", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index 87167de85..616e91f33 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -62,7 +62,7 @@ specifiers: safe-json-stringify: 1.2.0 seq-logging: ^1.1.1 supertest: 6.1.3 - tachi-common: 0.3.7 + tachi-common: 0.3.9 tap: 15.0.9 ts-node: 10.0.0 tsconfig-paths: 3.10.1 @@ -105,7 +105,7 @@ dependencies: rimraf: 3.0.2 safe-json-stringify: 1.2.0 seq-logging: 1.1.1 - tachi-common: 0.3.7 + tachi-common: 0.3.9 ts-node: 10.0.0_83f53b0a0c5616d3fa00ed4e30b9ce1b typescript: 4.3.4 winston: 3.3.3 @@ -4906,8 +4906,8 @@ packages: strip-ansi: 6.0.0 dev: true - /tachi-common/0.3.7: - resolution: {integrity: sha512-l95qLUDKLeBK8eSf+ZHEruP1XgmWD/t6tq1kcKpFaS2JuaDfUrjbnQ37QMsriP4Ftoeryx+FulJNI0oZnsUKTA==} + /tachi-common/0.3.9: + resolution: {integrity: sha512-h+DEsSYjNZ6aeMcTSJeKQetfPxqDF4zuNULx1gyb7qK3NnUQXVPEd7yOld/6IDh8Lkf+CYk6zzA5PTXWNzSvjQ==} dependencies: monk: 7.3.4 transitivePeerDependencies: diff --git a/server/scripts/__KT_DATABASE_MIGRATION/scores/chunithm.ts b/server/scripts/__KT_DATABASE_MIGRATION/scores/chunithm.ts new file mode 100644 index 000000000..9f50bc958 --- /dev/null +++ b/server/scripts/__KT_DATABASE_MIGRATION/scores/chunithm.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import db from "external/mongo/db"; +import CreateLogCtx from "lib/logger/logger"; +import { CreateScoreID } from "lib/score-import/framework/score-importing/score-id"; +import { GetGameConfig, GetGamePTConfig, ScoreDocument } from "tachi-common"; +import MigrateRecords from "../migrate"; +import { oldKTDB } from "../old-db"; + +const logger = CreateLogCtx(__filename); + +async function ConvertFn(c: any): Promise { + const game = c.game; + const playtype = c.scoreData.playtype; + + const gameConfig = GetGameConfig(game); + + if (!gameConfig.validPlaytypes.includes(playtype)) { + logger.warn(`Ignored game pt ${game}, ${playtype}`); + throw new Error(`Ignored game pt ${game}, ${playtype}`); + } + + const gptConfig = GetGamePTConfig(game, playtype); + + if (!gptConfig) { + logger.error(`No gptconfig for ${game} ${playtype}?`); + throw new Error(`No gptconfig for ${game} ${playtype}?`); + } + + // @ts-expect-error implicit any is expected + const chartDoc = await db.charts[game].findOne({ + songID: c.songID, + difficulty: c.scoreData.difficulty, + playtype, + }); + + if (!chartDoc) { + logger.warn(`Cannot find ChartDoc for ${c.songID} ${c.scoreData.difficulty} ${playtype} `); + return null; + } + + const base: Omit, "scoreID"> = { + userID: c.userID, + songID: chartDoc.songID, + playtype, + chartID: chartDoc.chartID, + game: c.game, + timeAdded: c.timeAdded, + timeAchieved: Number.isNaN(c.timeAchieved) ? null : c.timeAchieved, + comment: c.comment ?? null, + highlight: c.highlight ?? false, + service: c.service, + importType: null, + // we'll just recalc calculated data instead of trying to update + calculatedData: {}, + isPrimary: chartDoc.isPrimary, + scoreData: { + esd: c.scoreData.esd ?? null, + grade: c.scoreData.grade, + gradeIndex: gptConfig.grades.indexOf(c.scoreData.grade), + lamp: c.scoreData.lamp, + lampIndex: gptConfig.lamps.indexOf(c.scoreData.lamp), + percent: c.scoreData.percent, + score: c.scoreData.score, + judgements: c.scoreData.hitData, + hitMeta: c.scoreData.hitMeta, + }, + scoreMeta: {}, + }; + + const scoreID = CreateScoreID(base.userID, base, base.chartID); + + const exists = await db.scores.findOne({ scoreID }); + + if (exists) { + logger.warn(`Skipping duplicate score ${base.chartID} ${base.userID}.`); + return null; + } + + const score: ScoreDocument = { + ...base, + scoreID, + }; + + await oldKTDB.get("score-id-lookup").insert({ + old: c.scoreID, + new: scoreID, + }); + + return score; +} + +export async function MigrateCHUNITHMScores() { + await MigrateRecords(db.scores, "scores", ConvertFn, { game: "chunithm" }, true); +} diff --git a/server/scripts/__KT_DATABASE_MIGRATION/scores/migrate-all.ts b/server/scripts/__KT_DATABASE_MIGRATION/scores/migrate-all.ts index 9de93cccf..a07e44638 100644 --- a/server/scripts/__KT_DATABASE_MIGRATION/scores/migrate-all.ts +++ b/server/scripts/__KT_DATABASE_MIGRATION/scores/migrate-all.ts @@ -1,5 +1,6 @@ import CreateLogCtx from "lib/logger/logger"; import { MigrateBMSScores } from "./bms"; +import { MigrateCHUNITHMScores } from "./chunithm"; import { MigrateIIDXScores } from "./iidx"; import { MigrateMusecaScores } from "./museca"; import { MigrateSDVXScores } from "./sdvx"; @@ -12,7 +13,6 @@ const logger = CreateLogCtx(__filename); await MigrateIIDXScores(); logger.info(`Migrating BMS Scores.`); - await MigrateBMSScores(); logger.info(`Migrating MUSECA Scores.`); @@ -22,4 +22,12 @@ const logger = CreateLogCtx(__filename); logger.info(`Migrating SDVX Scores.`); await MigrateSDVXScores(); + + logger.info(`Migrating CHUNITHM Scores.`); + + await MigrateCHUNITHMScores(); + + logger.info("Done."); + + process.exit(0); })(); diff --git a/server/scripts/__KT_DATABASE_MIGRATION/sessions.ts b/server/scripts/__KT_DATABASE_MIGRATION/sessions.ts index 04700d6f8..dce3d322c 100644 --- a/server/scripts/__KT_DATABASE_MIGRATION/sessions.ts +++ b/server/scripts/__KT_DATABASE_MIGRATION/sessions.ts @@ -31,7 +31,7 @@ async function ConvertScoreToScoreInfo( }); if (!scoreIDs) { - logger.warn(`No score for ${score.scoreID}? Skipping.`); + logger.verbose(`No score for ${score.scoreID}? Skipping.`); return null; } diff --git a/server/scripts/__KT_DATABASE_MIGRATION/state-sync/sync-state.ts b/server/scripts/__KT_DATABASE_MIGRATION/state-sync/sync-state.ts index d79b13889..1819df468 100644 --- a/server/scripts/__KT_DATABASE_MIGRATION/state-sync/sync-state.ts +++ b/server/scripts/__KT_DATABASE_MIGRATION/state-sync/sync-state.ts @@ -1,8 +1,7 @@ import CreateLogCtx from "lib/logger/logger"; +import { RecalcAllScores, UpdateAllPBs } from "utils/calculations/recalc-scores"; import { CreateGameProfiles } from "./create-game-profiles"; -import { RecalcAllScores } from "./recalc-all-scores"; import { RecalcSessions } from "./recalc-sessions"; -import { UpdateAllPBs } from "./update-all-pbs"; const logger = CreateLogCtx(__filename);