From d164e3373108d0c0f83452fbea22f8569b84eec6 Mon Sep 17 00:00:00 2001 From: salmonik Date: Mon, 26 Oct 2026 17:53:40 +0100 Subject: Docs/cleanup: refresh CONTEXT, update ISurface status, remove dead code - rewrite CONTEXT.md for the current architecture, interfaces, netvars, menu tree, bones/ESP, aimbot/vischeck, triggerbot, silent aim and ABH - update ISURFACE_STATUS.md: DrawLine slot, current menu/config path, 9 build TUs, current file layout - remove the stale root-level `tree` file - drop unused class_health_off/per-class health scan (NPC HP is not networked), surf_call_slot, and unused scancode helpers --- src/ISURFACE_STATUS.md | 36 +++++++++++++++++++++++------------- src/hl2h.h | 5 ----- src/menu.cpp | 24 ------------------------ src/netvars.cpp | 44 ++++---------------------------------------- 4 files changed, 27 insertions(+), 82 deletions(-) (limited to 'src') 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 @@ # HL2hake ISurface Drawing — Status Report -## Date: 2026-09-12 (final round) +## Date: 2026-09-12, updated 2026-10-26 ## Result: WORKING Overlay drawing works in-game and in menus. Draw path: `PaintTraverseEx` hook (slot 114) on the copied ISurface vtable, wrapping our draws in `PushMakeCurrent(panel, false)` / `PopMakeCurrent(panel)` around ISurface -slots 6/10/12/17/18/20/22/66/67. +slots 6/10/12/15/17/18/20/22/66/67. ## Confirmed ISurface VTable Slots (disassembly-verified, binary=SDK header+4) @@ -18,6 +18,8 @@ slots 6/10/12/17/18/20/22/66/67. | 9 | `PopMakeCurrent(VPANEL)` | verified via disassembly | | 10 | `DrawSetColor(int r,g,b,a)` | stores RGBA at `this+0x24..0x27` | | 12 | `DrawFilledRect(int x0,y0,x1,y1)` | verified via disassembly | +| 14 | `DrawOutlinedRect(int x0,y0,x1,y1)` | SDK header 10 + 4 | +| 15 | `DrawLine(int x0,y0,x1,y1)` | SDK header 11 + 4 (skeleton ESP) | | 17 | `DrawSetTextFont(HFont)` | stores HFont at `this+0x290` | | 18 | `DrawSetTextColor(int r,g,b,a)` | stores RGBA at `this+0x28..0x2b` | | 20 | `DrawSetTextPos(int x,y)` | stores at `this+0x2c/0x30` | @@ -65,24 +67,27 @@ fc-match findings (system fontconfig): ## Menu -- Tree: HL2hake → Bunnyhop/ABH, children indented (`g_depth[]`, +12px/level). -- Right-aligned state at x=200: `[on]`/`[off]` for Active rows, - `[keyname]` for Bind rows, `[press key]` while binding. +- Starts fully collapsed on first open; `Insert` toggles it. +- Tree: HL2hake -> Bunnyhop (Active, Auto-strafe), ABH (Active), ESP (Active, + Show neutral/healthbar/healthnum/name/skeleton/box), Aimbot (Active, Bind, + Vischeck, Bones, Smoothness), Triggerbot (Active, Bind), Silent aim + (Active, Bind). Children indented by `g_depth[]` (+12px/level). +- Right-aligned state at x=270: `[on]`/`[off]` for toggles, `[keyname]` for + binds, `[press key]` while binding, `N deg/tick` for values. - Feature gating: `feature_active(int)` (menu.cpp) — active AND - (bind==0 or key held). Called from `do_move` (hl2h.cpp) to gate - bhop (jump) and ABH branches. -- Config: INI at `~/.hl2hake.ini` (bhop/abh active+bind). + (bind==0 or key held), used by `do_move` and the aim features. +- Config: `$XDG_CONFIG_HOME/hl2hake/config` (fallback `~/.config/hl2hake/config`). ## Build / Run -- `./build.sh`: g++ `-m32 -O2 -fPIC -shared`, links 5 TUs, `-ldl`, +- `./build.sh`: g++ `-m32 -O2 -std=c++17 -fPIC -shared`, 9 TUs + (`hl2h modules cinput netvars menu esp server bones vischeck`), `-ldl`, `-Wall -Wextra -Werror` (all warnings fatal). - `./play.sh -windowed +map d1_trainstation_01` (Steam runtime wrapper, `LD_PRELOAD=libhl2hake.so`). -- Logs: `/tmp/hl2hake.log` (logf), `/tmp/hl2run.log` (stderr). -- Probe logging (`hook fired:`, `probe:`) removed 2026-09-12. +- Logs: `/tmp/hl2hake.log` (logf), stderr. - `HL2H_DRAW_TEST=1` env: draws red rect + "HL2H DRAW TEST" without - opening the menu. + opening the menu. `HL2H_BONE_DEBUG=1` draws head-hitbox markers. ## Lessons @@ -98,7 +103,12 @@ fc-match findings (system fontconfig): ## File Locations - Project: `/home/salmon/Documents/rust/hl2h/` -- Hook + feature logic: `src/hl2h.cpp` +- Hook + movement/feature logic: `src/hl2h.cpp` - Menu + drawing + config + input: `src/menu.cpp` +- ESP / skeleton drawing / aimbot / silent aim: `src/esp.cpp` +- Bones + hitboxes: `src/bones.cpp` +- Server-side entity/health access: `src/server.cpp` +- World vischeck / entity trace: `src/vischeck.cpp` - Shared API: `src/hl2h.h` +- Current project overview: `CONTEXT.md` - 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); uint32_t usercmd_checksum(const CUserCmd *c); bool find_input_global(); void resolve_netvars(); -int class_health_off(const char *name); bool resolve_server_netvars(); int server_entity_health(int idx, int *maxhealth, int *lifestate, void **base_out); int server_model_index(void *base); @@ -203,10 +202,6 @@ bool head_position(int idx, Vector &out); int aim_points(int idx, unsigned group_mask, Vector *out, int max); void outer_draw(); -// raw ISurface slot calls used by the PaintTraverseEx hook (hl2h.cpp) -using SurfFn = void (*)(void *, ...); -long surf_call_slot(void *surf, int slot, long a1 = 0, long a2 = 0); - // ISurface pointer (defined in menu.cpp, used for drawing tests) struct ISurface; extern 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() { return dir + "/config"; } -[[maybe_unused]] static const char *sdl_scancode_name(int sc) { - if (sc == 0) - return "None"; - static char buf[32]; - snprintf(buf, sizeof(buf), "Key%d", sc); - return buf; -} - -[[maybe_unused]] static int parse_sdl_scancode(const char *s) { - if (strcmp(s, "None") == 0 || strcmp(s, "") == 0) - return 0; - if (strncmp(s, "Key", 3) == 0) - return atoi(s + 3); - return 0; -} - static void config_save() { FILE *f = fopen(config_path().c_str(), "w"); if (!f) @@ -758,14 +742,6 @@ void outer_draw() { surf_pop_make_current(panel); } -// Call an arbitrary ISurface vtable slot with up to 2 long args (cdecl thiscall -// on i386: this first, rest on stack). -long surf_call_slot(void *surf, int slot, long a1, long a2) { - void **vt = *(void ***)surf; - using Fn = long (*)(void *, long, long); - return ((Fn)vt[slot])(surf, a1, a2); -} - // --------------------------------------------------------------------------- // ISurface discovery — try known modules and all loaded .so files // --------------------------------------------------------------------------- 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) { static int g_dumped_tables = 0; -// per-client-class health offset (m_iHealth lives at different offsets per -// class chain: CBasePlayer via DT_BasePlayer=128, NPCs via DT_BaseCombatCharacter) -static struct { - char name[32]; - int off; -} g_class_health[256]; -static int g_class_health_n = 0; - -int class_health_off(const char *name) { - for (int i = 0; i < g_class_health_n; i++) - if (strcmp(name, g_class_health[i].name) == 0) - return g_class_health[i].off; - return -1; -} - -static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth, - int *out_health) -{ +static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) { if (depth > 8) return; uintptr_t props = *(uintptr_t *)(table + 0x00); @@ -85,13 +68,10 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth, logf(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2, ptype, poff, poff, ptable ? "yes" : "no", parray ? "yes" : "no"); if (ptable) { - collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1, - out_health); + collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1); continue; } - if (out_health && *out_health < 0 && strcmp(pname2, "m_iHealth") == 0) - *out_health = (int)(base_off + (uint32_t)poff); if (strcmp(pname2, "m_lifeState") == 0 && g_net.lifestate < 0) { g_net.lifestate = (int)(base_off + (uint32_t)poff); } else if (strcmp(pname2, "m_nModelIndex") == 0 && g_net.modelindex < 0) { @@ -217,25 +197,9 @@ void resolve_netvars() { for (uintptr_t cc = head; cc && g_client.contains(cc) && classes < 1024; cc = *(uintptr_t *)(cc + 0x10)) { classes++; - char cname[32]; - int hoff = -1; - // per-class health offset — NPCs send m_iHealth via their own table chain, - // not DT_BasePlayer's; g_net.health keeps the player's for aimbot use - if (module_string(*(uintptr_t *)(cc + 0x08), cname, sizeof(cname))) { - collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0, &hoff); - if (hoff >= 0 && g_class_health_n < 256) { - char *dst = g_class_health[g_class_health_n].name; - const char *src = cname; - size_t n = sizeof(g_class_health[g_class_health_n].name) - 1; - for (size_t i = 0; i < n && src[i]; i++) dst[i] = src[i]; - dst[n] = 0; - g_class_health[g_class_health_n].off = hoff; - g_class_health_n++; - } - } + collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0); } - logf("client classes walked: %d, health-offset classes: %d", classes, - g_class_health_n); + logf("client classes walked: %d", classes); if (g_net.movetype < 0 && !resolve_movetype()) { // movetype unresolved — bhop still works, just no noclip/ladder guard -- cgit v1.2.3