26 lines
1.6 KiB
JavaScript
26 lines
1.6 KiB
JavaScript
import { readFileSync } from 'node:fs';
|
|
import { createHash } from 'node:crypto';
|
|
import { readGameDbTable } from './game-db-source.mjs';
|
|
import { susScoreWeight } from './sus-score-weight.mjs';
|
|
import { scoreRatioFromFormula } from '../src/lib/engine/score.ts';
|
|
|
|
const music = new Map(readGameDbTable('kor', 'Music.json').map(({ data }) => [data.id, data]));
|
|
const levels = new Map(readGameDbTable('kor', 'MusicDifficulty.json').map(({ data }) =>
|
|
[data.musicId + '.' + data.difficultyType.split('_').at(-1).toLowerCase(), data.difficultyLevel]));
|
|
|
|
export function formulaScoreMetadata(songId, difficulty, difficultyLevel, totalNotes, coefficient, expectedHash) {
|
|
const master = music.get(songId), key = songId + '.' + difficulty;
|
|
if (!master || levels.get(key) !== difficultyLevel) throw new Error(key + ': DB metadata mismatch');
|
|
const bytes = readFileSync(new URL('../data/raw/sus/chart_' + songId + '_' + difficulty + '.sus', import.meta.url));
|
|
const hash = createHash('sha256').update(bytes).digest('hex');
|
|
if (expectedHash && hash !== expectedHash) throw new Error(key + ': SUS hash mismatch');
|
|
const weight = susScoreWeight(bytes.toString('utf8'));
|
|
if (weight.songId !== songId || weight.fullComboNoteCount !== totalNotes ||
|
|
(coefficient !== undefined && coefficient !== master.liveScoreCoefficientPermil)) {
|
|
throw new Error(key + ': SUS / DB score inputs mismatch');
|
|
}
|
|
const scoreFormula = { perfectNoteWeight: weight.perfectNoteWeight,
|
|
liveScoreCoefficientPermil: master.liveScoreCoefficientPermil, difficultyLevel };
|
|
return { scoreRatio: scoreRatioFromFormula(scoreFormula), scoreCalibrationSource: 'formula-v1', scoreFormula };
|
|
}
|