From f4f3a7aae7197a65f980c146dfefc9123ebc5f45 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 8 Sep 2026 07:08:39 -0400 Subject: [PATCH] sync generated headers (640 addresses) after wire merge --- include/generated/sots_addresses.h | 28 +++++++++++++++++++++++++- include/generated/sots_stream_schema.h | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/generated/sots_addresses.h b/include/generated/sots_addresses.h index e536dcc..c526501 100644 --- a/include/generated/sots_addresses.h +++ b/include/generated/sots_addresses.h @@ -1,5 +1,5 @@ // GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1). -// Source: sots-re ghidra/addresses.json @ 5a3f986, generated 2026-09-08 by tools/gen_addresses.py +// Source: sots-re ghidra/addresses.json @ 2308b6e, generated 2026-09-08 by tools/gen_addresses.py // Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated). #pragma once #include @@ -1261,5 +1261,31 @@ constexpr uint32_t TechTree_ProcessResearch_TechsUnlockedCollector = 0x00187cc3; constexpr uint32_t ServerPlayer_OnTechResearched_RecordObservedTech = 0x00491790; // site site in ServerPlayer::OnTechResearched, second statement: `if (this->ResT(+0x294) == def) { if (this->ResearchRollPending(+0x3b4)) RollResearchEvent(this); this->ResearchRollPending = 0; this->ResT = 0; }`. RollResearchEvent (0x0088df20) draws EXACTLY ONE NextFloat unconditionally and then enters 0x00889d60 only when roll < ResearchEventOdds -- the odds are 0 for every tech outside the plague and AI-rebellion families, so that branch is normally dead. This is the one extra RNG word a completion consumes, and clearing ResT means a second completion in the same pass consumes none [verified] constexpr uint32_t ServerPlayer_OnTechResearched_ResearchRollBlock = 0x00491790; +// cdecl Game::SVScriptObject* (int encID) // The EncObj factory. `dec eax; cmp eax,0x16; ja ; jmp dword [eax*4 + 0x0052bf60]` -- a 23-entry dword jump table indexed by encID-1. Live ids: 1 VonNeumann, 3 Swarm, 4 Derelict, 5 Monitor, 7 SystemKiller, 8 PuppetMaster, 9 SlaversRefuel, 10 SwarmQueen, 14 Locust, 17 CrowRuins, 20 Refugees, 21 Ortgay. Ids 2, 6, 11-13, 15, 16, 18, 19, 22, 23 and everything outside 1..23 return NULL. Class names read off the vftable store in each ctor [verified] +constexpr uint32_t SVScriptObject_FactoryByEncID = 0x0012bf00; +// data void* [23] // the jump table SVScriptObject_FactoryByEncID indexes with encID-1 [verified] +constexpr uint32_t SVScriptObject_EncIDJumpTable = 0x0012bf60; +// thiscall Game::SVScriptObject* (Game::SVSOSots* this, int encID) // scans the loaded (id, obj) pair vector at this+0x0C..0x10 first and only calls SVScriptObject_FactoryByEncID on a miss [verified] +constexpr uint32_t SVSOSots_GetOrCreateEncObj = 0x001a4450; +// cdecl Game::SVScriptObject* (const char* xscn) // the xsc factory: a flat four-way _stricmp chain, EXHAUSTIVE. "traps" -> Game::SVSOTraps (ctor 0x0052cbb0), "crowdefs" -> Game::SVSOCrowDefenders (0x0052b3c0), "indsys" -> Game::SVSOIndependentSystems (0x0075b530), "gmtrigger" -> Game::SVSOGrandMenaceTrigger (0x004f5630). Falls through with "Error creating extra script %s." [verified] +constexpr uint32_t SVScriptObject_FactoryByScenarioName = 0x001a7050; +// thiscall void (Game::SVSOSots* this) // registers exactly traps, crowdefs, indsys and -- only when ScnObj == NULL -- gmtrigger. Corroborates that the four scenario names are the whole set [verified] +constexpr uint32_t SVSOSots_SeedNewGameScripts = 0x001a7d70; +// thiscall void (Game::SVSOSots* this, Mars::IStream* s) // slot 2 of vftable 0x00A063C4. Emits ScnID, ScnObj (only when non-NULL), numx x (xscn, xsc), NEncObjs x (EncID, EncObj) [verified] +constexpr uint32_t SVSOSots_Write = 0x0019ddf0; +// thiscall void (Game::SVSOSots* this, Mars::IStream* s) // slot 1. Accepts two tags Write never emits -- NPCPlr (int, first) and hastraps (bool) with a following traps object -- read-only backward compatibility; a writer that omits them is correct [verified] +constexpr uint32_t SVSOSots_Read = 0x001a7a40; +// data Game::SVSOSots vftable (slot0 dtor, slot1 Read 0x005a7a40, slot2 Write 0x0059ddf0) [verified] +constexpr uint32_t SVSOSots_vftable = 0x006063c4; +// data Game::SVSOIndependentSystems vftable. slot0 dtor 0x0075afb0; slot1 Read AND slot2 Write are both 0x005f8ac0, the shared `ret 4` no-op stub -- so the "indsys" frame is genuinely empty on disk and the class's 0x1c4-byte body is runtime-only state [verified] +constexpr uint32_t SVSOIndependentSystems_vftable = 0x00620314; +// thiscall void (void*, Mars::IStream*) // `C2 04 00` -- a bare RET 4 shared as the inherited Read/Write for classes that serialize nothing [verified] +constexpr uint32_t Streamable_NoOpStub = 0x001f8ac0; +// thiscall void (Game::SVSOCrowDefenders* this, Mars::IStream* s) // sys; ndsys count then a loop writing dsys; ndes count then a loop writing des; drad. NOTE: `dsys` is INSIDE the ndsys loop -- objects/layouts.json records it as a plain member, which is wrong, and no save can settle it because both counts are 0 everywhere [verified] +constexpr uint32_t SVSOCrowDefenders_Write = 0x000f8c90; +// thiscall void (Game::SVSOMonitor* this, Mars::IStream* s) // calls SVSODerelict::Write (0x004fc2b0) as its first act -- Monitor derives from Derelict, which is why its tag run starts NDsn/DsnID/Dwght + NAsg/Eflt/Esys before nt/scnm/spwt/rsmd/dsgn [verified] +constexpr uint32_t SVSOMonitor_Write = 0x000fd810; +// thiscall void (Game::SVSODerelict* this, Mars::IStream* s) // NDsn count then a loop of (DsnID, Dwght); NAsg count then a loop of (Eflt, Esys). Two fields per iteration in each, confirmed by the 8-byte element strides [verified] +constexpr uint32_t SVSODerelict_Write = 0x000fc2b0; } // namespace sots::addr diff --git a/include/generated/sots_stream_schema.h b/include/generated/sots_stream_schema.h index e641849..83908a0 100644 --- a/include/generated/sots_stream_schema.h +++ b/include/generated/sots_stream_schema.h @@ -1,5 +1,5 @@ // GENERATED -- do not edit. Wire schema of Sword of the Stars.exe (GOG 1.8.1). -// Source: sots-re objects/streams.json @ 5a3f986, generated 2026-09-08 by tools/gen_stream_schema.py +// Source: sots-re objects/streams.json @ 2308b6e, generated 2026-09-08 by tools/gen_stream_schema.py // // For each serializable class, the ordered sequence of items its Mars::IStreamable // Write() puts on the stream. Recovered mechanically from the serializers; the