144 lines
7.9 KiB
Markdown
144 lines
7.9 KiB
Markdown
# GridFight extractor (Node ESM)
|
|
|
|
Faithful port of the sibling extractor. Node 22+ and built-in modules only;
|
|
validated with Node 26.12.0. Native reader proofs require GNU `objdump`.
|
|
Linux installers use `flock`. XXH64 is implemented locally: no FFI, libxxhash,
|
|
npm install, metadata dumper, network fetch or game launch is required.
|
|
|
|
Run from the repository root:
|
|
|
|
```sh
|
|
node tools/gridfight-extract-node/extract.mjs \
|
|
--client /path/to/client \
|
|
--dump /path/to/config/dump.cs \
|
|
--output /tmp/gridfight-core \
|
|
--traits --season-id 2 \
|
|
--evidence-dir /tmp/gridfight-core/evidence
|
|
node --test tools/gridfight-extract-node
|
|
```
|
|
|
|
The dump must contain `RPG.GameCore.Config.dll`; traits also need
|
|
`RPG.GameCore.Foundation.dll` and `RPG.GameCore.FixedMath.dll`. Use the matching
|
|
`config/dump.cs`, rather than assuming the top-level dump contains those rows.
|
|
Treat client files as read-only; place outputs and evidence outside the client.
|
|
|
|
`extract.mjs` retains `--language` (default `en`, choices `en cn cht jp kr de es
|
|
fr id pt ru th vi`), `--traits`, `--season-id`, and `--evidence-dir`. It publishes
|
|
roles, shop odds, traits/layers, season/divisions, offerings, schemas and
|
|
provenance with the same filenames and JSON contracts as the reference.
|
|
Season selection is explicit; it does not establish a live calendar.
|
|
|
|
Native mask tests and metadata establish field order. Every native indexed
|
|
collection must decode completely and re-encode to its exact original bytes.
|
|
Unknown types, absent/ambiguous assets, conflicting text and invalid references
|
|
fail. Required data documents publish only after the requested validations
|
|
succeed. Evidence may remain after failure. Each replacement is atomic; use a
|
|
staging directory for bundle-level installation. Large integers retain all 64
|
|
bits in JSON. Arrays, numeric dictionary ordering, indentation and Unicode
|
|
escaping retain the reference output representation.
|
|
|
|
Other entrypoints preserve their original flags (`.mjs` replaces `.py`):
|
|
|
|
| Entrypoint | Required flags | Optional flags/defaults |
|
|
|---|---|---|
|
|
| `stages.mjs` | `--client --dump --identity --output` | None |
|
|
| `items.mjs` | `--client --dump --identity --output` | None |
|
|
| `petpal.mjs` | `--client --dump --identity --output` | None |
|
|
| `rounds.mjs` | `--client --dump --literals --identity --output` | `--language en` |
|
|
| `trait_effects.mjs` | `--client` | `--output resources/grid_fight/trait_effects.json` |
|
|
| `trailblaze.mjs` | `--client` | `--output resources/grid_fight/trailblaze.json` |
|
|
| `jade.mjs` | `--client` | `--output resources/grid_fight/jade.json` |
|
|
| `equipment.mjs` | None | `--items`, `--catalog`, `--season 2`, `--output` |
|
|
| `portals.mjs` | None | `--items`, `--catalog`, `--season 2`, `--output`, `--augments` |
|
|
| `score.mjs` | None | `--catalog`, `--output` |
|
|
| `ui_names.mjs` | `--client --dump --resources --english --thai --output --evidence` | None |
|
|
| `native_slice.mjs` | `--client --dump --class --output` | Repeat `--class` |
|
|
| `audit_coverage.mjs` | `--dump --output` | `--source` defaults to repository root |
|
|
| `audit_battle_entry.mjs` | `--client --dump --assembly --roles --evidence` | None |
|
|
| `install_stages.mjs` | `--source --launcher --stage --report` | `--package stage` or `petpal` |
|
|
| `install_rounds.mjs` | `--server-root --launcher-root --stage` | None |
|
|
| `run_tests.mjs` | `--output` | `--zig zig` (requires 0.14.1 and cached protobuf) |
|
|
|
|
Default derived-table inputs and outputs remain repository-relative:
|
|
`resources/grid_fight/items.raw.json`, the matching basename's JSON, and
|
|
`protocol/evidence/cw-mechanics/catalog.json`. Portals also writes
|
|
`resources/grid_fight/augments.json`. Pass scratch output paths for comparison.
|
|
|
|
For example:
|
|
|
|
```sh
|
|
node tools/gridfight-extract-node/items.mjs \
|
|
--client /path/to/client --dump /path/to/config/dump.cs \
|
|
--identity /tmp/gridfight-core/provenance.json --output /tmp/gridfight-items
|
|
node tools/gridfight-extract-node/equipment.mjs \
|
|
--items /tmp/gridfight-items/items.raw.json --season 2 \
|
|
--catalog /path/to/matching/catalog.json --output /tmp/gridfight-equipment.json
|
|
```
|
|
|
|
`stages`, `items` and `petpal` consume the core extractor's identity manifest.
|
|
`rounds` consumes the client-table metadata identity (`client` and
|
|
`metadata_sha256`) and matching string literals. Its underscore raw filenames,
|
|
Supply `null`, and tagged DynamicValue contract intentionally differ from
|
|
`stages` (dot raw filenames, Supply `shop`, and `wire_tag`). Neither guesses
|
|
monster groups or tutorial selector meanings.
|
|
|
|
Installers retain identity/hash checks, a nonblocking runtime-refresh lock,
|
|
verified backups, atomic replacements, manifest refresh, protected-file checks
|
|
and rollback. They use a local Node port of the runtime verification helpers.
|
|
`install_rounds` stores its audit evidence in this new directory, preserving
|
|
the sibling reference directory. No installer was run against real resources;
|
|
installation was exercised only in disposable fixtures.
|
|
|
|
Full season-2 staging, including a fresh native catalog for equipment/score and a
|
|
file-by-file installed-data comparison:
|
|
|
|
```sh
|
|
node tools/gridfight-extract-node/stage_all.mjs \
|
|
--client /path/to/client --dump /path/to/config/dump.cs \
|
|
--literals /path/to/stringliterals.json \
|
|
--english /path/to/active/en/TextMap.bytes \
|
|
--thai /path/to/active/th/TextMap.bytes \
|
|
--resources /path/to/server/resources \
|
|
--baseline /path/to/server/resources/grid_fight \
|
|
--output /tmp/cw-stage
|
|
```
|
|
|
|
The output must be outside the client and installed resources. All flags are
|
|
required; no derived entrypoint falls back to the older repository catalog in
|
|
this workflow. The active language blobs must match the client. Logs, native
|
|
proofs, CHANGES.md, comparison.json and a hashed bundle manifest accompany the
|
|
runtime JSON. Root rounds use the existing stages contract; the alternate
|
|
rounds extractor's distinct contract is retained under rounds-alternative/.
|
|
Server-authored node_profiles/orb_rewards are carried byte-identically, marked
|
|
as third-party observations rather than freshly extracted client data. Old
|
|
backup files are compared in the report but excluded from the runtime bundle.
|
|
AvatarConfig/AeonCatalog provide existing UI identity/name lookup hints; UI text
|
|
is resolved from the supplied client TextMaps. Staging does not install data.
|
|
|
|
Validation on OSBETAWin4.6.53, season 2:
|
|
|
|
- 51 tests pass, including native 4.6.53 dispatch mutation rejection, relocated
|
|
4.6.51 layout, nested nulls, signed 64-bit limits, NaN payloads, dictionary
|
|
doubles and the Phainon schema's stack-write regression.
|
|
- DynamicValue FromByteBinary resolves from metadata (4.6.53 RVA 0x1e745df0;
|
|
4.6.51 RVA 0x1e58e120). Both use case offsets 0x85/0xc5/0x102/0x14f/0x18a/0x1cf
|
|
and dispatch offset 0x2b0. Typed case operations and dispatch bindings must
|
|
match before evidence is published. The wire layout is unchanged; both
|
|
projection modes support null tag 6. Integer and float bytes stay lossless.
|
|
- Stages: all 14 tables, including 29,715 StageConfig rows, re-encode exactly.
|
|
Fresh supplemental catalog: all 20 additional tables re-encode exactly,
|
|
including all nine Phainon fields (stack addresses are excluded from native
|
|
field candidates). Both stage and alternate-rounds extraction complete.
|
|
- 141 roles, 11 shop levels, 67 traits, 304 season-2 augments, 74 season-2 portals,
|
|
147 season-2 equipment entries, 493 routes, 12 partners. Trial-avatar audit:
|
|
5,200 rows re-encoded exactly and all 141 role identities verified.
|
|
- ui_names also exports item/augment/portal/trait hash maps for ID comparisons;
|
|
the current run resolves 1,816 English and Thai texts.
|
|
- No client data, installed resources, reference Python code, archives or live
|
|
processes are changed. No gameplay-correctness claim is made.
|
|
|
|
Use `node --test tools/gridfight-extract-node`. On hosts whose default test
|
|
isolation reports only a file-level result, add `--test-isolation=none` to see
|
|
all 51 individual results. Native proof fixtures are static objdump excerpts
|
|
from the matching beta DLL; method offsets come from config/dump.cs.
|