diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-27 15:40:52 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-27 15:40:52 +0100 |
| commit | a029f2e25586533eb3feebab64864a69919f93b9 (patch) | |
| tree | 233df88dac02f64cf83beede1a913ab5dcd70bbe /src/hl2h.cpp | |
| parent | Spread control: set random_seed after CInput::CreateMove (diff) | |
| download | hl2h-a029f2e25586533eb3feebab64864a69919f93b9.tar.gz hl2h-a029f2e25586533eb3feebab64864a69919f93b9.zip | |
Spread control: add server RandomSeed GOT diagnostic/override
Diffstat (limited to '')
| -rw-r--r-- | src/hl2h.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/hl2h.cpp b/src/hl2h.cpp index ee2e990..90e0990 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | #include "hl2h.h" | 2 | #include "hl2h.h" |
| 3 | #include <cmath> | 3 | #include <cmath> |
| 4 | #include <cstdarg> | 4 | #include <cstdarg> |
| 5 | #include <cstdlib> | ||
| 6 | #include <sys/mman.h> | ||
| 5 | 7 | ||
| 6 | // --------------------------------------------------------------------------- | 8 | // --------------------------------------------------------------------------- |
| 7 | // logging | 9 | // logging |
| @@ -403,7 +405,66 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags, | |||
| 403 | return cmd->buttons != before; | 405 | return cmd->buttons != before; |
| 404 | } | 406 | } |
| 405 | 407 | ||
| 408 | // --------------------------------------------------------------------------- | ||
| 409 | // server RandomSeed diagnostic / override | ||
| 410 | // --------------------------------------------------------------------------- | ||
| 411 | // | ||
| 412 | // The installed 2024 server build is stripped and its usercmd/server-random-seed | ||
| 413 | // handling differs from the 2013 SDK source. This hook is installed on the | ||
| 414 | // server.so GOT slot for RandomSeed (R_386_JUMP_SLOT at vaddr 0xce1348) so we | ||
| 415 | // can see which seed FireBullets actually uses and optionally force the chosen | ||
| 416 | // spread seed. Disabled unless HL2H_SEED_TRACE / HL2H_SEED_FORCE are set. | ||
| 417 | |||
| 418 | static void (*g_real_random_seed)(int) = nullptr; | ||
| 419 | static uintptr_t g_srv_base = 0; | ||
| 420 | static bool g_seed_hook_installed = false; | ||
| 421 | |||
| 422 | static void hkdSrvRandomSeed(int seed) { | ||
| 423 | uintptr_t ret = (uintptr_t)__builtin_return_address(0); | ||
| 424 | long off = (long)(ret - g_srv_base); | ||
| 425 | static bool trace = getenv("HL2H_SEED_TRACE") != nullptr; | ||
| 426 | static bool force = getenv("HL2H_SEED_FORCE") != nullptr; | ||
| 427 | static int logs = 0; | ||
| 428 | bool bullet_site = (off >= 0x216900 && off <= 0x216930); | ||
| 429 | if (trace && (bullet_site || logs < 12)) { | ||
| 430 | if (logs < 200) { | ||
| 431 | logs++; | ||
| 432 | logf("srvseed: seed=%d off=0x%lx bullet=%d", seed, off, | ||
| 433 | (int)bullet_site); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | if (force && bullet_site) | ||
| 437 | seed = 33; | ||
| 438 | if (g_real_random_seed) | ||
| 439 | g_real_random_seed(seed); | ||
| 440 | } | ||
| 441 | |||
| 442 | static void install_seed_hook() { | ||
| 443 | if (g_seed_hook_installed || !g_server.valid()) | ||
| 444 | return; | ||
| 445 | g_srv_base = g_server.ranges[0].lo; | ||
| 446 | uintptr_t slot = g_srv_base + 0xce1348; // R_386_JUMP_SLOT RandomSeed | ||
| 447 | if (!g_server.contains(slot)) | ||
| 448 | return; | ||
| 449 | g_real_random_seed = | ||
| 450 | (void (*)(int))dlsym(RTLD_NEXT, "RandomSeed"); | ||
| 451 | if (!g_real_random_seed) | ||
| 452 | g_real_random_seed = (void (*)(int))dlsym(RTLD_DEFAULT, "RandomSeed"); | ||
| 453 | if (!g_real_random_seed) { | ||
| 454 | logf("seed hook: real RandomSeed not found"); | ||
| 455 | return; | ||
| 456 | } | ||
| 457 | mprotect((void *)(slot & ~(uintptr_t)0xFFF), 0x1000, | ||
| 458 | PROT_READ | PROT_WRITE | PROT_EXEC); | ||
| 459 | *(uint32_t *)slot = (uint32_t)(uintptr_t)&hkdSrvRandomSeed; | ||
| 460 | g_seed_hook_installed = true; | ||
| 461 | logf("seed hook: server GOT %#lx -> %p (real %p)", | ||
| 462 | (unsigned long)slot, (void *)&hkdSrvRandomSeed, | ||
| 463 | (void *)g_real_random_seed); | ||
| 464 | } | ||
| 465 | |||
| 406 | static void do_move(int seq, float frametime) { | 466 | static void do_move(int seq, float frametime) { |
| 467 | install_seed_hook(); | ||
| 407 | static bool g_echo_sent = false; | 468 | static bool g_echo_sent = false; |
| 408 | if (!g_input || !g_net.ok()) | 469 | if (!g_input || !g_net.ok()) |
| 409 | return; | 470 | return; |
