tarinai/scripts/achievement_spell_binary_compression_audit.js
2026-07-15 16:27:56 +09:00

55 lines
2.6 KiB
JavaScript

"use strict";
const fs = require("fs");
const path = require("path");
const vm = require("vm");
const root = path.join(__dirname, "..");
const context = {
console, Date, Math, JSON, Object, Array, Map, Set, Uint8Array,
TextEncoder, TextDecoder, URLSearchParams, performance,
CompressionStream, DecompressionStream,
location: { search: "" },
TarinaiSnapshot: { version: 35 },
TarinaiSaveSchema: {
BINARY_SCHEMA_VERSION: 43,
FIELD_IDS: ["garden"],
itemTypeValue(_id, fallback = "") { return fallback; },
},
};
context.globalThis = context;
context.window = context;
vm.createContext(context);
vm.runInContext(fs.readFileSync(path.join(root, "js", "save_codec.js"), "utf8"), context, { filename: "save_codec.js" });
const legacySpell = "た㣏洰祶蘬䕘㘎㗱餞皤庒袿랿涾뎳夃靅㸊倄遲诡㶣莡䵡錻缀袔鐨묪辶鎽묽砻菏뼿椳欛琛뺯琘뀛矎䗁蓐筓俇뗇㛂熋汯伂磌鉡䞳搶逷礣됽뷻鏲㨝尻㷿㭫牫㬈焂铤䅳㸢粃腓誘岜圉缴聦秮杰醆㳇幖豣羬懄䫌릘㾎惛橉芊芰㙞랷邆묒罸䅰哿鷔鉐皣栠䝹燂䒹蟜㲈婑裈㲵嫡䋪㲛갭效处彤䒴庭䴐姜脈礩弔粋肫䬑熶嬔翈哥渖㤈㱶闔䒚抉弐㡝酵义秮肘醃䆿傏铪彂櫾佌뭰叺馞稘焤봾岲䆫㐝";
const progress = [77, 13, 64, 2222, 19, 11, 12, 1025, 31, 444, 222, 555];
const metadata = {
w: [[1, 2, 3, 4, 5], [3, 4, 5], 12, 187, 6, 145.5, 20, 18, 100, 90, -1],
t: [],
i: [],
s: [3, 0xffffffff, (2 ** 22) - 1, Math.floor(1700000000 / 60), Array.from({ length: 54 }, (_value, index) => Math.floor(index * 12345 / 60)), progress],
};
const snapshot = {
v: 35,
a: "tj1",
m: [1, 0, "garden"],
w: [0, 0, 0, 120, 0, -9990, 1, 0, "seed", 0, 0, 0],
t: [],
i: [],
g: metadata,
};
(async () => {
const legacyDecoded = await context.TarinaiSaveCodec.decodeSnapshot(legacySpell);
if (legacyDecoded?.g?.s?.[0] !== 1) throw new Error("legacy schema-41 spell was not decoded");
const encoded = await context.TarinaiSaveCodec.encodeSnapshot(snapshot);
const decoded = await context.TarinaiSaveCodec.decodeSnapshot(encoded);
if (decoded?.g?.s?.[0] !== 3) throw new Error("binary achievement spell did not roundtrip");
const saved = legacySpell.length - encoded.length;
const ratio = saved / legacySpell.length;
if (saved <= 0 || ratio < 0.35) throw new Error(`achievement spell compression regression: ${legacySpell.length} -> ${encoded.length}`);
console.log(`[OK] achievement spell binary compression ${legacySpell.length} -> ${encoded.length} chars (${(ratio * 100).toFixed(1)}% reduction), legacy decode passed`);
})().catch(error => {
console.error(error);
process.exitCode = 1;
});