mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-07 06:18:03 +03:00
Add GSM and Versioning support.
This commit is contained in:
Generated
+3
-3
@@ -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:
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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<FervidexScore, EmptyObject> = async (
|
||||
export const ConverterIRFervidex: ConverterFunction<FervidexScore, FervidexContext> = async (
|
||||
data,
|
||||
context,
|
||||
importType,
|
||||
@@ -139,7 +142,13 @@ export const ConverterIRFervidex: ConverterFunction<FervidexScore, EmptyObject>
|
||||
) => {
|
||||
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<FervidexScore, EmptyObject>
|
||||
maxCombo: data.max_combo,
|
||||
gaugeHistory,
|
||||
gauge,
|
||||
bp: data.bad + data.poor,
|
||||
comboBreak: null,
|
||||
gsm: data["2dx-gsm"],
|
||||
},
|
||||
},
|
||||
scoreMeta: {
|
||||
|
||||
@@ -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<string, unknown>,
|
||||
headers: FerHeaders,
|
||||
logger: KtLogger
|
||||
): ParserFunctionReturnsSync<FervidexScore, EmptyObject> {
|
||||
let err = p(body, PR_Fervidex);
|
||||
): ParserFunctionReturnsSync<FervidexScore, FervidexContext> {
|
||||
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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user