From 6a7e0b3bae04a5a4667267b6a45baddeb66fc570 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 13:19:50 +0100 Subject: Fix No spread on the hl2_complete server build The server RandomSeed GOT slot was hardcoded to 0xce1348, measured on the older bin/server.so. The anniversary branch loads hl2_complete/bin/server.so, whose R_386_JMP_SLOT for RandomSeed is 0xce5348, so the patch hit unrelated writable data and no spread silently did nothing. - Read the relocation from the loaded module's ELF (module_jump_slot) instead of hardcoding, with the two known offsets as fallback. - Override whenever the RandomSeed caller's `this` is the local server player (CBaseEntity::FireBullets) instead of matching a hardcoded return-address range that also moved between builds. - m_takedamage is a char (FIELD_CHARACTER) in the 2013 SDK; resolve it as such and read a byte, so the IMMUNE damage tag actually works. --- CONTEXT.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'CONTEXT.md') diff --git a/CONTEXT.md b/CONTEXT.md index 5e36328..bd3507a 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -205,8 +205,10 @@ vocabulary / decisions. - Aimbot/silent aim/triggerbot/melee skip `IMMUNE` targets always and `ARMORED` targets unless the active weapon is the RPG (`active_weapon_contains` for `rocket_launcher`/`rpg`). -- Server `m_takedamage` (`FIELD_INTEGER`) is resolved alongside - `m_NPCState`; `0/1` means no damage. +- Server `m_takedamage` is a `char` in the 2013 SDK + (`CNetworkVarForDerived(char, m_takedamage)`, `FIELD_CHARACTER`), so it is + resolved with that type (int fallback) and read as a byte. `0/1` means no + damage. ## Bones / ESP @@ -287,6 +289,15 @@ vocabulary / decisions. `FIRE_BULLETS_FIRST_SHOT_ACCURATE`, so the table excludes it; the secondary uses all 12. Separate best starting seeds are precomputed for 1, 8 and 12 pellets. +- The server `RandomSeed` PLT slot is found at runtime by reading the loaded + `server.so` ELF relocation table (`module_jump_slot`): the anniversary + branch's `hl2_complete/bin/server.so` moved the `R_386_JMP_SLOT` from + `0xce1348` (older `bin/server.so`) to `0xce5348`, and the hardcoded patch + silently hit unrelated data. The hook overrides the seed whenever the + `RandomSeed` caller's `this` is the local server player, i.e. + `CBaseEntity::FireBullets`; the `CUniformRandomStream` wrappers and + constructor-time `RandomSeed(0)` resets pass other objects and are left + alone. - This attacks the random cone offset only. The cone size, the pistol's `m_flAccuracyPenalty` growth, the server view punch added to `GetAutoaimVector`, and any damage falloff are server-side state. In -- cgit v1.2.3