Files
ps5-dump-forge/app/scripts/appcache.mjs
T
Quer3qandClaude Opus 5.5 4aabddcb11 PS5 Dump Forge 0.0.1-pre4: PS5 payload, fast verification by default
- PS5 payload (plain .elf): the core runs on the console, built in Docker against the
  ps5-payload-dev SDK v0.43 (ps5/: target JSON, ps5-ai-cli shims, entry.c, compat.c, linker.sh;
  FreeBSD 11 ABI via --cfg libc_unstable_freebsd_version="11", struct sizes asserted).
- New crate ps5-dump-forge-server and `ps5-dump-forge serve`: the React UI over HTTP on port 8095
  (fetch transport, polling, folder/file browser, Show path, Stop), no access control by design.
  Home-screen tile PDFG00001; the payload saves a copy of itself (two-stage build) so the tile's
  AppCache'd page can start it through elfldr after a restart.
- FreeBSD platform layer in core: destination probe (dest.rs), publish by link or checked rename
  behind a device guard, bounded dirty data with adaptive fsync cadence (durable.rs), read-ahead
  (prefetch.rs), drive-removal messages, rest-mode PowerTick. A retried fsync fails the job.
- Fast verification is the default on every platform: structure + sampled BLAKE3 slices;
  "Full verification" switch / --full-verify re-reads every byte; .pkg always full. One hash
  pass per byte.
- vendor patch 0015: UFS2 range reads (cached pointer blocks, contiguous runs, checked offsets).
- Tests and tooling: scripts/test-freebsd.sh (FreeBSD VM: UFS, FAT32, nullfs),
  scripts/release-ps5.sh (ELF, embedded UI, self copy and debug-route checks), CI and release
  jobs for the .elf.
- Hardware (PS5 fw 13.60, /data): .ffpkg/folder sources to .exfat and folder pass their checks;
  writes ~273 MB/s of the drive's ~288 MB/s; tile launch after a reboot works. Other output
  formats and USB output are not console-tested yet (TODO.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:05:27 +03:00

39 lines
1.5 KiB
JavaScript

// The http build's AppCache manifest (vite.config.ts writes it after the bundle; the PS5
// browser keeps the page offline with it, see src/appcache.ts). Plain node, so
// scripts/check-launcher.mjs runs the same code.
import { createHash } from "node:crypto";
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
export const MANIFEST = "forge.appcache";
/** Every file under `dir` but the manifest, `/`-separated and sorted. */
export function bundleFiles(dir, prefix = "") {
const out = [];
for (const e of readdirSync(join(dir, prefix), { withFileTypes: true })) {
const rel = prefix + e.name;
if (e.isDirectory()) out.push(...bundleFiles(dir, `${rel}/`));
else if (rel !== MANIFEST) out.push(rel);
}
return out.sort();
}
/** `CACHE MANIFEST`, a hash over every path and its bytes (any rebuild that changes a byte
* changes the manifest, so the browser fetches the new page), `/` and every file, then
* `NETWORK: *` (the API and elfldr). */
export function manifestText(dir) {
const files = bundleFiles(dir);
const hash = createHash("sha256");
for (const f of files) {
const bytes = readFileSync(join(dir, f));
hash.update(`${f}\0${bytes.length}\0`);
hash.update(bytes);
}
return ["CACHE MANIFEST", `# ${hash.digest("hex")}`, "", "CACHE:", "/", ...files.map(encodeURI), "", "NETWORK:", "*", ""].join("\n");
}
export function writeManifest(dir) {
writeFileSync(join(dir, MANIFEST), manifestText(dir));
}