diff --git a/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.test.ts b/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.test.ts index e49964f9f..0691d39ba 100644 --- a/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.test.ts +++ b/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.test.ts @@ -11,6 +11,7 @@ t.test("#ParseEamusementCSV", (t) => { t.test("Valid Rootage-Type CSV", (t) => { const { iterableData, hasBeginnerAndLegg, version } = IIDXCSVParse( TestingIIDXEamusementCSV26, + "SP", logger ); @@ -24,6 +25,7 @@ t.test("#ParseEamusementCSV", (t) => { t.test("Valid HV CSV", (t) => { const { iterableData, hasBeginnerAndLegg, version } = IIDXCSVParse( TestingIIDXEamusementCSV27, + "SP", logger ); @@ -44,7 +46,7 @@ t.test("#ParseEamusementCSV", (t) => { const buffer = Buffer.from(`${"a,".repeat(26)}a\n${"a,".repeat(3)}a`); t.throws( - () => IIDXCSVParse(buffer, logger), + () => IIDXCSVParse(buffer, "SP", logger), new ScoreImportFatalError(400, "Row 1 has an invalid amount of cells (4, expected 27)") ); @@ -59,7 +61,7 @@ t.test("#ParseEamusementCSV", (t) => { const InvalidVersions = Buffer.from(`${headerStr}\n${row}`); t.throws( - () => IIDXCSVParse(InvalidVersions, logger), + () => IIDXCSVParse(InvalidVersions, "SP", logger), new ScoreImportFatalError( 400, "Invalid/Unsupported Eamusement Version Name GARBAGE VERSION." @@ -71,12 +73,17 @@ t.test("#ParseEamusementCSV", (t) => { let { version } = IIDXCSVParse( Buffer.from([headerStr, row27th, row17th].join("\n")), + "SP", logger ); t.equal(version, "27", "Should pick the largest version from the list of scores."); - ({ version } = IIDXCSVParse(Buffer.from([headerStr, row17th, row27th].join("\n")), logger)); + ({ version } = IIDXCSVParse( + Buffer.from([headerStr, row17th, row27th].join("\n")), + "SP", + logger + )); // this is technically allowing invalid eam-csv, but, who cares? t.equal( diff --git a/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.ts b/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.ts index 07a08c1b1..4a3f5b5eb 100644 --- a/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.ts +++ b/server/src/lib/score-import/import-types/common/eamusement-iidx-csv/parser.ts @@ -1,9 +1,11 @@ import ScoreImportFatalError from "../../../framework/score-importing/score-import-error"; +import { GetGamePTConfig, Playtype } from "tachi-common"; +import { StringIsGameVersion } from "utils/misc"; import { CSVParseError, NaiveCSVParse } from "utils/naive-csv-parser"; import type { ParserFunctionReturns } from "../types"; import type { EamusementScoreData, IIDXEamusementCSVContext, IIDXEamusementCSVData } from "./types"; import type { KtLogger } from "lib/logger/logger"; -import type { integer } from "tachi-common"; +import type { integer, GPTSupportedVersions, Playtypes } from "tachi-common"; const EAM_VERSION_NAMES: Record = { "1st&substream": 1, @@ -94,7 +96,7 @@ export function ResolveHeaders(headers: Array, logger: KtLogger) { ); } -export function IIDXCSVParse(csvBuffer: Buffer, logger: KtLogger) { +export function IIDXCSVParse(csvBuffer: Buffer, playtype: Playtypes["iidx"], logger: KtLogger) { let rawHeaders: Array; let rawRows: Array>; @@ -123,7 +125,6 @@ export function IIDXCSVParse(csvBuffer: Buffer, logger: KtLogger) { const title = cells[1]!.trim(); const timestamp = cells[rawHeaders.length - 1]!.trim(); - // wtf typescript?? what's the point of enums? const versionNum = EAM_VERSION_NAMES[version!]; if (versionNum === undefined) { @@ -167,13 +168,16 @@ export function IIDXCSVParse(csvBuffer: Buffer, logger: KtLogger) { ); } - if (!["26", "27", "28", "29"].includes(gameVersion.toString())) { - throw new ScoreImportFatalError(400, `Only versions 26, 27, 28 and 29 are supported.`); + if (!StringIsGameVersion("iidx", playtype, gameVersion.toString())) { + throw new ScoreImportFatalError( + 400, + `Unsupported version '${gameVersion}'. Is your CSV properly filled out?` + ); } return { iterableData, - version: gameVersion.toString() as "26" | "27" | "28" | "29", + version: gameVersion.toString() as GPTSupportedVersions["iidx:DP" | "iidx:SP"], hasBeginnerAndLegg, }; } @@ -219,7 +223,11 @@ function GenericParseEamIIDXCSV( ); } - const { hasBeginnerAndLegg, version, iterableData } = IIDXCSVParse(fileData.buffer, logger); + const { hasBeginnerAndLegg, version, iterableData } = IIDXCSVParse( + fileData.buffer, + playtype, + logger + ); logger.verbose("Successfully parsed CSV."); diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index 6eed54268..53ff2b0a7 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -1,12 +1,19 @@ import { ONE_MEGABYTE } from "lib/constants/filesize"; import { ONE_HOUR } from "lib/constants/time"; import { TachiConfig } from "lib/setup/config"; -import { GetGameConfig } from "tachi-common"; +import { GetGameConfig, GetGamePTConfig } from "tachi-common"; import { exec } from "child_process"; import crypto from "crypto"; import { URL } from "url"; import type { KtLogger } from "lib/logger/logger"; -import type { Game, GamePTConfig, integer, Playtype } from "tachi-common"; +import type { + Game, + GamePTConfig, + integer, + Playtype, + GPTSupportedVersions, + IDStrings, +} from "tachi-common"; // https://github.com/sindresorhus/escape-string-regexp/blob/main/index.js // the developer of this has migrated everything to Force ES6 style modules, @@ -298,3 +305,14 @@ export function WrapScriptPromise(promise: Promise, logger: KtLogger) { export function ClassToObject(cls: unknown) { return JSON.parse(JSON.stringify(cls)) as unknown; } + +export function StringIsGameVersion( + game: Game, + playtype: Playtype, + version: string +): version is GPTSupportedVersions[IDStrings] { + const gptConfig = GetGamePTConfig(game, playtype); + + // @ts-expect-error yes, we know! + return gptConfig.supportedVersions.includes(version); +}