diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-28 13:54:16 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-28 13:54:16 +0100 |
| commit | d156c4d06abca9284cb116063494355f53354d86 (patch) | |
| tree | 5289eb9a99716af4fb32448adfd07a89748a6c84 /src | |
| parent | Melee: surface weapon state across maps; reset stale caches (diff) | |
| download | hl2h-d156c4d06abca9284cb116063494355f53354d86.tar.gz hl2h-d156c4d06abca9284cb116063494355f53354d86.zip | |
Handles: use the 11-bit networked EHANDLE entity index
The client m_hActiveWeapon is a networked EHANDLE: low 11 bits are the
entity index and the rest is the serial. Masking with 0xFFFF included serial
bits, so on later maps the weapon index became garbage (e.g. 49184/12319)
and melee killbot could not recognize the crowbar. Use 0x7FF for client and
server active-weapon handles, weapon owner checks and item-ESP weapon skips.
Document the layout in CONTEXT.
Diffstat (limited to '')
| -rw-r--r-- | src/esp.cpp | 8 | ||||
| -rw-r--r-- | src/server.cpp | 2 |
2 files changed, 5 insertions, 5 deletions
diff --git a/src/esp.cpp b/src/esp.cpp index a0d84dd..3db25e6 100644 --- a/src/esp.cpp +++ b/src/esp.cpp | |||
| @@ -675,7 +675,7 @@ static bool active_weapon_contains(void *local_ent, const char *needle) { | |||
| 675 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); | 675 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); |
| 676 | if (h == 0xFFFFFFFFu) | 676 | if (h == 0xFFFFFFFFu) |
| 677 | return false; | 677 | return false; |
| 678 | int idx = (int)(h & 0xFFFF); | 678 | int idx = (int)(h & 0x7FF); // networked EHANDLE: 11-bit entity index |
| 679 | if (idx <= 0 || idx > 4096) | 679 | if (idx <= 0 || idx > 4096) |
| 680 | return false; | 680 | return false; |
| 681 | void *wep = entitylist_get(idx); | 681 | void *wep = entitylist_get(idx); |
| @@ -902,7 +902,7 @@ bool melee_weapon_active(void *local_ent) { | |||
| 902 | if (g_net.activeweapon >= 0) { | 902 | if (g_net.activeweapon >= 0) { |
| 903 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); | 903 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); |
| 904 | if (h != 0xFFFFFFFFu) | 904 | if (h != 0xFFFFFFFFu) |
| 905 | idx = (int)(h & 0xFFFF); | 905 | idx = (int)(h & 0x7FF); // 11-bit entity index; upper bits are serial |
| 906 | } | 906 | } |
| 907 | const char *cls = nullptr, *model = nullptr; | 907 | const char *cls = nullptr, *model = nullptr; |
| 908 | bool crowbar = check(idx, &cls, &model); | 908 | bool crowbar = check(idx, &cls, &model); |
| @@ -1221,7 +1221,7 @@ static bool active_weapon_is_shotgun(void *local_ent) { | |||
| 1221 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); | 1221 | uint32_t h = *(uint32_t *)((uintptr_t)local_ent + g_net.activeweapon); |
| 1222 | if (h == 0xFFFFFFFFu) | 1222 | if (h == 0xFFFFFFFFu) |
| 1223 | return false; | 1223 | return false; |
| 1224 | int idx = (int)(h & 0xFFFF); | 1224 | int idx = (int)(h & 0x7FF); // networked EHANDLE: 11-bit entity index |
| 1225 | if (idx <= 0 || idx > 4096) | 1225 | if (idx <= 0 || idx > 4096) |
| 1226 | return false; | 1226 | return false; |
| 1227 | void *wep = entitylist_get(idx); | 1227 | void *wep = entitylist_get(idx); |
| @@ -1486,7 +1486,7 @@ static int local_active_weapon_idx(int local_idx) { | |||
| 1486 | uint32_t h = *(uint32_t *)((uintptr_t)local + g_net.activeweapon); | 1486 | uint32_t h = *(uint32_t *)((uintptr_t)local + g_net.activeweapon); |
| 1487 | if (!item_handle_valid(h)) | 1487 | if (!item_handle_valid(h)) |
| 1488 | return -1; | 1488 | return -1; |
| 1489 | return (int)(h & 0xFFFF); | 1489 | return (int)(h & 0x7FF); |
| 1490 | } | 1490 | } |
| 1491 | 1491 | ||
| 1492 | static int classify_weapon(const char *model, const char *cls, char *label, | 1492 | static int classify_weapon(const char *model, const char *cls, char *label, |
diff --git a/src/server.cpp b/src/server.cpp index 115cd53..5599227 100644 --- a/src/server.cpp +++ b/src/server.cpp | |||
| @@ -210,6 +210,6 @@ int server_active_weapon(int idx) { | |||
| 210 | uint32_t h = *(uint32_t *)((uintptr_t)base + g_srv_activeweapon); | 210 | uint32_t h = *(uint32_t *)((uintptr_t)base + g_srv_activeweapon); |
| 211 | if (h == 0xFFFFFFFFu) | 211 | if (h == 0xFFFFFFFFu) |
| 212 | return -1; | 212 | return -1; |
| 213 | int wi = (int)(h & 0xFFFF); | 213 | int wi = (int)(h & 0x7FF); // 11-bit entity index |
| 214 | return (wi > 0 && wi <= 4096) ? wi : -1; | 214 | return (wi > 0 && wi <= 4096) ? wi : -1; |
| 215 | } | 215 | } |
