1095 lines
98 KiB
Markdown
1095 lines
98 KiB
Markdown
## Multiplayer Session and Transport Flow
|
||
|
||
- Roots: `multiplayer_window_init_globals` at `0x004efe80`, `multiplayer_window_service_loop` at
|
||
`0x004f03f0`, the Multiplayer.win session-event callback table built by
|
||
`multiplayer_register_session_event_callbacks` at `0x0046a900`, the active session-event transport
|
||
object at `0x006cd970`, the Multiplayer preview dataset object at `0x006cd8d8`, and the lower
|
||
pending-template and text-stream helpers around `0x00597880..0x0059caf0`.
|
||
- Trigger/Cadence: shell-owned Multiplayer.win frame service plus event-driven session callbacks and
|
||
repeated transport pump steps.
|
||
- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`;
|
||
`multiplayer_register_session_event_callbacks`; `multiplayer_dispatch_requested_action`;
|
||
`multiplayer_reset_preview_dataset_and_request_action`;
|
||
`multiplayer_preview_dataset_service_frame`; `multiplayer_load_selected_map_preview_surface`;
|
||
`multiplayer_flush_session_event_transport`; `multiplayer_transport_service_frame`;
|
||
`multiplayer_transport_service_worker_once`;
|
||
`multiplayer_transport_service_route_callback_tables`;
|
||
`multiplayer_transport_service_status_and_live_routes`;
|
||
`multiplayer_transport_text_stream_service_io`;
|
||
`multiplayer_transport_dispatch_pending_template_node`;
|
||
`multiplayer_transport_service_pending_template_dispatch_store`.
|
||
- State Anchors: live session globals at `0x006d40d0`, active session-event transport object at
|
||
`0x006cd970`, status latch at `0x006cd974`, session-event mode latch at `0x006cd978`, retry
|
||
counter at `0x006cd984`, preview dataset object at `0x006cd8d8`, preview-valid flag at
|
||
`0x006ce9bc`, staged preview strings at `0x006ce670` and `[0x006cd8d8+0x8f48]`, Multiplayer.win
|
||
backing block at `0x006d1270`, selector-view store root at `[transport+0xab4]`, selector-view
|
||
generation counters at `[transport+0xab8]..[transport+0xac0]`, selector-view backing arrays around
|
||
`[transport+0xad0]..[transport+0xae4]`, selector-view entry probe-request id at `[entry+0x50]`,
|
||
live-state gate at `[entry+0x58]`, third-slot flag word at `[entry+0x64]`, probe-schedule tick at
|
||
`[entry+0x68]`, last-success tick at `[entry+0x6c]`, pending-probe latch at `[entry+0x74]`,
|
||
success generation at `[entry+0x78]`, consecutive-failure counter at `[entry+0x7c]`, rolling
|
||
average at `[entry+0x80]`, recent sample window at `[entry+0x84..]`, bounded sample-count at
|
||
`[entry+0x94]`, total-success count at `[entry+0x98]`, pending-template list at
|
||
`[transport+0x550]`, dispatch store at `[worker+0x54c]`, and text-stream buffers rooted under
|
||
`[worker+0x1c]`.
|
||
- The worker-owned text-stream seam is tighter now too: `0x59c670` constructs the two growable
|
||
text buffers, `0x59c6c0` resolves the remote host and opens one keepalive TCP socket into
|
||
`[worker+0x1c]`, `0x59cbd0` formats transient command lines through the shared static builder at
|
||
`0x00db8dd0`, `0x59caf0` appends those lines plus CRLF, and `0x59cad0` services the resulting
|
||
send/recv socket state. The current worker bring-up at `0x58f110` now reads cleanly through that
|
||
strip: after store construction it opens the text stream, connects it to the caller host/port,
|
||
and then emits either `CRYPT des 1 %s` or the fallback `USRIP` command into the send buffer. The
|
||
mode-`3` transport-text pair setter is tighter now too: `0x59ae20` takes the two payload strings
|
||
under `[msg+0x20]`, XORs each of them in place against the fixed repeating key band
|
||
`[transport+0x564]` through `0x5a1050`, seeds the paired RC4-style `0x102`-byte stream-cipher
|
||
states at `[transport+0x242]` and `[transport+0x140]` through `0x5a0d00`, marks `[transport+0x13c]`
|
||
active, and then refreshes the status line through `0x59caf0`. The
|
||
receive side is tighter now too: `0x59d210` peels one complete CRLF-delimited line out of the
|
||
receive buffer, `0x59cec0` decodes that isolated line into the transient field band rooted at
|
||
`[worker+0x328..+0x344]`, `0x59cc30` splits any `nick!user@host`-style prefix into owned
|
||
subfields, `0x59cdf0` tokenizes the later fields into the transient vector at
|
||
`[worker+0x348..+0x34c]`, and `0x59d400` returns the transient band only when one full line was
|
||
successfully decoded.
|
||
- Subsystem Handoffs: the Multiplayer.win initializer seeds the backing block at `0x006d1270`, later
|
||
reset paths construct the separate preview dataset at `0x006cd8d8`, and the shell-owned
|
||
active-mode frame services that dataset every frame through
|
||
`multiplayer_preview_dataset_service_frame`. That preview side publishes roster and status
|
||
controls through the Multiplayer window control paths, loads `.gmt` preview surfaces through
|
||
`multiplayer_load_selected_map_preview_surface`, and is even reused by the map/save coordinator’s
|
||
mode-`11` `.gmt` path when the dataset already exists. The preview owner now has a tighter
|
||
internal request split too. The fixed selector-descriptor list at `[0x006cd8d8+0x8f28]` is built
|
||
through `multiplayer_preview_dataset_append_named_callback_descriptor` `0x00469930`, whose
|
||
current grounded owner is the fixed registration block
|
||
`multiplayer_preview_dataset_register_fixed_named_callback_descriptors_1_to_10` `0x00473a60`;
|
||
the variable-size named UI-request list at `[0x006cd8d8+0x8f2c]` is built through
|
||
`multiplayer_preview_dataset_append_named_ui_request_record` `0x00469a50`; and the staged
|
||
profile/path strings live at `[0x006cd8d8+0x8e10]` and `[0x006cd8d8+0x8f48]`, with the broader
|
||
action-`2` staging path now bounded by
|
||
`multiplayer_preview_dataset_stage_profile_text_selected_path_and_sync_session_state`
|
||
`0x0046a030`. The companion action-`3` commit path is tighter too:
|
||
`multiplayer_preview_dataset_match_named_field_slot_copy_profile_text_and_probe_selection`
|
||
`0x0046a110` now sits directly above the lazily initialized `0x80 * 0x11c` field-slot table at
|
||
`[0x006cd8d8+0x10]`, whose owner is
|
||
`multiplayer_preview_dataset_ensure_field_slot_table_initialized` `0x0046a1a0`. The shared
|
||
submitter above those lists is now explicit too:
|
||
`multiplayer_preview_dataset_submit_transport_request` `0x00469d30` accepts the caller’s
|
||
request-id, selector, payload pointer and length, flag word, and optional auxiliary pointer,
|
||
optionally allocates one sidecar object, and then either sends the request directly through the
|
||
session-event transport or takes the slower packed branch through `0x00553000/0x00552ff0` into
|
||
`0x00521dc0`. One shell-side prompt owner above that submitter is now explicit too:
|
||
`shell_command_prompt_for_text_and_submit_selector1_multiplayer_transport_request_when_auxiliary_preview_ready`
|
||
`0x00441690` requires active scenario state, the auxiliary-preview-owner gate
|
||
`shell_has_auxiliary_preview_owner` `0x00434050`, and one live queued-preview record at
|
||
`[world+0x66ae]`, then opens prompt `0x0b6d` and forwards the returned text through
|
||
`0x00469d30` with selector `1`, request id `0`, flag `1`, and a null auxiliary payload while the
|
||
shell-global modal latch `0x0062be80` is held around the prompt. The constructor and teardown
|
||
side are tighter now too.
|
||
`multiplayer_preview_dataset_construct_reset_globals_and_seed_callback_owners` `0x0046be80`
|
||
is the real reset owner above the action-`2/3` branches in
|
||
`multiplayer_dispatch_requested_action`: it re-enters the paired release body
|
||
`multiplayer_preview_dataset_release_owned_lists_transients_and_session_side_state`
|
||
`0x0046bc40`, clears the surrounding launcher globals, allocates the field-slot table and the
|
||
keyed request/descriptor owners, seeds the render target and staging buffers, and then calls
|
||
`multiplayer_preview_dataset_reset_global_callback_state_and_register_selector_handlers`
|
||
`0x00473280` plus the smaller fixed-name block
|
||
`multiplayer_preview_dataset_register_fixed_named_callback_descriptors_1_to_10` `0x00473a60`.
|
||
That broader registration pass `0x00473280` now bounds the selector-handler family too: it
|
||
zeroes the global scratch bands `0x006ce808..0x006ce994` and `0x006ce290`, seeds default
|
||
callback root `[0x006cd8d8+0x08]` with `0x0046f4a0`, and populates the keyed selector table at
|
||
`[0x006cd8d8+0x04]` through
|
||
`multiplayer_preview_dataset_register_selector_callback_if_absent` `0x00468b10` for selectors
|
||
`1..0x83`. The concrete callback bodies under that table are tighter now too. The small split is
|
||
real rather than guessed: `0x0046c390` is the direct control-`0x109` publish leaf through
|
||
`0x00469d30`; `0x0046c3c0` is the fixed-session-token plus launch-latch arm path; and the large
|
||
sibling `0x0046c420` is the real apply-owner for one incoming session payload slab copied into
|
||
`0x006cec74` before the shell-refresh follow-ons. A second callback cluster now owns live
|
||
session-entry flags instead of just relaying transport payloads: `0x0046c7c0` rewrites the
|
||
elapsed-pair dwords `[entry+0x54/+0x58]`, `0x0046c840` sets bit `0x08` in `[entry+0x5c]`,
|
||
`0x0046c870` toggles bit `0x01` from payload byte `[msg+0x08]`, `0x0046cf10` sets bit `0x04`,
|
||
and `0x0046cf70` is the list-wide clear of that same bit-`0x01` lane across every live session
|
||
entry. The broader callback `0x0046c8c0` sits above those single-field leaves and applies either
|
||
one or many embedded session-field update records before republishing the list. The pending-state
|
||
side is separated now too: `0x0046cce0`, `0x0046cd10`, `0x0046ce90`, and `0x0046d230` are the
|
||
current small latch/state owners under `0x006cd91c`, `0x006d1280`, `0x006d1284`, and
|
||
`0x006ce9c8`, while `0x0046cd30` and `0x0046ce10` are the paired current-session string/scalar
|
||
submit-and-apply handlers over `[entry+0x258c/+0x268c/+0x2690/+0x2694]`. One neighboring
|
||
cross-subsystem callback is tighter now too: `0x0046cf40` mirrors one remote late
|
||
setup-preview/status payload block into `[world+0x66be]`, the same world band later serialized
|
||
and restored under bundle chunk ids `0x2ee0/0x2ee1` and re-normalized after restore through
|
||
`0x0047bc80`. The same callback table
|
||
also owns one small fixed transfer-progress family rooted at `0x006ce2e8`: `0x0046cfe0`
|
||
allocates the first free `0x5c` slot and optionally formats one label string, `0x0046d090`
|
||
appends progress payload into the matched slot while publishing one percent string through
|
||
`0x005387a0`, and `0x0046d1d0` clears the finished slot and frees that optional label. On the
|
||
release side, `0x0046bc40` now clearly owns the request-list,
|
||
descriptor-list, semicolon-name, pooled-span, render-target, and auxiliary-owner teardown, while
|
||
`multiplayer_shutdown_preview_dataset_session_object_and_global_helper` `0x0046c230` is the
|
||
final wrapper that additionally drops the live session object at `0x006d40d0` and the shared
|
||
helper at `0x00d973b4`. The small tuple staging below that family is bounded too:
|
||
`multiplayer_preview_dataset_touch_current_session_year_bucket_and_return_staged_tuple`
|
||
`0x0046b6d0` now owns the keyed session-bucket touch under `[session+0x2580]` for the staged
|
||
tuple at `[0x006cd8d8+0x9048]`, and the companion
|
||
`multiplayer_preview_dataset_stage_optional_selected_token_from_source_ptr` `0x0046d610` writes
|
||
the optional derived token into `[0x006cd8d8+0x8f38]`. The next service layer under the same
|
||
owner is tighter too: `multiplayer_preview_dataset_prune_session_buckets_below_current_year_key`
|
||
`0x0046b910` now bounds the older keyed-bucket drain under `[session+0x2580]`, while
|
||
`multiplayer_preview_dataset_service_current_session_buckets_and_publish_selector0x67`
|
||
`0x0046b9f0` owns the current-bucket walk, the local counters `[+0x987c/+0x9890]`, and the
|
||
later selector-`0x67` publish branch back through `0x00469d30`. Its local batch-publish child
|
||
`multiplayer_preview_dataset_publish_accumulated_selector0x71_record_batch` `0x00473bf0` is now
|
||
bounded too: it packages the fixed-width records at `0x006cd990`, prefixes `(0, count)`, sends
|
||
them as selector `0x71`, and then clears the live record count `0x006ce9a0`. The immediate local
|
||
helpers under that same band are now explicit too: `0x0046d260` is the fixed-record append
|
||
primitive that grows `0x006cd990` up to `0x80` entries, while `0x0046d240` is the paired release
|
||
of the optional selector-`0x71` staging blob at `0x006ce994`. The first fixed named-descriptor
|
||
block under `multiplayer_preview_dataset_register_fixed_named_callback_descriptors_1_to_10`
|
||
`0x00473a60` is tighter in the same way now. Its concrete roots `0x0046db10`, `0x0046db50`,
|
||
`0x0046db90`, `0x0046dbd0`, `0x0046dd10`, `0x0046de40`, `0x0046de80`, `0x0046e030`, and
|
||
`0x0046e250` all return small static records rooted at `0x006ce9dc..0x006cea3c`; each record
|
||
carries a leading tag byte plus the same derived world-year key from `[0x006cec78+0x0d]`, while
|
||
the heavier siblings add collection-backed totals from `0x0062be10`, `0x006ceb9c`, `0x0062b26c`,
|
||
`0x006cfca8`, or `0x006cfcbc` together with local overlay, geometry, or object-metric sample
|
||
paths. The immediate helper strip beneath that same first named block is tighter now too.
|
||
`0x0046d980` is the direct `0x006ceb9c` name-to-index lookup over `[entry+0x08]`, while
|
||
`0x0046d9e0` is the heavier companion that first resolves the current live session from
|
||
`0x006d40d0`, matches that session-side string against the same `0x006ceb9c` table, and returns
|
||
the matching entry index or `0xff`. Above those, `0x0046f8f0` resolves and validates one
|
||
`0x0062be10` entry, then keeps it only when its profile-index field `[entry+0x3b]` equals the
|
||
live-session-backed `0x006ceb9c` index from `0x0046d9e0`; and `0x0046f870` is the paired
|
||
rounded-delta leaf that takes one float plus one collection byte index and writes the rounded
|
||
positive/negative pair into metric ids `0x0f` and `0x0d` through `0x0042a040`. So this first
|
||
descriptor band is no longer just a bag of static record roots: it also owns a real local helper
|
||
family for `0x006ceb9c` name matching, live-session profile matching, and one narrow metric-pair
|
||
apply path beneath the higher callback bodies. The next selector layer above that helper strip is
|
||
tighter now too. Selector `0x12` is the small validate-or-error wrapper above selector `0x13`,
|
||
and selector `0x13` body `0x004706b0` resolves the same live-session company match, attempts the
|
||
placed-structure apply path through `0x004197e0`, `0x004134d0`, `0x0040eba0`, `0x0052eb90`, and
|
||
`0x0040ef10`, and otherwise falls back to a hashed selector-`0x6e` publish over the first
|
||
`0x1c` payload bytes. The same pattern appears again one pair later: selector `0x16` is the
|
||
thin validate-or-error wrapper above selector `0x17`, and selector `0x17` consumes a count plus
|
||
`0x33`-stride adjunct record band, resolves one live train-side entry under `0x006cfcbc`,
|
||
re-enters `0x004a77b0`, `0x0052e720`, `0x0040eba0`, `0x0052eb90`, and `0x0040ef10`, and again
|
||
falls back to hashed selector `0x6e` publish when the live apply path does not land. The later
|
||
status pair is bounded too: selector `0x19` is another thin wrapper, and selector `0x1a` either
|
||
derives a status code from `0x0046ed30` and current live-session name matching or treats the
|
||
four-byte payload directly as that status code before publishing localized status text
|
||
`0x0b7f/0x0b80`. One selector-pair above the metric leaf is now explicit too:
|
||
the earlier front edge of the same callback table is tighter now too. Selector `0x02` compares
|
||
staged profile text against the shell profile band at `[0x006cec7c+0x11]`, can advance the
|
||
requested-action fields `0x006d1280/0x006d1284`, can queue selector `0x53`, and on the success
|
||
path syncs the larger shell profile block rooted at `[0x006cec7c+0x44]`. The next small strip is
|
||
also grounded: selector `0x0a` clears `[world+0x19]`, seeds `[world+0x66ae]`, mirrors peer byte
|
||
`[peer+0x2690]` into named-profile byte `[entry+0x15c]`, refreshes `0x006ce98c`, and optionally
|
||
republishes one local status path. Selector `0x0b` is then the small token-staging wrapper above
|
||
selector `0x0c`, and selector `0x0c` itself forwards one signed byte pair into `0x00434680`
|
||
before adjusting dataset counter `0x006cd8e8`. The other small early leaves are now bounded too:
|
||
selector `0x0f` pops one node from the current session queue at `[session+0x64]`, publishes that
|
||
node through `0x00469d30`, and releases it; selector `0x10` looks one payload key up in the
|
||
session-side store `[session+0x60]` and forwards the result plus dataset string root
|
||
`[0x006cd8d8+0x8f48]` into `0x00521790`. One selector-pair above the metric leaf is now explicit too:
|
||
selector-`0x15` body `0x00470950` consumes the same compact `(float delta, company-index byte)`
|
||
payload shape, resolves the matching live-session company entry through `0x0046f8f0`, submits
|
||
selector `0x6b` through `0x00469d30`, and then immediately re-enters `0x0046f870` for the local
|
||
apply. The neighboring name-match lane is now explicit too:
|
||
selector-`0x61` body `0x00472700` scans `0x0062be10` for a company-name match against the caller
|
||
string at `[payload+0x08]` and then either submits selector `0x62` with the original payload or
|
||
falls back to the paired error-style `0x21` branch. The next registered band around selectors
|
||
`0x1c..0x5d` is tighter now too. Selector-adjacent helpers `0x00470ed0` and `0x00470fa0`
|
||
are the paired global preset passes beneath that strip: both walk the guarded named-profile
|
||
table `0x006ceb9c`, add opposite signed integer presets into qword field `[profile+0x154]`
|
||
through `0x00476050`, then walk `0x0062be10` and write opposite preset
|
||
scalars into metric id `0x0d` through `0x0042a040`. Above them, selectors `0x1d`, `0x1f`,
|
||
`0x21`, `0x23`, `0x25`, `0x27`, `0x29`, `0x2b`, `0x2d`, `0x2f`, `0x31`, `0x33`, `0x35`,
|
||
`0x37`, and `0x39` are now explicit token-staging forwarders into selectors `0x1e`, `0x20`,
|
||
`0x22`, `0x24`, `0x26`, `0x28`, `0x2a`, `0x2c`, `0x2e`, `0x30`, `0x32`, `0x34`, `0x36`,
|
||
`0x38`, and `0x3a`. The next live-train strip is also grounded: selectors `0x3b`, `0x3d`,
|
||
`0x3f`, `0x41`, and `0x43` resolve live train ids from `0x006cfcbc`, stage the current token,
|
||
and republish into selectors `0x3c`, `0x3e`, `0x40`, `0x42`, and `0x44`; selectors `0x3c`,
|
||
`0x3e`, and `0x40` then dispatch directly into `0x004abd70`, `0x004b2f00`, and `0x004b3000`,
|
||
while selector `0x42` is the heavier train-adjunct branch through `0x004b2b70`,
|
||
`0x004b3160`, `0x004b2c10`, `0x004a9460`, and `0x004ab980`. The prompt or bitmap cluster is
|
||
tighter too: selector `0x48` consumes one 12-byte record, either marks the current-session bit
|
||
directly or opens localized prompt `0x0b81` through `0x00469a50` and callback `0x004719c0`,
|
||
and then republishes selector `0x49`; selector `0x49` turns that 12-byte result into one keyed
|
||
bitset object and republishes selector `0x47`; selector `0x47` consumes the resulting ten-slot
|
||
masks and drops straight into `0x004eb230` plus
|
||
`shell_resolve_merger_vote_and_commit_outcome` `0x004ebd10`. The same pattern repeats one
|
||
size smaller for selectors `0x4c`, `0x4d`, and `0x4b`: selector `0x4c` consumes one 10-byte
|
||
record, either marks the current-session bit directly or opens localized prompt `0x0b82`
|
||
through `0x00469a50` and callback `0x00471d50`, selector `0x4d` folds that 10-byte result into
|
||
the keyed bitset object, and selector `0x4b` turns the resulting masks into one ten-dword cache
|
||
setter at `0x0050c4e0` rooted at `0x006d1a08` plus the paired outcome resolver
|
||
`0x0050c940`. The direct setter strip after that is explicit too: selector `0x4f` republishes
|
||
selector `0x6f` when the live session object exists and dataset
|
||
gate `0x006cd91c` is clear, selector `0x50` copies `[dataset+0x9058]` into `[dataset+0x9054]`,
|
||
selector `0x51` derives one small session-status code and either republishes selector `0x52` or
|
||
shell control `0x109`, selectors `0x55`, `0x56`, and `0x57` directly store dataset field
|
||
`0x9860`, a `0x006ceb9c` inline name, and guard field `[entry+0x1e1]`, selector `0x58` flushes
|
||
the deferred 16-slot named-profile clear queue `[dataset+0x9864..+0x9873]`, selector `0x59`
|
||
derives one roster or capacity status and republishes selector `0x5a`, selector `0x5b` is
|
||
another token-staging forwarder into selector `0x5c`, selector `0x5c` gates a
|
||
`0x00493960` dispatch plus optional local `0x0046f870` apply, and selector `0x5d` validates
|
||
one payload string before republishing selector `0x5e`. The next registered band around selectors
|
||
`0x5e..0x7d` is tighter too. Selector `0x5e` updates the named-profile side table
|
||
`0x006ceb9c`, mirrors the same string into the resolved live session object, and when the
|
||
session-side guard is active hashes that string back into `[session+0x48]` and dataset field
|
||
`[0x006cd8d8+0x8f48]`; selector `0x5f` then stages the current year-derived token and republishes
|
||
into selector `0x60`, whose body writes one guarded byte field into the same `0x006ceb9c` entry
|
||
family. The `0x62..0x64` strip forms the same kind of pair over `0x0062be10`: selector `0x62`
|
||
copies one fixed `0x32`-byte band into the matched company entry, selector `0x63` rejects
|
||
duplicate field-`0x37` values before forwarding, and selector `0x64` applies that same dword
|
||
field directly into the matched entry or one live fallback owner. The receive-side correction is
|
||
explicit now too: selector `0x6b` is the tiny local metric-apply wrapper
|
||
`0x00472db0 -> 0x0046f870`, selector `0x6c` is the separate train-record wrapper
|
||
`0x00472dc0 -> 0x0046d780`, selector `0x6d` formats localized status `0x0f4e` into the grounded
|
||
world outcome-text buffer `[world+0x4b47]`, and selector `0x6e` walks the current keyed bucket
|
||
under `[session+0x2580]` and marks the first matching companion record by payload hash. The
|
||
later wrappers are cleaner too: selectors `0x71`, `0x73`, `0x75`, `0x77`, `0x79`, `0x7b`, and
|
||
`0x7d` are all token-staging forwarders into selectors `0x72`, `0x74`, `0x76`, `0x78`, `0x7a`,
|
||
`0x7c`, and `0x7e`. Beneath them, selector `0x72` is the heavier counted live-world apply path
|
||
over `0x0062b2fc`, `0x0062b26c`, and `0x0062bae0`; selector `0x74` dispatches a resolved
|
||
company-entry id into `0x0062b26c` under the small latch `0x006ce9a8`; selectors `0x76`,
|
||
`0x7a`, and `0x7c` resolve one company-style entry and then tail into narrower local handlers;
|
||
and selector `0x78` is the broader projection-or-notify body over `0x0044b160`, `0x00538e00`,
|
||
and the local-session refresh strip. The next adjacent owner `0x0046e5c0` is broader but still
|
||
belongs to the same structural neighborhood: in mode `1` it serializes a dual-collection metric
|
||
blob from `0x0062be10` and `0x006ceb9c`, writing the two row counts into local header bytes and
|
||
then packing one `0x24`-stride band plus one `0x2c`-stride band behind a `0x10`-byte header; the
|
||
opposite branch starts validating and applying those packed metrics back into live entries. So
|
||
that first named block is no longer just a string-name registry; it already includes a real typed
|
||
static-record family beneath the preview dataset, and it now sits directly beside one broader
|
||
fixed-record callback-successor strip. Right after the selector-`0x71` batch publisher, the local
|
||
`0x005ce418` fixed-record family becomes explicit: `0x00473ce0` constructs one `0x187`-byte
|
||
record from two copied strings, shell-profile bytes `[0x006cec78+0x0d/+0x0f/+0x11]`, owner field
|
||
`[this+0x04]`, and monotonic sequence dword `[this+0x14]` seeded from `0x006cea48`;
|
||
`0x00473dc0`, `0x00473e70`, `0x00473ee0`, and `0x00473f30` are the max-sequence, min-sequence,
|
||
previous-sequence, and next-sequence queries over the same live collection; `0x00473e20` is the
|
||
boolean scan for any inactive record with a nonzero owner dword; and `0x00473f80` is the real
|
||
allocator or constructor owner, trimming the collection down to `0x19` entries, allocating one
|
||
live record through `0x00518900`, and then dispatching the heavier constructor. So the callback
|
||
registry now leads directly into a concrete preview-side fixed-record collection, not into
|
||
another anonymous transport helper band. The broader snapshot/apply owner still sits over the
|
||
same multiplayer collection state. In parallel,
|
||
`multiplayer_register_session_event_callbacks` allocates and registers the separate session-event
|
||
transport object at `0x006cd970`. The shell-side bridge into that deeper transport cadence is now
|
||
tighter: `multiplayer_window_service_loop` and neighboring reset or initializer branches call
|
||
`multiplayer_flush_session_event_transport`, which forces one status flush and then drops into
|
||
`multiplayer_transport_flush_and_maybe_shutdown`. That wrapper in turn runs
|
||
`multiplayer_transport_service_frame`, the recurring pump that services one worker step through
|
||
`multiplayer_transport_service_worker_once`, sweeps the transport-owned callback tables and field
|
||
caches through `multiplayer_transport_service_route_callback_tables`, services both the auxiliary
|
||
status route and the current live route through
|
||
`multiplayer_transport_service_status_and_live_routes`, and then descends one layer farther into
|
||
the shared GameSpy route helper `multiplayer_gamespy_route_service_frame` at `0x58d040`. The
|
||
transport also owns a separate selector-view sidecar beneath that route cadence.
|
||
The reset and teardown side of that same outer transport is tighter now too. The bounded local
|
||
callback-table attach validator `0x58d7e0` first clears selector registrations through
|
||
`multiplayer_transport_reset_selector_tables`, then ensures the keyed selector-view store, and
|
||
only then rebuilds the surrounding selector-view runtime through the auxiliary sidecar ensure
|
||
owner `0x593fe0` before returning success. That sidecar seam is now explicit too:
|
||
`0x593db0` hashes the ordered status-string pair `(entry, entry+0x40)` modulo the caller
|
||
divisor, `0x593e40` compares that same ordered pair for keyed equality, `0x593ef0` is a real
|
||
no-op release callback, and `0x593fb0` is the worker callback that resolves one selector-view
|
||
entry through `0x594b40` and commits probe success through `0x593f00`. One layer lower,
|
||
`0x58d810` is the common
|
||
runtime-reset strip that clears selector slots, releases the
|
||
keyed selector-view store, clears the auxiliary selector-view sidecar rooted at `[transport+0xac8]`,
|
||
and forwards into the remaining route-mode-sensitive selector cleanup. That lower strip is no
|
||
longer opaque either: `0x5955a0` is the bulk three-slot selector reset plus shared probe-marker
|
||
clear, `0x594080` is the auxiliary selector-view sidecar release when the keyed store is unbound,
|
||
and `0x595820` is the forced route-mode-`0` cleanup that preserves selector slot `2` ownership
|
||
across the reset. The next owner above that strip is now explicit too: `0x58de50` either latches
|
||
deferred reset at `[transport+0x1edc]`
|
||
while outstanding work remains or, once the transport is quiescent, clears `[transport+0xab0]`,
|
||
releases the live worker/runtime band through `0x58d860`, and immediately pumps one more service
|
||
step through `0x58d8d0(-1)`. The final destroy tail `0x58d8a0` then tears down queued work,
|
||
active opcode records, the Winsock guard, and the remaining owned runtime strings before freeing
|
||
the transport body. The constructor-side and shutdown-side owners are explicit now too.
|
||
`0x58dc50` enters the Winsock `1.1` guard, allocates and zeroes the full `0x1ee4`-byte transport
|
||
body, seeds local IPv4 `[transport+0x58]`, constructs the transient work-record collection,
|
||
copies one caller-supplied `0x70`-byte callback-vector/state seed block into
|
||
`[transport+0x178c..+0x17f8]`, then constructs the active opcode-record collection at
|
||
`[transport+0x17fc]` through `0x592750` and the shared plus slot-local selector callback-name stores at `[transport+0x18a8]`,
|
||
`[transport+0x1890..+0x1898]`, `[transport+0x189c..+0x18a4]`, and `[transport+0x18ac..+0x18b4]`
|
||
through `0x5966f0` before the object is considered live. The later callback-slot wrappers rooted
|
||
at `[transport+0x178c]`, `[transport+0x17c0]`, `[transport+0x17c4]`, and the sibling callback
|
||
contexts near `[transport+0x17f8]` now make that copied band read as the constructor-side
|
||
callback vector and companion state, not as a generic label blob. The paired runtime release strip
|
||
`0x58d860` tears the worker down, clears the configured transport latches, releases the transient
|
||
work-record side, reruns the selector/callback reset block, and clears `[transport+0x180c]`,
|
||
byte `[transport+0x1810]`, and deferred-reset latch `[transport+0x1edc]`. Above that, `0x58de90`
|
||
is the actual shutdown owner: it preserves the leading callback-vector dword at
|
||
`[transport+0x178c]` across `0x58de50`, disconnects the live route state, and then either marks
|
||
deferred-close flag `[transport+0x1ee0]` while work remains or falls straight into final destroy
|
||
owner `0x58d8a0`, which also releases the selector callback-name store family through `0x5967f0`.
|
||
The adjacent route-mode text side is tighter too. `0x58db70` is the small selector-text helper
|
||
that formats one caller mode string through the shared stack builder and sends it through
|
||
selector slot `3` or `4`, while the broader owner `0x58dfb0` sits above it and derives the live
|
||
route-mode status from transport latches, refreshes the mode-string band
|
||
`[transport+0xad0/+0xadc]`, stores companion state at `[transport+0xb34/+0xb40/+0xb44/+0xb54]`,
|
||
and then either submits the richer selector-text route request through `0x593c40` or falls back
|
||
to the probe/enqueue path `0x592a70`. That same owner also participates in the current
|
||
callback-table attach validation through `0x58d7e0`, with disconnect fallback `0x58d830`, and
|
||
reuses the same immediate-drain context-id wait loop as `0x58df20`.
|
||
The selector-status side underneath those owners is tighter now too. `0x5951f0` is not just a
|
||
generic transport pump: it builds up to three transient selector-mode strings from selector
|
||
presence lanes `[transport+0x384..+0x398]` and status latches `[transport+0xb40/+0xb44/+0xb54]`
|
||
plus `[transport+0x180c]`, appending the letters `s`, `r`, `h`, `g`, and `a` into three local
|
||
string bands and then hashing those bands through `0x594c40`. It only emits the matching
|
||
`SETCHANKEY`/`SETCKEY` lines through `0x58ece0` when the hashed mode state changed versus cached
|
||
masks `[transport+0x99c/+0x9a0/+0x9a4]`. The adjacent cleanup sibling `0x5965d0` is concrete
|
||
too: it optionally releases the status route through `0x597350`, clears the `h/g/r` latch band
|
||
`[transport+0xb40/+0xb44/+0xb54]`, and then reruns `0x5951f0` so the emitted selector-mode text
|
||
stays consistent with the cleared route state.
|
||
The adjacent selector and callback-table owners are tighter now too. `0x58e100` is the fixed
|
||
selector-`2` status publisher: it only runs when transport latches `[+0x60]`, `[+0x48]`,
|
||
`[+0x398]`, and `[+0xb40]` are all live, falls back to `0x005c87a8` when the caller token is
|
||
null, formats one line from the caller token plus `[transport+0x282]` and the current route IPv4
|
||
at `[transport+0x54]`, sends that line through selector `2`, sets `[transport+0xb44] = 1`, and
|
||
then either nudges route-mode helper `0x595650(5)` or falls into the auxiliary `0x597350 /
|
||
0x597370` branch. The adjacent dispatcher `0x596fd0` is now explicit too: it only exposes its
|
||
built-in status-field strip when `[transport+0x398]` is live and the `[transport+0xb44]` or
|
||
`[transport+0xb38]` gate allows it, then appends internal text `[transport+0x79c]`, decimal
|
||
state from `[transport+0xac0]`, `[transport+0xb48]`, and `[transport+0xb3c]`, one static
|
||
fallback token, or the boolean form of `[transport+0xb4c]`; outside those built-in ids it
|
||
dispatches into the local status-route callback-vector lanes or falls back to the owner callback
|
||
at `[transport+0x17dc]` with context `[transport+0x17f8]`. One level earlier, `0x58dce0` is now the setup-side sibling:
|
||
it copies the local name into `[transport+0x60]`, seeds the two status-text bands at
|
||
`[transport+0xad0/+0xadc]`, preserves those descriptor triplets only when selector-view result
|
||
slot `[transport+0xab0]` is already live, copies the route-label buffers at
|
||
`[transport+0xb58/+0xb78]`, clears route-label state bytes `[transport+0xb77/+0xb97]`, stores
|
||
callback-table metadata at `[transport+0xb98/+0xb9c]`, rebuilds the route callback-table family
|
||
through `0x596090`, and on success refreshes the current status text at `[transport+0xaf4]`
|
||
before rerunning `0x5965d0(1)`. The same local pass also makes the negative boundary tighter:
|
||
setup still touches the surrounding callback-table and replay-band fields without ever seeding a
|
||
nonzero value into `[transport+0x1778]`, so the local static seam is closed here: no ordinary
|
||
constructor, reset, service, or callback-table owner in `RT3.exe` currently writes that sidecar,
|
||
and the latest full-binary disassembly scan still finds only the `0x595bc0` read while the
|
||
neighboring lifecycle fields `[transport+0x177c/+0x1780/+0x1784/+0x178c/+0x17f8]` do show normal
|
||
constructor/reset/use sites. The producer therefore still looks upstream of this local cluster.
|
||
Beside it, `0x58e200` is the broader callback-table attach or refresh owner:
|
||
it seeds one immediate-drain context id, conditionally copies the local name into `[transport+0x04]`,
|
||
clears `[transport]`, `[transport+0x48]`, and `[transport+0x1edc]`, stores follow-on callback
|
||
fields `[+0x4c/+0x5c]`, sets `[transport+0x44] = 1`, attaches the descriptor block through
|
||
`0x593650`, whose worker-side callback pair is now explicit too: `0x593610` republishes the
|
||
staged work-record triplet through opcode-`5` binding enqueue helper `0x592c40`, while
|
||
`0x593630` stores the incoming route scalar at `[transport+0x54]` and then forwards the caller
|
||
text/buffer plus `[transport+0x5c]` into `0x597780`, the fixed-template encoded route-scalar
|
||
formatter beneath that attach path. On attach failure the outer owner falls through `0x58d860`,
|
||
dispatches the resolved binding through `0x592a40`, and optionally reuses the same
|
||
immediate-drain wait loop as the neighboring transport submit owners.
|
||
The direct selector-text seam under those owners is explicit now too. `0x58e630` is just the
|
||
current-local-name helper: it returns `[transport+0x36c]` while the worker root is live and
|
||
otherwise falls back to `0x005c87a8`. Above that, `0x58e7e0` is the real direct selector-text
|
||
variant publisher under `0x58d9e0`: it formats one line through `[transport+0x1c]` as
|
||
`PRIVMSG %s :%s`, action-prefixed `PRIVMSG`, `NOTICE %s :%s`, `UTM %s :%s`, or `ATM %s :%s`
|
||
depending on caller mode `0..4`, then probes the matching registered-name entry through
|
||
`0x59d7d0` and emits opcode `4` through `0x59b790` when that entry exists. The plain sibling
|
||
branch is explicit now too: `0x58ea60` formats the same five selector-text variants through
|
||
`[transport+0x1c]` but stops after appending the text line, without probing `0x59d7d0` or
|
||
emitting opcode `4`. The registered-name fastpath side is tighter at the same time:
|
||
`0x58eb10` is just the null-worker guard above
|
||
`multiplayer_transport_find_registered_name_entry_and_optionally_return_bucket` `0x59df60`,
|
||
which walks the worker-owned registered-name store at `[worker+0x548]` and can return both the
|
||
matched entry and its owning bucket pointer. One level earlier, `0x58e510` is the broader
|
||
fastpath owner under `0x593d60`: when the caller text is null, empty, too long, or
|
||
casefold-equal to current local name `[transport+0x36c]`, it takes the immediate callback-style
|
||
opcode-`0x1b` path through `0x598060 -> 0x59b790`; otherwise it formats one local-name command
|
||
through `[transport+0x1c]` using format `0x005e1c64`, packages that request through `0x598280`,
|
||
and on either branch reuses the same `0x58e3f0 / Sleep(10) / 0x58e370` immediate-drain loop when
|
||
requested.
|
||
The route-request side beneath those owners is explicit too. `0x58e720` is the common submit root
|
||
under `0x593bb0` and `0x593c40`: it formats one local route line through `[transport+0x1c]`,
|
||
packages the caller route payload and callback triplet into a type-`1` transient request through
|
||
`0x5981b0`, refreshes the registered-name side through `0x59d5b0`, and when requested loops
|
||
through `0x58e3f0`, `Sleep(10)`, and `0x58e370` until the request completes. That registered-name
|
||
refresh path is tighter too: `0x59d5b0` builds one zeroed `0x1e0`-byte stub from the caller
|
||
string and appends it into the flat registered-name vector `[transport+0x54c]` through the
|
||
shared `generic_vector_push_back` helper `0x59e4d0`, while the smaller sibling `0x58e7a0` sits
|
||
beside it as the selector-slot text and registered-name removal path. The selector-text submit
|
||
owner itself is explicit now too: `0x593c40` is not just a generic “route request” wrapper. It
|
||
rejects null, empty, or `>= 0x101`-byte text, falls back to fixed sample `0x005c87a8` when the
|
||
caller sample pointer is null, allocates a type-`2` transient work record through `0x5934e0`,
|
||
stores the selector id in work field `+0x1c`, refreshes selector-side naming through
|
||
`0x59fc80/0x595140`, and only then hands the request into `0x58e720` with callback `0x593bb0`.
|
||
under `0x5954b0` and formats one selector-slot line before removing the corresponding
|
||
registered-name entry through `0x59d760`. The selector callback-name side under the same reset
|
||
tail is explicit now too: `0x596900` first walks the shared selector callback-name store at
|
||
`[transport+0x18a8]` through the hashed-table reverse walk `0x58fa40` and callback `0x596840`,
|
||
pruning names that no longer correspond to any live selector-view entry or any of the three
|
||
slot-specific callback stores rooted at `[transport+0x1890/+0x1894/+0x1898]`. It then services
|
||
the slot-local callback collections at `[transport+0x18ac/+0x18b0/+0x18b4]`, clearing inactive
|
||
slots through the hashed-table clear helper `0x58fac0` and otherwise using `0x58fa40` plus
|
||
callback `0x5968b0` to prune any shared names whose current selector-view entry no longer owns
|
||
the current slot.
|
||
The drain side itself is tighter too. `0x58e3f0` no longer just “notifies a small observer
|
||
table”: its local child `0x58e310` walks the global `(command-name, callback)` table at
|
||
`0x00629d58/0x00629d5c`, compares the decoded command token at `[line+0x14]` through the shared
|
||
casefolded compare `0x5a57cf`, and on a match invokes the paired callback with the current
|
||
decoded-line band in `EDX` and the transport pointer in `ECX`.
|
||
`multiplayer_transport_ensure_selector_view_store` allocates the keyed selector-view store at
|
||
`[transport+0xab4]`, `multiplayer_transport_find_selector_view_entry_by_name` resolves entries
|
||
from that store, `multiplayer_transport_upsert_selector_name_entry` marks per-slot activity and
|
||
flags inside each entry, and `multiplayer_transport_mark_selector_slot_views_dirty` plus
|
||
`multiplayer_transport_reset_selector_view_entry_runtime_state` manage the dirty or refresh fields
|
||
at `+0xa0`, `+0xa4`, and `+0xa8`. That selector-view maintenance path is now split more cleanly
|
||
too. The recurring owner is `multiplayer_transport_service_selector_view_refresh_cycle`, which
|
||
first runs the fast deferred-probe lane:
|
||
`multiplayer_transport_collect_refreshable_selector_view_entries` walks the store through
|
||
`multiplayer_transport_filter_insert_refreshable_selector_view_entry`, which now shows that
|
||
`[entry+0x64]` is not a generic flag bucket but the third selector-slot flag word, parallel to
|
||
`[entry+0x5c]` and `[entry+0x60]`. In that collector, the `g` and `a` mode-letter bits produced by
|
||
`multiplayer_transport_parse_selector_mode_letters` become mask `0x0c` in the slot-local flag
|
||
words, and any third-slot entry carrying those bits at `[entry+0x64]` is excluded from the
|
||
refreshable set. Eligible entries then pass slot-aware retry timing on `[entry+0x68]`,
|
||
`[entry+0x6c]`, `[entry+0x78]`, and `[entry+0x7c]`, after which the service loop schedules refresh
|
||
probes through `multiplayer_transport_schedule_selector_view_entry_refresh_probe`. That fast lane
|
||
is narrower now too: the entry-side match key `[entry+0x50]` is no longer just an opaque request
|
||
field. The profile-key callback lanes feed
|
||
`multiplayer_transport_parse_selector_view_probe_marker`, which decodes one local `X%sX|%d` marker
|
||
into a probe request id plus displayed version/build integer, and
|
||
`multiplayer_transport_arm_selector_view_probe_tracking` stores those into `[entry+0x50]` and
|
||
`[entry+0x54]` before arming the live probe gate at `[entry+0x58]`. The current-selector callback
|
||
root at `0x59f8b0` is now bounded as well: it resolves and upserts the active selector name,
|
||
optionally reuses a cached `username` marker to arm probe tracking immediately, then submits the
|
||
same profile-key bundle with selector context and forwards that selector through callback slot
|
||
`17`, with the status-route side able to force route-mode transitions `2 -> 3 -> 4` afterward. One
|
||
layer lower, `multiplayer_transport_handle_profile_key_query_result` at `0x596970` now bounds the
|
||
per-key result path itself. It treats `username` as the probe-marker field, `b_flags` as the
|
||
selector mode-letter field, and `(END)` as a real sentinel that publishes a zeroed slot-`22`
|
||
payload instead of a marker pair. The same helper also hashes the selector-name, key-name, and
|
||
resolved value text back into the caller table, so the profile-key bundle now looks like a real
|
||
bounded handoff rather than an anonymous callback cloud. The owner above it is tighter too:
|
||
`0x596da0` is now the real per-slot bundle submitter, not just a vague wrapper. For one active
|
||
selector slot it first collects the slot-local key list from `[transport+0x1890+slot*4]` and
|
||
issues the synchronous `GETKEY` query through `0x58ec50`, using either the caller override or
|
||
the slot name at `[transport+0x80+slot*0x101]`. When no override is supplied it then collects a
|
||
second list from `[transport+0x189c+slot*4]`, conditionally adds built-in `username` and
|
||
`b_flags`, and sends the larger channel-key pair list through `0x58ef20` with callback
|
||
`0x596ce0`. That second-stage callback is now explicit too: the default-slot branch resolves the
|
||
returned selector name back into one slot and then walks one selector-name pair array through
|
||
`0x596b90` using the shared fallback text at `0x00629d54`, while the selector-name-override
|
||
branch uses the explicit override name and walks one parallel pair array through the same lower
|
||
helper with publication enabled. The thin wrappers above the owner are now grounded accordingly:
|
||
`0x596fa0` forwards one selector-name override, while `0x596fc0` forces the slot's fixed name.
|
||
The adjacent rename helper `0x596c10` now also makes the selector callback-name
|
||
maintenance side explicit: after a selector rename it walks the shared and slot-local callback
|
||
stores and rewrites any callback-name entry whose primary text still matches the old selector
|
||
name. One layer above the per-key helper, `0x596b10` now reads as the shared built-in key sweep:
|
||
it tries the same result helper `0x596970` across the shared store `[transport+0x18a8]` and the
|
||
three slot-local callback-name stores, stopping on the first success and then publishing callback
|
||
slot `27` through `0x5931b0`. The deferred callback shim
|
||
`multiplayer_transport_dispatch_selector_view_refresh_probe_result` then walks the keyed store
|
||
through `multiplayer_transport_finish_selector_view_refresh_probe_if_matching`, which only
|
||
completes entries whose pending latch `[entry+0x74]` is still armed and whose parsed marker
|
||
request id `[entry+0x50]` matches the finished request. A failed result `-1` clears the pending
|
||
latch and increments the consecutive-failure counter at `[entry+0x7c]`. A nonfailure result clears
|
||
the pending latch, increments the success generation at `[entry+0x78]` and total-success count
|
||
`[entry+0x98]`, clears `[entry+0x7c]`, stamps the last-success tick at `[entry+0x6c]`, appends the
|
||
returned sample into the short rolling history at `[entry+0x84..]`, grows the bounded sample-count
|
||
`[entry+0x94]` up to four, computes the current average into `[entry+0x80]`, and then publishes
|
||
that averaged `ms` sample through `multiplayer_transport_enqueue_callback_slot24_record`. So the
|
||
publication boundary is explicit and the request-id ownership is explicit: `[entry+0x80]` now
|
||
reads as the averaged millisecond probe sample and `[entry+0x54]` as the displayed version/build
|
||
companion integer. The adjacent route-callback side is tighter too, but it is now kept separate:
|
||
the staged route-callback path at `0x5958e0` and the later compatibility gate at
|
||
`multiplayer_transport_route_binding_matches_route_callback_descriptor_tuple` `0x595d00` operate
|
||
on a compact GameSpy-style server or route descriptor family with a primary endpoint tuple at
|
||
`[descriptor+0x00]/[+0x04]`, an optional secondary endpoint tuple at `[descriptor+0x08]/[+0x0c]`,
|
||
string-key lookups such as `hostname` and `gamever`, and numeric-key lookups such as
|
||
`numplayers`, `numservers`, `numwaiting`, and `gsi_am_rating`. The route-binding side uses that
|
||
descriptor family's primary dword and host-order port plus the optional secondary tuple against
|
||
route-binding offsets `+0x54/+0x58` and route word `+0x30`. The capacity-side gate above it is
|
||
tighter now too: `0x595d60` first tries that tuple match against the current bound route at
|
||
`[transport+0x1ecc]`, and on success immediately falls into
|
||
`multiplayer_transport_invoke_bound_route_callback_if_present` `0x592710`, which simply calls the
|
||
bound route's optional callback slot `[binding+0x14]` with companion argument `[binding+0x18]`.
|
||
When the tuple does not match, the same gate instead compares descriptor fields `maxplayers` and
|
||
`numplayers`; only a descriptor with spare capacity reaches that same callback handoff. The owner
|
||
directly above that gate is explicit now too: `0x595dc0` first rejects when staged-route busy
|
||
latch `[transport+0x1e8c]` or selector-slot object `[transport+0x38c]` is live, then reuses the
|
||
same tuple-or-capacity result from `0x595d60`; only a positive result lets it refresh selector
|
||
state through `0x5973b0`, reset selector slot `2` through `0x5954b0`, stage the descriptor
|
||
through `0x5958e0`, and finally drop route mode back to `0` through `0x595650` when that staging
|
||
path fails. That makes the seam read as one bounded ladder instead of three isolated helpers:
|
||
descriptor tuple match or spare-capacity gate, optional bound-route callback handoff, then the
|
||
busy-latch-screened route-transition owner above it. Current evidence now also closes the clone
|
||
side of that staged path: `0x596270` copies the first nine
|
||
dwords of the source staged callback payload, clears the intrusive next-link, and then replays
|
||
the source keyed-property list through shim `0x596260`, which simply reinserts each owned
|
||
`(key,value)` pair into the clone's property store through `0x58d0f0`, before the clone is
|
||
stored at `[transport+0xb50]` for later callback publication. Current
|
||
evidence still does not prove
|
||
that descriptor tuple is the same field family as the selector-view marker companion integer at
|
||
`[entry+0x54]`. The higher compact decode owners are tighter now too: `0x5907d0` is the
|
||
route-callback receive owner for one fresh compact payload, with a concrete return split of `0`
|
||
on malformed or undersized payloads, `-1` on the special global descriptor, and the consumed byte
|
||
count on successful decode through `0x58ff60`; `0x590d00` is the keyed upsert-by-primary-endpoint
|
||
lane that reuses an existing descriptor when possible, allocates only on miss, decodes in mode
|
||
`0`, and then publishes owner callback mode `1` before returning `0/4/5` for success, decode
|
||
failure, or special-global rejection. The route-callback-table runtime above that decode side is tighter now too:
|
||
`multiplayer_transport_route_callback_table_construct` `0x5905e0` seeds one transport-owned
|
||
table block, `multiplayer_transport_route_callback_table_release_decoded_schema_dictionary`
|
||
`0x5906f0` tears down the decoded schema dictionary rooted at `[this+0x08]`,
|
||
`multiplayer_route_callback_runtime_acquire_shared_string_copy` `0x590540` and
|
||
`multiplayer_route_callback_runtime_release_shared_string_copy` `0x5905a0` now bound the shared
|
||
string pool used by that decoded schema, and the higher bring-up owner `0x596090` now clearly
|
||
splits between `[transport+0xba4]` with owner callback `0x595a40`, the local field-cache family
|
||
`[transport+0x1724]` seeded through `0x5a08f0/0x595b60` with fixed stem `0x00629d50`, and
|
||
`[transport+0x1164]` with owner callback `0x595bc0`. The same constructor also builds the
|
||
`gsi_am_rating` primary-endpoint table `[transport+0x18bc]` from local transport name
|
||
`[transport+0x60]` plus suffix `0x005dccfc` under callback `0x595e10`, and seeds the queued
|
||
descriptor family `[transport+0x1e7c]` through `0x5a08f0/0x595f70` with fixed stem
|
||
`0x00629d54`, while
|
||
`multiplayer_transport_route_callback_table_service_receive_decode_state_machine` `0x5908c0`
|
||
is the current live receive/decode state machine serviced by `0x591290` in table states `2/3`.
|
||
The callback-owner mode split above that runtime is now explicit too: append-notify `0x590370`
|
||
publishes mode `0`, compact upsert `0x590d00` publishes mode `1`, remove-notify `0x590430`
|
||
publishes mode `2`, and the live receive/decode path `0x5908c0` publishes modes `6`, `5`, and
|
||
`3`.
|
||
The route-handle lifecycle above that decode path is tighter now too: `0x590740` cleanly resets
|
||
one table's live route plus decode-side runtime without destroying the outer object; `0x5907a0`
|
||
is the broader destroy path that also releases the active descriptor collection; `0x590ed0`
|
||
now reads as the real open-and-request owner rather than a generic connect wrapper: it bounds
|
||
both caller route-name strings to `0x100` bytes, stores the caller route-mode or flag dword into
|
||
`[this+0x5b4]`, seeds one staged request with fixed selector bytes `2/1/3`, appends
|
||
`[this+0x4a8]`, the route-label buffers `[this+0x0c]` and `[this+0x2c]`, the local label band
|
||
`[this+0x6c]`, the caller route strings, the converted host-order route scalar, and two optional
|
||
flag-driven branches, then sends that request through the live route handle at `[this+0x4a0]`
|
||
before seeding state `3` and the staged receive buffer; `0x5911e0` is the state-`2/3`
|
||
live-socket service wrapper, and it is tighter now than a generic feed loop: once one full frame
|
||
is buffered it switches on subtype byte `[frame+0x02]`, using subtype `1` for
|
||
`0x590c00` schema-dictionary rebuild, subtype `2` for `0x590d00` compact-descriptor upsert,
|
||
subtype `3` for raw payload forward through `0x5b3216`, and subtype `4` for `0x590cd0`
|
||
descriptor removal by primary endpoint before compacting the tail back to the front of the
|
||
receive buffer; `0x5912c0` is the
|
||
one-shot send-with-reopen-retry helper; and `0x590ea0` is the shared disconnect publication and
|
||
reset tail. The recurring service helper `0x591290` is tighter too: it now first clears the
|
||
staged intrusive descriptor list through `0x590490` before entering the state-driven seed-or-
|
||
receive branch. The upstream owners are tighter too: `0x5962e0` is now the field-subscription
|
||
route-table opener above `[transport+0xba4]`: it clears prior field-subscription runtime,
|
||
releases any live route on that table, builds the route label from either the optional suffix
|
||
path or the default stem block, seeds the field-cache family `[transport+0x1724]` with fixed key
|
||
ids `1` and `0x0b`, appends per-field selector names from `0x00629958`, and then opens the live
|
||
route in mode `4` through `0x590ed0`. Success seeds cached progress percentage
|
||
`[transport+0x1774] = 1` and immediately enqueues one mode-`3` field snapshot through `0x592b50`;
|
||
failure falls back through the same clear path. `0x596530` is the `gsi_am_rating` reopen
|
||
path above `[transport+0x18bc]`, and that owner is tighter now too: when precondition
|
||
`[transport+0xba0]` is clear it does not even attempt the reopen and instead stamps
|
||
`[transport+0x1ed4] = 1`; otherwise it resets the am-rating route family, clears the callback
|
||
table rooted at `[transport+0x18bc]`, tries `0x590ed0(mode 4)` from stored route label
|
||
`[transport+0x1ed0]`, and only on success sets `[transport+0x1ec4] = 1` while clearing
|
||
`[transport+0x1ed4]`. On that latter
|
||
branch, `0x590dc0` is now bounded as the
|
||
state-`0` raw-endpoint seed pass over the live route handle, repeatedly pulling endpoint tuples
|
||
through `0x58bc7e` record type `0x1f3` before stamping descriptor flag byte `0x15` with `0x11`.
|
||
That makes the remaining source-flag meaning narrower too: current evidence now supports reading
|
||
byte-`0x15` bit `0x1` as a primary-endpoint-seed or endpoint-only marker. In the `gsi_am_rating`
|
||
dispatcher, clear-bit descriptors can take the richer direct transition lane, while set-bit
|
||
descriptors are staged through the queued enrichment path and still suppress that direct
|
||
transition even after the ready bit arrives. The later modes in `0x595e10` are tighter now too:
|
||
mode `3` forces route mode `2` only when the primary-endpoint table is empty, mode `4` stamps
|
||
`[transport+0x1ed4] = 1` and then picks route mode `1` or `3` based on whether deferred
|
||
descriptor pointer `[transport+0x1ed8]` is null, and mode `5` mirrors staged companion dword
|
||
`[transport+0x490]` into both `[transport+0x54]` and `[transport+0x1724+0x24]`.
|
||
The adjacent capacity-descriptor side is tighter too: `0x595bc0` is now clearly the owner
|
||
callback for the capacity-descriptor route callback table rooted at `[transport+0x1164]`, not a
|
||
direct transport method on `ecx = transport`. The route-callback-table constructor `0x5905e0`
|
||
installs it with owner cookie `transport`, and the live route machinery later invokes it from
|
||
append-notify `0x590370` and decode-service `0x5908c0/0x5911e0` with `ecx = table object`, the
|
||
route descriptor or special decode frame on the stack, and the transport cookie on the stack.
|
||
Inside that callback it still always reads `[transport+0x1778]` first. Modes `3/5` consume that
|
||
sidecar immediately, while live mode `0` first resolves primary IPv4 plus `hostname`,
|
||
`numwaiting`, `maxwaiting`, `numservers`, and `numplayers` through `0x58d1f0`, `0x58d170`, and
|
||
`0x58d6d0`, and only then forwards those live payload lanes together with the same sidecar
|
||
triplet `[+0x0c/+0x10/+0x18]` into opcode-`2` builder `0x592ae0`. So mode `0` is not a
|
||
sidecar-free fallback; it still requires the borrowed sidecar before it can publish the
|
||
populated descriptor block. The replay-linked modes `3/5` instead enqueue an all-zero
|
||
descriptor payload while preserving only that same borrowed callback-wrapper triplet and then
|
||
unlinking the cached record through `0x5933a0`; and its callback modes `1/2/6` are now explicit
|
||
no-op fallthroughs. That sidecar at `[transport+0x1778]` is tighter now too: current evidence says it behaves as one cached pointer
|
||
into the transient work-record family at `[transport+0x1780]`, because every meaningful branch
|
||
in `0x595bc0` reads the same `+0x0c/+0x10/+0x18` metadata triplet and replay modes later consume
|
||
the pointer through `0x5933a0`. The negative result is stronger too: local text-side xrefs still
|
||
show no direct store to `[transport+0x1778]`, and a wider local sweep also failed to show any
|
||
obvious `lea`-based replay-band writer. The transient-request lifecycle tightens that further:
|
||
`0x593330/0x593370/0x593380/0x5934e0/0x5933a0` now fully bound `[transport+0x1780]`, `0x1784`,
|
||
and `0x1788` without ever touching `[transport+0x1778]`, and the neighboring active-opcode reset
|
||
helper `0x5929a0` is likewise scoped only to `[transport+0x17fc]`. A broader constructor and
|
||
teardown pass tightened that further too: `0x596090`, `0x5961b0`, and `0x5962e0` all touch the
|
||
neighboring replay-band fields without ever seeding `[transport+0x1778]`. A full-binary
|
||
literal-offset sweep tightens it further still: the only direct `0x1778` hit in `RT3.exe` is
|
||
the read in `0x595bc0`. One nearby ambiguity is now closed too: the
|
||
mode-`5` mirror path in `0x595a40` and `0x595e10` does not target `[transport+0x1778]`; it
|
||
writes `[transport+0x54]` and mirrors the same staged route companion dword only into queue-side
|
||
slot `[transport+0x1724+0x24]` through `0x005a0940`. So the sidecar writer remains upstream of this
|
||
leaf publisher. Mode `0` is now also tied more cleanly to the generic descriptor append-notify lane
|
||
at `0x590370`, while mode `2` stays outside this helper as the separate
|
||
remove-notify-and-stage path at `0x590430`. The opcode-`2` payload boundary is tighter too:
|
||
`0x592ae0` now grounds that payload
|
||
as a seven-dword block with an owned string slot at `+0x08`, so live mode supplies a populated
|
||
payload while modes `3` and `5` deliberately enqueue an all-zero payload and reuse only
|
||
the wrapper-side sidecar metadata. Those two modes are tighter now too: they are the live
|
||
receive-state owner callbacks emitted by `0x5911e0 -> 0x5908c0`, not loose generic replay
|
||
guesses. So those paths are better read as delayed metadata replays over one cached work record,
|
||
not over a separate anonymous cache blob. The neighboring
|
||
capacity-owner split is tighter now too: `0x595bc0` only stages descriptor records for modes
|
||
`0`, `3`, and `5`; the upstream route-callback-table owner still delivers modes `1`, `2`, and
|
||
`6`, but those are explicit no-ops in this capacity leaf. So the owner wiring itself is no
|
||
longer the open edge; only the upstream sidecar producer remains unresolved. The neighboring
|
||
work queue is tighter too: `0x593330/0x593370/0x593380` now bind `[transport+0x1780]` as the
|
||
construct/clear/destroy owner family and explicitly treat `[transport+0x1784]` and
|
||
`[transport+0x1788]` as the queued-work and completed-work counters beside that collection,
|
||
while `0x5933a0`, `0x5934e0`, and `0x593570` ground the remove, allocate, and completion side
|
||
over that same queue. The completion owner is tighter now too: `0x593570` clears in-flight
|
||
latch `[transport+0x44]`, stores the final attach result in `[transport+0x48]`, stamps current
|
||
route scalar `[transport+0x50]` from `0x58f450` on success, refreshes local name buffer
|
||
`[transport+0x04]` from `0x58e630`, republishes the staged metadata triplet through opcode-`1`
|
||
trigger wrapper `0x592a40`, and only then unlinks the consumed work record. When validation of a
|
||
nominal success fails through `0x58d7e0/0x58d810`, the same owner still replays that callback
|
||
trigger but also arms deferred reset latch `[transport+0x1edc]`. The small sibling
|
||
`0x593400` is tighter too: it is a pure work-record uniqueness predicate over field `+0x0c`. Its caller is
|
||
tighter now too: `0x58d720` is an immediate-drain quiescence gate over one transport context id,
|
||
using `0x593400` for the queued work family at `[transport+0x1780]` and `0x592970` for the
|
||
active opcode-record collection at `[transport+0x17fc]`. The strongest current read is that
|
||
`0x5934c0` seeds that shared drain context id first, then the transport copies it into queued
|
||
work field `+0x0c` and active opcode-record field `+0x14` before the immediate-drain roots wait
|
||
on one shared disappearance test rather than on a vague settle loop. The currently grounded
|
||
roots are `0x58df20`, the neighboring formatted selector-text publish path at `0x58dfb0`, and
|
||
callback-table registration at `0x58e200`. The `0x58df20` owner is tighter now too: it seeds one
|
||
shared context id through `0x5934c0`, gives that same id plus the caller callback wrapper to the
|
||
fastpath `0x593d60`, and only when that fastpath declines does it fall back into `0x593170`
|
||
using `[transport+0x04]` as the worker-side text base. Its immediate-drain tail is the same
|
||
shared quiescence rule as the neighboring owners: pump `0x58d8d0(-1)`, then wait in `0x58d720`
|
||
until the context id disappears from both queued work field `+0x0c` and active opcode-record
|
||
field `+0x14`, then honor deferred-close state if `[transport+0x1ee0]` is armed and
|
||
`[transport+0x1808]` has reached zero. The active-opcode side is tighter too: `0x5927b0`
|
||
now bounds the per-record service-and-retire path, `0x592800` the wider context-or-idle sweep,
|
||
`0x5929a0` the remove-by-opcode-type sweep, and `0x5929f0` the narrower opcode-`3`
|
||
field-snapshot removal keyed by the subscribed callback-pair payload. That also corrects
|
||
`0x595b80`, whose final cleanup is an active field-snapshot purge rather than a queued-work
|
||
drain. The adjacent route-callback descriptor-table lifecycle is tighter too: `0x590410` now
|
||
grounds `[table+0x5bc]` as the staged intrusive descriptor-list head, `0x590430` is the generic
|
||
remove-notify-and-stage lane, `0x590490` releases the staged list, and `0x5904d0` releases the
|
||
active descriptor collection before tearing that staged list down. That also makes the earlier
|
||
`0x5962e0` “release active descriptors” step explicit. The callback-table attach side now constrains the
|
||
same work-record metadata family a little further too: `0x593650` deliberately duplicates its
|
||
first caller metadata dword into both fields `+0x0c` and `+0x10`, while carrying the second
|
||
caller metadata dword in `+0x18`. The lower opcode wrappers are tighter now too: `0x592a40`
|
||
turned out to be the explicit opcode-`1` trigger wrapper whose constructor is a no-op and whose
|
||
active-side service is `0x5913c0`, while `0x592c40` is the real `0x08`-byte explicit opcode-`5`
|
||
binding leaf. The earlier opcode-`4` read was just the table-indexing mistake in `0x5928a0`:
|
||
selector `4` lands on the row at `0x5e2044`, not the row at `0x5e2034`. The producer side is tighter too:
|
||
bound-route requests, selector-text route requests, and the type-`9` text fastpath also stage
|
||
that same triplet through `0x5934e0`, and the fastpath shim `0x593d00` now gives the cleanest
|
||
proof of the callback split by first copying the returned text into the transport-local name
|
||
buffer at `[transport+0x04]`, then only re-emitting the follow-on lane when `+0x10` is nonnull,
|
||
and finally forwarding `(+0x10, +0x18, +0x0c)` into `0x593170` as callback function, callback
|
||
companion, and trailing drain context. So the replay-side triplet is clearly a broader
|
||
transport callback-wrapper family, not one fixed route-only tuple. The nearby
|
||
field-subscription side is tighter too: `0x592b50` now clearly uses `[transport+0x1774]` as a
|
||
cached progress percentage under `[transport+0xba4]`, and `0x5962e0` seeds that percentage to
|
||
`1` just before the first immediate mode-`3` snapshot. The nearby route-callback-table
|
||
lifecycle is tighter now too: `0x596090` is now the real constructor-side owner for the full
|
||
route-callback branch. It constructs `[transport+0xba4]` with callback `0x595a40`, seeds the
|
||
companion field-cache family `[transport+0x1724]` from fixed stem `0x00629d50`, constructs
|
||
`[transport+0x1164]` with callback `0x595bc0`, builds one fixed `0x20`-byte local route-label
|
||
buffer from the current local transport name at `[transport+0x60]` plus format `0x005dccfc`,
|
||
constructs `[transport+0x18bc]` with callback `0x595e10` and that stack-built label, seeds
|
||
queued descriptor family `[transport+0x1e7c]` through `0x595f70`, clears staged payload slot
|
||
`[transport+0xb50]`, and then sets callback-plumbing latch `[transport+0xba0] = 1`. That
|
||
constructor now reads cleanly as pure callback-table and cache bringup: it leaves the later
|
||
live-route entry to the dedicated open or reopen owners `0x5962e0` and `0x596530` instead of
|
||
trying to start either live route itself. One level lower, `0x5962e0` now reads as the
|
||
field-subscription open owner rather than a vague route
|
||
helper: it clears the old `[transport+0xba4]` runtime, rebuilds the route label from the
|
||
optional caller suffix plus the fixed tail word at `0x005d0b78`, materializes one callback-key
|
||
buffer from the fixed stem `0x005e22a0..0x005e22b2`, seeds fixed field ids `1` and `0x0b`,
|
||
appends per-field selector-name ids through `0x00629958`, opens the live route in mode `4`, and
|
||
then seeds `[transport+0x1774] = 1` before the first immediate field snapshot. `0x596210` is the
|
||
recurring service sweep over those same three tables plus the field-cache and queued-descriptor
|
||
families; `0x596060` is the explicit `gsi_am_rating` runtime-and-queue reset; `0x596530` is the
|
||
reopen-from-stored-label sibling above that same am-rating table; and `0x5965a0` is the single-shot
|
||
status-route connect latch that sets `[transport+0xb40]` before forwarding into `0x5973d0`,
|
||
leaving the rollback and clear path to `0x5965d0`. The matching local cleanup is tighter too: `0x595b80` is now
|
||
explicitly the field-subscription-side live-runtime reset plus field-cache clear plus active
|
||
opcode-`3` purge, `0x595ce0` resets only the capacity-descriptor route callback runtime at
|
||
`[transport+0x1164]`, `0x5961b0` is the full destroy-side owner over the three tables plus both
|
||
descriptor caches, and `0x5962c0` is the explicit staged route-callback payload clear on
|
||
`[transport+0xb50]`. The remaining gap on the capacity side is therefore narrower: the carried
|
||
sidecar fields themselves now read more cleanly as the cached callback-wrapper triplet reused
|
||
elsewhere (`drain context id +0x0c`, `callback fn +0x10`, `callback companion +0x18`), and the
|
||
negative result is stronger too: nearby replay-band fields `[transport+0x176c]`,
|
||
`[transport+0x1770]`, `[transport+0x1774]`, `[transport+0x177c]`, `[transport+0x1780]`, and
|
||
`[transport+0x1784]` all have direct local owners while `[transport+0x1778]` still appears only
|
||
as the single read in `0x595bc0`; even the broader callback-owner lifecycle now skips it while
|
||
seeding, servicing, resetting, reopening, or tearing down those neighboring tables and caches.
|
||
The constructor now closes that local search further: `0x58dc50` bulk-zeroes the full transport
|
||
body and still never writes a nonzero value into `[transport+0x1778]` before later explicit
|
||
neighbor initialization. The callback-binding owner stack now tightens that boundary too:
|
||
`0x5934e0` stages the shared work-record metadata triplet, `0x593650` binds it into the
|
||
callback-table worker path with one fixed second worker callback and one optional first worker
|
||
callback gated by `[transport+0x4c]`, and `0x593570` later consumes and republishes it, while
|
||
`[transport+0x1778]` still appears only as the borrowed sidecar read in `0x595bc0`. So this
|
||
local ownership seam is closed: within the mapped transport cluster there is no remaining
|
||
ordinary producer to find, and the remaining source now looks like an upstream callback or worker
|
||
handoff rather than one missing field store in the local binary. The neighboring callback-vector
|
||
strip is explicit now too: `0x597300` is a no-op owner-callback stub, `0x597303` is the
|
||
validated-cookie event forwarder over callback slot `[transport+0x17f0]`, and `0x597330` is the
|
||
validated extended-payload forwarder over `[transport+0x17f4]`; both reuse the same owner
|
||
context at `[transport+0x17f8]`. The adjacent staged-route
|
||
capacity gate is tighter now too: `0x595d60` is not another live-route opener. It is the
|
||
immediate bound-route fast path and capacity gate under `gsi_am_rating`. When the staged
|
||
descriptor already matches the current live route through `0x595d00`, it returns straight
|
||
through `0x592710`; otherwise it only reuses that same bound-route callback lane when
|
||
`numplayers < maxplayers`. `0x595dc0` then uses that result exactly as the already-bound-or-
|
||
capacity gate before it clears selector slot `2`, stages route-callback payload through
|
||
`0x5958e0`, and only then re-enters route mode `0`. The live-route connect owner is narrower in
|
||
the same way: `0x597480` mirrors success into deferred route-status flag `[transport+0x1ed8]`,
|
||
and the later mode-`4` branch in `0x595e10` is the place that actually consumes that flag to
|
||
choose route mode `1` versus `3`. The adjacent staged-route
|
||
callback side is tighter too: `0x595860` is now bounded as the
|
||
submit-result handler beneath `0x5958e0`, and the old `[transport+0xac0]` ambiguity there is now
|
||
gone. That branch is using the already-grounded third selector-generation counter at `[0xac0]`
|
||
together with target `[0xb48]` to decide whether staged route-callback traffic can push the
|
||
multiplayer route-mode ladder from `2` into `3` and later `4`. The selector-view counter beneath
|
||
that gate is tighter now too: `0x594e30` counts slot-`2` entries whose flag dword carries bit
|
||
`0x20`, optionally filtered by the current transport name buffer. The selector-view mutation
|
||
family under that same lane is tighter too: `0x594a30` is now the direct keyed-store remover,
|
||
`0x594fb0` clears one selector-slot ownership pointer plus its slot-local flag dword and drops
|
||
the whole entry when no slots remain, `0x595010` rekeys one selector-view entry under a new name
|
||
while preserving the `0x40..` runtime band, and callback root `0x59f9c0` now reads as the
|
||
sibling lane that clears one named selector-view slot, publishes callback slot `18`, and may
|
||
still re-enter the route-mode setter from the same slot-`2` status and generation gates. The
|
||
neighboring callback roots are tighter now too: `0x5950a0` clears one selector slot from every
|
||
selector-view entry in the keyed store, `0x59fab0` is the rename or relabel sibling above
|
||
`0x595010`, `0x59faf0` updates one selector slot's fixed sample-text buffer and refreshes the
|
||
active selector object when present, and `0x59fb60` replaces one selector slot's name set,
|
||
requests the default profile-key bundle for that slot, and publishes callback slot `20`. Slot
|
||
`16` is tighter now too: current grounded caller `0x59f440` forwards the staged route-callback
|
||
payload handle from `[transport+0xb50]` through `0x592ea0` just before route mode `5`. The
|
||
last adjacent callback root in that block is tighter now too: `0x59fbd0` is the built-in
|
||
per-slot profile-key query sibling. It resolves the caller selector name into one slot index,
|
||
forwards the caller trio into `0x596b90`, and then publishes callback slot `28`; that lower
|
||
helper indexes one slot-specific built-in string pair from `[transport+0x189c]` and
|
||
`[transport+0x18ac]`, reuses the generic per-key handler `0x596970`, and only republishes slot
|
||
`28` when that lower query path succeeds. The descriptor-lane installer above those callback
|
||
roots is explicit now too: `0x59fc80` zeroes one `0x30`-byte callback table, stores the owner
|
||
transport pointer at `[table+0x2c]`, and installs the full second selector-descriptor callback
|
||
vector `0x59f720/0x59f850/0x59f8b0/0x59f9c0/0x59fab0/0x59faf0/0x59fc50/0x59fc20/0x59fb60/
|
||
0x59fbd0` used by the selector-text and selector-view request owners `0x593aa0` and `0x593c40`.
|
||
The two smaller helper slots in that same lane are now bounded as well: `0x59fc20` resolves the
|
||
caller selector name and forwards one byte mask into
|
||
`multiplayer_transport_set_selector_presence_mask` `0x594d00`, while `0x59fc50` resolves that
|
||
same selector name and publishes callback slot `12` through `0x592d70`.
|
||
The compact-header side is tighter now too: `0x58fe20` and `0x58ff20` now show that compact
|
||
payloads always carry the primary IPv4 dword and that header bit `0x10` only gates whether the
|
||
primary port word is inline or inherited from the owner default port. `0x58fe90` now validates
|
||
the `0x40` inline keyed-property vector against the owner schema, and `0x58fe50` validates the
|
||
signed-`0x80` trailing string-pair tail before decode. `0x58ff60` then grounds bit `0x02` as
|
||
the inline secondary IPv4 dword branch, bit `0x20` as the paired secondary-port word branch with
|
||
owner-port fallback, bit `0x08` as the compact-header auxiliary inline dword stored at
|
||
`[descriptor+0x10]`, bit `0x40` as one inline keyed-property vector decoded through the
|
||
property-store writers, and signed bit `0x80` as one trailing string-pair tail. The
|
||
descriptor-state side is tighter now too: the shared queue helper at
|
||
`0x005a09a0` stamps pending state `0x4` for the local field-cache family `[transport+0x1724]`
|
||
and pending state `0x8` for the `gsi_am_rating` queued-descriptor family `[transport+0x1e7c]`,
|
||
while the adjacent active-send owner `0x005a07c0` now makes the fast path explicit instead of
|
||
looking like a missing growth helper: it stamps the descriptor into the active list, timestamps
|
||
`[entry+0x1c]`, and immediately emits the mode-selected outbound query packet through the queue
|
||
socket, with the secondary endpoint tuple `[entry+0x08/+0x0c]` only taking over when queue
|
||
companion dword `[queue+0x24]` matches the primary dword and descriptor state bit `0x2` is live.
|
||
The receive-side owner layer is tighter too: `0x005a0b40` drains queue socket `[queue+0x20]`,
|
||
matches inbound replies against the active list's primary or secondary endpoint tuples, and then
|
||
routes the matched entry into `0x005a0a00` for queue mode `1` or `0x005a0ad0` for the alternate
|
||
grounded mode. The broader maintenance pass `0x005a0c80` then adds the stale-active expiry sweep
|
||
`0x005a0c00` and the pending-to-active promotion pass `0x005a0c50`, so the ready-bit transition
|
||
now reads as a full queue lifecycle instead of one isolated state-byte write. That makes the
|
||
current transport-side tests cleaner:
|
||
`0x58d1c0` is the field-cache ready gate, `0x58d1d0` is the `gsi_am_rating` queued-descriptor
|
||
ready gate, and `0x58d230` is the remaining flag-byte split between direct primary-endpoint
|
||
handling at `[transport+0x18bc]` and the queued path at `[transport+0x1e7c]`. That byte-`0x14`
|
||
story is no longer queue-only either: `0x58ff60` can also OR in bit `0x1` after the inline
|
||
keyed-property vector and bit `0x2` after the signed string-pair tail. The flag-byte split is no
|
||
longer purely behavioral either: current evidence now says byte `[descriptor+0x15]` bit `0x1` is
|
||
a source-side descriptor header bit, explicitly seeded during the primary-endpoint table refresh
|
||
around `0x590dc0` and preserved by the compact descriptor decode path at `0x58ff60`, rather than
|
||
a queue-generated runtime state. The `gsi_am_rating` dispatcher side is tighter too: that same
|
||
bit no longer just looks like a direct-versus-queued routing split, because `0x595e10` also uses
|
||
it to suppress the direct `0x595dc0` transition even after queued ready bit `0x2` is present.
|
||
The descriptor body is tighter too: `[descriptor+0x20]` is now the intrusive next-link used by
|
||
the transport-owned primary-endpoint list headed at `[table+0x5bc]`, and `[descriptor+0x1c]` is
|
||
now the special numeric scalar behind the current `queryid`/`ping` fallback pair. That special
|
||
numeric path now has one clearer owner too: `0x58d6a0` lazily bootstraps the shared key
|
||
dictionary at `0x00db8b48` for the grounded strings `queryid` and `ping`, using the local
|
||
dereferenced-string hash, compare, and release callbacks `0x58d690`, `0x58d070`, and `0x58d090`.
|
||
The descriptor property-store seam is tighter in the same way now. The keyed store rooted at
|
||
`[descriptor+0x18]` is allocated by `0x58d5b0` with explicit per-entry key callbacks:
|
||
`0x58d550` releases the owned shared key/value string pair, `0x58d570` hashes the dereferenced
|
||
key string through `0x58d510`, and `0x58d580` compares two dereferenced keys through the shared
|
||
locale-aware casefolded compare `0x5a57cf`. The fixed-reply side above that store is no longer
|
||
anonymous either: when queue mode-`1` reply owner `0x5a0a00` sees descriptor flag bit `0x4`
|
||
clear, it routes the payload into `0x58d3a0`, which first consumes one backslash key/value
|
||
prefix and then walks exactly two counted reply sections, each with its own NUL-stem dictionary;
|
||
the later value strings are reinserted under synthetic decimal-suffixed keys built from those
|
||
stems plus one running per-section index.
|
||
The compact-header
|
||
auxiliary inline dword at `[descriptor+0x10]` is tighter in a negative way too: local xref scans now
|
||
only show it being preserved by later generic helpers like
|
||
`generic_record_0x1c_deep_copy_with_owned_string_at_0x08` `0x591410` and the adjacent
|
||
callback-marshaling wrappers `0x591480` and `0x591510`, not read through any dedicated semantic
|
||
accessor yet. The mode-`5` tails in both
|
||
callback families do not copy a descriptor-local field but instead mirror the transport-staged
|
||
companion dword at `[this+0x490]` into `[this+0x54]` and queue-side slot `[this+0x1724+0x24]`. The
|
||
`gsi_am_rating` maintenance lane is tighter now too: after pruning failed descriptors it sorts
|
||
the surviving primary-endpoint table through `0x590310` in mode `1` with key `gsi_am_rating`,
|
||
then selects the new head through `0x590480` before re-entering the route-transition path. The
|
||
owner above that handoff is explicit now too: mode `2` in `0x595f70` requires current route mode
|
||
`1`, no live selector object at `[transport+0x398]`, and no busy slot object at `[transport+0x38c]`;
|
||
it refreshes every surviving endpoint entry's `gsi_am_rating`, forces route mode `2` when the
|
||
table empties, and otherwise stages the fixed `gsi_am_rating` key for the current head entry
|
||
before falling into `0x5958e0`; only a submit failure drops that branch back to route mode `0`,
|
||
while success leaves the later `0x595860` callback to drive the `2 -> 3 -> 4` route-mode ladder. The
|
||
same service loop also owns a slower sidecar lane keyed off `[entry+0xa4]`:
|
||
`multiplayer_transport_select_stale_selector_view_progress_entry` walks the store through
|
||
`multiplayer_transport_pick_stale_selector_view_progress_entry`, picks one stale entry whose
|
||
progress latch `[entry+0x9c]` is clear and whose last progress tick `[entry+0x70]` is old enough,
|
||
and then hands it to `multiplayer_transport_stage_selector_view_progress_snapshot`. That helper
|
||
now looks more bounded too: it rebuilds the core `X%sX` marker text from `[entry+0x50]` through
|
||
`multiplayer_transport_format_selector_view_probe_marker_core`, formats one `PNG %s %d` line
|
||
around that marker and the entry-local averaged millisecond sample at `[entry+0x80]`, appends bounded
|
||
selector-slot `PNG` fragments for live overlapping slots, marks progress-snapshot state in flight
|
||
at `[entry+0x9c]`, and stamps both `[entry+0x70]` and the transport-wide throttle tick
|
||
`[transport+0xaec]`. So the selector-view sidecar no longer looks like one undifferentiated
|
||
refresh bucket: it has a faster deferred-probe lane plus a slower progress-snapshot lane, both
|
||
still under the shell-owned multiplayer transport cadence. The two descriptor lanes installed by
|
||
`multiplayer_transport_submit_selector_text_route_request` are tighter in the same family too:
|
||
when the entry-local marker text at `[entry+0x9ac]` is empty, the request path falls back to
|
||
`multiplayer_transport_format_selector_view_probe_marker_fallback_with_fixed_template_0x5e2350`
|
||
`0x597710` before handing the text into `0x593c40`. The parser split is explicit now too:
|
||
`multiplayer_transport_parse_selector_view_probe_marker` `0x5977b0` consumes the wider
|
||
`X%sX|%d` form, while
|
||
`multiplayer_transport_try_parse_selector_view_probe_marker_core` `0x597860` only decodes the
|
||
wrapped request-id from the shorter sentinel form and leaves any decimal tail to the caller. The
|
||
linked pending-template strip is tighter in the same way: after
|
||
`multiplayer_transport_unlink_pending_template_node` removes a node from the list rooted at
|
||
`[transport+0x550]`, it now tails into
|
||
`multiplayer_transport_release_pending_template_node` `0x597960`, which frees the node-owned
|
||
payload graph, both selector strings, and the node body itself.
|
||
The two descriptor lanes installed by
|
||
`multiplayer_transport_attach_callback_table_descriptor` are now tighter too. The first lane
|
||
rooted at `0x59f5c0` can arm deferred-close state on the owner transport and then forward through
|
||
callback slot `23`. The second lane is no longer just a loose selector-view bucket:
|
||
`multiplayer_transport_callback_dispatch_selector_name_payload_lane` at `0x59f650` classifies
|
||
selector payloads through `multiplayer_transport_is_selector_control_line`, routes `@@@NFO`
|
||
control lines into `multiplayer_transport_sync_selector_view_nfo_r_flag`, and otherwise publishes
|
||
either callback slot `13` or the split token-plus-tail callback slot `14` through
|
||
`multiplayer_transport_split_selector_payload_token_and_tail`. That local `@@@NFO` helper is now
|
||
bounded more tightly too: it only accepts lines ending in the literal `X\` tail, searches for the
|
||
field marker `\$flags$\`, and then sets or clears bit `0x2` in the third selector-slot flag word
|
||
at `[entry+0x64]` depending on whether that field contains the letter `r` before the next
|
||
backslash. The sibling `multiplayer_transport_callback_dispatch_current_selector_payload_lane` at
|
||
`0x59f720` first resolves the active selector through `0x5951a0`, then handles the
|
||
current-selector variants of the same control vocabulary: `@@@NFO` continues into the same local
|
||
`r`-flag sync helper, `@@@GML` plus mode-`3/4` payloads feed the shared control-token helper
|
||
`multiplayer_transport_handle_gml_or_png_selector_control`, and the remaining non-control payloads
|
||
publish callback slot `9`. That shared helper now narrows the `GML` and `PNG` split materially:
|
||
when the token is `GML` and the tail is `Disconnected`, it requires the active selector-view entry
|
||
to pass `multiplayer_transport_selector_view_entry_has_gml_disconnect_gate`, which currently means
|
||
the entry participates in the third selector slot and has bit `0x20` set in `[entry+0x64]`, before
|
||
it forces one status-pump pass, emits callback slot `16`, and re-enters route mode `5`. Its
|
||
sibling `PNG` branch resolves a named selector-view entry from the tail text and, when that entry
|
||
overlaps the active selector-slot ownership, refreshes selector-view runtime state through
|
||
`0x5948f0` and republishes callback slot `25`. Alongside those dispatchers, one grounded branch at
|
||
`0x59f560` still updates selector-view runtime state through `0x5948f0` and forwards the same
|
||
selector-name pair through callback slot `25`, while `0x59f850` resets selector text state through
|
||
`0x5954b0`, forwards through callback slot `19`, and when selector `2` is active in a nonterminal
|
||
route mode re-enters `multiplayer_transport_set_route_mode` with mode `1`. The low-level route
|
||
helper still looks like a two-part cycle:
|
||
`multiplayer_gamespy_route_service_retry_and_keepalive_timers` handles challenge or retry pressure
|
||
and periodic outbound control traffic around the `master.gamespy.com`, `PING`, `natneg`,
|
||
`localport`, `localip%d`, and `statechanged` strings, while
|
||
`multiplayer_gamespy_route_drain_inbound_packets` drains inbound datagrams and dispatches
|
||
semicolon lines, backslash-delimited key bundles, and `0xfe 0xfd` GameSpy control packets. The
|
||
outbound side is tighter now too: `0x0058cd40` is the shared decimal-text appender beneath both
|
||
the route builders and the shell-side status publishers; `0x0058c950` is the dedicated
|
||
field-class-`8` `PING` sender that refreshes `[route+0xac]`; and `0x0058cd70` is the broader
|
||
mode-selected control-packet owner that appends `localip%d`, `localport`, optional
|
||
`statechanged`, the route-name text, and then either the encoded three-slice suffix through
|
||
`0x0058c300` or a bare terminator before `sendto`. The read side is tighter too:
|
||
`0x0058f4e0` is the zero-timeout socket-readiness probe that `multiplayer_gamespy_route_drain_inbound_packets`
|
||
uses immediately before `recvfrom`. The
|
||
local control-payload seam is tighter now too: the immediate three-slice emitter wrapper
|
||
`0x0058c300` packages predecoded slices as field classes `0`, `1`, and `2`, while `0x0058c340`
|
||
decodes one length-coded three-part payload and re-emits those slices through the shared
|
||
packet-field builder `0x0058c0c0`; that
|
||
builder uses `0x0058c010` for the field header, `0x0058c030` for the encoded payload append, the
|
||
RC4-style transform `0x0058bee0`, the Base64-like text appender `0x0058be50`, and the six-bit
|
||
alphabet mapper `0x0058be20`. The same local support strip also now includes `0x0058bcb0` for
|
||
bounded control-id list append and `0x0058bce0` for bounded C-string append into the shared
|
||
`0x800`-byte text builders. The backslash-query side is tighter too: `0x0058c3e0` is the shared
|
||
callback-driven field-group emitter that maps key ids through `0x00629958`, appends the key
|
||
stems into the same builder, and then dispatches value production through callback slots
|
||
`[route+0x88]`, `[route+0x8c]`, and `[route+0x90]` before `0x0058c5c0` adds the final
|
||
terminator. The transport-owned callback story is now narrower too. The shared route constructor
|
||
`multiplayer_gamespy_route_construct_and_seed_callback_vector` seeds `[route+0x88]` through
|
||
`[route+0x9c]` from the caller-supplied transport callback table, records the owner transport at
|
||
`[route+0x104]`, and explicitly zeroes `[route+0xa0]`, `[route+0xa4]`, and `[route+0xd4]` before
|
||
any later patch-up. For the transport-owned status route,
|
||
`multiplayer_transport_try_connect_status_route` then seeds the six-entry callback vector
|
||
`0x596fd0/0x5970e0/0x597180/0x5971b0/0x597270/0x5972c0`, chooses either default route id
|
||
`0x1964` or the caller route id, copies stored route-label pointer `[transport+0x9a8]` into
|
||
`[transport+0xb3c]`, and patches `[route+0xa0]` through
|
||
`multiplayer_gamespy_route_set_extended_payload_callback` to point at
|
||
`multiplayer_transport_forward_validated_extended_route_payload` `0x00597330`, which simply
|
||
forwards the validated payload wrapper into the owner callback at `[transport+0x17f4]` with
|
||
context `[transport+0x17f8]`; success also clears `[transport+0xb38]`. The adjacent owner strip
|
||
is now explicit too: `0x597350` releases the auxiliary status route, `0x597370` services that
|
||
route alone through the shared low-level tick helper, and `0x597380` is the broader recurring
|
||
sweep that services both the status route and the current live route. The connect-side endpoint
|
||
setup is tighter now too:
|
||
`0x0058f540` resolves the current local hostname into one hostent, `0x0058bd50` copies up to
|
||
five local IPv4 dwords from that hostent into the global table at `0x00db8a28`, and
|
||
`0x0058bd90` builds one `sockaddr_in` with `AF_INET`, `htons(port)`, direct dotted-quad parse,
|
||
and host-name fallback. In the grounded status-route path,
|
||
`multiplayer_transport_try_connect_status_route` formats `%s.master.gamespy.com`, uses port
|
||
`27900`, and feeds that pair through `0x0058bd90` before the route opens its UDP handle. The
|
||
local bind side is tighter too: `0x0058cb50` opens a UDP socket, retries a `0x64`-wide local
|
||
port range or an ephemeral bind through the same sockaddr helper, normalizes literal
|
||
`127.0.0.1` to `INADDR_ANY` before `bind`, and returns both the live socket and chosen local
|
||
port; `0x0058cc40` is the wrapper above it that hands that socket and port into
|
||
`multiplayer_gamespy_route_construct_and_seed_callback_vector` and then marks `[route+0xbc] = 1`
|
||
on the resulting object. The startup or teardown calls around that path are now explicit too:
|
||
`0x0058f470` is the local `WSAStartup(0x0101, ...)` guard and `0x0058f490` is the matching
|
||
`WSACleanup` wrapper. The direct Winsock thunk strip under the same family is now mostly named
|
||
too: `0x0058bc42/48/4e/54/5a/60/6c/72/78/7e/8a` line up with `gethostbyname`, `gethostname`,
|
||
`closesocket`, `sendto`, `htons`, `htonl`, `socket`, `WSACleanup`, `WSAStartup`, `recvfrom`,
|
||
and `bind`, while `0x0058bc3c` is the dotted-quad conversion thunk used under the `localip%d`
|
||
builder path. The local-address selection side is narrower too: `0x0058d750` resolves the same
|
||
hostent list and picks the first private or loopback IPv4 through `0x0058f580` before the
|
||
transport-side bring-up path consumes it. The grounded live-route connect path at
|
||
`multiplayer_gamespy_udp_global_callback_worker_bootstrap` now sits beside that route layer as a
|
||
separate helper family rather than more route-object state. `0x0059fe30` resolves an optional
|
||
host and port into a stack `sockaddr_in`, and `0x0059fe8e` then opens the global UDP socket
|
||
`0x00629f28`, applies `SO_REUSEADDR`, and binds that prepared address. `0x005a0000` seeds the
|
||
callback-state globals `0x00db9fd8..0x00db9ffc`, allocates the timeout-registration vector
|
||
`0x00db9ff0` and queued-callback vector `0x00db9fec`, and optionally opens the socket
|
||
immediately; `0x005a0120` is the matching shutdown path. The control-packet codec under that
|
||
worker is explicit too: `0x0059fd00` accepts only fixed `0x91/0x01` packets with kind `1..3`
|
||
and an optional trailing `0x18`-byte payload, while `0x0059fdc0` emits that same `0x20`-byte
|
||
packet shape back through `sendto`. The kind handlers above it are now bounded as well:
|
||
`0x005a0200` handles kind `1` by issuing the kind-`2` reply and optionally staging one
|
||
timeout-registration record, `0x005a02f0` handles kind `2` by resolving that staged
|
||
registration, optionally emitting kind `3`, and queuing the completed callback, and `0x005a03d0`
|
||
is the shorter kind-`3` completion path. `0x005a0440` is the dispatch switch over those three
|
||
packet kinds. The receive and timeout side now reads coherently too: `0x005a0490` waits on the
|
||
global socket, drains one datagram through `recvfrom`, timestamps it, decodes it, and dispatches
|
||
it; `0x005a0550` then sweeps expired timeout-registration records from `0x00db9ff0`, optionally
|
||
queuing timeout callbacks through `0x0059fef0`; and `0x0059ff70` drains and frees the queued
|
||
callback vector `0x00db9fec`. So `0x005a05d0` now reads cleanly as the one-shot service tick for
|
||
the whole global UDP callback worker rather than another anonymous transport loop. One layer
|
||
higher, `0x005a0600` is the synchronous send-side owner over that same worker: it emits the fixed
|
||
kind-`1` query packet, stages one timeout-registration record, and can then pump
|
||
`0x005a05d0` plus `Sleep(1)` until the registration clears before draining the queued callbacks.
|
||
The immediate queue-side support strip is explicit now too: `0x005a0700`, `0x005a0720`,
|
||
`0x005a0740`, `0x005a0760`, and `0x005a07b0` are the append, prepend, pop, remove, and clear
|
||
helpers for the intrusive list family that links nodes through offset `+0x20`, and
|
||
`0x005a08f0` is the constructor-side queue bootstrap that opens the queue-owned UDP socket and
|
||
clears the active and pending list roots. The grounded
|
||
live-route connect path at
|
||
`multiplayer_transport_try_connect_live_route` now matches the status-route side on the main
|
||
callback seam: after a successful connect it also patches `[route+0xa0]` through
|
||
`0x58bc90 -> 0x597330`. The remaining negative boundary is narrower now: current local evidence
|
||
still does not show matching post-construction writes to `[route+0xa4]` or `[route+0xd4]`, and
|
||
the higher route-mode state machine now looks consistent with that. `multiplayer_transport_set_route_mode` first applies one pre-dispatch gate:
|
||
when a bound route still exists at `[this+0x1ec8]`, requested mode `2`, and selector slot `2`
|
||
is not active, it submits one bound-route status request through `0x5959e0`. That request itself
|
||
is now narrower too: it derives one request token from the current binding through `0x5934c0`,
|
||
then forwards binding dword `[route+0x2c]`, binding word `[route+0x30]`, local counter
|
||
`[this+0xb48]`, and default sample text `0x005c87a8` into `0x593980` using completion callback
|
||
`0x595980`, and a submit failure immediately sets `[this+0x1ed8]` so the route-mode owner can
|
||
fall back without waiting for the callback. That callback is tighter now too: nonzero results
|
||
force mode `2` when `[this+0xac0] <= 1` and otherwise promote through mode `3` or `4` according
|
||
to `[this+0xb48]`, while zero results set `[this+0x1ed8] = 1` and then fall back through route
|
||
mode `0` or `1` according to deferred am-rating latch `[this+0x1ed4]`. On success the route-mode setter stores the current
|
||
mode at `[this+0x18b8]`, mirrors mode changes into the bound-route callback lane through
|
||
`multiplayer_transport_enqueue_bound_route_mode_snapshot_opcode4_if_live` `0x5932a0`, and then
|
||
runs one of the concrete branches: mode `0` releases the current
|
||
live route, resets selector slot `2`, and only when the am-rating route is not already live at
|
||
`[this+0x1ec4]` tries to reopen the `gsi_am_rating` callback-table family through `0x596530`;
|
||
a failed reopen then falls back according to deferred route-status flag `[this+0x1ed8]`. Mode
|
||
`1` conditionally reopens that am-rating family only when both `[this+0x1ec4]` and
|
||
`[this+0x1ed4]` are clear and then, when no live route is present, tries to connect the live
|
||
route through `multiplayer_transport_try_connect_live_route` `0x597480`; once that family is already populated, the later callback-owner at
|
||
`0x595f70` takes over by pruning stale entries, refreshing `gsi_am_rating`, selecting the
|
||
current head endpoint, and staging the route-callback payload through `0x5958e0`. Mode `2`
|
||
first releases any stale live route through `multiplayer_transport_release_live_route`
|
||
`0x5973b0` when status latch `[this+0xb40]` is clear, then resets the am-rating family and
|
||
promotes a successful live-route connect into mode `1`. Mode `3` resets the am-rating family,
|
||
releases the live route through `0x5973b0`, resets selector slot `2`, and then tears down the
|
||
current bound-route payload through
|
||
`multiplayer_transport_release_current_route_binding_detach_descriptor_callback_and_clear_slot`
|
||
`0x595620`; mode `4` is the narrow status-route recovery retry; and mode `5` resets the
|
||
am-rating family, releases the live route through `0x5973b0`, and runs that same
|
||
`0x595620` teardown path without the selector-slot reset. That helper is narrower than the older
|
||
generic wording implied: it detaches the current binding from route-label object `[this+0x1ed0]`
|
||
through `0x58f3c0`, releases the staged bound-route callback payload at `[this+0x1ec8]` through
|
||
`0x5933a0`, and only then clears `[this+0x1ec8]`. The status-route connect path is tighter now too:
|
||
`0x5973d0` seeds `[this+0xaf4]`, uses the same six callback lanes, mirrors stored route label
|
||
`[this+0x9a8]` into `[this+0xb3c]`, patches the created route's extended-payload callback slot,
|
||
and clears `[this+0xb38]` on success; when the caller route id is not `-1` it also zero-extends
|
||
the supplied route word before forwarding it into `0x58c9b0`. The local status-route helper
|
||
strip is explicit too: `0x597350` releases `[this+0xaf0]` through `0x58cfd0`, `0x597370`
|
||
services only that route through `0x58cf90`, and `0x597380` is the broader two-route sweep that
|
||
services `[this+0xaf0]` and `[this+0x1ecc]` through the common route-object service helper
|
||
`0x58d040`. The live-route connect path is tighter in the same way:
|
||
`0x597480` builds one `0x20`-byte local identifier from `[this+0x60]` plus suffix template
|
||
`0x005dccfc`, seeds the callback vector `0x596fd0/0x5970e0/0x597180/0x5971b0/0x597270/0x5972c0`,
|
||
and chooses either the default route id `0x1964` through `0x58cc40` or the binding-specific id
|
||
in `[binding+0x30]` through `0x58c9b0`; on the binding-specific path it also clears pending
|
||
rebuild cookie `[binding+0x34]` and marks the constructed route live via `[route+0xbc] = 1`,
|
||
while the success tail mirrors stored route label `[this+0x9a8]` into `[this+0xb3c]`, patches
|
||
`[route+0xa0]` through `0x58bc90 -> 0x597330`, and clears live-route mode mask `[this+0xb38]`.
|
||
The callback boundary is closed more tightly now too: current local evidence still does not show
|
||
companion writes to `[route+0xa4]` or `[route+0xd4]` in either grounded transport-owned connect
|
||
path, so the stable transitions still switch by releasing route objects or route bindings and
|
||
rebuilding route state, not by mutating those optional callback slots in place. The parser behavior is now tighter as well: semicolon lines only dispatch when
|
||
`[route+0xd4]` is non-null, and the subtype-`6` raw fallback only dispatches when `[route+0xa4]`
|
||
is non-null. For the currently grounded transport-owned status and live routes, those two branches
|
||
therefore stay intentionally inactive and can cleanly no-op instead of implying a hidden mandatory
|
||
transport callback path. Inside the packet parser, subtype `4` is no longer an unknown callback hop: after cookie
|
||
validation it dispatches through `[route+0x9c]`, which the transport-owned status and live routes
|
||
seed to `multiplayer_transport_handle_validated_route_cookie_event` `0x005972c0`. That helper
|
||
either marks route progress and re-enters `multiplayer_transport_set_route_mode`, or forwards the
|
||
event id plus payload into the owner callback at `[transport+0x17f0]` with context
|
||
`[transport+0x17f8]`. The surrounding status-route callback vector is tighter now too:
|
||
`0x005970e0` publishes either the active selector text or the averaged probe sample at
|
||
`[entry+0x80]` and otherwise falls back to owner callback `[transport+0x17e0]`;
|
||
`0x00597180` is a straight owner-forwarding lane through `[transport+0x17e4]`;
|
||
`0x005971b0` seeds the local status-control id list and can then notify owner callback
|
||
`[transport+0x17e8]`; and `0x00597270` returns the third selector-slot generation counter
|
||
`[transport+0xac0]` on its bounded local branch before falling back to owner callback
|
||
`[transport+0x17ec]`. Subtype `6` still validates the same cookie, dedupes one 32-bit cookie or
|
||
packet id, and then dispatches the trailing payload through the natneg-or-raw callback layer
|
||
rooted at `[route+0xa0]` and `[route+0xa4]`; for the grounded transport-owned status and live
|
||
routes that currently means validated NATNEG-style payloads forward through `0x00597330` on
|
||
`[route+0xa0]`, while the raw fallback stays disabled because `[route+0xa4]` remains null. This
|
||
separates the shell-frame preview refresh at
|
||
`0x006cd8d8` from the actual transport cadence at `0x006cd970`, and also separates that transport
|
||
cadence from the lower GameSpy route-service and packet-parser layer beneath it.
|
||
- Evidence: `function-map.csv`, `pending-template-store-management.md`,
|
||
`pending-template-store-functions.csv`, plus objdump caller traces showing
|
||
`multiplayer_window_service_loop` reaching `multiplayer_flush_session_event_transport` and the
|
||
transport pump chain `multiplayer_flush_session_event_transport ->
|
||
multiplayer_transport_flush_and_maybe_shutdown -> multiplayer_transport_service_frame ->
|
||
multiplayer_transport_service_worker_once -> multiplayer_transport_drain_request_text_queue`.
|
||
- Closure note: the older broad request-id question is now replaced by the grounded lane split
|
||
already exposed above. `multiplayer_dispatch_requested_action` bounds the outer
|
||
`Multiplayer.win` action family, while the concrete transport submit owners are the bound-route
|
||
status lane `0x5959e0 -> 0x593980`, the selector-text route-request lane `0x593c40`, and the
|
||
second selector-descriptor callback lane rooted at `0x59fc80`. The preview-dataset reuse
|
||
boundary is also closed at the current evidence level: beyond `Multiplayer.win`, the same owner
|
||
family is reused by the `.gmt` save-mode hook in `0x00445de0`, `BuildingDetail.win` auxiliary
|
||
sync, `Start New Company...` side-owner submission, `CompanyDetail.win` async multiplayer
|
||
actions, and dataset-side selector or update branches, but not by a broader ordinary
|
||
world-service path.
|