From 16546e5818408f35adc60c2d937cf4541ff7840a Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 28 Oct 2026 12:24:10 +0100 Subject: Logging: per-session file and debug-gated verbose logs - Open /tmp/hl2hake.log once in the library constructor with "w" so each session starts clean, use line buffering, flush each line, and close it via atexit. No more fopen/fclose per message. - Add logd() for verbose diagnostics, enabled only with HL2H_DEBUG=1. - Move ESP/NPC scans, item-prop/item-classification logs, aimbot/silent-aim/ melee/triggerbot/spread details, jumpbug tracking, bone dumps, netvar dumps, cmd-modified and ground-trace noise to logd(). - Keep logf() for lifecycle, config, warnings/errors, GUI open/close, item category/tagging summaries and item-crate detections so crate debugging works without the ESP stream. - Supply crates now respect the max-distance slider (user change), with the stale comment and CONTEXT updated. - Document HL2H_DEBUG=1 in play.sh and CONTEXT. --- src/bones.cpp | 10 ++++---- src/cinput.cpp | 2 +- src/esp.cpp | 52 +++++++++++++++++++------------------- src/hl2h.cpp | 76 +++++++++++++++++++++++++++++++++++++++++--------------- src/hl2h.h | 1 + src/menu.cpp | 4 +-- src/netvars.cpp | 14 +++++------ src/server.cpp | 2 +- src/vischeck.cpp | 2 +- 9 files changed, 99 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/bones.cpp b/src/bones.cpp index 787af1b..0df13f2 100644 --- a/src/bones.cpp +++ b/src/bones.cpp @@ -265,22 +265,22 @@ static void build_core_mask(BoneEntry *e) { static void dump_hitboxes(const BoneEntry *e) { const StudioHdr *h = e->hdr; - logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets, + logd("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets, h->hitboxsetindex); const HitboxSet *s = hitbox_set0(h); if (!s) { - logf("hitbox dump: no usable hitbox set"); + logd("hitbox dump: no usable hitbox set"); return; } const Hitbox *hb = hitboxes(s); - logf("hitbox dump: set0 n=%d hitboxindex=%d", s->numhitboxes, + logd("hitbox dump: set0 n=%d hitboxindex=%d", s->numhitboxes, s->hitboxindex); int n = s->numhitboxes < 24 ? s->numhitboxes : 24; for (int i = 0; i < n; i++) { const char *bn = (hb[i].bone >= 0 && hb[i].bone < e->count) ? bone_name_raw(h, hb[i].bone) : nullptr; - logf(" hb %d name='%s' bone=%d(%s) bb=(%.1f %.1f %.1f)-(%.1f %.1f %.1f)", + logd(" hb %d name='%s' bone=%d(%s) bb=(%.1f %.1f %.1f)-(%.1f %.1f %.1f)", i, hitbox_name(hb[i]), hb[i].bone, bn ? bn : "?", hb[i].bbmin.x, hb[i].bbmin.y, hb[i].bbmin.z, hb[i].bbmax.x, hb[i].bbmax.y, hb[i].bbmax.z); @@ -370,7 +370,7 @@ bool bones_update(int idx, void *ent) { e->stamp = now; if (g_logged < 4) { g_logged++; - logf("bones: idx=%d count=%d invalid=%d bone0=%s", idx, e->count, + logd("bones: idx=%d count=%d invalid=%d bone0=%s", idx, e->count, invalid_bones, bone_name_raw(hdr, 0) ? bone_name_raw(hdr, 0) : "?"); } diff --git a/src/cinput.cpp b/src/cinput.cpp index f466c53..08686a1 100644 --- a/src/cinput.cpp +++ b/src/cinput.cpp @@ -225,7 +225,7 @@ bool find_input_global() { uintptr_t f3 = *(uintptr_t *)(vtbl + 3 * sizeof(void *)); if (!g_client.contains(f3)) continue; - logf("CInput* = %#lx (ptr var %#lx, vfunc[3] %#lx)", (unsigned long)input, + logd("CInput* = %#lx (ptr var %#lx, vfunc[3] %#lx)", (unsigned long)input, (unsigned long)var, (unsigned long)f3); g_input = input; if (!install_input_hook()) diff --git a/src/esp.cpp b/src/esp.cpp index ec3e94b..50549a1 100644 --- a/src/esp.cpp +++ b/src/esp.cpp @@ -208,7 +208,7 @@ static void esp_collect(int local_idx) { g_net.modelindex >= 0 ? *(int *)(e + g_net.modelindex) : -1; int srv_mi = server_model_index(sbase); srv_trusted = (cli_mi == srv_mi); - logf("ESP server check: idx=%d base=%p cli_model=%d srv_model=%d " + logd("ESP server check: idx=%d base=%p cli_model=%d srv_model=%d " "hp=%d maxhp=%d life=%d trusted=%d", idx, sbase, cli_mi, srv_mi, shp, smax, slife, (int)srv_trusted); if (!srv_trusted) @@ -223,7 +223,7 @@ static void esp_collect(int local_idx) { if (dbg && npc && dbg_lines < 40) { dbg_lines++; - logf("ESP npc %d cls=%s life=%d(cli %d) hp=%d(cli %d) maxhp=%d model=%s", + logd("ESP npc %d cls=%s life=%d(cli %d) hp=%d(cli %d) maxhp=%d model=%s", idx, cls, life, cli_life, hp, cli_hp, maxhp, model ? model : "?"); } @@ -266,10 +266,10 @@ static void esp_collect(int local_idx) { } if (dbg) - logf("ESP scan: hi=%d npc_alive=%d targets=%d", hi, npc_alive, g_ntargets); + logd("ESP scan: hi=%d npc_alive=%d targets=%d", hi, npc_alive, g_ntargets); if (g_ntargets && !g_esp_logged) { g_esp_logged = true; - logf("ESP: first targets, %d", g_ntargets); + logd("ESP: first targets, %d", g_ntargets); } } @@ -442,7 +442,7 @@ static void draw_skeleton(const EspTarget &t) { static int logged = 0; if (core_count > 0 && logged < 4) { logged++; - logf("skeleton: idx=%d bones=%d core=%d humanoid=%d", t.idx, n, core_count, + logd("skeleton: idx=%d bones=%d core=%d humanoid=%d", t.idx, n, core_count, (int)bones_is_humanoid(t.idx)); } if (t.friendly) @@ -565,7 +565,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask, static int lock_logs = 0; if (lock_logs < 5) { lock_logs++; - logf("%s: lock idx=%d fov=%.2f", tag, out_idx, f); + logd("%s: lock idx=%d fov=%.2f", tag, out_idx, f); } return true; } @@ -636,7 +636,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask, double now = esp_now(); if (now - last_none >= 2.0) { last_none = now; - logf("%s: no hostile target within %.0f deg", tag, max_fov); + logd("%s: no hostile target within %.0f deg", tag, max_fov); } return false; } @@ -654,7 +654,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask, static int sel_logs = 0; if (sel_logs < 5) { sel_logs++; - logf("%s: target idx=%d fov=%.2f vischeck=%d", tag, out_idx, f, + logd("%s: target idx=%d fov=%.2f vischeck=%d", tag, out_idx, f, (int)vischeck); } return true; @@ -664,7 +664,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask, double now = esp_now(); if (now - last_vis >= 2.0) { last_vis = now; - logf("%s: no visible aim point (vischeck=%d)", tag, (int)vischeck); + logd("%s: no visible aim point (vischeck=%d)", tag, (int)vischeck); } return false; } @@ -688,7 +688,7 @@ bool aimbot_apply(CUserCmd *cmd) { static int want_logs = 0; if (want_logs < 10) { want_logs++; - logf("aimbot: target=%d aim=(%.1f %.1f %.1f) fov=%.2f want=%.2f/%.2f", + logd("aimbot: target=%d aim=(%.1f %.1f %.1f) fov=%.2f want=%.2f/%.2f", target, point.x, point.y, point.z, fov, desired.x, desired.y); } float dp = desired.x - cmd->viewangles[0]; @@ -723,7 +723,7 @@ bool aimbot_apply(CUserCmd *cmd) { static int mod_logs = 0; if (mod_logs < 10) { mod_logs++; - logf("aimbot: view %.2f/%.2f -> %.2f/%.2f", old_pitch, old_yaw, np, ny); + logd("aimbot: view %.2f/%.2f -> %.2f/%.2f", old_pitch, old_yaw, np, ny); } return true; } @@ -785,7 +785,7 @@ bool silent_aim_apply(CUserCmd *cmd) { static int logs = 0; if (logs < 5) { logs++; - logf("silentaim: fire idx=%d fov=%.2f aim=%.2f/%.2f", target, fov, np, ny); + logd("silentaim: fire idx=%d fov=%.2f aim=%.2f/%.2f", target, fov, np, ny); } return true; } @@ -855,7 +855,7 @@ bool melee_weapon_active(void *local_ent) { if (idx != last_idx || crowbar != last_crowbar) { last_idx = idx; last_crowbar = crowbar; - logf("melee: active idx=%d cls=%s model=%s crowbar=%d", idx, + logd("melee: active idx=%d cls=%s model=%s crowbar=%d", idx, cls ? cls : "?", model ? model : "?", (int)crowbar); } return crowbar; @@ -1033,7 +1033,7 @@ bool melee_aimbot_apply(CUserCmd *cmd) { static int logs = 0; if (logs < 10) { logs++; - logf("melee: swing idx=%d dist=%.1f aim=(%.1f %.1f %.1f)", c.idx, + logd("melee: swing idx=%d dist=%.1f aim=(%.1f %.1f %.1f)", c.idx, c.dist, aim.x, aim.y, aim.z); } return true; @@ -1043,7 +1043,7 @@ bool melee_aimbot_apply(CUserCmd *cmd) { double now = esp_now(); if (now - last_none >= 2.0) { last_none = now; - logf("melee: no visible target within %.0f", MELEE_RANGE); + logd("melee: no visible target within %.0f", MELEE_RANGE); } return false; } @@ -1132,7 +1132,7 @@ static void spread_compute() { g_spread_seed12 = window(12, 0); seed(0); - logf("spread: seeds single=%d shotgun8=%d shotgun12=%d", g_spread_seed1, + logd("spread: seeds single=%d shotgun8=%d shotgun12=%d", g_spread_seed1, g_spread_seed8, g_spread_seed12); g_spread_ready = true; } @@ -1182,7 +1182,7 @@ bool spread_control_apply(CUserCmd *cmd, void *local_ent) { static int logs = 0; if (logs < 10) { logs++; - logf("spread: seed=%d pellets=%d", seed, pellets); + logd("spread: seed=%d pellets=%d", seed, pellets); } return true; } @@ -1243,7 +1243,7 @@ bool triggerbot_apply(CUserCmd *cmd) { static int logs = 0; if (logs < 5) { logs++; - logf("triggerbot: fire idx=%d model=%s", idx, model ? model : "?"); + logd("triggerbot: fire idx=%d model=%s", idx, model ? model : "?"); } return true; } @@ -1255,7 +1255,7 @@ void esp_draw() { if (!g_scr_w) { using Fn = void (*)(void *, int &, int &); vfunc(g_surface, SURF_GetScreenSize)(g_surface, g_scr_w, g_scr_h); - logf("ESP: screen %dx%d", g_scr_w, g_scr_h); + logd("ESP: screen %dx%d", g_scr_w, g_scr_h); if (!g_scr_w) return; } draw_fov_circle(); @@ -1323,7 +1323,7 @@ void esp_draw() { static int no_head = 0; if (no_head < 4) { no_head++; - logf("head: idx=%d no head hitbox/bone", t.idx); + logd("head: idx=%d no head hitbox/bone", t.idx); } continue; } @@ -1334,7 +1334,7 @@ void esp_draw() { surf_rect(1, (int)hx - 2, (int)hy - 2, (int)hx + 3, (int)hy + 3); if (!head_logged) { head_logged = true; - logf("bone debug: idx=%d bones=%d head=(%.1f %.1f %.1f)", t.idx, + logd("bone debug: idx=%d bones=%d head=(%.1f %.1f %.1f)", t.idx, bones_count(t.idx), head.x, head.y, head.z); } } @@ -1700,7 +1700,7 @@ static void items_collect(int local_idx) { if (propish && dist < 1500.0f && prop_logs < 40) { prop_logs++; - logf("item prop: idx=%d cls=%s model=%s kind=%d dist=%.0f " + logd("item prop: idx=%d cls=%s model=%s kind=%d dist=%.0f " "origin=(%.0f %.0f %.0f)", idx, cls ? cls : "?", model ? model : "?", kind, dist, origin.x, origin.y, origin.z); @@ -1721,10 +1721,8 @@ static void items_collect(int local_idx) { if (idx == active_idx || item_weapon_is_owned(ent)) continue; } - // Crates are rare and always worth knowing about; the distance slider - // filters the common ammo/health clutter. - if (kind != IK_CRATE && g_item_max_dist > 0 && - dist > (float)g_item_max_dist) + // Distance applies to every tag, including supply crates. + if (g_item_max_dist > 0 && dist > (float)g_item_max_dist) continue; ItemTarget &t = g_item_targets[g_nitems++]; @@ -1734,7 +1732,7 @@ static void items_collect(int local_idx) { snprintf(t.label, sizeof(t.label), "%s", label); if (dbg_lines < 8) { dbg_lines++; - logf("item: idx=%d kind=%d cls=%s model=%s", idx, kind, + logd("item: idx=%d kind=%d cls=%s model=%s", idx, kind, cls ? cls : "?", model ? model : "?"); } } diff --git a/src/hl2h.cpp b/src/hl2h.cpp index 8c6b5db..256b9ab 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp @@ -10,21 +10,56 @@ // logging // --------------------------------------------------------------------------- -void logf(const char *fmt, ...) { - va_list ap, ap2; - va_start(ap, fmt); - va_copy(ap2, ap); - fprintf(stderr, "hl2hake: "); - vfprintf(stderr, fmt, ap2); - fprintf(stderr, "\n"); +static FILE *g_log = nullptr; +static bool g_log_debug = false; +static pthread_mutex_t g_log_mu = PTHREAD_MUTEX_INITIALIZER; + +static void log_close() { + pthread_mutex_lock(&g_log_mu); + if (g_log) { + fclose(g_log); + g_log = nullptr; + } + pthread_mutex_unlock(&g_log_mu); +} + +// Open once per process and truncate, so /tmp/hl2hake.log only ever contains +// the current session. HL2H_DEBUG=1 enables logd() noise. +static void log_open() { + const char *dbg = getenv("HL2H_DEBUG"); + g_log_debug = dbg && *dbg && strcmp(dbg, "0") != 0; + g_log = fopen("/tmp/hl2hake.log", "w"); + if (g_log) + setvbuf(g_log, nullptr, _IOLBF, 0); + atexit(log_close); +} + +static void log_write(const char *fmt, va_list ap) { + char buf[4096]; + vsnprintf(buf, sizeof(buf), fmt, ap); + pthread_mutex_lock(&g_log_mu); + fprintf(stderr, "hl2hake: %s\n", buf); fflush(stderr); - va_end(ap2); - if (FILE *f = fopen("/tmp/hl2hake.log", "a")) { - fprintf(f, "hl2hake: "); - vfprintf(f, fmt, ap); - fprintf(f, "\n"); - fclose(f); + if (g_log) { + fprintf(g_log, "hl2hake: %s\n", buf); + fflush(g_log); } + pthread_mutex_unlock(&g_log_mu); +} + +void logf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + log_write(fmt, ap); + va_end(ap); +} + +void logd(const char *fmt, ...) { + if (!g_log_debug) + return; + va_list ap; + va_start(ap, fmt); + log_write(fmt, ap); va_end(ap); } @@ -93,7 +128,7 @@ void note_modified(const CUserCmd *cmd, int flags, const float *vel) { fix_verified_crc(cmd->command_number, usercmd_checksum(cmd)); if (g_modified_logged < 5) { - logf("cmd modified: seq=%d flags=0x%X buttons=0x%X fw=%.2f " + logd("cmd modified: seq=%d flags=0x%X buttons=0x%X fw=%.2f " "vel=(%.1f,%.1f,%.1f)", cmd->command_number, flags, cmd->buttons, cmd->forwardmove, vel[0], vel[1], vel[2]); @@ -311,7 +346,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags, } if (!jb_tracked) { jb_tracked = true; - logf("jumpbug: tracking x=%.1f vz=%.1f impact=%.1f", x, vz, impact); + logd("jumpbug: tracking x=%.1f vz=%.1f impact=%.1f", x, vz, impact); } bool assist = jumpbug_assist_enabled(); @@ -345,7 +380,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags, jb_tracked = false; if (jb_logs < 30) { jb_logs++; - logf("jumpbug: trigger x=%.2f drop=%.2f vz=%.1f assist=%d", x, jb_drop, + logd("jumpbug: trigger x=%.2f drop=%.2f vz=%.1f assist=%d", x, jb_drop, vz, (int)assist); } } else { @@ -357,7 +392,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags, if (jb_force_next_distance(local, ent, vel, x, JB_TARGET_DIST)) { if (jb_logs < 30) { jb_logs++; - logf("jumpbug: assist duck x=%.2f next=%.2f -> vz=%.1f", x, + logd("jumpbug: assist duck x=%.2f next=%.2f -> vz=%.1f", x, next_x, vel[2]); } } else { @@ -391,10 +426,10 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags, if (jb_logs < 30) { jb_logs++; if (assist) - logf("jumpbug: setup assist x=%.2f drop=%.2f vz=%.1f ok=%d", x, + logd("jumpbug: setup assist x=%.2f drop=%.2f vz=%.1f ok=%d", x, jb_drop, vel[2], (int)forced); else - logf("jumpbug: setup x=%.2f drop=%.2f pred=%.2f vz=%.1f", x, + logd("jumpbug: setup x=%.2f drop=%.2f pred=%.2f vz=%.1f", x, jb_drop, x + JB_DUCK_RAISE - jb_drop, vz); } } @@ -458,7 +493,7 @@ static void hkdSrvRandomSeed(int seed) { if (trace && (bullet_site || logs < 12)) { if (logs < 200) { logs++; - logf("srvseed: seed=%d off=0x%lx bullet=%d self=%p local=%d", seed, off, + logd("srvseed: seed=%d off=0x%lx bullet=%d self=%p local=%d", seed, off, (int)bullet_site, self, (int)local); } } @@ -893,6 +928,7 @@ static void *setup_thread(void *) { __attribute__((constructor)) static void hl2hake_load() { if (!is_hl2_process()) return; + log_open(); logf("loaded (pid %d) build %s %s", getpid(), __DATE__, __TIME__); pthread_t t; if (pthread_create(&t, nullptr, setup_thread, nullptr) == 0) diff --git a/src/hl2h.h b/src/hl2h.h index cc11e0d..9b4fa8a 100644 --- a/src/hl2h.h +++ b/src/hl2h.h @@ -21,6 +21,7 @@ constexpr float PI_F = 3.14159265f; // --------------------------------------------------------------------------- void logf(const char *fmt, ...); +void logd(const char *fmt, ...); // debug-only (HL2H_DEBUG=1) // --------------------------------------------------------------------------- // on-screen toasts diff --git a/src/menu.cpp b/src/menu.cpp index 9d07b72..6d7143d 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -682,7 +682,7 @@ void outer_draw() { } if (font_reset && g_font) { g_font = 0; - logf("font: reset (local entity change)"); + logd("font: reset (local entity change)"); } bool overlay_font = true; @@ -697,7 +697,7 @@ void outer_draw() { continue; if (surf_set_font_glyph_set(g_font, families[fi], 16, 400, 0, 0, 0x400, 0x20, 0xFF)) { - logf("outer_draw: font family %s", families[fi]); + logd("outer_draw: font family %s", families[fi]); font_ok = true; } else { g_font = 0; diff --git a/src/netvars.cpp b/src/netvars.cpp index 4980acc..adb5a6a 100644 --- a/src/netvars.cpp +++ b/src/netvars.cpp @@ -46,7 +46,7 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) { strcmp(tname, "DT_BasePlayer") == 0); if (dump) { g_dumped_tables++; - logf("dump %s: %d props @ table %#lx (base_off %#lx)", tname, nprops, + logd("dump %s: %d props @ table %#lx (base_off %#lx)", tname, nprops, (unsigned long)table, (unsigned long)base_off); } @@ -65,7 +65,7 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) { continue; if (dump) - logf(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2, + logd(" [%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); @@ -150,7 +150,7 @@ static bool resolve_movetype() { break; } if (!str_va) { - logf("m_MoveType string not found"); + logd("m_MoveType string not found"); return false; } @@ -181,7 +181,7 @@ static bool resolve_movetype() { } } if (ncand == 0) { - logf("m_MoveType typedescription not found"); + logd("m_MoveType typedescription not found"); return false; } int best = 0; @@ -210,7 +210,7 @@ static bool resolve_absvelocity() { break; } if (!str_va) { - logf("m_vecAbsVelocity string not found"); + logd("m_vecAbsVelocity string not found"); return false; } @@ -241,7 +241,7 @@ static bool resolve_absvelocity() { } } if (ncand == 0) { - logf("m_vecAbsVelocity typedescription not found"); + logd("m_vecAbsVelocity typedescription not found"); return false; } int best = 0; @@ -266,7 +266,7 @@ void resolve_netvars() { classes++; collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0); } - logf("client classes walked: %d", classes); + logd("client classes walked: %d", classes); if (g_net.movetype < 0 && !resolve_movetype()) { // movetype unresolved — bhop still works, just no noclip/ladder guard diff --git a/src/server.cpp b/src/server.cpp index cfb4dd1..115cd53 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -100,7 +100,7 @@ bool resolve_server_netvars() { if (!g_server.valid()) { if (!fail_logged) { fail_logged = true; - logf("server datamap: server.so not mapped yet"); + logd("server datamap: server.so not mapped yet"); } return false; } diff --git a/src/vischeck.cpp b/src/vischeck.cpp index 6d453c5..dcb5c3c 100644 --- a/src/vischeck.cpp +++ b/src/vischeck.cpp @@ -185,7 +185,7 @@ float ground_distance(const Vector &origin, void *ignore, float max_dist) { static int solid_logs = 0; if (tr.startsolid && solid_logs < 4) { solid_logs++; - logf("ground trace: startsolid at (%.1f %.1f %.1f)", origin.x, + logd("ground trace: startsolid at (%.1f %.1f %.1f)", origin.x, origin.y, origin.z); } return -1.0f; -- cgit v1.2.3