summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ISURFACE_STATUS.md6
-rw-r--r--src/esp.cpp124
-rw-r--r--src/hl2h.cpp15
-rw-r--r--src/hl2h.h25
-rw-r--r--src/menu.cpp35
-rw-r--r--src/netvars.cpp56
6 files changed, 224 insertions, 37 deletions
diff --git a/src/ISURFACE_STATUS.md b/src/ISURFACE_STATUS.md
index 32a27bb..de952cd 100644
--- a/src/ISURFACE_STATUS.md
+++ b/src/ISURFACE_STATUS.md
@@ -65,13 +65,13 @@ fc-match findings (system fontconfig):
65 65
66## Menu 66## Menu
67 67
68- Tree: HL2hake → Climb/Bunnyhop/ABH, children indented (`g_depth[]`, +12px/level). 68- Tree: HL2hake → Bunnyhop/ABH, children indented (`g_depth[]`, +12px/level).
69- Right-aligned state at x=200: `[on]`/`[off]` for Active rows, 69- Right-aligned state at x=200: `[on]`/`[off]` for Active rows,
70 `[keyname]` for Bind rows, `[press key]` while binding. 70 `[keyname]` for Bind rows, `[press key]` while binding.
71- Feature gating: `feature_active(int)` (menu.cpp) — active AND 71- Feature gating: `feature_active(int)` (menu.cpp) — active AND
72 (bind==0 or key held). Called from `do_move` (hl2h.cpp) to gate 72 (bind==0 or key held). Called from `do_move` (hl2h.cpp) to gate
73 climb (middle-mouse) and bhop (jump) branches. 73 bhop (jump) and ABH branches.
74- Config: INI at `~/.hl2hake.ini` (climb/bhop/abh active+bind). 74- Config: INI at `~/.hl2hake.ini` (bhop/abh active+bind).
75 75
76## Build / Run 76## Build / Run
77 77
diff --git a/src/esp.cpp b/src/esp.cpp
new file mode 100644
index 0000000..87d0b80
--- /dev/null
+++ b/src/esp.cpp
@@ -0,0 +1,124 @@
1// esp.cpp — ESP drawing + shared world_to_screen / entity gather (aimbot reuses these)
2#include "hl2h.h"
3#include <cmath>
4#include <cstring>
5#include <cstddef>
6
7static constexpr float PI_F = 3.14159265358979323846f;
8
9// ISurface slots (binary = SDK header + 4, disassembly-confirmed)
10enum SurfSlot {
11 SURF_DrawSetColor = 10, SURF_FilledRect = 12, SURF_OutlinedRect = 14,
12 SURF_GetScreenSize = 38,
13};
14
15struct EspTarget {
16 float sx, sy; // screen pos of feet
17 float h; // box height px
18 float health, maxhealth;
19 int teamnum;
20 char name[48];
21};
22static EspTarget g_targets[128];
23static int g_ntargets = 0;
24static int g_scr_w = 0, g_scr_h = 0;
25static bool g_esp_logged = false;
26
27bool world_to_screen(const Vector &w, float &sx, float &sy) {
28 float pitch = g_cam_view.x * PI_F / 180.0f;
29 float yaw = g_cam_view.y * PI_F / 180.0f;
30 float sp = sinf(pitch), cp = cosf(pitch);
31 float syy = sinf(yaw), cy = cosf(yaw);
32 float fwd[3] = {cp * cy, cp * syy, -sp};
33 float right[3] = {syy, -cy, 0};
34 float up[3] = {sp * cy, sp * syy, cp};
35 float dx = w.x - g_cam_eye.x, dy = w.y - g_cam_eye.y, dz = w.z - g_cam_eye.z;
36 float z = dx * fwd[0] + dy * fwd[1] + dz * fwd[2];
37 if (z < 1.0f) return false;
38 float x = dx * right[0] + dy * right[1] + dz * right[2];
39 float y = dx * up[0] + dy * up[1] + dz * up[2];
40 float tanfov = tanf(75.0f * 0.5f * PI_F / 180.0f);
41 sx = (float)g_scr_w * 0.5f + (x / z) * ((float)g_scr_w * 0.5f / tanfov);
42 sy = (float)g_scr_h * 0.5f - (y / z) * ((float)g_scr_w * 0.5f / tanfov);
43 return true;
44}
45
46static void esp_collect(int local_idx) {
47 g_ntargets = 0;
48 using Fn = int (*)(void *);
49 int maxent = vfunc<Fn>(g_iface.entitylist, 5)(g_iface.entitylist); // GetHighestEntityIndex
50 if (maxent < 0 || maxent > 512) maxent = 512;
51 for (int idx = 0; idx <= maxent && g_ntargets < 128; idx++) {
52 if (idx == local_idx) continue;
53 void *ent = entitylist_get(idx);
54 if (!ent) continue;
55 uintptr_t e = (uintptr_t)ent;
56 float hpv = (float)*(int *)(e + g_net.health); // m_iHealth is int
57 if (!(hpv > 0)) continue;
58 Vector origin{*(float *)(e + g_net.origin), *(float *)(e + g_net.origin + 4),
59 *(float *)(e + g_net.origin + 8)};
60 // ponytail: maxs netvar may be unresolved; fixed 72-unit torso fallback
61 float maxsz = g_net.maxs >= 0 ? *(float *)(e + g_net.maxs) : 72.0f;
62 Vector top{origin.x, origin.y, origin.z + maxsz};
63 float sx, sy, tx, ty;
64 if (!world_to_screen(origin, sx, sy) || !world_to_screen(top, tx, ty))
65 continue;
66 float h = sy - ty;
67 if (h < 4.0f || sy < 0 || ty > (float)g_scr_h) continue; // behind / offscreen
68 EspTarget &t = g_targets[g_ntargets++];
69 t.sx = sx; t.sy = sy; t.h = h;
70 t.health = hpv;
71 t.maxhealth = (float)*(int *)(e + g_net.maxhealth);
72 if (t.maxhealth <= 0) t.maxhealth = hpv;
73 // classname via IClientNetworkable::GetClientClass (slot 2) -> m_pNetworkName @ +8
74 using CCFn = void *(*)(void *);
75 void *cc = vfunc<CCFn>(ent, 2)(ent);
76 const char *nn = cc ? *(const char **)((uintptr_t)cc + 8) : nullptr;
77 strncpy(t.name, nn ? nn : "?", sizeof(t.name) - 1);
78 t.name[sizeof(t.name) - 1] = 0;
79 }
80}
81
82static void surf_rect(int filled, int x0, int y0, int x1, int y1) {
83 using Fn = void (*)(void *, int, int, int, int);
84 vfunc<Fn>(g_surface, filled ? SURF_FilledRect : SURF_OutlinedRect)(g_surface, x0, y0, x1, y1);
85}
86static void surf_color(int r, int g, int b, int a) {
87 using Fn = void (*)(void *, int, int, int, int);
88 vfunc<Fn>(g_surface, SURF_DrawSetColor)(g_surface, r, g, b, a);
89}
90
91void esp_draw() {
92 if (!g_surface || !g_iface.entitylist || !g_net.esp_ok()) return;
93 if (!g_scr_w) {
94 using Fn = void (*)(void *, int &, int &);
95 vfunc<Fn>(g_surface, SURF_GetScreenSize)(g_surface, g_scr_w, g_scr_h);
96 logf("ESP: screen %dx%d", g_scr_w, g_scr_h);
97 if (!g_scr_w) return;
98 }
99 esp_collect(engine_get_local_player());
100 if (g_ntargets && !g_esp_logged) {
101 g_esp_logged = true;
102 logf("ESP: first draw, %d targets", g_ntargets);
103 }
104 for (int i = 0; i < g_ntargets; i++) {
105 const EspTarget &t = g_targets[i];
106 // team color: 3 combine red, 2 rebels green, else white
107 if (t.teamnum == 3) surf_color(255, 60, 60, 255);
108 else if (t.teamnum == 2) surf_color(60, 255, 60, 255);
109 else surf_color(255, 255, 255, 255);
110 float w = t.h * 0.45f; // ponytail: constant aspect, no OBB width — swap for m_vecMins/maxs span later
111 surf_rect(0, (int)(t.sx - w / 2), (int)(t.sy - t.h), (int)(t.sx + w / 2), (int)t.sy);
112 // health bar under box
113 float frac = t.health / t.maxhealth;
114 if (frac > 1) frac = 1;
115 surf_color(0, 0, 0, 200);
116 surf_rect(1, (int)(t.sx - w / 2), (int)t.sy + 1, (int)(t.sx + w / 2), (int)t.sy + 4);
117 if (frac > 0.5f) surf_color(40, 255, 40, 255);
118 else if (frac > 0.25f) surf_color(255, 255, 0, 255);
119 else surf_color(255, 40, 40, 255);
120 surf_rect(1, (int)(t.sx - w / 2), (int)t.sy + 2,
121 (int)(t.sx - w / 2 + w * frac), (int)t.sy + 3);
122 draw_text_col((int)(t.sx - w / 2), (int)(t.sy - t.h) - 14, t.name, 255, 255, 255);
123 }
124}
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index c6c0aeb..01fdb0f 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -32,7 +32,8 @@ void logf(const char *fmt, ...) {
32Module g_client, g_engine; 32Module g_client, g_engine;
33GameInterfaces g_iface; 33GameInterfaces g_iface;
34NetVars g_net; 34NetVars g_net;
35uintptr_t g_input = 0; 35Vector g_cam_eye{0, 0, 0};
36Vector g_cam_view{0, 0, 0};
36 37
37// --------------------------------------------------------------------------- 38// ---------------------------------------------------------------------------
38// vector math 39// vector math
@@ -81,7 +82,7 @@ float getfov(const QAngle &my_view, const QAngle &aim_ang) {
81} 82}
82 83
83// --------------------------------------------------------------------------- 84// ---------------------------------------------------------------------------
84// feature logic (bhop, ABH, climb) 85// feature logic (bhop, ABH)
85// --------------------------------------------------------------------------- 86// ---------------------------------------------------------------------------
86 87
87static int g_modified_logged = 0; 88static int g_modified_logged = 0;
@@ -103,19 +104,16 @@ void note_modified(const CUserCmd *cmd, int flags, const float *vel) {
103 104
104static bool g_logged_local = false; 105static bool g_logged_local = false;
105 106
106static int engine_get_local_player() { 107int engine_get_local_player() {
107 using Fn = int (*)(void *); 108 using Fn = int (*)(void *);
108 return vfunc<Fn>(g_iface.engine, 12)(g_iface.engine); 109 return vfunc<Fn>(g_iface.engine, 12)(g_iface.engine);
109} 110}
110 111
111static void *entitylist_get(int idx) { 112void *entitylist_get(int idx) {
112 using Fn = void *(*)(void *, int); 113 using Fn = void *(*)(void *, int);
113 return vfunc<Fn>(g_iface.entitylist, 3)(g_iface.entitylist, idx); 114 return vfunc<Fn>(g_iface.entitylist, 3)(g_iface.entitylist, idx);
114} 115}
115 116
116
117
118
119static void do_move(int seq) { 117static void do_move(int seq) {
120 static bool g_echo_sent = false; 118 static bool g_echo_sent = false;
121 if (!g_input || !g_net.ok()) 119 if (!g_input || !g_net.ok())
@@ -148,6 +146,9 @@ static void do_move(int seq) {
148 return; 146 return;
149 147
150 uintptr_t e = (uintptr_t)ent; 148 uintptr_t e = (uintptr_t)ent;
149 g_cam_eye = {*(float *)(e + g_net.origin), *(float *)(e + g_net.origin + 4), *(float *)(e + g_net.origin + 8)};
150 g_cam_eye.z += *(float *)(e + g_net.viewoffset);
151 g_cam_view = {cmd->viewangles[0], cmd->viewangles[1], cmd->viewangles[2]};
151 int flags = *(int *)(e + g_net.flags); 152 int flags = *(int *)(e + g_net.flags);
152 bool onground = (flags & FL_ONGROUND) != 0; 153 bool onground = (flags & FL_ONGROUND) != 0;
153 bool inwater = (flags & FL_INWATER) != 0; 154 bool inwater = (flags & FL_INWATER) != 0;
diff --git a/src/hl2h.h b/src/hl2h.h
index 88c6c0d..d6a005e 100644
--- a/src/hl2h.h
+++ b/src/hl2h.h
@@ -59,12 +59,20 @@ template <typename Fn> inline Fn vfunc(void *obj, size_t idx) {
59// --------------------------------------------------------------------------- 59// ---------------------------------------------------------------------------
60// netvars 60// netvars
61// --------------------------------------------------------------------------- 61// ---------------------------------------------------------------------------
62
63struct NetVars { 62struct NetVars {
64 int flags = -1; 63 int flags = -1;
65 int velocity = -1; 64 int velocity = -1;
66 int movetype = -1; 65 int movetype = -1;
66 int health = -1;
67 int maxhealth = -1;
68 int teamnum = -1;
69 int origin = -1;
70 int viewoffset = -1;
71 int mins = -1;
72 int maxs = -1;
73 // ponytail: mins/maxs may be absent from some HL2 netvar tables; esp.cpp falls back to h=72
67 bool ok() const { return flags >= 0 && velocity >= 0 && movetype >= 0; } 74 bool ok() const { return flags >= 0 && velocity >= 0 && movetype >= 0; }
75 bool esp_ok() const { return ok() && health >= 0 && maxhealth >= 0 && teamnum >= 0 && origin >= 0 && viewoffset >= 0; }
68}; 76};
69extern NetVars g_net; 77extern NetVars g_net;
70 78
@@ -116,16 +124,15 @@ enum { MOVETYPE_NOCLIP = 8, MOVETYPE_LADDER = 9 };
116 124
117struct Vector { float x, y, z; }; 125struct Vector { float x, y, z; };
118struct QAngle { float x, y, z; }; 126struct QAngle { float x, y, z; };
127// camera state captured each CreateMove (used by ESP / future aimbot)
128extern Vector g_cam_eye;
129extern Vector g_cam_view;
119QAngle vector_angles(const Vector &forward); 130QAngle vector_angles(const Vector &forward);
120Vector angle_forward_vector(const QAngle &angles); 131enum FeatureId { FEAT_BHOP = 0, FEAT_ABH = 1, FEAT_ESP = 2 };
121float getfov(const QAngle &my_view, const QAngle &aim_ang);
122 132
123// --------------------------------------------------------------------------- 133// ---------------------------------------------------------------------------
124// cross-file declarations 134// cross-file declarations
125// --------------------------------------------------------------------------- 135// ---------------------------------------------------------------------------
126
127// feature ids shared by menu (feature_active) and hl2h.cpp (do_move)
128enum FeatureId { FEAT_BHOP = 0, FEAT_ABH = 1 };
129void note_modified(const CUserCmd *cmd, int flags, const float *vel); 136void note_modified(const CUserCmd *cmd, int flags, const float *vel);
130CUserCmd *get_usercmd(int seq); 137CUserCmd *get_usercmd(int seq);
131void fix_verified_crc(int seq, uint32_t crc); 138void fix_verified_crc(int seq, uint32_t crc);
@@ -135,6 +142,12 @@ void resolve_netvars();
135void find_modules(); 142void find_modules();
136void init_conmsg(); 143void init_conmsg();
137bool feature_active(int feature); 144bool feature_active(int feature);
145void *entitylist_get(int idx);
146int engine_get_local_player();
147void draw_text_col(int x, int y, const char *s, int r, int g, int b);
148void esp_draw();
149bool world_to_screen(const Vector &w, float &sx, float &sy);
150
138void outer_draw(); 151void outer_draw();
139// raw ISurface slot calls used by the PaintTraverseEx hook (hl2h.cpp) 152// raw ISurface slot calls used by the PaintTraverseEx hook (hl2h.cpp)
140using SurfFn = void (*)(void *, ...); 153using SurfFn = void (*)(void *, ...);
diff --git a/src/menu.cpp b/src/menu.cpp
index 6dccf1c..302eab3 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -52,29 +52,32 @@ struct FeatureState {
52}; 52};
53 53
54static FeatureState g_bhop{true, 0}; 54static FeatureState g_bhop{true, 0};
55static FeatureState g_abh{true, 0};
56 55
56static FeatureState g_abh{true, 0};
57static FeatureState g_esp{true, 0};
57// tree 58// tree
58static MenuNode g_root{NODE_ROOT, "HL2hake", true, 0, {}, nullptr, nullptr, nullptr}; 59static MenuNode g_root{NODE_ROOT, "HL2hake", true, 0, {}, nullptr, nullptr, nullptr};
59static MenuNode g_bhop_feat{NODE_FEATURE, "Bunnyhop", true, 1, {}, nullptr, nullptr, nullptr}; 60static MenuNode g_bhop_feat{NODE_FEATURE, "Bunnyhop", true, 1, {}, nullptr, nullptr, nullptr};
60static MenuNode g_bhop_active{NODE_TOGGLE, "Active", false, 0, {}, &g_bhop.active, nullptr, nullptr}; 61static MenuNode g_bhop_active{NODE_TOGGLE, "Active", false, 0, {}, &g_bhop.active, nullptr, nullptr};
61static MenuNode g_abh_feat{NODE_FEATURE, "ABH", true, 1, {}, nullptr, nullptr, nullptr}; 62static MenuNode g_abh_feat{NODE_FEATURE, "ABH", true, 1, {}, nullptr, nullptr, nullptr};
62static MenuNode g_abh_active{NODE_TOGGLE, "Active", false, 0, {}, &g_abh.active, nullptr, nullptr}; 63static MenuNode g_abh_active{NODE_TOGGLE, "Active", false, 0, {}, &g_abh.active, nullptr, nullptr};
64static MenuNode g_esp_feat{NODE_FEATURE, "ESP", true, 1, {}, nullptr, nullptr, nullptr};
65static MenuNode g_esp_active{NODE_TOGGLE, "Active", false, 0, {}, &g_esp.active, nullptr, nullptr};
63 66
64static MenuNode *g_visible[16]; // flattened visible nodes for arrow navigation 67static MenuNode *g_visible[16]; // flattened visible nodes for arrow navigation
65static int g_visible_count = 0; 68static int g_visible_count = 0;
66static int g_selected = 0; 69static int g_selected = 0;
67bool g_menu_open = false; 70bool g_menu_open = false;
68 71
69// bind-select state 72static bool g_bind_mode = false;
70static bool g_bind_mode = false; // true = waiting for key press
71
72static void build_tree() { 73static void build_tree() {
73 g_bhop_feat.children[0] = &g_bhop_active; 74 g_bhop_feat.children[0] = &g_bhop_active;
74 g_abh_feat.children[0] = &g_abh_active; 75 g_abh_feat.children[0] = &g_abh_active;
76 g_esp_feat.children[0] = &g_esp_active;
75 g_root.children[0] = &g_bhop_feat; 77 g_root.children[0] = &g_bhop_feat;
76 g_root.children[1] = &g_abh_feat; 78 g_root.children[1] = &g_abh_feat;
77 g_root.child_count = 2; 79 g_root.children[2] = &g_esp_feat;
80 g_root.child_count = 3;
78} 81}
79 82
80static int g_depth[16]; // depth of each visible row (for indentation) 83static int g_depth[16]; // depth of each visible row (for indentation)
@@ -136,6 +139,7 @@ static void config_save() {
136 return; 139 return;
137 fprintf(f, "[bhop]\nactive=%d\nbind=%d\n", g_bhop.active, g_bhop.bind); 140 fprintf(f, "[bhop]\nactive=%d\nbind=%d\n", g_bhop.active, g_bhop.bind);
138 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); 141 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind);
142 fprintf(f, "[esp]\nactive=%d\nbind=%d\n", g_esp.active, g_esp.bind);
139 fclose(f); 143 fclose(f);
140} 144}
141 145
@@ -152,6 +156,8 @@ static void config_load() {
152 cur = &g_bhop; 156 cur = &g_bhop;
153 else if (strstr(line, "[abh]")) 157 else if (strstr(line, "[abh]"))
154 cur = &g_abh; 158 cur = &g_abh;
159 else if (strstr(line, "[esp]"))
160 cur = &g_esp;
155 else 161 else
156 cur = nullptr; 162 cur = nullptr;
157 } else if (cur) { 163 } else if (cur) {
@@ -234,6 +240,7 @@ static void poll_mouse() {
234 return; 240 return;
235 int mx, my; 241 int mx, my;
236 unsigned mask = SDL_GetMouseState_real(&mx, &my); 242 unsigned mask = SDL_GetMouseState_real(&mx, &my);
243
237 for (int b = 0; b < 5; b++) { 244 for (int b = 0; b < 5; b++) {
238 bool down = (mask & (1u << b)) != 0; // SDL buttons 1..5 = bits 0..4 245 bool down = (mask & (1u << b)) != 0; // SDL buttons 1..5 = bits 0..4
239 int sc = MOUSE_BASE + b; 246 int sc = MOUSE_BASE + b;
@@ -269,8 +276,8 @@ static bool key_pressed(int sc) {
269// feature gate queried from hl2h.cpp do_move(): feature must be Active AND 276// feature gate queried from hl2h.cpp do_move(): feature must be Active AND
270// its bind key held (always-on when unbound). 277// its bind key held (always-on when unbound).
271bool feature_active(int feature) { 278bool feature_active(int feature) {
272 static FeatureState *feats[2] = {&g_bhop, &g_abh}; 279 static FeatureState *feats[3] = {&g_bhop, &g_abh, &g_esp};
273 if (feature < 0 || feature > 1) 280 if (feature < 0 || feature > 2)
274 return false; 281 return false;
275 FeatureState *f = feats[feature]; 282 FeatureState *f = feats[feature];
276 if (!f->active) 283 if (!f->active)
@@ -456,6 +463,15 @@ static void draw_text(int x, int y, const char *text) {
456 surf_draw_set_text_pos(x, y); 463 surf_draw_set_text_pos(x, y);
457 surf_draw_print_text(wtext, len); 464 surf_draw_print_text(wtext, len);
458} 465}
466void draw_text_col(int x, int y, const char *text, int r, int g, int b) {
467 wchar_t wtext[256];
468 mbstowcs(wtext, text, 255);
469 wtext[255] = 0;
470 surf_draw_set_text_font(g_font);
471 surf_draw_set_text_color(r, g, b, 255);
472 surf_draw_set_text_pos(x, y);
473 surf_draw_print_text(wtext, (int)wcslen(wtext));
474}
459 475
460// Draw overlay. MUST be called from inside the ISurface paint path 476// Draw overlay. MUST be called from inside the ISurface paint path
461// (see hkdDrawPrintText hook in hl2h.cpp): we wrap our draws in 477// (see hkdDrawPrintText hook in hl2h.cpp): we wrap our draws in
@@ -464,7 +480,8 @@ void outer_draw() {
464 menu_handle_input(); 480 menu_handle_input();
465 // HL2H_DRAW_TEST=1 draws a probe rect without needing the menu open 481 // HL2H_DRAW_TEST=1 draws a probe rect without needing the menu open
466 static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; 482 static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr;
467 if (!g_surface || (!g_menu_open && !draw_test)) 483 bool esp_on = feature_active(FEAT_ESP);
484 if (!g_surface || (!g_menu_open && !draw_test && !esp_on))
468 return; 485 return;
469 if (!g_font) { 486 if (!g_font) {
470 g_font = surf_create_font(); 487 g_font = surf_create_font();
@@ -485,6 +502,8 @@ void outer_draw() {
485 if (!panel) 502 if (!panel)
486 return; 503 return;
487 surf_push_make_current(panel, false); 504 surf_push_make_current(panel, false);
505 if (esp_on)
506 esp_draw();
488 if (draw_test) { 507 if (draw_test) {
489 surf_draw_set_color(255, 0, 0, 255); 508 surf_draw_set_color(255, 0, 0, 255);
490 surf_draw_filled_rect(20, 20, 180, 60); 509 surf_draw_filled_rect(20, 20, 180, 60);
diff --git a/src/netvars.cpp b/src/netvars.cpp
index 41070c7..5c8c296 100644
--- a/src/netvars.cpp
+++ b/src/netvars.cpp
@@ -82,10 +82,44 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) {
82 } else { 82 } else {
83 g_net.velocity = (int)(base_off + (uint32_t)poff); 83 g_net.velocity = (int)(base_off + (uint32_t)poff);
84 } 84 }
85 } else if (strcmp(pname2, "m_iHealth") == 0 && g_net.health < 0) {
86 g_net.health = (int)(base_off + (uint32_t)poff);
87 } else if (strcmp(pname2, "m_iMaxHealth") == 0 && g_net.maxhealth < 0) {
88 g_net.maxhealth = (int)(base_off + (uint32_t)poff);
89 } else if (strcmp(pname2, "m_iTeamNum") == 0 && g_net.teamnum < 0) {
90 g_net.teamnum = (int)(base_off + (uint32_t)poff);
91 } else if (strcmp(pname2, "m_vecOrigin") == 0 && g_net.origin < 0) {
92 if (parray && g_client.contains(parray)) {
93 int32_t eoff = *(int32_t *)(parray + 0x2C);
94 g_net.origin = (int)(base_off + (uint32_t)(eoff ? eoff : poff));
95 } else {
96 g_net.origin = (int)(base_off + (uint32_t)poff);
97 }
98 } else if (strcmp(pname2, "m_vecViewOffset") == 0 && g_net.viewoffset < 0) {
99 if (parray && g_client.contains(parray)) {
100 int32_t eoff = *(int32_t *)(parray + 0x2C);
101 g_net.viewoffset = (int)(base_off + (uint32_t)(eoff ? eoff : poff));
102 } else {
103 g_net.viewoffset = (int)(base_off + (uint32_t)poff);
104 }
105 } else if (strcmp(pname2, "m_vecMins") == 0 && g_net.mins < 0) {
106 if (parray && g_client.contains(parray)) {
107 int32_t eoff = *(int32_t *)(parray + 0x2C);
108 g_net.mins = (int)(base_off + (uint32_t)(eoff ? eoff : poff));
109 } else {
110 g_net.mins = (int)(base_off + (uint32_t)poff);
111 }
112 } else if (strcmp(pname2, "m_vecMaxs") == 0 && g_net.maxs < 0) {
113 if (parray && g_client.contains(parray)) {
114 int32_t eoff = *(int32_t *)(parray + 0x2C);
115 g_net.maxs = (int)(base_off + (uint32_t)(eoff ? eoff : poff));
116 } else {
117 g_net.maxs = (int)(base_off + (uint32_t)poff);
118 }
85 } 119 }
86 if (g_net.ok()) 120 if (g_net.esp_ok())
87 return; 121 return;
88 } 122}
89} 123}
90 124
91// prediction datamap scan for m_MoveType (FIELD_CHARACTER, fieldOffset in range) 125// prediction datamap scan for m_MoveType (FIELD_CHARACTER, fieldOffset in range)
@@ -161,11 +195,9 @@ void resolve_netvars() {
161 for (uintptr_t cc = head; cc && g_client.contains(cc) && classes < 1024; 195 for (uintptr_t cc = head; cc && g_client.contains(cc) && classes < 1024;
162 cc = *(uintptr_t *)(cc + 0x10)) { 196 cc = *(uintptr_t *)(cc + 0x10)) {
163 classes++; 197 classes++;
164 char name[64];
165 if (!module_string(*(uintptr_t *)(cc + 0x08), name, sizeof(name)))
166 break;
167 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0); 198 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0);
168 if (g_net.flags >= 0 && g_net.velocity >= 0) 199 if (g_net.esp_ok() || (g_net.flags >= 0 && g_net.velocity >= 0 &&
200 g_net.health < 0))
169 break; 201 break;
170 } 202 }
171 logf("client classes walked: %d", classes); 203 logf("client classes walked: %d", classes);
@@ -175,11 +207,9 @@ void resolve_netvars() {
175 logf("movetype guard disabled"); 207 logf("movetype guard disabled");
176 } 208 }
177 209
178 if (g_net.ok()) { 210 logf("netvars: flags=%d velocity=%d movetype=%d health=%d maxhealth=%d "
179 logf("netvars: m_fFlags=+0x%X m_vecVelocity[0]=+0x%X m_MoveType=+0x%X", 211 "teamnum=%d origin=%d viewoffset=%d mins=%d maxs=%d",
180 g_net.flags, g_net.velocity, g_net.movetype); 212 g_net.flags, g_net.velocity, g_net.movetype, g_net.health,
181 } else { 213 g_net.maxhealth, g_net.teamnum, g_net.origin, g_net.viewoffset,
182 logf("netvar resolution incomplete: flags=%d velocity=%d movetype=%d", 214 g_net.mins, g_net.maxs);
183 g_net.flags, g_net.velocity, g_net.movetype);
184 }
185} 215}