fix: repair SUS timing and note classification for 18 charts
Publish GitHub Pages output / publish (push) Successful in 47s
Publish GitHub Pages output / publish (push) Successful in 47s
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { readFile, writeFile } from 'node:fs/promises';
|
||||
import vm from 'node:vm';
|
||||
|
||||
const report = JSON.parse(await readFile('data/wf-audit/latest.json','utf8'));
|
||||
const audit = await readFile('scripts/audit-wf-charts.mjs','utf8');
|
||||
const context = vm.createContext({});
|
||||
vm.runInContext(audit.slice(audit.indexOf('const counts ='),audit.indexOf('async function worker()')),context);
|
||||
const simulator = await readFile('data/wf-audit/simulator.js','utf8');
|
||||
const catalogText=simulator.match(/\b\w+=JSON\.parse\(`(\[\{"key":"m[\s\S]*?)`\)/)?.[1];
|
||||
if(!catalogText)throw new Error('wf chart catalog not found');
|
||||
const catalog = JSON.parse(catalogText.replaceAll('\\\\','\\').replaceAll('\\`','`').replaceAll('\\${','${'));
|
||||
const collection=JSON.parse(await readFile('data/raw/sus/collection-manifest.json','utf8'));
|
||||
for(const row of report.rows) {
|
||||
const data=JSON.parse(await readFile(`data/wf-audit/charts/${row.songId}.${row.difficulty}.json`,'utf8'));
|
||||
const local=JSON.parse(await readFile(`static/data/charts/${row.songId}.${row.difficulty}.json`,'utf8'));
|
||||
const events=data.note_events;
|
||||
// Match pn() in the saved wf simulator: preserve its explicit note_type/is_flick.
|
||||
const native=[...(events.blue??[]).map(n=>({...n,type:'regular',isFlick:n.is_flick??false})),
|
||||
...(events.pink??[]).map(n=>({...n,type:'regular',isFlick:n.is_flick??true})),
|
||||
...(events.green_blocks??[]).flatMap(block=>block.map((n,i)=>({...n,type:n.note_type??(i===0||i===block.length-1?'regular':'mid'),isFlick:n.is_flick??false})))
|
||||
].map(n=>({timeSeconds:n.time_seconds,type:n.type,isFlick:n.isFlick}));
|
||||
context.left=local.notes;context.right=native;
|
||||
row.localVsWfNative=vm.runInContext('compare(left,right)',context);
|
||||
row.wfNativeCounts=vm.runInContext('counts(right)',context);
|
||||
row.wfNativeCategoryMatchesSus=Object.keys(row.susExpected).every(k=>row.susExpected[k]===row.wfNativeCounts[k]);
|
||||
row.wfSourceMatchesSus=row.wfSource.sha256===collection.files.find(f=>f.name===`chart_${row.songId}_${row.difficulty}.sus`).sha256;
|
||||
const metadata=catalog.find(c=>c.key===`${row.songId}::${row.difficulty.toUpperCase()}`);
|
||||
row.ratio={local:local.scoreRatio,wfCatalog:metadata?.scoreRatio,wfCatalogSource:metadata?.scoreCalibrationSource};
|
||||
}
|
||||
report.summary.wfNativeCategoryMismatchSus=report.rows.filter(r=>!r.wfNativeCategoryMatchesSus).length;
|
||||
report.summary.localVsWfNativeMatches=report.rows.filter(r=>!r.localVsWfNative.extra&&!r.localVsWfNative.missing).length;
|
||||
report.summary.wfSourceHashMismatchSus=report.rows.filter(r=>!r.wfSourceMatchesSus).length;
|
||||
await writeFile('data/wf-audit/latest.json',JSON.stringify(report,null,2));
|
||||
const lines=['# wf-calc 전체 채보 비교','',`비교 시각: ${report.generatedAt}`,`스냅샷: ${report.simulatorUrl}`,'',
|
||||
'## 해석','',
|
||||
'- wf 원본: 사이트의 pn() 함수처럼 note_type/is_flick을 그대로 읽은 데이터입니다. 사이트의 최종 점수 엔진 전체를 재현했다는 뜻은 아닙니다.',
|
||||
'- 우리 어댑터: 기존 수집기의 flattenEvents를 거친 결과입니다. 이 단계의 분류 차이를 wf 자체 오류라고 부르면 안 됩니다.',
|
||||
'- 시간 비교 허용치는 1마이크로초이며 동시 노트는 개수까지 비교합니다.',
|
||||
'- wf 카탈로그 scoreRatio는 estimated 등 출처가 표시된 카탈로그 값입니다. 사이트에서 최종 계산 시 사용하는 값과 같은지는 별도 검증이 필요합니다.',
|
||||
'- 원본 SUS 헤더는 노트 종류별 개수와 분모 검증에 사용했습니다. 기존 SUS 타이밍 재구성 후보의 미해결 사항은 그대로 남아 있습니다.','',
|
||||
'## 집계','','```json',JSON.stringify(report.summary,null,2),'```','',
|
||||
'## Mekurumeku Rendezvous Expert','','```json',JSON.stringify(report.rows.find(r=>r.songId==='m0527'&&r.difficulty==='expert'),null,2),'```','',
|
||||
'## 전곡 결과','','|곡|난이도|우리 어댑터 적용 후 차이 초과/누락|wf 원본 분류 차이 초과/누락|스페셜 차이|wf 원본 해시 변경|', '|---|---|---|---|---|---|'];
|
||||
for(const r of report.rows)lines.push(`|${r.title}|${r.difficulty}|${r.localVsWf.extra}/${r.localVsWf.missing}|${r.localVsWfNative.extra}/${r.localVsWfNative.missing}|${r.localSpecialMismatch}|${!r.wfSourceMatchesSus}|`);
|
||||
await writeFile('data/wf-audit/latest.md',lines.join('\n')+'\n');
|
||||
console.log(JSON.stringify(report.summary,null,2));
|
||||
console.log(JSON.stringify(report.rows.find(r=>r.songId==='m0527'&&r.difficulty==='expert'),null,2));
|
||||
Reference in New Issue
Block a user