From 710e8cc59557bc95ed74af8726ea13012fde50c3 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 17:25:31 +0100 Subject: Items: read ammo and inventory from the server arrays The client m_iAmmo/m_hMyWeapons recv props still do not resolve, but the listen server has the same CBaseCombatCharacter arrays in its datamap. Resolve m_iAmmo and m_hMyWeapons there: - reserve ammo comes from server_player_ammo() when the client array is missing, so full-ammo filtering works (RPG rockets at 3); - the owned-weapon mask is filled from the server m_hMyWeapons[48] handles, so fallen weapons count as ammo before the player equips them. Widen the datamap field-size filter to 512 for the 192-byte handle array. --- src/esp.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/esp.cpp') diff --git a/src/esp.cpp b/src/esp.cpp index 1d4a6a5..b4d3eee 100644 --- a/src/esp.cpp +++ b/src/esp.cpp @@ -2396,9 +2396,14 @@ static int ammo_max(int type) { } static int local_ammo(void *local_ent, int type) { - if (!local_ent || g_net.ammo < 0 || type < 0 || type >= 32) + if (type < 0 || type >= 32) return -1; - return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4); + if (local_ent && g_net.ammo >= 0) + return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4); + // Client array offset may not resolve; the listen-server player has the + // same array in its datamap. + int local = engine_get_local_player(); + return local > 0 ? server_player_ammo(local, type) : -1; } static int classify_item(const char *model, const char *cls, char *label, @@ -2627,6 +2632,30 @@ static void items_collect(int local_idx) { if (wt > 0) owned_mask |= 1u << wt; } + // Server-side inventory, independent of the client recv-table arrays. + if (g_iface.engineserver) { + for (int slot = 0; slot < 48; slot++) { + uint32_t h = server_player_weapon(local_idx, slot); + if (!item_handle_valid(h)) + continue; + int wi = (int)(h & 0x7FF); + if (wi <= 0 || wi > 4096) + continue; + void *wep = entitylist_get(wi); + void *net = entity_networkable(wi); + const char *wc = net ? entity_class_name(net, nullptr) : nullptr; + const char *wm = wep ? entity_model_name(wep) : nullptr; + if (!wm) { + void *sb = nullptr; + server_entity_health(wi, nullptr, nullptr, &sb); + if (sb) + wm = model_name_from_index(server_model_index(sb)); + } + int wt = weapon_type_id(wm, wc); + if (wt > 0) + owned_mask |= 1u << wt; + } + } bool owned_weapon[WT_COUNT] = {}; for (int t = 1; t < WT_COUNT; t++) owned_weapon[t] = (owned_mask & (1u << t)) != 0; -- cgit v1.2.3