summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ISURFACE_STATUS.md36
-rw-r--r--src/hl2h.h5
-rw-r--r--src/menu.cpp24
-rw-r--r--src/netvars.cpp44
4 files changed, 27 insertions, 82 deletions
diff --git a/src/ISURFACE_STATUS.md b/src/ISURFACE_STATUS.md
index de952cd..00a7adf 100644
--- a/src/ISURFACE_STATUS.md
+++ b/src/ISURFACE_STATUS.md
@@ -1,13 +1,13 @@
1# HL2hake ISurface Drawing — Status Report 1# HL2hake ISurface Drawing — Status Report
2 2
3## Date: 2026-09-12 (final round) 3## Date: 2026-09-12, updated 2026-10-26
4 4
5## Result: WORKING 5## Result: WORKING
6 6
7Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx` 7Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx`
8hook (slot 114) on the copied ISurface vtable, wrapping our draws in 8hook (slot 114) on the copied ISurface vtable, wrapping our draws in
9`PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface 9`PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface
10slots 6/10/12/17/18/20/22/66/67. 10slots 6/10/12/15/17/18/20/22/66/67.
11 11
12## Confirmed ISurface VTable Slots (disassembly-verified, binary=SDK header+4) 12## Confirmed ISurface VTable Slots (disassembly-verified, binary=SDK header+4)
13 13
@@ -18,6 +18,8 @@ slots 6/10/12/17/18/20/22/66/67.
18| 9 | `PopMakeCurrent(VPANEL)` | verified via disassembly | 18| 9 | `PopMakeCurrent(VPANEL)` | verified via disassembly |
19| 10 | `DrawSetColor(int r,g,b,a)` | stores RGBA at `this+0x24..0x27` | 19| 10 | `DrawSetColor(int r,g,b,a)` | stores RGBA at `this+0x24..0x27` |
20| 12 | `DrawFilledRect(int x0,y0,x1,y1)` | verified via disassembly | 20| 12 | `DrawFilledRect(int x0,y0,x1,y1)` | verified via disassembly |
21| 14 | `DrawOutlinedRect(int x0,y0,x1,y1)` | SDK header 10 + 4 |
22| 15 | `DrawLine(int x0,y0,x1,y1)` | SDK header 11 + 4 (skeleton ESP) |
21| 17 | `DrawSetTextFont(HFont)` | stores HFont at `this+0x290` | 23| 17 | `DrawSetTextFont(HFont)` | stores HFont at `this+0x290` |
22| 18 | `DrawSetTextColor(int r,g,b,a)` | stores RGBA at `this+0x28..0x2b` | 24| 18 | `DrawSetTextColor(int r,g,b,a)` | stores RGBA at `this+0x28..0x2b` |
23| 20 | `DrawSetTextPos(int x,y)` | stores at `this+0x2c/0x30` | 25| 20 | `DrawSetTextPos(int x,y)` | stores at `this+0x2c/0x30` |
@@ -65,24 +67,27 @@ fc-match findings (system fontconfig):
65 67
66## Menu 68## Menu
67 69
68- Tree: HL2hake → Bunnyhop/ABH, children indented (`g_depth[]`, +12px/level). 70- Starts fully collapsed on first open; `Insert` toggles it.
69- Right-aligned state at x=200: `[on]`/`[off]` for Active rows, 71- Tree: HL2hake -> Bunnyhop (Active, Auto-strafe), ABH (Active), ESP (Active,
70 `[keyname]` for Bind rows, `[press key]` while binding. 72 Show neutral/healthbar/healthnum/name/skeleton/box), Aimbot (Active, Bind,
73 Vischeck, Bones, Smoothness), Triggerbot (Active, Bind), Silent aim
74 (Active, Bind). Children indented by `g_depth[]` (+12px/level).
75- Right-aligned state at x=270: `[on]`/`[off]` for toggles, `[keyname]` for
76 binds, `[press key]` while binding, `N deg/tick` for values.
71- Feature gating: `feature_active(int)` (menu.cpp) — active AND 77- Feature gating: `feature_active(int)` (menu.cpp) — active AND
72 (bind==0 or key held). Called from `do_move` (hl2h.cpp) to gate 78 (bind==0 or key held), used by `do_move` and the aim features.
73 bhop (jump) and ABH branches. 79- Config: `$XDG_CONFIG_HOME/hl2hake/config` (fallback `~/.config/hl2hake/config`).
74- Config: INI at `~/.hl2hake.ini` (bhop/abh active+bind).
75 80
76## Build / Run 81## Build / Run
77 82
78- `./build.sh`: g++ `-m32 -O2 -fPIC -shared`, links 5 TUs, `-ldl`, 83- `./build.sh`: g++ `-m32 -O2 -std=c++17 -fPIC -shared`, 9 TUs
84 (`hl2h modules cinput netvars menu esp server bones vischeck`), `-ldl`,
79 `-Wall -Wextra -Werror` (all warnings fatal). 85 `-Wall -Wextra -Werror` (all warnings fatal).
80- `./play.sh -windowed +map d1_trainstation_01` (Steam runtime wrapper, 86- `./play.sh -windowed +map d1_trainstation_01` (Steam runtime wrapper,
81 `LD_PRELOAD=libhl2hake.so`). 87 `LD_PRELOAD=libhl2hake.so`).
82- Logs: `/tmp/hl2hake.log` (logf), `/tmp/hl2run.log` (stderr). 88- Logs: `/tmp/hl2hake.log` (logf), stderr.
83- Probe logging (`hook fired:`, `probe:`) removed 2026-09-12.
84- `HL2H_DRAW_TEST=1` env: draws red rect + "HL2H DRAW TEST" without 89- `HL2H_DRAW_TEST=1` env: draws red rect + "HL2H DRAW TEST" without
85 opening the menu. 90 opening the menu. `HL2H_BONE_DEBUG=1` draws head-hitbox markers.
86 91
87## Lessons 92## Lessons
88 93
@@ -98,7 +103,12 @@ fc-match findings (system fontconfig):
98## File Locations 103## File Locations
99 104
100- Project: `/home/salmon/Documents/rust/hl2h/` 105- Project: `/home/salmon/Documents/rust/hl2h/`
101- Hook + feature logic: `src/hl2h.cpp` 106- Hook + movement/feature logic: `src/hl2h.cpp`
102- Menu + drawing + config + input: `src/menu.cpp` 107- Menu + drawing + config + input: `src/menu.cpp`
108- ESP / skeleton drawing / aimbot / silent aim: `src/esp.cpp`
109- Bones + hitboxes: `src/bones.cpp`
110- Server-side entity/health access: `src/server.cpp`
111- World vischeck / entity trace: `src/vischeck.cpp`
103- Shared API: `src/hl2h.h` 112- Shared API: `src/hl2h.h`
113- Current project overview: `CONTEXT.md`
104- SDK headers: `source-sdk-2013/src/public/vgui/` 114- SDK headers: `source-sdk-2013/src/public/vgui/`
diff --git a/src/hl2h.h b/src/hl2h.h
index a08f029..37c849f 100644
--- a/src/hl2h.h
+++ b/src/hl2h.h
@@ -168,7 +168,6 @@ void fix_verified_crc(int seq, uint32_t crc);
168uint32_t usercmd_checksum(const CUserCmd *c); 168uint32_t usercmd_checksum(const CUserCmd *c);
169bool find_input_global(); 169bool find_input_global();
170void resolve_netvars(); 170void resolve_netvars();
171int class_health_off(const char *name);
172bool resolve_server_netvars(); 171bool resolve_server_netvars();
173int server_entity_health(int idx, int *maxhealth, int *lifestate, void **base_out); 172int server_entity_health(int idx, int *maxhealth, int *lifestate, void **base_out);
174int server_model_index(void *base); 173int server_model_index(void *base);
@@ -203,10 +202,6 @@ bool head_position(int idx, Vector &out);
203int aim_points(int idx, unsigned group_mask, Vector *out, int max); 202int aim_points(int idx, unsigned group_mask, Vector *out, int max);
204 203
205void outer_draw(); 204void outer_draw();
206// raw ISurface slot calls used by the PaintTraverseEx hook (hl2h.cpp)
207using SurfFn = void (*)(void *, ...);
208long surf_call_slot(void *surf, int slot, long a1 = 0, long a2 = 0);
209
210// ISurface pointer (defined in menu.cpp, used for drawing tests) 205// ISurface pointer (defined in menu.cpp, used for drawing tests)
211struct ISurface; 206struct ISurface;
212extern ISurface *g_surface; 207extern ISurface *g_surface;
diff --git a/src/menu.cpp b/src/menu.cpp
index c3bb9ae..d628873 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -217,22 +217,6 @@ static std::string config_path() {
217 return dir + "/config"; 217 return dir + "/config";
218} 218}
219 219
220[[maybe_unused]] static const char *sdl_scancode_name(int sc) {
221 if (sc == 0)
222 return "None";
223 static char buf[32];
224 snprintf(buf, sizeof(buf), "Key%d", sc);
225 return buf;
226}
227
228[[maybe_unused]] static int parse_sdl_scancode(const char *s) {
229 if (strcmp(s, "None") == 0 || strcmp(s, "") == 0)
230 return 0;
231 if (strncmp(s, "Key", 3) == 0)
232 return atoi(s + 3);
233 return 0;
234}
235
236static void config_save() { 220static void config_save() {
237 FILE *f = fopen(config_path().c_str(), "w"); 221 FILE *f = fopen(config_path().c_str(), "w");
238 if (!f) 222 if (!f)
@@ -758,14 +742,6 @@ void outer_draw() {
758 surf_pop_make_current(panel); 742 surf_pop_make_current(panel);
759} 743}
760 744
761// Call an arbitrary ISurface vtable slot with up to 2 long args (cdecl thiscall
762// on i386: this first, rest on stack).
763long surf_call_slot(void *surf, int slot, long a1, long a2) {
764 void **vt = *(void ***)surf;
765 using Fn = long (*)(void *, long, long);
766 return ((Fn)vt[slot])(surf, a1, a2);
767}
768
769// --------------------------------------------------------------------------- 745// ---------------------------------------------------------------------------
770// ISurface discovery — try known modules and all loaded .so files 746// ISurface discovery — try known modules and all loaded .so files
771// --------------------------------------------------------------------------- 747// ---------------------------------------------------------------------------
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