regenerate addresses header: lane AG's gate-indexed audit fragment (1269 entries)

This commit is contained in:
alex 2026-09-08 22:29:08 -04:00
parent e62d974601
commit 35b05ebc18

View file

@ -1,5 +1,5 @@
// GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1). // GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1).
// Source: sots-re ghidra/addresses.json @ bdaa26f, generated 2026-09-08 by tools/gen_addresses.py // Source: sots-re ghidra/addresses.json @ 48db3cc, generated 2026-09-08 by tools/gen_addresses.py
// Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated). // Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated).
#pragma once #pragma once
#include <cstdint> #include <cstdint>
@ -1237,6 +1237,50 @@ constexpr uint32_t Game_StarSystem_OutputRates_Write = 0x00345190;
constexpr uint32_t Game_StarSystem_OutputRates_Read = 0x003472a0; constexpr uint32_t Game_StarSystem_OutputRates_Read = 0x003472a0;
// layout sizeof(Game::StarSystem::OutputRates) -- enumeration meets embedding [verified] // layout sizeof(Game::StarSystem::OutputRates) -- enumeration meets embedding [verified]
constexpr uint32_t sizeof_Game_StarSystem_OutputRates = 0x0000001c; constexpr uint32_t sizeof_Game_StarSystem_OutputRates = 0x0000001c;
// thiscall int __thiscall (ServerSystem* this, int speciesIdx) // 91 B, RET 4. Reads this->addiction[speciesIdx] at +0x1e4+4k -- the int[7] table serialised as `nadct` + sparse (`ads`,`adt`) pairs. Returns 0 when the slot is 0; otherwise 1/2/3 by (Frame - stamp) against *StrategyVar_ADDICTION_PHASE2_START (10) and *_PHASE3_START (15). EVERY non-zero return path ends in `setne al`, so a caller reading AL gets the BOOLEAN `addiction[k] != 0` and the phase is discarded -- which is how ServerTradeManagerImpl_vslot15 uses it [verified]
constexpr uint32_t ServerSystem_GetAddictionPhase = 0x00345e40;
// thiscall void __thiscall (ServerSystem* this, int speciesIdx) // 621 B, RET 4. Refuses if this->+0x100 (owner) is null, if bit 5 of owner->[0x348 + 4*speciesIdx] is set, or if ServerSystem_GetAddictionPhase already reports the slot stamped. Otherwise computes a money term, posts EVENTSUM/EVENTMSG_ADDICTION_OUTBREAK and writes this->addiction[speciesIdx] = GetGame()->Frame(+0xc). DRAWS NOTHING. ONLY TWO CALLERS IMAGE-WIDE, both inside ServerTradeManagerImpl_vslot15 (0x0082cd50 the un-rolled seed grant, 0x0082cdc4 behind the Chance) -- so this function is the sole way any system becomes addicted, and the Chance-gated spread cannot fire until the un-rolled grant has seeded it [verified]
constexpr uint32_t ServerSystem_BeginAddiction = 0x0034ef70;
// thiscall void __thiscall (int speciesIdx /*ECX*/, int* out /*EAX*/) // jump table at 0x0053b6e8, seven entries; Ghidra's size 78 truncates before the table (rule 17). Writes the 10000-based TechID of that species' ADDICT TECH: k=0 0x2799, 1 0x279a, 2 0x279b, 3 0x279c, 4 and 5 -> 0xC5 (the image's `no tech` sentinel), 6 0x279d. Out-of-range logs `Species %s: No addict tech.` (0x009f9630). Called once, from InitTable 0x005453a0 at 0x005458a7, filling SpeciesDef+0x88 -- which is BIT 4 of ServerPlayer+0x348+4k in ServerPlayer_RebuildSpeciesTechFlags, the bit that gates the un-rolled addiction grant. NOT a wire techId, so tools/techid_table.py does not name these [verified]
constexpr uint32_t SpeciesDef_AddictTechForSpecies = 0x0013b620;
// data float -- the probability ServerTradeManagerImpl_vslot15 passes to Mars::RNG::Chance at 0x0082cdb8, reached as `mov ecx,ds:0x00af0c50; fld [ecx]` (0x00af0c50 holds a pointer to this storage word). Image default 0.2f, strictly inside (0,1), so Chance takes NEITHER early-out and the site costs EXACTLY ONE WORD per evaluation. Registered by a GlobalConst static-init stub against Data/Strategy/StrategyVars.txt with the %f parser 0x008b7020 [verified]
constexpr uint32_t StrategyVar_ADDICTION_SPREAD_ODDS = 0x006f0c4c;
// data int -- image default 10. ServerSystem_GetAddictionPhase returns 2 rather than 1 once (Frame - addiction[k]) exceeds this. Pointer at 0x00aeca58. Dead for the vslot15 gate, which only reads the boolean [verified]
constexpr uint32_t StrategyVar_ADDICTION_PHASE2_START = 0x006eca54;
// data int -- image default 15. ServerSystem_GetAddictionPhase returns 3 once (Frame - addiction[k]) exceeds this. Pointer at 0x00aeca60 [verified]
constexpr uint32_t StrategyVar_ADDICTION_PHASE3_START = 0x006eca5c;
// thiscall bool __thiscall (ServerSystem* this) // 12 B. `return this->+0x1c8 != 0` -- the IndependenceInfo* that the wire carries as `hindi` (present) + `indi`. ServerSpyManager_vslot14 rejects a spy whose target system passes this, which is conjunct G3 of the 0x0088dc43 counter-mission roll [verified]
constexpr uint32_t ServerSystem_IsIndependent = 0x00343fa0;
// marker The last byte of ServerSpyManager_vslot14's body (the `ret`). GHIDRA REPORTS 387 BYTES, i.e. an end of 0x0088dd03, WHICH IS INSIDE THE FUNCTION -- a third instance of rule 17 after 0x007aa240 and 0x00893290. A five-entry jump table for the mission-stage switch sits at 0x0088dd2c..0x0088dd3f, past both the Ghidra end and the real end; padding then runs to the next function start 0x0088dd40 [verified]
constexpr uint32_t ServerSpyManager_vslot14_RealEnd = 0x0048dd2b;
// cdecl bool __cdecl (StarFleet* fleet) // 91 B. `fleet && GetLocationAsTradeSector(fleet) && !FUN_00813ab0(fleet,0x80000,0) && TradeSector_PlayerTradesHere(sector, fleet->owner) && !FUN_006fe1d0(fleet, 0x800)`. TradeManager_Slot13RngCalleeB uses it to choose between two candidate filters. IT IS DETERMINISTICALLY FALSE for any fleet that reached B through vslot13: TradeSector_FleetMayRaid (0x0080ed50) demands the OPPOSITE on the last two conjuncts, so the `raid your own routes` arm of B is unreachable from the tail. PlayerAlliances_Relation returning 3 for self is the second, independent reason [verified]
constexpr uint32_t TradeSector_FleetRaidsOwnRoutes = 0x0040ecf0;
// thiscall ServerTradeManager method, 974 B. The function that DISAMBIGUATES Game::TradeRoute's endpoint fields: `if (rt->trfrs(+0x10) == 0) endpoint = GetGame()->Systems(+0x44)[rt->trfr(+0xc)] else endpoint = registry_lookup(GetGame()+0x84, rt->trfrs)`. So trfr / trto are SYSTEM INDICES into StrategyServer's system vector and trfrs / trtos are non-system endpoint IDS with 0 meaning `use the index`. Only the endpoint-resolution head of this function was read; the rest is unread [mapped]
constexpr uint32_t TradeManager_ResolveRouteEndpointOwner = 0x00441cd0;
// thiscall bool __thiscall (ServerTradeManager* this, Vector3* out, TradeRoute* rt, void* arg3) // 425 B, RET 0xC. Places the raid interception point along the route: a = Systems[rt->trfr]->Pos, b = Systems[rt->trto]->Pos, dist = |b-a|; frac = 1.0 when the route owner's species (+0x5c) is 1 or when either of two species tests on arg3 passes, ELSE frac = float(NextFloat()) drawn at 0x00820c1b; out = a + dir*(frac*dist + <double 0x009e20a0>). TWO CALLERS: 0x0082cf65 (inside CreateRaidEncounter's subtree) and 0x0088b62c (TradeManager_Slot13RngCalleeB, immediately after the target pick) [verified]
constexpr uint32_t TradeManager_ComputeRaidInterceptPoint = 0x00420af0;
// site call RNG_NextFloat (0x0047d830) inside TradeManager_ComputeRaidInterceptPoint, ECX = GetGame()->RNG(+0x16c) + 4. ONE STRATEGIC-GENERATOR WORD, unless the species short-circuit at 0x00820bc2/0x00820bd7/0x00820bf2 sets frac = 1.0 first. NOT IN ANY EARLIER INVENTORY. It makes TradeManager_Slot13RngCalleeB cost TWO words on a success (this plus RNG_NextInt at 0x0088b613), not the 0 lane AC measured on a state whose candidate list was empty [verified]
constexpr uint32_t TradeManager_RaidInterceptPoint_DrawSite = 0x00420c1b;
// thiscall ServerTradeManager method called at 0x008938ed as the FIRST act of ServerTradeManager_CreateRaidEncounter; fills the local vector at [ebp-0x1c]. When it comes back EMPTY, CreateRaidEncounter returns false at 0x008938fa -- BEFORE every draw in the function and its subtree. This is the gate lane H measured as `entered 3 times, 0 words'. Body not read [mapped]
constexpr uint32_t TradeManager_BuildRaidCandidates = 0x0043b110;
// site `jne 0x00893932` -- taken when TradeManager_BuildRaidCandidates produced a non-empty vector; the fall-through frees the vector and returns false with AL = 0. EVERY draw in CreateRaidEncounter and its subtree lies past this branch: 0x008939ee, then through 0x00892640 the five sites 0x0088f1eb, 0x0088f356, 0x0083b460, 0x00848fd9, 0x00820c1b. tail-rng-ledger.md section 11.1's `a success costs 0 or 1 further word' is right about the corpus and wrong about the code [verified]
constexpr uint32_t CreateRaidEncounter_EmptyCandidateListReturn = 0x004938fa;
// thiscall ServerTradeManager method, single caller ServerTradeManager_CreateRaidEncounter at 0x00893a25 (i.e. past the empty-candidate-list gate AND past the target pick at 0x008939ee). Calls TradeManager_SpawnEncounterSquadron 0x0088f070 (@0x008926ce), 0x00848e50 (@0x008926d9) and 0x0082ce00 (@0x00892700). The whole draw subtree of a SUCCESSFUL raid encounter hangs off it and has never been reached by any measurement in this campaign [verified]
constexpr uint32_t TradeManager_BuildRaidEncounter = 0x00492640;
// site call RNG_NextInt (0x004271c0) inside TradeManager_SpawnEncounterSquadron 0x0088f070, generator loaded at 0x0088f1da from +0x16c. One word plus its rejection loop. Reachable only past CreateRaidEncounter_EmptyCandidateListReturn [verified]
constexpr uint32_t SpawnEncounterSquadron_DrawSite1 = 0x0048f1eb;
// site call RNG_NextInt (0x004271c0) inside TradeManager_SpawnEncounterSquadron 0x0088f070, generator loaded at 0x0088f334. Same reachability [verified]
constexpr uint32_t SpawnEncounterSquadron_DrawSite2 = 0x0048f356;
// thiscall Called only from TradeManager_SpawnEncounterSquadron at 0x0088f0f7. Draws RNG_NextInt at 0x0083b460 on the strategic generator (loaded at 0x0083b44c). Body not read; listed because the sweep places it inside CreateRaidEncounter's unreached subtree [mapped]
constexpr uint32_t RaidEncounter_SquadronHelper = 0x0043b1e0;
// site call RNG_NextInt (0x004271c0) inside 0x0083b1e0, generator from +0x16c at 0x0083b44c [verified]
constexpr uint32_t RaidEncounter_SquadronHelper_DrawSite = 0x0043b460;
// thiscall Called only from TradeManager_BuildRaidEncounter at 0x008926d9. Draws RNG_NextInt at 0x00848fd9 on the strategic generator (loaded at 0x00848fc8). Body not read [mapped]
constexpr uint32_t RaidEncounter_Helper848e50 = 0x00448e50;
// site call RNG_NextInt (0x004271c0) inside 0x00848e50, generator from +0x16c at 0x00848fc8 [verified]
constexpr uint32_t RaidEncounter_Helper848e50_DrawSite = 0x00448fd9;
// thiscall Called only from TradeManager_BuildRaidEncounter at 0x00892700; calls TradeManager_ComputeRaidInterceptPoint at 0x0082cf65, which is where the NextFloat at 0x00820c1b is spent on this path. Body not read [mapped]
constexpr uint32_t RaidEncounter_Helper82ce00 = 0x0042ce00;
// thiscall void (Game::StrategyAIAgent::Streamable* this, Mars::Stream* s) // the body of every `Player.<id>.AIAgent` CD block. 36 wire items, NO conditionals: the only `if` the decompiler shows around `lnat` is an inlined std::vector destructor whose operator delete is marked noreturn, and both paths converge at 0x006c72e8. The agent object is *(this+4) [verified] // thiscall void (Game::StrategyAIAgent::Streamable* this, Mars::Stream* s) // the body of every `Player.<id>.AIAgent` CD block. 36 wire items, NO conditionals: the only `if` the decompiler shows around `lnat` is an inlined std::vector destructor whose operator delete is marked noreturn, and both paths converge at 0x006c72e8. The agent object is *(this+4) [verified]
constexpr uint32_t Game_StrategyAIAgent_Streamable_Write = 0x002c6f00; constexpr uint32_t Game_StrategyAIAgent_Streamable_Write = 0x002c6f00;
// thiscall bool (Game::StrategyAIAgent::Streamable* this, Mars::Stream* s) [verified] // thiscall bool (Game::StrategyAIAgent::Streamable* this, Mars::Stream* s) [verified]