summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bones.cpp10
-rw-r--r--src/cinput.cpp2
-rw-r--r--src/esp.cpp52
-rw-r--r--src/hl2h.cpp76
-rw-r--r--src/hl2h.h1
-rw-r--r--src/menu.cpp4
-rw-r--r--src/netvars.cpp14
-rw-r--r--src/server.cpp2
-rw-r--r--src/vischeck.cpp2
9 files changed, 99 insertions, 64 deletions
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) {
265 265
266static void dump_hitboxes(const BoneEntry *e) { 266static void dump_hitboxes(const BoneEntry *e) {
267 const StudioHdr *h = e->hdr; 267 const StudioHdr *h = e->hdr;
268 logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets, 268 logd("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets,
269 h->hitboxsetindex); 269 h->hitboxsetindex);
270 const HitboxSet *s = hitbox_set0(h); 270 const HitboxSet *s = hitbox_set0(h);
271 if (!s) { 271 if (!s) {
272 logf("hitbox dump: no usable hitbox set"); 272 logd("hitbox dump: no usable hitbox set");
273 return; 273 return;
274 } 274 }
275 const Hitbox *hb = hitboxes(s); 275 const Hitbox *hb = hitboxes(s);
276 logf("hitbox dump: set0 n=%d hitboxindex=%d", s->numhitboxes, 276 logd("hitbox dump: set0 n=%d hitboxindex=%d", s->numhitboxes,
277 s->hitboxindex); 277 s->hitboxindex);
278 int n = s->numhitboxes < 24 ? s->numhitboxes : 24; 278 int n = s->numhitboxes < 24 ? s->numhitboxes : 24;
279 for (int i = 0; i < n; i++) { 279 for (int i = 0; i < n; i++) {
280 const char *bn = (hb[i].bone >= 0 && hb[i].bone < e->count) 280 const char *bn = (hb[i].bone >= 0 && hb[i].bone < e->count)
281 ? bone_name_raw(h, hb[i].bone) 281 ? bone_name_raw(h, hb[i].bone)
282 : nullptr; 282 : nullptr;
283 logf(" hb %d name='%s' bone=%d(%s) bb=(%.1f %.1f %.1f)-(%.1f %.1f %.1f)", 283 logd(" hb %d name='%s' bone=%d(%s) bb=(%.1f %.1f %.1f)-(%.1f %.1f %.1f)",
284 i, hitbox_name(hb[i]), hb[i].bone, bn ? bn : "?", hb[i].bbmin.x, 284 i, hitbox_name(hb[i]), hb[i].bone, bn ? bn : "?", hb[i].bbmin.x,
285 hb[i].bbmin.y, hb[i].bbmin.z, hb[i].bbmax.x, hb[i].bbmax.y, 285 hb[i].bbmin.y, hb[i].bbmin.z, hb[i].bbmax.x, hb[i].bbmax.y,
286 hb[i].bbmax.z); 286 hb[i].bbmax.z);
@@ -370,7 +370,7 @@ bool bones_update(int idx, void *ent) {
370 e->stamp = now; 370 e->stamp = now;
371 if (g_logged < 4) { 371 if (g_logged < 4) {
372 g_logged++; 372 g_logged++;
373 logf("bones: idx=%d count=%d invalid=%d bone0=%s", idx, e->count, 373 logd("bones: idx=%d count=%d invalid=%d bone0=%s", idx, e->count,
374 invalid_bones, 374 invalid_bones,
375 bone_name_raw(hdr, 0) ? bone_name_raw(hdr, 0) : "?"); 375 bone_name_raw(hdr, 0) ? bone_name_raw(hdr, 0) : "?");
376 } 376 }
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() {
225 uintptr_t f3 = *(uintptr_t *)(vtbl + 3 * sizeof(void *)); 225 uintptr_t f3 = *(uintptr_t *)(vtbl + 3 * sizeof(void *));
226 if (!g_client.contains(f3)) 226 if (!g_client.contains(f3))
227 continue; 227 continue;
228 logf("CInput* = %#lx (ptr var %#lx, vfunc[3] %#lx)", (unsigned long)input, 228 logd("CInput* = %#lx (ptr var %#lx, vfunc[3] %#lx)", (unsigned long)input,
229 (unsigned long)var, (unsigned long)f3); 229 (unsigned long)var, (unsigned long)f3);
230 g_input = input; 230 g_input = input;
231 if (!install_input_hook()) 231 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) {
208 g_net.modelindex >= 0 ? *(int *)(e + g_net.modelindex) : -1; 208 g_net.modelindex >= 0 ? *(int *)(e + g_net.modelindex) : -1;
209 int srv_mi = server_model_index(sbase); 209 int srv_mi = server_model_index(sbase);
210 srv_trusted = (cli_mi == srv_mi); 210 srv_trusted = (cli_mi == srv_mi);
211 logf("ESP server check: idx=%d base=%p cli_model=%d srv_model=%d " 211 logd("ESP server check: idx=%d base=%p cli_model=%d srv_model=%d "
212 "hp=%d maxhp=%d life=%d trusted=%d", 212 "hp=%d maxhp=%d life=%d trusted=%d",
213 idx, sbase, cli_mi, srv_mi, shp, smax, slife, (int)srv_trusted); 213 idx, sbase, cli_mi, srv_mi, shp, smax, slife, (int)srv_trusted);
214 if (!srv_trusted) 214 if (!srv_trusted)
@@ -223,7 +223,7 @@ static void esp_collect(int local_idx) {
223 223
224 if (dbg && npc && dbg_lines < 40) { 224 if (dbg && npc && dbg_lines < 40) {
225 dbg_lines++; 225 dbg_lines++;
226 logf("ESP npc %d cls=%s life=%d(cli %d) hp=%d(cli %d) maxhp=%d model=%s", 226 logd("ESP npc %d cls=%s life=%d(cli %d) hp=%d(cli %d) maxhp=%d model=%s",
227 idx, cls, life, cli_life, hp, cli_hp, maxhp, 227 idx, cls, life, cli_life, hp, cli_hp, maxhp,
228 model ? model : "?"); 228 model ? model : "?");
229 } 229 }
@@ -266,10 +266,10 @@ static void esp_collect(int local_idx) {
266 } 266 }
267 267
268 if (dbg) 268 if (dbg)
269 logf("ESP scan: hi=%d npc_alive=%d targets=%d", hi, npc_alive, g_ntargets); 269 logd("ESP scan: hi=%d npc_alive=%d targets=%d", hi, npc_alive, g_ntargets);
270 if (g_ntargets && !g_esp_logged) { 270 if (g_ntargets && !g_esp_logged) {
271 g_esp_logged = true; 271 g_esp_logged = true;
272 logf("ESP: first targets, %d", g_ntargets); 272 logd("ESP: first targets, %d", g_ntargets);
273 } 273 }
274} 274}
275 275
@@ -442,7 +442,7 @@ static void draw_skeleton(const EspTarget &t) {
442 static int logged = 0; 442 static int logged = 0;
443 if (core_count > 0 && logged < 4) { 443 if (core_count > 0 && logged < 4) {
444 logged++; 444 logged++;
445 logf("skeleton: idx=%d bones=%d core=%d humanoid=%d", t.idx, n, core_count, 445 logd("skeleton: idx=%d bones=%d core=%d humanoid=%d", t.idx, n, core_count,
446 (int)bones_is_humanoid(t.idx)); 446 (int)bones_is_humanoid(t.idx));
447 } 447 }
448 if (t.friendly) 448 if (t.friendly)
@@ -565,7 +565,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask,
565 static int lock_logs = 0; 565 static int lock_logs = 0;
566 if (lock_logs < 5) { 566 if (lock_logs < 5) {
567 lock_logs++; 567 lock_logs++;
568 logf("%s: lock idx=%d fov=%.2f", tag, out_idx, f); 568 logd("%s: lock idx=%d fov=%.2f", tag, out_idx, f);
569 } 569 }
570 return true; 570 return true;
571 } 571 }
@@ -636,7 +636,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask,
636 double now = esp_now(); 636 double now = esp_now();
637 if (now - last_none >= 2.0) { 637 if (now - last_none >= 2.0) {
638 last_none = now; 638 last_none = now;
639 logf("%s: no hostile target within %.0f deg", tag, max_fov); 639 logd("%s: no hostile target within %.0f deg", tag, max_fov);
640 } 640 }
641 return false; 641 return false;
642 } 642 }
@@ -654,7 +654,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask,
654 static int sel_logs = 0; 654 static int sel_logs = 0;
655 if (sel_logs < 5) { 655 if (sel_logs < 5) {
656 sel_logs++; 656 sel_logs++;
657 logf("%s: target idx=%d fov=%.2f vischeck=%d", tag, out_idx, f, 657 logd("%s: target idx=%d fov=%.2f vischeck=%d", tag, out_idx, f,
658 (int)vischeck); 658 (int)vischeck);
659 } 659 }
660 return true; 660 return true;
@@ -664,7 +664,7 @@ static bool select_aim_target(const QAngle &view, unsigned bone_mask,
664 double now = esp_now(); 664 double now = esp_now();
665 if (now - last_vis >= 2.0) { 665 if (now - last_vis >= 2.0) {
666 last_vis = now; 666 last_vis = now;
667 logf("%s: no visible aim point (vischeck=%d)", tag, (int)vischeck); 667 logd("%s: no visible aim point (vischeck=%d)", tag, (int)vischeck);
668 } 668 }
669 return false; 669 return false;
670} 670}
@@ -688,7 +688,7 @@ bool aimbot_apply(CUserCmd *cmd) {
688 static int want_logs = 0; 688 static int want_logs = 0;
689 if (want_logs < 10) { 689 if (want_logs < 10) {
690 want_logs++; 690 want_logs++;
691 logf("aimbot: target=%d aim=(%.1f %.1f %.1f) fov=%.2f want=%.2f/%.2f", 691 logd("aimbot: target=%d aim=(%.1f %.1f %.1f) fov=%.2f want=%.2f/%.2f",
692 target, point.x, point.y, point.z, fov, desired.x, desired.y); 692 target, point.x, point.y, point.z, fov, desired.x, desired.y);
693 } 693 }
694 float dp = desired.x - cmd->viewangles[0]; 694 float dp = desired.x - cmd->viewangles[0];
@@ -723,7 +723,7 @@ bool aimbot_apply(CUserCmd *cmd) {
723 static int mod_logs = 0; 723 static int mod_logs = 0;
724 if (mod_logs < 10) { 724 if (mod_logs < 10) {
725 mod_logs++; 725 mod_logs++;
726 logf("aimbot: view %.2f/%.2f -> %.2f/%.2f", old_pitch, old_yaw, np, ny); 726 logd("aimbot: view %.2f/%.2f -> %.2f/%.2f", old_pitch, old_yaw, np, ny);
727 } 727 }
728 return true; 728 return true;
729} 729}
@@ -785,7 +785,7 @@ bool silent_aim_apply(CUserCmd *cmd) {
785 static int logs = 0; 785 static int logs = 0;
786 if (logs < 5) { 786 if (logs < 5) {
787 logs++; 787 logs++;
788 logf("silentaim: fire idx=%d fov=%.2f aim=%.2f/%.2f", target, fov, np, ny); 788 logd("silentaim: fire idx=%d fov=%.2f aim=%.2f/%.2f", target, fov, np, ny);
789 } 789 }
790 return true; 790 return true;
791} 791}
@@ -855,7 +855,7 @@ bool melee_weapon_active(void *local_ent) {
855 if (idx != last_idx || crowbar != last_crowbar) { 855 if (idx != last_idx || crowbar != last_crowbar) {
856 last_idx = idx; 856 last_idx = idx;
857 last_crowbar = crowbar; 857 last_crowbar = crowbar;
858 logf("melee: active idx=%d cls=%s model=%s crowbar=%d", idx, 858 logd("melee: active idx=%d cls=%s model=%s crowbar=%d", idx,
859 cls ? cls : "?", model ? model : "?", (int)crowbar); 859 cls ? cls : "?", model ? model : "?", (int)crowbar);
860 } 860 }
861 return crowbar; 861 return crowbar;
@@ -1033,7 +1033,7 @@ bool melee_aimbot_apply(CUserCmd *cmd) {
1033 static int logs = 0; 1033 static int logs = 0;
1034 if (logs < 10) { 1034 if (logs < 10) {
1035 logs++; 1035 logs++;
1036 logf("melee: swing idx=%d dist=%.1f aim=(%.1f %.1f %.1f)", c.idx, 1036 logd("melee: swing idx=%d dist=%.1f aim=(%.1f %.1f %.1f)", c.idx,
1037 c.dist, aim.x, aim.y, aim.z); 1037 c.dist, aim.x, aim.y, aim.z);
1038 } 1038 }
1039 return true; 1039 return true;
@@ -1043,7 +1043,7 @@ bool melee_aimbot_apply(CUserCmd *cmd) {
1043 double now = esp_now(); 1043 double now = esp_now();
1044 if (now - last_none >= 2.0) { 1044 if (now - last_none >= 2.0) {
1045 last_none = now; 1045 last_none = now;
1046 logf("melee: no visible target within %.0f", MELEE_RANGE); 1046 logd("melee: no visible target within %.0f", MELEE_RANGE);
1047 } 1047 }
1048 return false; 1048 return false;
1049} 1049}
@@ -1132,7 +1132,7 @@ static void spread_compute() {
1132 g_spread_seed12 = window(12, 0); 1132 g_spread_seed12 = window(12, 0);
1133 seed(0); 1133 seed(0);
1134 1134
1135 logf("spread: seeds single=%d shotgun8=%d shotgun12=%d", g_spread_seed1, 1135 logd("spread: seeds single=%d shotgun8=%d shotgun12=%d", g_spread_seed1,
1136 g_spread_seed8, g_spread_seed12); 1136 g_spread_seed8, g_spread_seed12);
1137 g_spread_ready = true; 1137 g_spread_ready = true;
1138} 1138}
@@ -1182,7 +1182,7 @@ bool spread_control_apply(CUserCmd *cmd, void *local_ent) {
1182 static int logs = 0; 1182 static int logs = 0;
1183 if (logs < 10) { 1183 if (logs < 10) {
1184 logs++; 1184 logs++;
1185 logf("spread: seed=%d pellets=%d", seed, pellets); 1185 logd("spread: seed=%d pellets=%d", seed, pellets);
1186 } 1186 }
1187 return true; 1187 return true;
1188} 1188}
@@ -1243,7 +1243,7 @@ bool triggerbot_apply(CUserCmd *cmd) {
1243 static int logs = 0; 1243 static int logs = 0;
1244 if (logs < 5) { 1244 if (logs < 5) {
1245 logs++; 1245 logs++;
1246 logf("triggerbot: fire idx=%d model=%s", idx, model ? model : "?"); 1246 logd("triggerbot: fire idx=%d model=%s", idx, model ? model : "?");
1247 } 1247 }
1248 return true; 1248 return true;
1249 } 1249 }
@@ -1255,7 +1255,7 @@ void esp_draw() {
1255 if (!g_scr_w) { 1255 if (!g_scr_w) {
1256 using Fn = void (*)(void *, int &, int &); 1256 using Fn = void (*)(void *, int &, int &);
1257 vfunc<Fn>(g_surface, SURF_GetScreenSize)(g_surface, g_scr_w, g_scr_h); 1257 vfunc<Fn>(g_surface, SURF_GetScreenSize)(g_surface, g_scr_w, g_scr_h);
1258 logf("ESP: screen %dx%d", g_scr_w, g_scr_h); 1258 logd("ESP: screen %dx%d", g_scr_w, g_scr_h);
1259 if (!g_scr_w) return; 1259 if (!g_scr_w) return;
1260 } 1260 }
1261 draw_fov_circle(); 1261 draw_fov_circle();
@@ -1323,7 +1323,7 @@ void esp_draw() {
1323 static int no_head = 0; 1323 static int no_head = 0;
1324 if (no_head < 4) { 1324 if (no_head < 4) {
1325 no_head++; 1325 no_head++;
1326 logf("head: idx=%d no head hitbox/bone", t.idx); 1326 logd("head: idx=%d no head hitbox/bone", t.idx);
1327 } 1327 }
1328 continue; 1328 continue;
1329 } 1329 }
@@ -1334,7 +1334,7 @@ void esp_draw() {
1334 surf_rect(1, (int)hx - 2, (int)hy - 2, (int)hx + 3, (int)hy + 3); 1334 surf_rect(1, (int)hx - 2, (int)hy - 2, (int)hx + 3, (int)hy + 3);
1335 if (!head_logged) { 1335 if (!head_logged) {
1336 head_logged = true; 1336 head_logged = true;
1337 logf("bone debug: idx=%d bones=%d head=(%.1f %.1f %.1f)", t.idx, 1337 logd("bone debug: idx=%d bones=%d head=(%.1f %.1f %.1f)", t.idx,
1338 bones_count(t.idx), head.x, head.y, head.z); 1338 bones_count(t.idx), head.x, head.y, head.z);
1339 } 1339 }
1340 } 1340 }
@@ -1700,7 +1700,7 @@ static void items_collect(int local_idx) {
1700 1700
1701 if (propish && dist < 1500.0f && prop_logs < 40) { 1701 if (propish && dist < 1500.0f && prop_logs < 40) {
1702 prop_logs++; 1702 prop_logs++;
1703 logf("item prop: idx=%d cls=%s model=%s kind=%d dist=%.0f " 1703 logd("item prop: idx=%d cls=%s model=%s kind=%d dist=%.0f "
1704 "origin=(%.0f %.0f %.0f)", 1704 "origin=(%.0f %.0f %.0f)",
1705 idx, cls ? cls : "?", model ? model : "?", kind, dist, origin.x, 1705 idx, cls ? cls : "?", model ? model : "?", kind, dist, origin.x,
1706 origin.y, origin.z); 1706 origin.y, origin.z);
@@ -1721,10 +1721,8 @@ static void items_collect(int local_idx) {
1721 if (idx == active_idx || item_weapon_is_owned(ent)) 1721 if (idx == active_idx || item_weapon_is_owned(ent))
1722 continue; 1722 continue;
1723 } 1723 }
1724 // Crates are rare and always worth knowing about; the distance slider 1724 // Distance applies to every tag, including supply crates.
1725 // filters the common ammo/health clutter. 1725 if (g_item_max_dist > 0 && dist > (float)g_item_max_dist)
1726 if (kind != IK_CRATE && g_item_max_dist > 0 &&
1727 dist > (float)g_item_max_dist)
1728 continue; 1726 continue;
1729 1727
1730 ItemTarget &t = g_item_targets[g_nitems++]; 1728 ItemTarget &t = g_item_targets[g_nitems++];
@@ -1734,7 +1732,7 @@ static void items_collect(int local_idx) {
1734 snprintf(t.label, sizeof(t.label), "%s", label); 1732 snprintf(t.label, sizeof(t.label), "%s", label);
1735 if (dbg_lines < 8) { 1733 if (dbg_lines < 8) {
1736 dbg_lines++; 1734 dbg_lines++;
1737 logf("item: idx=%d kind=%d cls=%s model=%s", idx, kind, 1735 logd("item: idx=%d kind=%d cls=%s model=%s", idx, kind,
1738 cls ? cls : "?", model ? model : "?"); 1736 cls ? cls : "?", model ? model : "?");
1739 } 1737 }
1740 } 1738 }
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 @@
10// logging 10// logging
11// --------------------------------------------------------------------------- 11// ---------------------------------------------------------------------------
12 12
13void logf(const char *fmt, ...) { 13static FILE *g_log = nullptr;
14 va_list ap, ap2; 14static bool g_log_debug = false;
15 va_start(ap, fmt); 15static pthread_mutex_t g_log_mu = PTHREAD_MUTEX_INITIALIZER;
16 va_copy(ap2, ap); 16
17 fprintf(stderr, "hl2hake: "); 17static void log_close() {
18 vfprintf(stderr, fmt, ap2); 18 pthread_mutex_lock(&g_log_mu);
19 fprintf(stderr, "\n"); 19 if (g_log) {
20 fclose(g_log);
21 g_log = nullptr;
22 }
23 pthread_mutex_unlock(&g_log_mu);
24}
25
26// Open once per process and truncate, so /tmp/hl2hake.log only ever contains
27// the current session. HL2H_DEBUG=1 enables logd() noise.
28static void log_open() {
29 const char *dbg = getenv("HL2H_DEBUG");
30 g_log_debug = dbg && *dbg && strcmp(dbg, "0") != 0;
31 g_log = fopen("/tmp/hl2hake.log", "w");
32 if (g_log)
33 setvbuf(g_log, nullptr, _IOLBF, 0);
34 atexit(log_close);
35}
36
37static void log_write(const char *fmt, va_list ap) {
38 char buf[4096];
39 vsnprintf(buf, sizeof(buf), fmt, ap);
40 pthread_mutex_lock(&g_log_mu);
41 fprintf(stderr, "hl2hake: %s\n", buf);
20 fflush(stderr); 42 fflush(stderr);
21 va_end(ap2); 43 if (g_log) {
22 if (FILE *f = fopen("/tmp/hl2hake.log", "a")) { 44 fprintf(g_log, "hl2hake: %s\n", buf);
23 fprintf(f, "hl2hake: "); 45 fflush(g_log);
24 vfprintf(f, fmt, ap);
25 fprintf(f, "\n");
26 fclose(f);
27 } 46 }
47 pthread_mutex_unlock(&g_log_mu);
48}
49
50void logf(const char *fmt, ...) {
51 va_list ap;
52 va_start(ap, fmt);
53 log_write(fmt, ap);
54 va_end(ap);
55}
56
57void logd(const char *fmt, ...) {
58 if (!g_log_debug)
59 return;
60 va_list ap;
61 va_start(ap, fmt);
62 log_write(fmt, ap);
28 va_end(ap); 63 va_end(ap);
29} 64}
30 65
@@ -93,7 +128,7 @@ void note_modified(const CUserCmd *cmd, int flags, const float *vel) {
93 fix_verified_crc(cmd->command_number, usercmd_checksum(cmd)); 128 fix_verified_crc(cmd->command_number, usercmd_checksum(cmd));
94 129
95 if (g_modified_logged < 5) { 130 if (g_modified_logged < 5) {
96 logf("cmd modified: seq=%d flags=0x%X buttons=0x%X fw=%.2f " 131 logd("cmd modified: seq=%d flags=0x%X buttons=0x%X fw=%.2f "
97 "vel=(%.1f,%.1f,%.1f)", 132 "vel=(%.1f,%.1f,%.1f)",
98 cmd->command_number, flags, cmd->buttons, cmd->forwardmove, vel[0], 133 cmd->command_number, flags, cmd->buttons, cmd->forwardmove, vel[0],
99 vel[1], vel[2]); 134 vel[1], vel[2]);
@@ -311,7 +346,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags,
311 } 346 }
312 if (!jb_tracked) { 347 if (!jb_tracked) {
313 jb_tracked = true; 348 jb_tracked = true;
314 logf("jumpbug: tracking x=%.1f vz=%.1f impact=%.1f", x, vz, impact); 349 logd("jumpbug: tracking x=%.1f vz=%.1f impact=%.1f", x, vz, impact);
315 } 350 }
316 351
317 bool assist = jumpbug_assist_enabled(); 352 bool assist = jumpbug_assist_enabled();
@@ -345,7 +380,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags,
345 jb_tracked = false; 380 jb_tracked = false;
346 if (jb_logs < 30) { 381 if (jb_logs < 30) {
347 jb_logs++; 382 jb_logs++;
348 logf("jumpbug: trigger x=%.2f drop=%.2f vz=%.1f assist=%d", x, jb_drop, 383 logd("jumpbug: trigger x=%.2f drop=%.2f vz=%.1f assist=%d", x, jb_drop,
349 vz, (int)assist); 384 vz, (int)assist);
350 } 385 }
351 } else { 386 } else {
@@ -357,7 +392,7 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags,
357 if (jb_force_next_distance(local, ent, vel, x, JB_TARGET_DIST)) { 392 if (jb_force_next_distance(local, ent, vel, x, JB_TARGET_DIST)) {
358 if (jb_logs < 30) { 393 if (jb_logs < 30) {
359 jb_logs++; 394 jb_logs++;
360 logf("jumpbug: assist duck x=%.2f next=%.2f -> vz=%.1f", x, 395 logd("jumpbug: assist duck x=%.2f next=%.2f -> vz=%.1f", x,
361 next_x, vel[2]); 396 next_x, vel[2]);
362 } 397 }
363 } else { 398 } else {
@@ -391,10 +426,10 @@ static bool jumpbug_apply(CUserCmd *cmd, int local, void *ent, int flags,
391 if (jb_logs < 30) { 426 if (jb_logs < 30) {
392 jb_logs++; 427 jb_logs++;
393 if (assist) 428 if (assist)
394 logf("jumpbug: setup assist x=%.2f drop=%.2f vz=%.1f ok=%d", x, 429 logd("jumpbug: setup assist x=%.2f drop=%.2f vz=%.1f ok=%d", x,
395 jb_drop, vel[2], (int)forced); 430 jb_drop, vel[2], (int)forced);
396 else 431 else
397 logf("jumpbug: setup x=%.2f drop=%.2f pred=%.2f vz=%.1f", x, 432 logd("jumpbug: setup x=%.2f drop=%.2f pred=%.2f vz=%.1f", x,
398 jb_drop, x + JB_DUCK_RAISE - jb_drop, vz); 433 jb_drop, x + JB_DUCK_RAISE - jb_drop, vz);
399 } 434 }
400 } 435 }
@@ -458,7 +493,7 @@ static void hkdSrvRandomSeed(int seed) {
458 if (trace && (bullet_site || logs < 12)) { 493 if (trace && (bullet_site || logs < 12)) {
459 if (logs < 200) { 494 if (logs < 200) {
460 logs++; 495 logs++;
461 logf("srvseed: seed=%d off=0x%lx bullet=%d self=%p local=%d", seed, off, 496 logd("srvseed: seed=%d off=0x%lx bullet=%d self=%p local=%d", seed, off,
462 (int)bullet_site, self, (int)local); 497 (int)bullet_site, self, (int)local);
463 } 498 }
464 } 499 }
@@ -893,6 +928,7 @@ static void *setup_thread(void *) {
893__attribute__((constructor)) static void hl2hake_load() { 928__attribute__((constructor)) static void hl2hake_load() {
894 if (!is_hl2_process()) 929 if (!is_hl2_process())
895 return; 930 return;
931 log_open();
896 logf("loaded (pid %d) build %s %s", getpid(), __DATE__, __TIME__); 932 logf("loaded (pid %d) build %s %s", getpid(), __DATE__, __TIME__);
897 pthread_t t; 933 pthread_t t;
898 if (pthread_create(&t, nullptr, setup_thread, nullptr) == 0) 934 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;
21// --------------------------------------------------------------------------- 21// ---------------------------------------------------------------------------
22 22
23void logf(const char *fmt, ...); 23void logf(const char *fmt, ...);
24void logd(const char *fmt, ...); // debug-only (HL2H_DEBUG=1)
24 25
25// --------------------------------------------------------------------------- 26// ---------------------------------------------------------------------------
26// on-screen toasts 27// 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() {
682 } 682 }
683 if (font_reset && g_font) { 683 if (font_reset && g_font) {
684 g_font = 0; 684 g_font = 0;
685 logf("font: reset (local entity change)"); 685 logd("font: reset (local entity change)");
686 } 686 }
687 687
688 bool overlay_font = true; 688 bool overlay_font = true;
@@ -697,7 +697,7 @@ void outer_draw() {
697 continue; 697 continue;
698 if (surf_set_font_glyph_set(g_font, families[fi], 16, 400, 0, 0, 0x400, 698 if (surf_set_font_glyph_set(g_font, families[fi], 16, 400, 0, 0, 0x400,
699 0x20, 0xFF)) { 699 0x20, 0xFF)) {
700 logf("outer_draw: font family %s", families[fi]); 700 logd("outer_draw: font family %s", families[fi]);
701 font_ok = true; 701 font_ok = true;
702 } else { 702 } else {
703 g_font = 0; 703 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) {
46 strcmp(tname, "DT_BasePlayer") == 0); 46 strcmp(tname, "DT_BasePlayer") == 0);
47 if (dump) { 47 if (dump) {
48 g_dumped_tables++; 48 g_dumped_tables++;
49 logf("dump %s: %d props @ table %#lx (base_off %#lx)", tname, nprops, 49 logd("dump %s: %d props @ table %#lx (base_off %#lx)", tname, nprops,
50 (unsigned long)table, (unsigned long)base_off); 50 (unsigned long)table, (unsigned long)base_off);
51 } 51 }
52 52
@@ -65,7 +65,7 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) {
65 continue; 65 continue;
66 66
67 if (dump) 67 if (dump)
68 logf(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2, 68 logd(" [%s] %s type=%d off=%d(0x%x) table=%s array=%s", tname, pname2,
69 ptype, poff, poff, ptable ? "yes" : "no", parray ? "yes" : "no"); 69 ptype, poff, poff, ptable ? "yes" : "no", parray ? "yes" : "no");
70 if (ptable) { 70 if (ptable) {
71 collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1); 71 collect_netvars(ptable, base_off + (uint32_t)poff, depth + 1);
@@ -150,7 +150,7 @@ static bool resolve_movetype() {
150 break; 150 break;
151 } 151 }
152 if (!str_va) { 152 if (!str_va) {
153 logf("m_MoveType string not found"); 153 logd("m_MoveType string not found");
154 return false; 154 return false;
155 } 155 }
156 156
@@ -181,7 +181,7 @@ static bool resolve_movetype() {
181 } 181 }
182 } 182 }
183 if (ncand == 0) { 183 if (ncand == 0) {
184 logf("m_MoveType typedescription not found"); 184 logd("m_MoveType typedescription not found");
185 return false; 185 return false;
186 } 186 }
187 int best = 0; 187 int best = 0;
@@ -210,7 +210,7 @@ static bool resolve_absvelocity() {
210 break; 210 break;
211 } 211 }
212 if (!str_va) { 212 if (!str_va) {
213 logf("m_vecAbsVelocity string not found"); 213 logd("m_vecAbsVelocity string not found");
214 return false; 214 return false;
215 } 215 }
216 216
@@ -241,7 +241,7 @@ static bool resolve_absvelocity() {
241 } 241 }
242 } 242 }
243 if (ncand == 0) { 243 if (ncand == 0) {
244 logf("m_vecAbsVelocity typedescription not found"); 244 logd("m_vecAbsVelocity typedescription not found");
245 return false; 245 return false;
246 } 246 }
247 int best = 0; 247 int best = 0;
@@ -266,7 +266,7 @@ void resolve_netvars() {
266 classes++; 266 classes++;
267 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0); 267 collect_netvars(*(uintptr_t *)(cc + 0x0C), 0, 0);
268 } 268 }
269 logf("client classes walked: %d", classes); 269 logd("client classes walked: %d", classes);
270 270
271 if (g_net.movetype < 0 && !resolve_movetype()) { 271 if (g_net.movetype < 0 && !resolve_movetype()) {
272 // movetype unresolved — bhop still works, just no noclip/ladder guard 272 // 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() {
100 if (!g_server.valid()) { 100 if (!g_server.valid()) {
101 if (!fail_logged) { 101 if (!fail_logged) {
102 fail_logged = true; 102 fail_logged = true;
103 logf("server datamap: server.so not mapped yet"); 103 logd("server datamap: server.so not mapped yet");
104 } 104 }
105 return false; 105 return false;
106 } 106 }
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) {
185 static int solid_logs = 0; 185 static int solid_logs = 0;
186 if (tr.startsolid && solid_logs < 4) { 186 if (tr.startsolid && solid_logs < 4) {
187 solid_logs++; 187 solid_logs++;
188 logf("ground trace: startsolid at (%.1f %.1f %.1f)", origin.x, 188 logd("ground trace: startsolid at (%.1f %.1f %.1f)", origin.x,
189 origin.y, origin.z); 189 origin.y, origin.z);
190 } 190 }
191 return -1.0f; 191 return -1.0f;