Skip to content

Add --json-trace flag for BO3 fastfile load traces - #41

Open
Kenshin9977 wants to merge 3 commits into
ate47:mainfrom
Kenshin9977:feature-json-trace-bo3
Open

Add --json-trace flag for BO3 fastfile load traces#41
Kenshin9977 wants to merge 3 commits into
ate47:mainfrom
Kenshin9977:feature-json-trace-bo3

Conversation

@Kenshin9977

Copy link
Copy Markdown
Contributor

Scoped, additive flag, not a tool wide rewrite. Adds --json-trace, which switches BO3's fastfile handler (handler_game_bo3.cpp) to emit one structured JSON object per trace event instead of a text line, for DB_LoadXFileData, Load_Stream (and its hex dump loop), Load_XStringCustom, and the "Load asset" debug line. Text mode is untouched code at every site; JSON is only selected when the flag is passed. Every other game's handler is unaffected.

Verified against a real BO3 zone from the retail install:

  • Text mode regression: all 2850 asset loading lines byte for byte identical to the installed release build on the same zone, after normalizing timestamps and ASLR base addresses.
  • JSON mode content parity: order tolerant multiset comparison against the text trace (JSON legitimately consolidates 2+ text lines into 1 event in the nested DB_LoadXFileData case). Exact match across all 1238 events, every field identical except raw heap pointer values, which legitimately differ between separate process runs.

Includes #40 (GetLibBase binary mode fix), needed for correct module/offset resolution in the JSON output. Will rebase to just this commit once that merges.

utils::InFileCE is{ lib } defaulted to Windows text mode (CRLF translation,
0x1A treated as EOF), which reliably corrupts a binary read of a PE executable
- every other InFileCE backing a FileReader in this codebase already passes
std::ios::binary; this one call site was missed. Found while building acts
from source locally to verify an unrelated change (a real, pre-existing bug,
unrelated to that change).
@Kenshin9977
Kenshin9977 force-pushed the feature-json-trace-bo3 branch from 6fc0e2a to 25877fc Compare August 29, 2026 10:19
Scoped, additive flag - not a tool-wide rewrite. The -l t/-l d trace printer
isn't one function: LOG_TRACE/LOG_DEBUG wrap std::format-baked strings at
~666 call sites across 132 files, and each game hand-duplicates its own
Load_Stream-style native hook in a separate handler (BO3, BO4, CW, mw19, vg,
mwii, mwiii, bo6, bo7 all have their own). A blanket JSON mode across every
game would mean touching ~9 files with no shared abstraction - too much
surface for a personal fork to carry safely. The actual need (per Greyhoundx's
own BO3 zone-walker methodology) is specifically BO3's own load trace, so this
scopes to handler_game_bo3.cpp: DB_LoadXFileData, Load_Stream (+ its hex-dump
loop), Load_XStringCustom, and the "Load asset" debug line - 4 functions, ~9
call sites, each now emitting one structured JSON object per event when
--json-trace is passed (JsonAddCodePointer resolves the return address to
real module/moduleBase/offset fields via the existing hook::library::
GetLibraryInfo, not a re-parsed string; JsonAddBytes hex-encodes the same
byte window the text hex-dump already uses). Text mode is untouched code at
every site (if (jsonMode) {...} else {<original>}), selected via a new
core::logs::isjsontrace()/setjsontrace() pair and a --json-trace CLI flag.

Verified, not just built:
- Text-mode regression: a real BO3 zone (zm_factory_patch.ff, retail install)
  traced with this build vs. a baseline captured from the installed release
  binary on the same zone before any change - all 2850 asset-loading lines
  byte-for-byte identical after normalizing volatile values (timestamps, ASLR
  bases).
- JSON-mode content parity: same zone, --json-trace, order-tolerant multiset
  comparison against the text trace (JSON legitimately consolidates 2+ text
  lines into 1 structured event for the nested DB_LoadXFileData case, which
  shifts relative order - a deliberate design choice, not a bug). Exact match
  across all 1238 events (846 Load_Stream, 190 DB_LoadXFileData, 133
  Load_XStringCustom, 69 LoadAsset) - every field identical (offset, size,
  streamIndex, hex byte content, resolved strings, asset type/id/index/count,
  len/remaining). Only excluded field: raw heap pointer values, which
  legitimately differ between separate process runs.
@Kenshin9977
Kenshin9977 force-pushed the feature-json-trace-bo3 branch from 25877fc to 058738c Compare August 29, 2026 10:53
@ate47

ate47 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Before all the complaints that I might have, why do you need this code/feature?

@Kenshin9977

Copy link
Copy Markdown
Contributor Author

Yes sorry I sould've start with that. I'm reverse-engineering BO3's zone format and needed structured trace output to drive automated diffing/summary tooling. Parsing -l t's text log by hand doesn't scale across hundreds of assets per zone. It's opt-in (--json-trace) and doesn't change any existing default output

@Kenshin9977
Kenshin9977 force-pushed the feature-json-trace-bo3 branch from 7993bb1 to a154e9f Compare August 31, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants