Files
Currency-War-SR/tools/gridfight-extract-node/README.md
T
2026-10-30 23:54:07 +07:00

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.