summaryrefslogtreecommitdiffstats
path: root/src/netvars.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/netvars.cpp44
1 files changed, 4 insertions, 40 deletions
diff --git a/src/netvars.cpp b/src/netvars.cpp
index f702c41..b4e31d5 100644
--- a/src/netvars.cpp
+++ b/src/netvars.cpp
@@ -27,24 +27,7 @@ static bool module_string(uintptr_t p, char *out, size_t outn) {
27 27
28static int g_dumped_tables = 0; 28static int g_dumped_tables = 0;
29 29
30// per-client-class health offset (m_iHealth lives at different offsets per 30static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) {
31// class chain: CBasePlayer via DT_BasePlayer=128, NPCs via DT_BaseCombatCharacter)
32static struct {
33 char name[32];
34 int off;
35} g_class_health[256];
36static int g_class_health_n = 0;
37
38int class_health_off(const char *name) {
39 for (int i = 0; i < g_class_health_n; i++)
40 if (strcmp(name, g_class_health[i].name) == 0)
41 return g_class_health[i].off;
42 return -1;
43}
44
45static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth,
46 int *out_health)
47{
48 if (depth > 8) 31 if (depth > 8)
49 return; 32 return;
50 uintptr_t props = *(uintptr_t *)(table + 0x00); 33 uintptr_t props = *(uintptr_t *)(table + 0x00);
@@ -85,13 +68,10 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth,
85 logf(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2, 68 logf(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2,
86 ptype, poff, poff, ptable ? "yes" : "no", parray ? "yes" : "no"); 69 ptype, poff, poff, ptable ? "yes" : "no", parray ? "yes" : "no");
87 if (ptable) { 70 if (ptable) {
88 collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1, 71 collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1);
89 out_health);
90 continue; 72 continue;
91 } 73 }
92 74
93 if (out_health && *out_health < 0 && strcmp(pname2, "m_iHealth") == 0)
94 *out_health = (int)(base_off + (uint32_t)poff);
95 if (strcmp(pname2, "m_lifeState") == 0 && g_net.lifestate < 0) { 75 if (strcmp(pname2, "m_lifeState") == 0 && g_net.lifestate < 0) {
96 g_net.lifestate = (int)(base_off + (uint32_t)poff); 76 g_net.lifestate = (int)(base_off + (uint32_t)poff);
97 } else if (strcmp(pname2, "m_nModelIndex") == 0 && g_net.modelindex < 0) { 77 } else if (strcmp(pname2, "m_nModelIndex") == 0 && g_net.modelindex < 0) {
@@ -217,25 +197,9 @@ void resolve_netvars() {
217 for (uintptr_t cc = head; cc && g_client.contains(cc) && classes < 1024; 197 for (uintptr_t cc = head; cc && g_client.contains(cc) && classes < 1024;
218 cc = *(uintptr_t *)(cc + 0x10)) { 198 cc = *(uintptr_t *)(cc + 0x10)) {
219 classes++; 199 classes++;
220 char cname[32]; 200 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0);
221 int hoff = -1;
222 // per-class health offset — NPCs send m_iHealth via their own table chain,
223 // not DT_BasePlayer's; g_net.health keeps the player's for aimbot use
224 if (module_string(*(uintptr_t *)(cc + 0x08), cname, sizeof(cname))) {
225 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0, &hoff);
226 if (hoff >= 0 && g_class_health_n < 256) {
227 char *dst = g_class_health[g_class_health_n].name;
228 const char *src = cname;
229 size_t n = sizeof(g_class_health[g_class_health_n].name) - 1;
230 for (size_t i = 0; i < n && src[i]; i++) dst[i] = src[i];
231 dst[n] = 0;
232 g_class_health[g_class_health_n].off = hoff;
233 g_class_health_n++;
234 }
235 }
236 } 201 }
237 logf("client classes walked: %d, health-offset classes: %d", classes, 202 logf("client classes walked: %d", classes);
238 g_class_health_n);
239 203
240 if (g_net.movetype < 0 && !resolve_movetype()) { 204 if (g_net.movetype < 0 && !resolve_movetype()) {
241 // movetype unresolved — bhop still works, just no noclip/ladder guard 205 // movetype unresolved — bhop still works, just no noclip/ladder guard