This commit is contained in:
1 parent
2127f5f459
commit
8b80d05ca2
56 files changed
+6910
-1
No files matched your search
@@ -0,0 +1,63 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { execFileSync } from "node:child_process";
|
||||
|
||||
const root = ".reference/pokecrystal";
|
||||
const expected = "f2f52230b536214ef7c9924f483392993e226cfb";
|
||||
const romPath =
|
||||
process.env.CRYSTAL_ROM_PATH ??
|
||||
"Pokemon - Crystal Version (UE) (V1.1) [C][!].gbc";
|
||||
const supplied = readFileSync(romPath),
|
||||
rebuilt = readFileSync(`${root}/pokecrystal11.gbc`);
|
||||
if (
|
||||
createHash("sha1").update(supplied).digest("hex") !== expected ||
|
||||
!supplied.equals(rebuilt)
|
||||
)
|
||||
throw new Error(
|
||||
"The supplied ROM and reference rebuild must exactly match revision 1.1.",
|
||||
);
|
||||
const revision = execFileSync("git", ["-C", root, "rev-parse", "HEAD"], {
|
||||
encoding: "utf8",
|
||||
}).trim();
|
||||
if (revision !== "7a7881d0d62e0ddbd82dcf10e7116807487ac651")
|
||||
throw new Error("Unexpected PRET revision.");
|
||||
const symbols = new Map(
|
||||
readFileSync(`${root}/pokecrystal11.sym`, "utf8")
|
||||
.split("\n")
|
||||
.flatMap((line) => {
|
||||
const match = /^([0-9a-f]{2}):([0-9a-f]{4}) (\S+)$/.exec(line);
|
||||
if (!match) return [];
|
||||
const bank = parseInt(match[1], 16),
|
||||
address = parseInt(match[2], 16);
|
||||
return [
|
||||
[
|
||||
match[3],
|
||||
address < 0x4000 ? address : bank * 0x4000 + address - 0x4000,
|
||||
],
|
||||
];
|
||||
}),
|
||||
);
|
||||
const names = {
|
||||
mapGroups: "MapGroupPointers",
|
||||
tilesets: "Tilesets",
|
||||
collisions: "CollisionPermissionTable",
|
||||
environmentColors: "EnvironmentColorsPointers",
|
||||
backgroundPalettes: "TilesetBGPalette",
|
||||
objectPalettes: "MapObjectPals",
|
||||
roofPalettes: "RoofPals",
|
||||
roofTypes: "MapGroupRoofs",
|
||||
roofs: "Roofs",
|
||||
housePalettes: "HousePalette",
|
||||
sprites: "OverworldSprites",
|
||||
facings: "Facings",
|
||||
standardScripts: "StdScripts",
|
||||
};
|
||||
const profile = readFileSync("src/game/rom/profile.ts", "utf8");
|
||||
for (const [key, symbol] of Object.entries(names)) {
|
||||
const match = new RegExp(`${key}:\\s*(0x[0-9a-f]+)`, "i").exec(profile);
|
||||
if (!match || Number(match[1]) !== symbols.get(symbol))
|
||||
throw new Error(`Profile address mismatch: ${key} / ${symbol}`);
|
||||
}
|
||||
console.log(
|
||||
"User ROM, pinned PRET rebuild and all native profile addresses match.",
|
||||
);
|
||||
@@ -0,0 +1,30 @@
|
||||
import { readdirSync, readFileSync, statSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
let files = 0,
|
||||
size = 0;
|
||||
function inspect(directory) {
|
||||
for (const name of readdirSync(directory)) {
|
||||
const path = join(directory, name);
|
||||
if (statSync(path).isDirectory()) {
|
||||
inspect(path);
|
||||
continue;
|
||||
}
|
||||
if (!/\.(html|js|css|svg)$/.test(name))
|
||||
throw new Error(`Unexpected production asset: ${path}`);
|
||||
if (/reference|vendor|binjgb/i.test(path))
|
||||
throw new Error(`Reference tool in production: ${path}`);
|
||||
const bytes = readFileSync(path),
|
||||
text = bytes.toString("utf8");
|
||||
if (/Binjgb|_emulator_|binjgb\.wasm|\.reference\/pokecrystal/.test(text))
|
||||
throw new Error(`Reference dependency in production: ${path}`);
|
||||
if (/data:(image|audio|application\/octet-stream)[^,]*;base64,/i.test(text))
|
||||
throw new Error(`Embedded binary asset in production: ${path}`);
|
||||
files++;
|
||||
size += bytes.length;
|
||||
}
|
||||
}
|
||||
inspect("dist");
|
||||
console.log(
|
||||
`Native release verified: ${files} HTML/JS/CSS/SVG files, ${size} bytes; no emulator, ROM, extracted binary assets or reference checkout.`,
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
|
||||
const expected = {
|
||||
LICENSE: "5a7b61a51a5efb789721b3480b502f324094911aeca46937956c561b52638009",
|
||||
"binjgb.js":
|
||||
"a68e5854b5d68339a34c0aa0b6dbeacd615ed316657ee17b63dafa5e00561b09",
|
||||
"binjgb.wasm":
|
||||
"52c165069441a09180b4bd63464318aa7b861b1d36e0d05e8047b48619fd2f0b",
|
||||
};
|
||||
for (const [name, hash] of Object.entries(expected)) {
|
||||
const actual = createHash("sha256")
|
||||
.update(readFileSync(`reference/public/vendor/binjgb/${name}`))
|
||||
.digest("hex");
|
||||
if (actual !== hash) throw new Error(`Vendor integrity mismatch: ${name}`);
|
||||
}
|
||||
for (const path of readdirSync("public", { recursive: true })) {
|
||||
if (/\.(gbc?|rom|sav|zip)$/i.test(path))
|
||||
throw new Error(`Game data must not be shipped: ${path}`);
|
||||
}
|
||||
console.log("Pinned emulator integrity and public game-file checks passed.");
|
||||
Reference in new issue
Block a user