36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
export const CRYSTAL_ROM = {
|
|
name: "Pokémon Crystal · English US/Europe 1.1",
|
|
sha1: "f2f52230b536214ef7c9924f483392993e226cfb",
|
|
size: 2 * 1024 * 1024,
|
|
} as const;
|
|
|
|
export interface ValidatedRom {
|
|
bytes: Uint8Array;
|
|
sha1: string;
|
|
name: string;
|
|
}
|
|
|
|
export async function validateRom(file: File): Promise<ValidatedRom> {
|
|
if (file.size !== CRYSTAL_ROM.size) {
|
|
throw new Error(
|
|
"Choose an uncompressed Pokémon Crystal English US/Europe 1.1 ROM (.gbc, 2 MiB).",
|
|
);
|
|
}
|
|
if (!globalThis.crypto?.subtle) {
|
|
throw new Error(
|
|
"ROM verification needs HTTPS or localhost. Open this player over a secure connection.",
|
|
);
|
|
}
|
|
const buffer = await file.arrayBuffer();
|
|
const digest = await crypto.subtle.digest("SHA-1", buffer);
|
|
const sha1 = Array.from(new Uint8Array(digest), (byte) =>
|
|
byte.toString(16).padStart(2, "0"),
|
|
).join("");
|
|
if (sha1 !== CRYSTAL_ROM.sha1) {
|
|
throw new Error(
|
|
"This ROM is not the supported English US/Europe revision 1.1. Other languages, revisions, and modified ROMs are not supported yet.",
|
|
);
|
|
}
|
|
return { bytes: new Uint8Array(buffer), sha1, name: CRYSTAL_ROM.name };
|
|
}
|