trampler: hash lifecycle RE'd via live round-trip (client recomputes all 5 on save)

- All 5 walker hashes are recomputed client-side on save from the local
  CompartmentsDatabase + CompartmentDefinitionDto (same build => byte-identical
  hashes; no per-walker secret). Wiping any/all hashes loads/opens/edits fine;
  one in-editor save regenerates everything (+ new file UUID & UniqueId).
- VERSION flag (WalkerBlueprintContainer.ValidateVersion) depends only on the
  structural Compartments/Connections hashes, not the Definition hashes; ERRORS
  is a separate structural check. Hashes = integrity/version-staleness markers,
  not security. Server upsert validation still untested.
- Document the 5-hash table (3 top-level + 2 per-part) and offline-computability
  in docs/TRAMPLER.md + CLAUDE.md; include experiment artifacts + baseline.
This commit is contained in:
DownloadPizza
2026-06-16 09:48:50 +02:00
parent aa7425221f
commit bd01d6753a
5 changed files with 163 additions and 6 deletions

View File

@@ -37,6 +37,12 @@ The four data sources, and which tools own them:
- IL2CPP source of truth: `il2cpp/dump.cs` (Il2CppDumper output — signatures/RVAs only, no method
bodies). `il2cpp/`, `ghidra/`, `snapshots/`, `bundles`, `Walkers`, `reverse/.secrets/` are
git-ignored (large/regenerable/secret). Live PlayFab token: `reverse/.secrets/playfab_token.json`.
- **Game runtime data dir** (`%USERPROFILE%\AppData\LocalLow\Hologryph\SAND`, here
`/mnt/c/Users/DownloadPizza/AppData/LocalLow/Hologryph/SAND/`) holds:
- **`Player.log`** — Unity log; check it to see what the client did (walker file reads:
`[FS_STANDALONE] ReadAllFilesAsync … Path: …/Data/Walkers`; master-server handshake:
`[MasterServer] … Login / Connection failed to /connect`). `Player-prev.log` = previous run.
- **`Data/Walkers/*.wbt`** — the live walker saves (the `Walkers/` symlink points here).
## The `.wbt` walker save format (current focus)
@@ -71,6 +77,16 @@ offline, `build_wbt.py pack` recomputes the two Compartment* hashes and **copies
Definition* hashes from the source — correct as long as the *set of part definitions* is unchanged;
it raises if you add a part whose `DefinitionHash` has never been harvested.
**Hash lifecycle (verified live 2026-06-16 — see `docs/TRAMPLER.md`):** the client **recomputes all 5
hashes on save** from its own database (same build ⇒ byte-identical hashes; no per-walker secret —
plain unsalted MD5, they're integrity/version-staleness markers, **not** security). Wiping any/all
hashes is harmless: a walker with blank hashes still **loads, lists, and opens in the editor**, and
**one in-editor save regenerates everything** (and mints a new file UUID + `UniqueId`). The `VERSION`
flag in `Player.log`'s `CheckValidBlueprint: ERRORS {0}, VERSION:{1}` (=`WalkerBlueprintContainer
.ValidateVersion`, which recomputes against the *current* DB/definitions) tracks only the **structural**
hashes (Compartments/Connections); Definition hashes don't affect client validation. Server-side upsert
validation is untested (blocked by master-server `/connect` errors during the playtest).
Enum tables (from `dump.cs`): `ConnectionSlotType` 0 DOOR,1 HATCH,2 STRUCTURE,3 BALCONY,4 DECK ·
`ConnectionState` 0 DEFAULT,1 DOOR,2 OPEN · `ConnectionsCount` 0 FULL,1 PARTIAL,2 ERROR. Note the
master-server **WS form** serializes these as integers and omits null `EpbId`; the storage/hash form