Extend atlas seam annotations across subsystems
This commit is contained in:
parent
81316e6e49
commit
97295d4060
8 changed files with 2837 additions and 234 deletions
File diff suppressed because one or more lines are too long
|
|
@ -9,9 +9,67 @@
|
|||
- State Anchors: CRT heap and file-handle tables; process environment and argv storage.
|
||||
- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first
|
||||
RT3-owned coordinator.
|
||||
- Local CRT side seams are tighter now too: `0x005a2c30/0x005a2cb0/0x005a2cd8/0x005a2d10` own the
|
||||
global on-exit callback table at `0x00dbb8dc/0x00dbb8d8`, `0x005a2d22` is the optional
|
||||
`mscoree.dll!CorExitProcess` bridge before the normal process-exit tail,
|
||||
`0x005a2dc9/0x005a2e9c/0x005a2ead/0x005a2ebe/0x005a2ecd` are the shared exit-cleanup owner plus
|
||||
its four terminate-vs-return and cleanup-vs-skip variants, and `0x005a2d64` is now bounded as
|
||||
the higher init owner that walks fixed callback tables `0x005ed018..0x005ed034` and
|
||||
`0x005ed000..0x005ed014` before registering callback `0x005acaa1` into that dynamic on-exit
|
||||
table. The same startup-owned table path is now tighter internally too: `0x005acaa1` is the
|
||||
fixed callback-table walker over `0x005eab28..`, `0x005ac9e7` is the capacity query helper that
|
||||
prefers the local CRT heap fast path over `KERNEL32!HeapSize`, and `0x005a6649` is the
|
||||
region-descriptor probe under that fast path. The surrounding early-init side is tighter now
|
||||
too: `__heap_init` `0x005a644d` is the real `HeapCreate + heap-mode + small-block-heap` owner,
|
||||
and `startup_run_init_callback_table` `0x005aca5d` is the fixed startup callback walker over the
|
||||
currently empty `0x005eab20..` band.
|
||||
- the adjacent CRT runtime-report seam is explicit now too: `0x005acdb0` is the shared
|
||||
runtime-error or math-error message emitter by code, selecting texts like `R6002`, `R6024`,
|
||||
`DOMAIN error`, `SING error`, and `TLOSS error` from `0x0062aac0`, then emitting them through
|
||||
the GUI report path or the console `WriteFile` path. `0x005acf27` is the smaller banner-pair
|
||||
wrapper around that emitter, and `0x005acf60` is the registered floating-point exception
|
||||
dispatcher that translates Windows exception codes into the local runtime math codes before
|
||||
falling back to `UnhandledExceptionFilter`. The nearby unhandled-exception bridge is grounded now
|
||||
too: `0x005b1ddd` is the top-level filter callback that first recognizes the VC++ exception
|
||||
signature before tailing into the previously installed filter, and `0x005b1e23/0x005b1e36` are
|
||||
its install and restore wrappers over `SetUnhandledExceptionFilter`. The neighboring fatal
|
||||
security-report owner `0x005b1c31` is now explicit too: it formats either the buffer-overrun or
|
||||
unknown-security-failure message, appends the current program path, emits that body through the
|
||||
same GUI runtime-report path, and then forces CRT termination. The nearby startup helper
|
||||
`0x005ad0c4` is the common command-line program-name-tail extractor used by the CRT argument
|
||||
path. The adjacent locale-startup strip is grounded now too: `0x005ad524/0x005ad88b/0x005ada1b`
|
||||
build, release, and publish the primary `0xb8` locale text record, while `0x005adad9` and
|
||||
`0x005add7f` rebuild the narrower active locale-text bands rooted at `0x0062acd4`; those
|
||||
owners all materialize their individual fields through `0x005b1a42`. The startup-side locale
|
||||
option path is tighter now too: it resolves the older locale selector through `0x005ae9d5`,
|
||||
which chooses one LCID pair plus codepage from the incoming locale strings, validates them, and
|
||||
writes the resulting triple into `0x00dba060`.
|
||||
- the adjacent startup argument and environment seam is explicit now too: `0x005ad1f4` is the
|
||||
shared two-pass command-line parser that counts and optionally copies argv pointers plus bytes
|
||||
while honoring quotes, backslashes, and the multibyte lead-byte table at `0x00dba541`.
|
||||
`startup_build_argv` `0x005ad360` is the owner above it: it chooses either raw command line
|
||||
`0x00dbb8d0` or the cached module-path fallback in `0x00dba1e8`, runs that parser once to size
|
||||
the allocation and once to materialize the final table, then stores `argc-1` in `0x00dba024`
|
||||
and the argv root in `0x00dba028`. On the environment side, `___crtGetEnvironmentStringsA`
|
||||
`0x005ad402` materializes one CRT-owned multibyte copy of the Windows environment block using
|
||||
`GetEnvironmentStringsW + WideCharToMultiByte` when available and `GetEnvironmentStringsA`
|
||||
otherwise, and `__setenvp` `0x005ad12d` then filters that block into the final envp table by
|
||||
skipping leading-`=` entries and cloning the admitted `name=value` strings into `0x00dba030`.
|
||||
- the broader startup owners above those helpers are tighter now too: `startup_init_tls_state`
|
||||
`0x005abd49` is the real `TlsAlloc + TlsSetValue + per-thread-block` bootstrap. Beneath it,
|
||||
`startup_init_multithread_lock_table` `0x005a649e` seeds the fixed CRT lock table from the
|
||||
static lock-storage band at `0x00dba078`, `startup_release_tls_slot_and_multithread_lock_table`
|
||||
`0x005abcba` is the shared failure cleanup owner, and the adjacent `0x005a653c/0x005a6551/0x005a65d0`
|
||||
strip now reads cleanly as the generic unlock, lazy-init, and lock-acquire helpers for those CRT
|
||||
multithread slots. The neighboring `crt_get_or_create_current_thread_data_preserving_last_error`
|
||||
`0x005abcd8` is also grounded now as the older CRT per-thread data getter that allocates a zeroed
|
||||
`0x88`-byte record on first use while preserving `GetLastError`. `startup_init_file_handle_table`
|
||||
`0x005abf1b` is the concrete CRT handle-table owner that seeds
|
||||
the `0x00dba780` descriptor pages, imports inherited handles from `STARTUPINFO`, grows the table
|
||||
in `0x20`-entry chunks, and finally backfills the three standard streams from `GetStdHandle`
|
||||
plus `GetFileType`.
|
||||
- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`,
|
||||
`artifacts/exports/rt3-1.06/function-map.csv`.
|
||||
- Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned
|
||||
bootstrap helper; whether any nontrivial startup callbacks seed game globals before
|
||||
`app_bootstrap_main`.
|
||||
|
||||
|
|
|
|||
|
|
@ -71,9 +71,43 @@ The broader map-editor page owner is now bounded through
|
|||
lines into one repeated array of identical `0xbc`-byte runtime descriptors with no row-index
|
||||
special casing, and the candidate-side rebuild pass at
|
||||
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` then
|
||||
projects those descriptors into the live structure collection at `0x0062ba8c` before
|
||||
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0` rebuilds the
|
||||
per-cargo runtime summary tables. The current local file-side result is now tighter too: the
|
||||
projects those descriptors into the live structure collection at `0x0062b268` in two
|
||||
availability-bank passes. The current local disassembly now shows that this bridge reuses live
|
||||
candidate slots by prior ordinal field `[candidate+0x794]` when possible, otherwise allocates one
|
||||
fresh candidate, clones from the current bank's template source candidate, and only then copies in
|
||||
the imported recipe-line count, shared production-cap float, and packed `0xbc` descriptor strip
|
||||
from scenario state. Each rebuilt candidate then feeds
|
||||
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0`, which rebuilds
|
||||
the per-cargo runtime summary tables. That helper now reads more concretely too: it clears both
|
||||
emitted cargo-id tables at `[candidate+0x79c]` and `[candidate+0x7a0]`, rebuilds one local
|
||||
`0x35`-cargo mark band from the descriptor strip, accumulates the scaled per-cargo runtime rates
|
||||
into `[candidate+0xa1..+0xb8]`, and then allocates the two final compact membership tables from
|
||||
the `mark>=1` and `mark>=2` sets with counts stored at `[candidate+0x7a4]` and `[candidate+0x7a8]`.
|
||||
The same scan also makes the production-mode split explicit on the runtime side: descriptor mode
|
||||
`0` uses the shared production cap at `[candidate+0x2a]` divided by the descriptor amount, while
|
||||
nonzero mode bypasses that scaling path. The immediate sibling
|
||||
`structure_candidate_refresh_recipe_runtime_mode_flags_0x78c_0x790` `0x00411ce0`, which for
|
||||
subtype byte `[candidate+0x32] == 2` scans the imported descriptor strip and derives two compact
|
||||
post-import flags from mode `0` presence and subordinate-row presence. The stream-load side is
|
||||
tighter in the same way: the constructor-side load owner
|
||||
`structure_candidate_collection_construct_and_stream_load_runtime_records` `0x004131f0`
|
||||
seeds global pool `0x0062b268` and immediately re-enters the broader collection importer
|
||||
`structure_candidate_collection_stream_load_rebuild_runtime_summaries_and_refresh_named_availability`
|
||||
`0x00412fb0`. That owner streams each packed candidate body back through
|
||||
`structure_candidate_stream_load_runtime_record_and_rebuild_cargo_state` `0x004120b0`, then
|
||||
reruns the same scenario-side recipe projection at `0x00412d70`, the same stem-policy sweep at
|
||||
`0x00412ab0`, the collection aggregate subtotal pass over `[pool+0x8c..+0x9c]`, rebuilds the
|
||||
fixed name catalog at `0x0061dbc2/0x0061dc09` for non-subtype-`1` zero-availability candidates
|
||||
with live ids `<= 0x6e` via localized string `0x0b53`, and only then re-enters the same
|
||||
named-availability refresh at `0x00412c10` before returning. The neighboring placed-structure
|
||||
side is bounded too: global pool `0x0062b26c` comes from
|
||||
`placed_structure_collection_construct_empty_runtime_pool` `0x00413230`, while the paired tagged
|
||||
collection owners `0x00413280` and `0x00413440` now own the broader placed-structure stream
|
||||
load/save path around tags `0x36b1/0x36b2/0x36b3` and the per-entry virtual load/save slots
|
||||
`+0x40/+0x44`. The adjacent collection pass `0x00412ab0` is tighter in
|
||||
the same way: it now reads as a pure stem-policy sweep that refreshes candidate dword `[+0xbc]`
|
||||
from defaults `0x1869f/3/4` plus the fixed override table at `0x005edca8..0x005edd20`. The
|
||||
current local file-side result is now tighter too: the
|
||||
grounded recipe-book root at `0x0fe7` is preserved byte-for-byte across the checked map/save
|
||||
scenario pairs, so the loader can safely treat the twelve `0x4e1`-byte books as preserved
|
||||
scenario payload rather than a drifting save-only band. A conservative summary probe now only
|
||||
|
|
@ -148,24 +182,29 @@ The broader map-editor page owner is now bounded through
|
|||
The raw token windows beneath those branch labels are tighter now too. The checked mode-zero
|
||||
demand rows preserve string-bearing windows at `line+0x1c`, and the current probe shows those
|
||||
conservatively as prefixed ASCII previews such as `..Grain`, `..Corn`, `..Livestock`, and
|
||||
`..Milk`; local `objdump` over `0x0041e9f0` then shows the importer feeding the corresponding
|
||||
token buffer into an exact cargo-name matcher built over the live cargo collection at
|
||||
`0x0062ba8c`. By contrast, the imported `supply-marker-entry` rows feed nonprintable windows such
|
||||
as `.@...` from `line+0x08` through that same matcher, and the resolver path currently shows no
|
||||
special-case decoding for those marker forms. So the strongest static read is now: the stem-like
|
||||
demand rows preserve cargo-name text but are skipped because their mode is zero, while the
|
||||
nonzero imported marker rows are the live descriptor inputs yet likely fail exact cargo-name
|
||||
resolution unless another upstream transform exists.
|
||||
`..Milk`; local `objdump` now grounds `0x0041e9f0` itself as
|
||||
`cargo_collection_find_entry_by_exact_name`, a direct exact-string walk over the live cargo
|
||||
collection at `0x0062ba8c`. The importer at `0x00435630` feeds both token lanes through that same
|
||||
matcher after one conservative in-place cleanup pass: empty strings are replaced with the first
|
||||
live cargo name, and mode `3` loops until the supplied and demanded token strings no longer
|
||||
compare equal. By contrast, the imported `supply-marker-entry` rows still feed nonprintable
|
||||
windows such as `.@...` from `line+0x08` through that same exact matcher, and the resolver path
|
||||
currently shows no special-case decoding for those marker forms. So the strongest static read is
|
||||
now: the stem-like demand rows preserve cargo-name text but are skipped because their mode is
|
||||
zero, while the nonzero imported marker rows are the live descriptor inputs yet likely fail exact
|
||||
cargo-name resolution unless another upstream transform exists.
|
||||
The wrapper layer above that query no longer looks like a hiding place for special treatment
|
||||
either. Local `objdump` now shows `0x00412960` simply summing the two supply-side floats returned
|
||||
by `0x00412650`, while `0x004129a0` returns the single scaled production-output lane directly;
|
||||
neither wrapper checks for cargo id `0` after the query returns. The broader world-side
|
||||
accumulator at `0x0041e7be` is tighter in the same way: it calls `0x00412650`, requires all four
|
||||
returned channels to be positive before continuing, and only then scales those four channel
|
||||
values by one linked-instance count from `0x00413940` into caller-owned accumulators. So the
|
||||
current strongest read remains structural rather than semantic: unresolved marker rows can still
|
||||
propagate through the first bank bucket, but the first place that meaning matters is a normal
|
||||
positivity-gated cargo-channel consumer, not a dedicated null-cargo branch.
|
||||
returned channels to be positive before continuing, queries one linked-instance count through
|
||||
`0x00413940`, scales each of the four channel values by that count, and then writes the finished
|
||||
quartet into candidate dwords `[candidate+0x8e/+0x92/+0x96/+0x9a]` while stamping
|
||||
`[candidate+0x8a]` from current world field `[0x006cec78+0x15]`. So the current strongest read
|
||||
remains structural rather than semantic: unresolved marker rows can still propagate through the
|
||||
first bank bucket, but the first place that meaning matters is a normal positivity-gated
|
||||
cargo-channel consumer, not a dedicated null-cargo branch.
|
||||
The caller side is narrower than before too. The steady-state site bitset owner
|
||||
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` starts its inner cargo
|
||||
loop at id `1` and only walks upward through the current live cargo count, so it never
|
||||
|
|
@ -199,9 +238,13 @@ The broader map-editor page owner is now bounded through
|
|||
`0x0048a090(1)` reports that all three anchor-slot dwords `[entry+0x206]`, `[entry+0x20a]`, and
|
||||
`[entry+0x20e]` are still `-1`. So the strongest current read is no longer just "linked-site
|
||||
capable" in the abstract: this latch consistently fronts the local linked-peer class gate
|
||||
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, and the later linked-peer
|
||||
collection sweep `0x004138b0`, which keeps the `cargo id 0` bypass path firmly on the
|
||||
linked-site route-anchor or classification side rather than on an ordinary cargo lane.
|
||||
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, the route-link cleanup sweep
|
||||
`0x004138b0`, and the later linked-peer collection families `0x004139a0`, `0x00413a00`,
|
||||
`0x00413aa0`, and `0x00413b40`, which count linked peers that pass the station-or-transit gate,
|
||||
narrow that same subset to candidate class `3/4`, or stay on the subtype-`4` side and only
|
||||
inspect raw linked-instance candidate byte `0xb9`.
|
||||
That keeps the `cargo id 0` bypass path firmly on the linked-site route-anchor or classification
|
||||
side rather than on an ordinary cargo lane.
|
||||
One smaller ownership boundary is tighter too: byte `[site+0x42]` is not private scratch owned
|
||||
only by that pair. Local `objdump` shows tiny direct setters at `0x0040cbc0` and `0x0040cbd0`
|
||||
plus a raw getter at `0x0040cbf0`, so the `0x0040dba0/0x0040dbf0` pair is writing one shared
|
||||
|
|
@ -313,13 +356,18 @@ The broader map-editor page owner is now bounded through
|
|||
`shell_station_detail_present_selected_station_not_controlled_notice` `0x005043f0` is the
|
||||
localized not-controlled popup beneath the same action family,
|
||||
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590` is the
|
||||
scenario-latched station-to-station triplet popup that formats three per-destination scalar lanes
|
||||
with `%5.2f` or `N/C`, and
|
||||
scenario-latched station-to-station triplet popup that walks the current station's
|
||||
`0x24`-byte per-destination table, skips invalid or self ids, and formats three five-byte-stepped
|
||||
per-destination scalar lanes as `%5.2f` after dividing by `100.0`, or `N/C` when the lane is
|
||||
absent, and
|
||||
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0` is the alternate
|
||||
class-`3/4` branch that rebuilds the `Trains Serviced` / `Trains Maintained` matrix before
|
||||
reusing the shared haul-popup callback wiring,
|
||||
`shell_station_detail_refresh_class_gated_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
|
||||
refreshes the lower class-gated action strip rather than the older guessed `0xb3f8` lane. The
|
||||
`shell_station_detail_refresh_class_partitioned_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
|
||||
is tighter now too: it does not just gate one vague lower strip. It partitions the lower action
|
||||
row into two class-sensitive families, leaving `0xb3bb/0xb3bd/0xb3be` active only when the linked
|
||||
candidate class is `0`, while `0xb3bc/0xb3bf` stay active only when that class is exactly `1`.
|
||||
The
|
||||
adjacent lifecycle and navigation side is tighter now too:
|
||||
`shell_station_detail_window_destruct_release_preview_helpers_and_clear_singleton` `0x00505bf0`
|
||||
is the real `StationDetail.win` destructor, and
|
||||
|
|
@ -877,7 +925,22 @@ The broader map-editor page owner is now bounded through
|
|||
`0x00441980`, `0x004419c0`, and `0x00441a00` are the five repeated `Overview.win` page toggles
|
||||
over detail-manager mode `9`, each closing the current page through
|
||||
`shell_detail_panel_transition_manager` `0x004ddbd0(-1, 0)` when that exact page is already
|
||||
active and otherwise requesting mode `9` with page ordinals `0..4`.
|
||||
active and otherwise requesting mode `9` with page ordinals `0..4`. One nearby idle-shell gate
|
||||
is tighter now too: `0x004414d0` only forwards into the queued-record prompt owner `0x00438840`
|
||||
when the live world object exists and the active shell presentation stack depth
|
||||
`[0x006d401c+0xc64]` is not positive. The neighboring shell-command leaves are now explicit too:
|
||||
`shell_command_open_overview_for_previous_or_latest_fixed_preview_record` `0x00441490` walks the
|
||||
fixed preview-record sequence family at `0x005ce418`, preferring the predecessor of the current
|
||||
inactive minimum-sequence record and otherwise falling back to the max-sequence record before
|
||||
opening `Overview.win` through `0x004f3a10`; `shell_command_prompt_for_class0_region_name_and_focus_matching_world_region`
|
||||
`0x00441500` opens prompt `0x16a`, scans the live class-`0` region records in `0x0062bae0` by
|
||||
name `[region+0x356]`, and on a match centers the live world view through
|
||||
`shell_world_view_center_on_object_with_mode_specific_zoom_policy` `0x00433900`, while misses
|
||||
fall back to prompt `0x16b`; and
|
||||
`shell_command_prompt_for_text_and_submit_selector1_multiplayer_transport_request_when_auxiliary_preview_ready`
|
||||
`0x00441690` requires the auxiliary-preview owner gate `0x00434050` plus one live queued-preview
|
||||
record at `[world+0x66ae]`, opens prompt `0x0b6d`, and submits the entered text through
|
||||
`multiplayer_preview_dataset_submit_transport_request` `0x00469d30` with selector `1`.
|
||||
`shell_station_list_format_freight_and_express_availability_summary` `0x00506e50` feeds the
|
||||
station-list summary `%1 has %2 freight loads and %3 express loads available for hauling...`, and
|
||||
the paired modifier helper `shell_station_list_handle_center_or_rename_action` `0x00506d50` owns
|
||||
|
|
@ -887,6 +950,28 @@ The broader map-editor page owner is now bounded through
|
|||
`0x61aa`, wiring the visible summary and modifier callbacks, mirroring the shared selected-station
|
||||
latch at `[0x006cec78+0x4cba]` when it still belongs to the current company, and updating the two
|
||||
status labels `0x61af` and `0x61b0`. The row-side callout lane is tighter too:
|
||||
one adjacent active-window follow-on strip is explicit now too. The no-arg helper
|
||||
`shell_refresh_active_window_followons_without_subject_gate` `0x00436070` refreshes the live
|
||||
company-detail, stock-buy, and `Overview.win` branches for modes `7`, `0x0b`, and `9`.
|
||||
The helper
|
||||
`shell_refresh_active_window_followons_for_subject_and_optional_company_match` `0x004360d0`
|
||||
refreshes the live company-detail branch in mode `7`, the stock-buy branch in mode `0x0b`, the
|
||||
mode-`8` timed overlay only when the current subject id matches the caller dword, and the
|
||||
`Overview.win` side in mode `9`. Its wrapper
|
||||
`shell_refresh_active_window_followons_and_adjacent_station_or_company_lists` `0x00436170`
|
||||
forwards through that helper and then adds the station-list refresh through
|
||||
`shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30` when mode `4` is
|
||||
active plus the company-list refresh through `0x005158f0(-1)` when mode `1` is active. The
|
||||
shared world-side follow-on beneath those shell branches is explicit now too:
|
||||
`world_refresh_collection_side_effects_after_broad_state_change` `0x004361d0` sweeps the live
|
||||
region, placed-structure, and three adjacent world collections, re-entering their per-record
|
||||
refresh owners after broader state changes. Current grounded callers include the larger
|
||||
world/status owner at `0x44b160` and the TrackLay teardown path at `0x50dba7`. The
|
||||
nearby train-detail lower-action special case
|
||||
`shell_handle_train_detail_lower_action_0x3f9_follow_current_route_object` `0x00435ac0` is now
|
||||
bounded too: it validates the current train, resolves its linked route object, recenters the
|
||||
world view on that route object, and then re-enters the shell detail manager with mode `2`.
|
||||
The row-side callout lane is tighter too:
|
||||
`shell_station_list_row_callback_publish_station_callout_card` `0x00506ac0` is the actual
|
||||
row callback beneath both list controls, resolving the selected station, deriving one category
|
||||
header through `0x0053de00` and `0x00552560`, and then publishing the station-name plus freight
|
||||
|
|
|
|||
|
|
@ -44,7 +44,14 @@
|
|||
load-screen call shape is `(4, 0)`, not a one-arg mode switch. The second stack argument is now
|
||||
tighter too: current local evidence reads it as an old-active-mode teardown flag, because the
|
||||
`0x482fc6..0x482fff` branch only runs when it is nonzero and then releases the prior active-mode
|
||||
world through `0x434300`, `0x433730`, and the common free path before clearing `0x006cec78`.
|
||||
world through `0x434300`, falls through the neighboring no-op placeholder `0x433730`, and then
|
||||
reaches the common free path before clearing `0x006cec78`. The teardown owner itself is tighter
|
||||
now too: `0x434300` first destroys the two indexed world collections at `[world+0x66b2]` and
|
||||
`[world+0x66b6]`, then releases the typed global roots `0x0062b244`, `0x006cfcbc`,
|
||||
`0x0062be10`, `0x006ceb9c`, `0x0062c120`, `0x0062ba8c`, `0x006ada84`, `0x0062ba88`,
|
||||
`0x0062b2fc`, `0x0062b268`, `0x006cea4c`, and `0x006acd34` in that order before it drains the
|
||||
shell-helper handle band `[world+0x46a80..+0x46aa0]`, the variable owner band `[world+0x46aa4]`,
|
||||
and the linked chains at `[world+0x66a6]` and `[world+0x66aa]`.
|
||||
The later world-entry reactivation branch correspondingly uses `(1, esi)` rather than `(1, 0)`.
|
||||
The current live hook probes now push the remaining auto-load gap much later too: on the
|
||||
hook-driven path `shell_transition_mode(4, 0)` returns cleanly, and the full old-mode teardown
|
||||
|
|
@ -447,4 +454,3 @@
|
|||
whether `0x00443a50` is world entry. It is where the long-lived simulation cadence takes over
|
||||
after this bring-up and whether that cadence still rendezvous with the shell-owned frame path or
|
||||
escapes into a separate gameplay loop.
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,24 @@
|
|||
`[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
|
||||
|
|
@ -58,7 +76,14 @@
|
|||
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`. The constructor and teardown side are tighter now too.
|
||||
`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
|
||||
|
|
@ -253,6 +278,141 @@
|
|||
`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 that sidecar remains an upstream producer gap.
|
||||
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
|
||||
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
|
||||
|
|
@ -285,7 +445,26 @@
|
|||
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 deferred callback shim
|
||||
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
|
||||
|
|
@ -306,12 +485,27 @@
|
|||
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`. Current evidence still does not prove
|
||||
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. 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
|
||||
allocate-and-append lane for one self-consistent compact payload, while `0x590d00` is the keyed
|
||||
upsert-by-primary-endpoint lane that reuses an existing descriptor when possible and then notifies
|
||||
the owner callback. The route-callback-table runtime above that decode side is tighter now too:
|
||||
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]`,
|
||||
|
|
@ -330,14 +524,30 @@
|
|||
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`
|
||||
opens the live route handle into `[this+0x4a0]`, stages the initial outbound request, and seeds
|
||||
state `3` plus the staged receive buffer; `0x5911e0` is the state-`2/3` socket-service wrapper
|
||||
that reads new bytes, grows the staged buffer, and re-enters `0x5908c0`; `0x5912c0` is the
|
||||
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]`, while `0x596530` is the `gsi_am_rating` reopen
|
||||
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]`. 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`.
|
||||
|
|
@ -345,10 +555,19 @@
|
|||
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.
|
||||
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` now clearly publishes a
|
||||
descriptor block from live descriptor properties `hostname`, `numwaiting`, `maxwaiting`,
|
||||
`numservers`, and `numplayers` plus three carried sidecar scalars. That sidecar at
|
||||
`numservers`, and `numplayers` plus three carried sidecar scalars. Its live mode `0` path reads
|
||||
those descriptor properties through `0x58d1f0`, `0x58d170`, and `0x58d6d0`, then forwards them
|
||||
through opcode-`2` builder `0x592ae0`; its replay-linked modes `3/5` instead enqueue an all-zero
|
||||
descriptor payload while preserving only the borrowed callback-wrapper triplet from the cached
|
||||
sidecar record and then unlink that 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
|
||||
|
|
@ -381,8 +600,12 @@
|
|||
longer the open edge; only the upstream sidecar producer remains unresolved. The neighboring
|
||||
work queue is tighter too: `0x593330/0x593370/0x593380` now bound `[transport+0x1780]` as the
|
||||
construct/clear/destroy owner family, while `0x5933a0`, `0x5934e0`, and `0x593570` ground the
|
||||
remove, allocate, and completion side over that same collection. The small sibling `0x593400` is
|
||||
tighter too: it is a pure work-record uniqueness predicate over field `+0x0c`. Its caller is
|
||||
remove, allocate, and completion side over that same collection. The completion owner is tighter
|
||||
now too: `0x593570` clears in-flight latch `[transport+0x44]`, stores the final attach result in
|
||||
`[transport+0x48]`, stamps `[transport+0x50]` 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. 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
|
||||
|
|
@ -390,7 +613,14 @@
|
|||
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 active-opcode side is tighter too: `0x5927b0`
|
||||
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
|
||||
|
|
@ -409,23 +639,31 @@
|
|||
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 only re-emitting the follow-on lane when `+0x10` is nonnull and
|
||||
then forwarding `(+0x10, +0x18, +0x0c)` into `0x593170` as callback function, callback
|
||||
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` seeds `[transport+0xba0]` as the callback-plumbing
|
||||
enable latch, clears staged payload slot `[transport+0xb50]`, and constructs the three owner
|
||||
branches rooted at `[transport+0xba4]`, `[transport+0x1164]`, and `[transport+0x18bc]`;
|
||||
`0x596210` is the recurring service sweep over those same three tables plus the local field
|
||||
cache and queued-descriptor family; `0x596060` is the explicit `gsi_am_rating` reset; and
|
||||
`0x596530` is the reopen-from-stored-label sibling above that same am-rating table. The
|
||||
matching local cleanup is tighter too: `0x5962c0` is the explicit staged route-callback payload
|
||||
clear on `[transport+0xb50]`, while `0x595ce0` now clearly resets only the capacity-descriptor
|
||||
route callback table at `[transport+0x1164]`, not the field-subscription table at
|
||||
`[transport+0xba4]`. The remaining gap on the capacity side is therefore narrower: the carried
|
||||
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`. `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; and `0x596530` is the reopen-from-stored-label sibling
|
||||
above that same am-rating table. 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]`,
|
||||
|
|
@ -466,7 +704,15 @@
|
|||
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.
|
||||
`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
|
||||
|
|
@ -479,8 +725,18 @@
|
|||
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 later service through `0x005a0c80` promotes those pending tags into ready bits `0x1` and
|
||||
`0x2` in descriptor byte `[entry+0x14]`. That makes the current transport-side tests cleaner:
|
||||
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`
|
||||
|
|
@ -494,17 +750,42 @@
|
|||
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. The compact-only
|
||||
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-only
|
||||
auxiliary 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 route-event dispatcher side is tighter too: the mode-`5` tails in both
|
||||
accessor yet. The route-event dispatcher side is tighter too: `0x595dc0` is no longer just one
|
||||
vague transition shim. It first rejects when staged-route busy latch `[transport+0x1e8c]` or
|
||||
selector-slot object `[transport+0x38c]` is live, then reuses `0x595d60`; only a positive
|
||||
capacity result lets it refresh selector state through `0x5973b0`, reset selector slot `2`
|
||||
through `0x5954b0`, and stage the descriptor through `0x5958e0` before route mode `0` is
|
||||
entered through `0x595650`. 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
|
||||
|
|
@ -518,6 +799,20 @@
|
|||
`[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:
|
||||
|
|
@ -552,27 +847,126 @@
|
|||
`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
|
||||
transport-owned callback story is now narrower too. The shared route constructor
|
||||
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 patches `[route+0xa0]` through
|
||||
`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]`. The grounded live-route connect path at
|
||||
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` does not currently perform any matching
|
||||
post-construction patch for `[route+0xa0]`, `[route+0xa4]`, or `[route+0xd4]`, and the higher
|
||||
route-mode state machine now looks consistent with that: `multiplayer_transport_set_route_mode`
|
||||
latches the requested small mode at `[this+0x18b8]`, then uses mode `0` for the direct-versus
|
||||
queued `gsi_am_rating` split, mode `1` for the ready-bit plus queued fallback, mode `2` for
|
||||
pending-descriptor cleanup, mode `3` for the empty-table fallback, mode `4` for deferred
|
||||
route-status recovery, and mode `5` for copying the staged route companion dword into `[this+0x54]`
|
||||
and queue-side slot `[this+0x1724+0x24]`. The current grounded mode transitions still switch by releasing route
|
||||
objects through `multiplayer_gamespy_route_release_and_free` and rebuilding them through
|
||||
`multiplayer_transport_try_connect_live_route`, not by mutating callback slots in place. The
|
||||
parser behavior is now tighter as well: semicolon lines only dispatch when
|
||||
route-mode state machine now looks consistent with that, but the owner is tighter than the old
|
||||
flat mode list. `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]` and then runs one of the concrete branches: mode `0` refreshes
|
||||
selector-route side effects through `0x5973b0`, resets selector slot `2`, tries to reopen the
|
||||
`gsi_am_rating` callback-table family, and then falls back according to deferred route-status
|
||||
flag `[this+0x1ed8]`; mode `1` conditionally reopens that family and then, when no live route is
|
||||
present, tries to connect the live route through `0x597480`; mode `2` resets the am-rating
|
||||
family and promotes a successful live-route connect into mode `1`; 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 `3` resets the
|
||||
am-rating family, refreshes selector-route state, resets selector slot `2`, and releases the
|
||||
current route binding; mode `4` is the narrow status-route recovery retry; and mode `5` resets
|
||||
the am-rating family, refreshes selector-route state, and releases the current route binding
|
||||
without the selector-slot reset. The live-route connect path is tighter now too: `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`. The stable
|
||||
transitions therefore still switch by releasing route objects or route bindings and rebuilding
|
||||
route state, not by mutating 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 remain optional and can cleanly no-op instead of implying a hidden mandatory callback
|
||||
|
|
@ -604,4 +998,3 @@
|
|||
`[route+0xa4]` and `[route+0xd4]` for the transport-owned status/live routes, or whether those
|
||||
packet families are simply unused in this stack; and how far the Multiplayer preview-dataset
|
||||
machinery is reused outside `Multiplayer.win` beyond the currently grounded `.gmt` save-mode hook.
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,23 @@ The same brush strip is tighter now too:
|
|||
trailing caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly
|
||||
linked list rooted at `[state+0x66a6]`. The gameplay label for that queued-record family is still
|
||||
open, but the structural link from periodic region selection into the scenario-state queue is now
|
||||
direct instead of speculative. One neighboring narrow counter is bounded too: `0x00422850`
|
||||
direct instead of speculative. One neighboring owner is tighter now too: `0x004358d0` walks the
|
||||
same live region collection and services those pending amounts after linked-site refreshes. When a
|
||||
region's pending amount at `[region+0x276]` is live and the city-connection peer probes
|
||||
`0x00420030` and `0x00420280` can resolve one matching peer site plus linked company through
|
||||
`0x0047efe0`, it formats one localized notice from region name `[region+0x356]`, world scalar
|
||||
`[region+0x23a]`, and the pending amount, publishes that notice through `0x004554e0`, posts the
|
||||
amount into company stat slot `4` through `0x0042a080`, then clears `[region+0x276]` and stamps
|
||||
completion latch `[region+0x302] = 1`. When no peer-company branch is available and byte
|
||||
`[region+0x316]` is still clear, the same owner publishes one alternate one-shot notice from the
|
||||
same amount and region scalar before setting `[region+0x316]`. So the pending-region bonus lane
|
||||
is no longer just a queued setup artifact: it has a concrete later service owner and an explicit
|
||||
shell-facing fallback above the same queue family now too. `0x00438710` is the recurring queue
|
||||
service owner above `[world+0x66a6]` and `[world+0x66aa]`, while `0x00438840` is the tiny
|
||||
dispatch-or-fallback sibling: it forwards the currently active queue node at `[world+0x66aa]`
|
||||
into the same node-handler table `0x00437c00`, or opens the fixed custom modal rooted at
|
||||
localized id `0x153` when no active node is staged.
|
||||
company-credit side effect. One neighboring narrow counter is bounded too: `0x00422850`
|
||||
counts class-0 regions that pass a second `0x00420030` peer-probe variant with fixed flags
|
||||
`(1,1,1)` plus one caller-supplied trailing dword, and current callers are the query/script
|
||||
dispatch at `0x0042f856` and the later region-stats formatter at
|
||||
|
|
@ -71,18 +87,67 @@ The same brush strip is tighter now too:
|
|||
same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` it
|
||||
refreshes the auxiliary route-entry tracker collection `0x006cfcb4`, then runs
|
||||
`placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`,
|
||||
which first drains the queued local-runtime rebuild ids through collection `0x0062b2fc` and then
|
||||
sweeps the live placed-structure collection `0x0062b26c` for the later position-triplet side
|
||||
refresh,
|
||||
then a flagged world-grid cleanup sweep through the compact grid-flag query
|
||||
`0x00448af0` plus the neighboring local chunk-cell write helper `0x00533fe0`, and only after
|
||||
that the later route-entry post-pass at `0x00491c20`. The same `319` lane is tighter internally
|
||||
now too:
|
||||
the surrounding placed-structure collection side is no longer just the per-record loader family.
|
||||
`0x004131f0` now cleanly constructs and stream-loads the live placed-structure collection,
|
||||
`0x00413230` constructs the empty runtime pool, `0x00413280` stream-loads tagged placed-structure
|
||||
entries with progress publishing, `0x00413260` is the matching release-and-free owner, and
|
||||
`0x00413550` now clearly resolves one site id, re-enters `0x0040e080` to release local runtime
|
||||
and linked-site follow-on state, and only then unlinks the entry from the live collection. The
|
||||
adjacent helper strip is tighter too: `0x00413620` is the collection-wide linked-peer overlay
|
||||
refresh sweep above `0x0040d2d0`; `0x00413660` and `0x004136e0` are the neighboring owner-color
|
||||
and scalar publish sweeps; `0x00413750` is the shared mode-`3/6` linked-site preview membership
|
||||
refresh owner; `0x00413860` is the collection-side center-cell roster sweep above `0x0040cd10`;
|
||||
`0x004138b0` is the route-link cleanup sweep keyed by one center-cell `u16` roster token;
|
||||
`0x004138f0` counts live placed structures whose cached candidate id `[site+0x3d0]` matches one
|
||||
caller-supplied structure id; `0x00413940` walks the same matching subset and accumulates source
|
||||
field `[source+0x141]` from `0x0040cec0` with a floor of `1`; `0x004139a0` counts entries whose
|
||||
linked peer passes the narrower station-or-transit gate `0x0040d230`; `0x00413a00/0x00413aa0`
|
||||
narrow that same linked-peer subset to candidate class `3` and `4`; and `0x00413b40` is the
|
||||
subtype-`4` companion counter whose last gate is the raw linked-instance candidate byte `0xb9`.
|
||||
That `0x00413940` sum is now the direct link-count scale factor consumed by `0x0041e7be` above
|
||||
the four cargo-summary banks.
|
||||
One neighboring year-side owner is tighter now too: `0x00435b50` is the shared year-threshold
|
||||
and structure-milestone news pass beneath periodic simulation and startup bring-up. It suppresses
|
||||
itself when the cached previous year still matches or scenario gate `[0x006cec78+0x46c38]` is
|
||||
live, then publishes fixed year notices for `1865/1895/1920/1958`, formatted numeric notices for
|
||||
`1850/1900/1950`, and later structure-milestone notices keyed by live counts of specific placed
|
||||
structures resolved through `0x00412af0` and counted through `0x004138f0`, appending the finished
|
||||
records into the existing fixed-record/news lanes at `0x006cea4c` and `0x004337c0` rather than
|
||||
through a separate hidden journal family.
|
||||
before that later world and shell reactivation tail, `world_entry_transition_and_runtime_bringup`
|
||||
runs one distinct post-bundle status and runtime refresh phase that posts progress ids `0x196`
|
||||
and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes the
|
||||
live event collection at `0x0062be18` through
|
||||
`scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the
|
||||
scenario-side port-or-warehouse cargo recipe runtime tables through `0x00435630`, and then runs
|
||||
the named-candidate availability preseed through `0x00437743`. One later subphase is tighter now
|
||||
too: before the broad world-reactivation sweep it posts progress ids `0x32dc/0x3714/0x3715`,
|
||||
the named-candidate availability preseed through `0x00437743`. The recipe rebuild lane itself is
|
||||
tighter now too: `0x00435630` resolves both supplied and demanded token strings through the exact
|
||||
live cargo-name matcher `cargo_collection_find_entry_by_exact_name` `0x0041e9f0`, fills empty
|
||||
token strings from the first live cargo entry before that match, and in mode `3` loops until the
|
||||
supplied and demanded strings no longer compare equal. The importer-side bridge is tighter now
|
||||
too: each of the twelve recipe books writes its active-line count into the paired runtime count
|
||||
lane beside the imported `0xbc` descriptor strip, and after the full twelve-book sweep the helper
|
||||
explicitly re-enters
|
||||
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` when
|
||||
the live candidate collection exists. That keeps the strongest current static split narrow and
|
||||
concrete: mode-zero demand rows can still preserve readable cargo-name text in the saved recipe
|
||||
books, but only the nonzero imported rows reach the live `0xbc` descriptor array, and the
|
||||
unresolved supply-marker forms still have no special decode path before the exact matcher runs.
|
||||
The immediate helper strip under that bridge is tighter now too: `0x00411d50` is the narrow
|
||||
descriptor-pattern predicate that returns true only when every imported descriptor keeps mode `0`
|
||||
and at least one descriptor has no subordinate rows, while `0x00411da0`, `0x00411e10`, and
|
||||
`0x00411e50` are conservative fixed-table accessors over candidate slot `[candidate+0x798]`,
|
||||
exposing one copied name plus either a scalar pair or scalar triplet from the same fixed row in
|
||||
`0x005ed338..0x005edca4` rather than a separate loader family.
|
||||
One later subphase is tighter now too: before the broad world-reactivation sweep it
|
||||
posts progress ids `0x32dc/0x3714/0x3715`,
|
||||
reloads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged
|
||||
runtime-profile bytes back into `0x006cec7c` while latch `[profile+0x97]` is set, mirrors the
|
||||
grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world
|
||||
|
|
@ -94,6 +159,22 @@ The same brush strip is tighter now too:
|
|||
adjustment branch: non-editor startup mode can decrement the lane by `1` or `3` depending on
|
||||
shell-state editor gate `[0x006cec74+0x68]`, shell-side selected-year-adjust policy
|
||||
`[0x006cec74+0x178]`, and the saved special-condition slot `[0x006cec78+0x4af7]`, and only that
|
||||
save/load bridge is narrower on the candidate side too: the constructor-side load owner
|
||||
`structure_candidate_collection_construct_and_stream_load_runtime_records` `0x004131f0`
|
||||
seeds global pool `0x0062b268` and immediately re-enters the broader collection importer
|
||||
`structure_candidate_collection_stream_load_rebuild_runtime_summaries_and_refresh_named_availability`
|
||||
`0x00412fb0`. That owner streams each packed candidate body back through
|
||||
`structure_candidate_stream_load_runtime_record_and_rebuild_cargo_state` `0x004120b0`, reruns the
|
||||
scenario-side recipe projection at `0x00412d70`, refreshes the stem-policy lane at `0x00412ab0`,
|
||||
rebuilds the collection aggregate subtotal band at `[pool+0x8c..+0x9c]`, repopulates the fixed
|
||||
name catalog at `0x0061dbc2/0x0061dc09` for non-subtype-`1` zero-availability candidates whose
|
||||
live ids stay within `0x6e`, and then reruns the named-availability pass at `0x00412c10` before
|
||||
returning. The neighboring placed-structure side
|
||||
is bounded too: global pool `0x0062b26c` comes from
|
||||
`placed_structure_collection_construct_empty_runtime_pool` `0x00413230`, while the paired tagged
|
||||
collection owners `0x00413280` and `0x00413440` now own the broader placed-structure stream
|
||||
load/save path around tags `0x36b1/0x36b2/0x36b3` and the per-entry virtual load/save slots
|
||||
`+0x40/+0x44`.
|
||||
adjusted lane then feeds
|
||||
helper `0x0051d390` before `world_set_selected_year_and_refresh_calendar_presentation_state`
|
||||
`0x00409e80` stores the final absolute counter into `[world+0x15]` and refreshes
|
||||
|
|
@ -170,6 +251,11 @@ The same brush strip is tighter now too:
|
|||
profile name and writes that string into the same destination; and one compact runtime-effect
|
||||
branch inside `world_apply_compact_runtime_effect_record_to_resolved_targets` `0x00431b20` resets
|
||||
the same destination to the fixed placeholder token at `0x005c87a8`. That gives a grounded live
|
||||
owner above the latch too: `simulation_service_world_outcome_mode_prompt_and_transition_effects`
|
||||
`0x00436350` is the frame-serviced consumer of `[world+0x4a73]`, stamping completion latch
|
||||
`[world+0x4a77]`, driving the outcome-mode prompt rooted at localized id `0x169`, and triggering
|
||||
the world-side transition paths around `0x482150` while leaving `[world+0x4b47]` as the current
|
||||
outcome-status payload source. That gives a grounded live
|
||||
interpretation for the start of the tail: `[world+0x4b47]` is the start of a victory or outcome
|
||||
status-text buffer, not a float lane. The same evidence also gives a useful caution: those live
|
||||
helpers copy up to `0x12c` bytes into `[world+0x4b47..+0x4c73]`, so the current bounded file-tail
|
||||
|
|
@ -188,7 +274,18 @@ The same brush strip is tighter now too:
|
|||
`Starting Building Density Level`, `0x0f61` maps to `[world+0x4c7c]` `Building Density Growth`,
|
||||
`0x0f65` maps to grounded dword `[world+0x4c80]` `leftover simulation time accumulator`, and
|
||||
`0x0f6d` maps to byte `[world+0x4c88]` `selected-year lane snapshot`. The first later grounded
|
||||
dword after that is `[world+0x4c8c]` at `0x0f71`. That means the simple 4-byte file-lane model
|
||||
dword after that is `[world+0x4c8c]` at `0x0f71`. The frame-side follow-on above the outcome
|
||||
prompt is grounded now too: after `0x00436350` stamps `[world+0x4a77]`, internal branch
|
||||
`0x0043963d` keeps running only while `[world+0x4a7b]` still matches the current step-local
|
||||
marker, then services the queued runtime-effect record family rooted at `[world+0x66a6]`
|
||||
through `0x00438710`, conditionally opens `Overview.win` through `0x004f3a10` when the preview
|
||||
fixed-record collection at `0x006cea4c` still has one admissible entry, and conditionally opens
|
||||
`LoadScreen.win` page `0` through `0x004e4ee0` when shell latch `0x006d4000` is clear and
|
||||
world flag `[world+0x4d]` is still nonzero. The same branch also conditionally toggles pause or
|
||||
resume through `0x00437a60` when no live multiplayer session object is present at `0x006cd8d8`.
|
||||
That splits the outcome prompt owner `0x00436350` cleanly from the later post-transition
|
||||
follow-on strip instead of leaving both behaviors folded into one unnamed frame tail. That means
|
||||
the simple 4-byte file-lane model
|
||||
stops matching grounded live field boundaries immediately after the text-buffer edge: the post-
|
||||
`0x0f58` file bytes are still offset-correlated to live state, but they are no longer naturally
|
||||
dword-aligned with the next grounded object fields. The new byte-neighborhood probe makes the
|
||||
|
|
@ -381,7 +478,22 @@ The same brush strip is tighter now too:
|
|||
safest semantic read is that this shared catalog is the bundled source form of the scenario-side
|
||||
named candidate-availability table later mirrored into `[state+0x66b2]`, with each entry's
|
||||
trailing dword now reading as the same availability override bit later copied into
|
||||
`[candidate+0x7ac]`. The loader-side coverage is tighter now too: the same table parser now
|
||||
`[candidate+0x7ac]`. The candidate-side refresh strip is tighter now too: `0x00412c10` walks
|
||||
the live candidate pool, forces `[candidate+0x7ac] = 1` whenever availability bytes
|
||||
`[candidate+0xba/+0xbb]` are already set or subtype `[candidate+0x32]` is not `2`, and only for
|
||||
the remaining subtype-`2` records does it consult `0x00434ea0` by stem before tailing into the
|
||||
dependent cargo-economy filter rebuild `0x0041eac0`. The adjacent collection helpers also read
|
||||
cleanly now: `0x00412bd0` is the collection-wide `0x00411ee0` cargo-summary rebuild sweep over
|
||||
imported `0xbc` descriptor arrays, while `0x00412ba0` is the remove-and-release sibling that
|
||||
clears one candidate's dependent runtime descriptor and cargo-membership tables through
|
||||
`0x00411cb0` before erasing that id from the pool. One lower runtime detail is explicit now too:
|
||||
`0x00411ee0` does not just “refresh summary tables.” It rebuilds the two emitted cargo-id tables
|
||||
at `[candidate+0x79c]` and `[candidate+0x7a0]` from one temporary `0x35`-cargo mark band, stores
|
||||
their counts at `[candidate+0x7a4]` and `[candidate+0x7a8]`, and accumulates the scaled runtime
|
||||
rates into `[candidate+0xa1..+0xb8]`; mode-`0` descriptor rows use the shared production cap at
|
||||
`[candidate+0x2a]` divided by the descriptor amount, while nonzero mode rows bypass that cap
|
||||
scaling. The loader-side coverage is tighter now too:
|
||||
the same table parser now
|
||||
attaches both to the common-save bridge payload and directly to the fixed source range in
|
||||
`.gmp` files and the non-common `rt3-105-scenario-save` / `rt3-105-alt-save` branches. That
|
||||
makes the scenario variation explicit instead of anecdotal. `Alternate USA` keeps only three
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -31,6 +31,19 @@ The neighboring connection-state note pair now appears
|
|||
through the wider multiplayer preview launch-state service. So the station-detail overlay
|
||||
currently owns only the `Coming To`, `Going From`, `Current Supply`, `Current Demand`, `--None--`,
|
||||
and `All` legend lanes.
|
||||
|
||||
That formatter boundary is tighter now too. `0x004207d0` returns `0` immediately when preview-global
|
||||
`0x0062be84` is armed, forwards directly into the shared fallback formatter `0x00455860` when
|
||||
subtype dword `[this+0x23e]` is nonzero, and only otherwise runs its own connection-status path. On
|
||||
that main path it rounds the current normalized city coordinates, samples one world-view-dependent
|
||||
alpha byte through `world_view_query_city_label_alpha_byte_from_normalized_xy_and_view_scalars`
|
||||
`0x0043ad50`, and then tries to resolve one linked station-or-transit site through the active
|
||||
selection or scenario fallback object. When that linked-site path succeeds, the formatter forces a
|
||||
highlighted top color lane with alpha `0xff` and appends localized id `207` `(Connected)`; when it
|
||||
does not, it only reuses the sampled byte from `0x0043ad50` when that value is nonzero and below
|
||||
`0xff`. The tail also splits cleanly now: one branch returns style code `1`, while the other derives
|
||||
one label-priority scalar from `[this+0x25e]` or the piecewise-scaled `[this+0x312]` path, clamps
|
||||
that priority to `0x95`, resolves the final style through `0x0053de00`, and returns style code `3`.
|
||||
#### Ownership side
|
||||
|
||||
One reusable site helper is grounded now too.
|
||||
|
|
@ -60,12 +73,17 @@ The city bonus formatter no longer depends only on
|
|||
The reusable bridge between the status formatter and the
|
||||
company news lane is now bounded too. `city_connection_bonus_build_peer_route_candidate` at
|
||||
`0x004046a0` reuses `city_connection_bonus_select_first_matching_peer_site` with both selector
|
||||
flags forced on, samples the selected peer's derived coordinates through `0x0047df30` and
|
||||
`0x0047df50`, and then either tries the shared heavy builder
|
||||
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` or falls
|
||||
back to the smaller wrapper `city_connection_bonus_try_compact_route_builder_from_region_entry`
|
||||
`0x00404640` before handing the result back to the company-side announcement sweep at
|
||||
`0x00406050`. The score side of that announcement lane is tighter now as well:
|
||||
flags forced on, rounds both the source-city and selected-peer normalized coordinates through
|
||||
`0x005a10d0`, and then first tries the shared heavy builder
|
||||
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` when the
|
||||
caller already supplied a live route-anchor tuple. When that direct attempt does not apply or no
|
||||
peer survives, it falls back to the smaller wrapper
|
||||
`city_connection_bonus_try_compact_route_builder_from_region_entry` `0x00404640`; and when both
|
||||
early attempts fail it builds one mixed 10-byte candidate list from the dense pair store
|
||||
`0x006cfcb4` and the route-entry store `0x006cfca8`, marks only route-anchor-eligible class-`2`
|
||||
sites through the `0x0048a1c0/0x0048a1a0/0x0048f290` route-anchor tests, and then retries
|
||||
`0x00402cb0` with the best surviving span-ranked candidate. The score side of that announcement
|
||||
lane is tighter now as well:
|
||||
`city_compute_connection_bonus_candidate_weight` at `0x004010f0` provides the per-city opportunity
|
||||
weight, `company_query_min_linked_site_distance_to_xy` at `0x00405920` provides the nearest
|
||||
linked-site distance term, `company_count_linked_transit_sites` at `0x00426590` provides one of
|
||||
|
|
@ -97,14 +115,32 @@ The reusable bridge between the status formatter and the
|
|||
narrower city-connection public-opinion lane or as part of a broader management-attitude family,
|
||||
not the ownership of the connection-bonus formatter, peer-route candidate path, or company news
|
||||
gate.
|
||||
|
||||
The ordinary `StationDetail.win` caller strip is tighter now too. In the non-scenario, non-class
|
||||
`3/4` branch, `shell_station_detail_window_refresh_controls` `0x00506610` rebuilds the nearby-site
|
||||
lane first through `shell_station_detail_refresh_nearby_structure_jump_rows` `0x00505470`, then
|
||||
rebuilds the paired hauled-traffic widgets through two calls to
|
||||
`shell_station_detail_build_to_from_haul_summary_widget` `0x00505150`. That hauled-traffic helper
|
||||
does more than publish a heading: it normalizes the incoming float lane into a bounded ten-step
|
||||
fill count, resolves per-step styles through `0x0053de00/0x00552560`, and on first build wires the
|
||||
matching `0xb3f6` or `0xb3f7` click target back to
|
||||
`shell_station_detail_present_to_from_haul_stats_popup` `0x00504770` through `0x00540120`. The
|
||||
nearby-site helper has a similarly concrete split now: for each of the fixed five categories it
|
||||
counts entries through `0x0047dc90`, emits the descriptive text block through `0x0051b700 ->
|
||||
0x0053f9c0`, and then builds the paired jump-control payload through `0x0053b070 -> 0x0055a040 ->
|
||||
0x0053f9c0`, with text rows under `0xb40a..0xb40e` and jump controls under `0xb410..0xb414`. So
|
||||
the remaining uncertainty in the ordinary branch is no longer the ownership of those lanes; it is
|
||||
the broader user-facing meaning of later callers above the row callbacks.
|
||||
#### Route-list side
|
||||
|
||||
The neighboring helper
|
||||
`placed_structure_append_unique_route_entry` at `0x0047f010` is now grounded as the
|
||||
append-if-missing builder for the six-byte route-entry list rooted at `[site+0x462]` and
|
||||
`[site+0x466]`. That matters here because the directional overlay query at `0x0047e690` consumes
|
||||
the same list, so the remaining uncertainty is no longer list ownership. It is down to the exact
|
||||
semantics of each entry's `u32` payload.
|
||||
`[site+0x466]`. One tighter boundary closes the overlay-side uncertainty further: the directional
|
||||
overlay query at `0x0047e690` only consumes the leading `u16` peer-site key when it walks that
|
||||
list and does not currently read the trailing `u32` companion payload at all. So the remaining
|
||||
uncertainty is no longer route-list ownership or overlay dependence on that payload; it is only
|
||||
the broader meaning of the payload for other caller families.
|
||||
#### Route-entry and Cache Side
|
||||
|
||||
The adjacent helper strip is tighter now too.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue