BREAKING: make batch-manual classes take strings instead of ints

This commit is contained in:
zkldi
2022-04-22 21:13:26 +01:00
parent ed149f6fa8
commit ea7d36e2ae
4 changed files with 89 additions and 10 deletions
+1 -1
View File
@@ -85,7 +85,7 @@
"rimraf": "3.0.2",
"safe-json-stringify": "1.2.0",
"seq-logging": "1.1.1",
"tachi-common": "0.9.3",
"tachi-common": "0.10.1",
"ts-node": "10.4.0",
"tsconfig-paths": "3.12.0",
"typescript": "4.5.5",
+4 -4
View File
@@ -65,7 +65,7 @@ specifiers:
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
supertest: 6.2.2
tachi-common: 0.9.3
tachi-common: 0.10.1
tap: 15.1.6
ts-node: 10.4.0
tsconfig-paths: 3.12.0
@@ -112,7 +112,7 @@ dependencies:
rimraf: 3.0.2
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
tachi-common: 0.9.3
tachi-common: 0.10.1
ts-node: 10.4.0_2615db9039ce432b4abf2fc39ef336ec
tsconfig-paths: 3.12.0
typescript: 4.5.5
@@ -5364,8 +5364,8 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/tachi-common/0.9.3:
resolution: {integrity: sha512-7wM+WAfdt0EJw5Bahu5puL0Am/5Nmop68maEyHwHZXTZDQoOqREYxv9+5+Co/wvdcApTZ2T3ctWl1UaPBQyhyQ==}
/tachi-common/0.10.1:
resolution: {integrity: sha512-FAKSQUokg6em9NIu+dYCk78XG1wBx8nF0yoiR5Cjpz21b8y20bkyEAsysSJRPYjKfSxMbFGZ3ghFNvq3BggTmQ==}
dependencies:
'@types/express-serve-static-core': 4.17.28
'@types/mongodb': 3.6.18
@@ -0,0 +1,70 @@
import ScoreImportFatalError from "lib/score-import/framework/score-importing/score-import-error";
import { ClassHandler } from "lib/score-import/framework/user-game-stats/types";
import { GamePTConfig, GetGamePTConfig, IDStrings } from "tachi-common";
import { GameClasses, GameClassSets } from "tachi-common/js/game-classes";
// Note: This is tested by batch-manuals parser.test.ts.
export function CreateBatchManualClassHandler(
classes: Record<GameClassSets[IDStrings], string>
): ClassHandler {
return (game, playtype, userID, ratings, logger) => {
const gptConfig = GetGamePTConfig(game, playtype);
const newObj: Partial<GameClasses<IDStrings>> = {};
for (const [s, classID] of Object.entries(classes)) {
const set = s as GameClassSets[IDStrings];
const index = ClassIDToIndex(gptConfig, set, classID);
if (index === null) {
logger.warn(
`User passed invalid class of ${classID} for set ${set}. Expected any of ${gptConfig.classHumanisedFormat[
set
]
.map((e) => e.id)
.join(", ")}`
);
throw new ScoreImportFatalError(
400,
`Invalid class of ${classID} for set ${set}. Expected any of ${gptConfig.classHumanisedFormat[
set
]
.map((e) => e.id)
.join(", ")}`
);
}
newObj[set] = index;
}
return newObj;
};
}
/**
* Given a gpt classes ID, return its index value.
*
* Returns null if the classID doesn't exist.
* @returns
*/
function ClassIDToIndex(
gptConfig: GamePTConfig,
classSet: GameClassSets[IDStrings],
classID: string
) {
const classes = gptConfig.classHumanisedFormat[classSet];
for (let i = 0; i < classes.length; i++) {
const classInfo = classes[i];
// Object.entries on an array returns [string, T], counterintuitively.
// Ah well. We'll just iterate over it like this.
if (classInfo.id === classID) {
return i;
}
}
return null;
}
@@ -1,5 +1,4 @@
import deepmerge from "deepmerge";
import { IIDXDans, SDVXDans, WACCA_STAGEUPS } from "lib/constants/classes";
import { KtLogger } from "lib/logger/logger";
import { TachiConfig } from "lib/setup/config";
import p, { PrudenceSchema, ValidSchemaValue } from "prudence";
@@ -15,6 +14,7 @@ import {
import { FormatPrError } from "utils/prudence";
import ScoreImportFatalError from "../../../framework/score-importing/score-import-error";
import { ParserFunctionReturns } from "../types";
import { CreateBatchManualClassHandler } from "./class-handler";
import { BatchManualContext } from "./types";
const optNull = (v: ValidSchemaValue) => p.optional(p.nullable(v));
@@ -201,20 +201,27 @@ const PR_BatchManualScore = (game: Game, playtype: Playtypes[Game]): PrudenceSch
};
};
// both iidx sp and dp share dans.
const IIDXStringDans = GetGamePTConfig("iidx", "SP").classHumanisedFormat.dan.map((e) => e.id);
const SDVXStringDans = GetGamePTConfig("sdvx", "Single").classHumanisedFormat.dan.map((e) => e.id);
const WaccaStringStageUps = GetGamePTConfig("wacca", "Single").classHumanisedFormat.stageUp.map(
(e) => e.id
);
const PR_BatchManualClasses = (game: Game): PrudenceSchema => {
switch (game) {
// This can be implemented for any non-static class (i.e. dans).
case "iidx":
return {
dan: optNull(p.isBoundedInteger(IIDXDans.KYU_7, IIDXDans.KAIDEN)),
dan: optNull(p.isIn(IIDXStringDans)),
};
case "sdvx":
return {
dan: optNull(p.isBoundedInteger(SDVXDans.DAN_1, SDVXDans.INF)),
dan: optNull(p.isIn(SDVXStringDans)),
};
case "wacca":
return {
stageUp: optNull(p.isBoundedInteger(WACCA_STAGEUPS.I, WACCA_STAGEUPS.XIV)),
stageUp: optNull(p.isIn(WaccaStringStageUps)),
};
default:
return {};
@@ -321,6 +328,8 @@ export function ParseBatchManualFromObject(
iterable: batchManual.scores,
// if classes are provided, use those as a class handler. Otherwise, we
// don't care.
classHandler: batchManual.classes ? () => batchManual.classes! : null,
classHandler: batchManual.classes
? CreateBatchManualClassHandler(batchManual.classes!)
: null,
};
}