From 0909fad7bcbe8edd47358f9c761ae8afe0b2ba52 Mon Sep 17 00:00:00 2001 From: zkldi Date: Thu, 13 May 2021 22:58:07 +0100 Subject: [PATCH] Add GSM and Versioning support. --- server/pnpm-lock.yaml | 6 +-- server/src/common/database-lookup/chart.ts | 32 +++++++++++++ .../import-types/ir/fervidex/converter.ts | 20 +++++++-- .../import-types/ir/fervidex/parser.ts | 45 +++++++++++++++++-- .../import-types/ir/fervidex/types.ts | 11 +++++ server/src/types.ts | 4 +- 6 files changed, 105 insertions(+), 13 deletions(-) diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index c557b4be5..857d5ab90 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -60,7 +60,7 @@ dependencies: express-async-errors: 3.1.1_express@4.17.1 express-session: 1.17.1 fast-json-stable-hash: 1.0.2 - kamaitachi-common: github.com/zkldi/Kamaitachi-common/1cee2138f309c9c2e4c8382056099bbc32f3105a + kamaitachi-common: github.com/zkldi/Kamaitachi-common/9ec6904b471f44aebf5c486b80856020d3eef448 mongodb: 3.6.6 monk: 7.3.4 multer: 1.4.2 @@ -4637,8 +4637,8 @@ packages: '@types/yoga-layout': 1.9.2 dev: true - github.com/zkldi/Kamaitachi-common/1cee2138f309c9c2e4c8382056099bbc32f3105a: - resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/1cee2138f309c9c2e4c8382056099bbc32f3105a} + github.com/zkldi/Kamaitachi-common/9ec6904b471f44aebf5c486b80856020d3eef448: + resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/9ec6904b471f44aebf5c486b80856020d3eef448} name: kamaitachi-common version: 0.1.0 dependencies: diff --git a/server/src/common/database-lookup/chart.ts b/server/src/common/database-lookup/chart.ts index 5e6a89449..957e8d3a4 100644 --- a/server/src/common/database-lookup/chart.ts +++ b/server/src/common/database-lookup/chart.ts @@ -1,3 +1,4 @@ +import { version } from "commander"; import { Difficulties, Game, integer, Playtypes, IDStrings } from "kamaitachi-common"; import db from "../../db/db"; @@ -63,12 +64,19 @@ export function FindDDRChartOnSongHash( }); } +/** + * Find a BMS chart on either its md5sum or its sha256sum. + * @param hash The md5 or sha256 hash to look for. + */ export function FindBMSChartOnHash(hash: string) { return db.charts.bms.findOne({ $or: [{ "data.hashMD5": hash }, { "data.hashSHA256": hash }], }); } +/** + * Find a chart on its in-game-ID, playtype and difficulty. + */ export function FindChartOnInGameID( game: Game, inGameID: number, @@ -84,6 +92,30 @@ export function FindChartOnInGameID( }); } +/** + * Find a chart on its in-game-ID, playtype, difficulty and version. + */ +export function FindChartOnInGameIDVersion( + game: Game, + inGameID: number, + playtype: Playtypes[Game], + difficulty: Difficulties[IDStrings], + version: string +) { + return db.charts[game].findOne({ + "data.inGameID": inGameID, + versions: version, + playtype, + difficulty, + }); +} + +/** + * Find an SDVX Chart on its in game ID. This exists to handle + * oddities with SDVX difficulties - If "ANY_INF" is sent, it actually + * refers to any of INF, GRV, HVN or VVD. This is because some services treat + * all of those as the same difficulty, but we do not. + */ export function FindSDVXChartOnInGameID( inGameID: number, playtype: Playtypes[Game], diff --git a/server/src/score-import/import-types/ir/fervidex/converter.ts b/server/src/score-import/import-types/ir/fervidex/converter.ts index bc91e2440..a453e7daf 100644 --- a/server/src/score-import/import-types/ir/fervidex/converter.ts +++ b/server/src/score-import/import-types/ir/fervidex/converter.ts @@ -9,9 +9,12 @@ import { InvalidScoreFailure, KTDataNotFoundFailure, } from "../../../framework/score-importing/converter-failures"; -import { FervidexScore } from "./types"; +import { FervidexContext, FervidexScore } from "./types"; import { Lamps, Grades, Difficulties, Playtypes } from "kamaitachi-common"; -import { FindChartOnInGameID } from "../../../../common/database-lookup/chart"; +import { + FindChartOnInGameID, + FindChartOnInGameIDVersion, +} from "../../../../common/database-lookup/chart"; const LAMP_LOOKUP = { 0: "NO PLAY", @@ -131,7 +134,7 @@ function SplitFervidexChartRef(ferDif: FervidexScore["chart"]) { return { playtype, difficulty }; } -export const ConverterIRFervidex: ConverterFunction = async ( +export const ConverterIRFervidex: ConverterFunction = async ( data, context, importType, @@ -139,7 +142,13 @@ export const ConverterIRFervidex: ConverterFunction ) => { let { difficulty, playtype } = SplitFervidexChartRef(data.chart); - let chart = await FindChartOnInGameID("iidx", data.entry_id, playtype, difficulty); + let chart = await FindChartOnInGameIDVersion( + "iidx", + data.entry_id, + playtype, + difficulty, + context.version + ); if (!chart) { throw new KTDataNotFoundFailure( @@ -197,6 +206,9 @@ export const ConverterIRFervidex: ConverterFunction maxCombo: data.max_combo, gaugeHistory, gauge, + bp: data.bad + data.poor, + comboBreak: null, + gsm: data["2dx-gsm"], }, }, scoreMeta: { diff --git a/server/src/score-import/import-types/ir/fervidex/parser.ts b/server/src/score-import/import-types/ir/fervidex/parser.ts index 0ff364d48..5ac013e93 100644 --- a/server/src/score-import/import-types/ir/fervidex/parser.ts +++ b/server/src/score-import/import-types/ir/fervidex/parser.ts @@ -2,7 +2,7 @@ import { EmptyObject, KtLogger, ParserFunctionReturnsSync } from "../../../../ty import p, { PrudenceSchema } from "prudence"; import ScoreImportFatalError from "../../../framework/score-importing/score-import-error"; import { FormatPrError, optNull } from "../../../../common/prudence"; -import { FervidexScore } from "./types"; +import { FervidexContext, FervidexScore } from "./types"; import { ConverterIRFervidex } from "./converter"; const PR_Fervidex: PrudenceSchema = { @@ -40,13 +40,50 @@ const PR_Fervidex: PrudenceSchema = { // we dont use it and we dont care. pacemaker: p.optional(p.any), + + "2dx-gsm": p.optional({ + // @ts-expect-error recursive types error + EASY: [p.isBoundedInteger(0, 255)], + NORMAL: [p.isBoundedInteger(0, 255)], + HARD: [p.isBoundedInteger(0, 255)], + EX_HARD: [p.isBoundedInteger(0, 255)], + }), }; +/** + * Converts a string of the form LDJ:X:X:X:2020092900 into a game version. + * I don't really understand the software model format, so this is lazy. + */ +function ParseSoftwareModel(model: string) { + if (model.startsWith("LDJ")) { + // heroic verse + if (model.endsWith("2020092900")) { + return "27"; + } + + // i *really* don't care enough to support rootage or cannonballers. + throw new ScoreImportFatalError(400, `Unsupported Software Model ${model}.`); + } else if (model.startsWith("P2D")) { + // accept anything since this will probably change underfoot a lot. + return "inf2020"; + } + + throw new ScoreImportFatalError(400, `Unsupported Software Model ${model}.`); +} + +interface FerHeaders { + model: string; +} + export function ParseFervidexSingle( body: Record, + headers: FerHeaders, logger: KtLogger -): ParserFunctionReturnsSync { - let err = p(body, PR_Fervidex); +): ParserFunctionReturnsSync { + let version = ParseSoftwareModel(headers.model); + + // more mods may be added in the future, so lets ignore excess keys. + let err = p(body, PR_Fervidex, undefined, { allowExcessKeys: true }); if (err) { throw new ScoreImportFatalError(400, FormatPrError(err, "Invalid Fervidex Request?")); @@ -54,7 +91,7 @@ export function ParseFervidexSingle( // asserted using prudence. return { - context: {}, + context: { version }, game: "iidx", iterable: ([body] as unknown) as FervidexScore[], ConverterFunction: ConverterIRFervidex, diff --git a/server/src/score-import/import-types/ir/fervidex/types.ts b/server/src/score-import/import-types/ir/fervidex/types.ts index 6c65face3..607320ff3 100644 --- a/server/src/score-import/import-types/ir/fervidex/types.ts +++ b/server/src/score-import/import-types/ir/fervidex/types.ts @@ -43,4 +43,15 @@ export interface FervidexScore { score?: integer | null; type?: string | null; // too lazy to type this and we dont use it. }; + + "2dx-gsm"?: { + EASY: (number | null)[]; + NORMAL: (number | null)[]; + HARD: (number | null)[]; + EX_HARD: (number | null)[]; + } | null; +} + +export interface FervidexContext { + version: string; } diff --git a/server/src/types.ts b/server/src/types.ts index a749f6145..cdecfa4ff 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -20,7 +20,7 @@ import { IIDXEamusementCSVData, } from "./score-import/import-types/file/eamusement-iidx-csv/types"; import { BarbatosScore } from "./score-import/import-types/ir/barbatos/types"; -import { FervidexScore } from "./score-import/import-types/ir/fervidex/types"; +import { FervidexContext, FervidexScore } from "./score-import/import-types/ir/fervidex/types"; declare module "express-session" { // Inject additional properties on express-session @@ -137,7 +137,7 @@ export interface ImportTypeContextMap { "file/batch-manual": BatchManualContext; "ir/direct-manual": BatchManualContext; "ir/barbatos": EmptyObject; - "ir/fervidex": EmptyObject; + "ir/fervidex": FervidexContext; "ir/fervidex-static": EmptyObject; }