summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/esp.cpp106
-rw-r--r--src/hl2h.cpp7
-rw-r--r--src/hl2h.h4
-rw-r--r--src/menu.cpp30
4 files changed, 110 insertions, 37 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index e6981f7..f7c24ce 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -334,12 +334,16 @@ static QAngle angle_to(const Vector &from, const Vector &to) {
334 return a; 334 return a;
335} 335}
336 336
337bool aimbot_apply(CUserCmd *cmd) { 337static constexpr float AIM_MAX_FOV = 60.0f;
338
339static bool select_aim_target(const QAngle &view, unsigned bone_mask,
340 bool vischeck, const char *tag, int &out_idx,
341 Vector &out_point, float &out_fov) {
342 out_idx = -1;
343 out_point = {};
344 out_fov = 0.0f;
338 if (!g_iface.entitylist || g_net.origin < 0 || g_net.maxs < 0) 345 if (!g_iface.entitylist || g_net.origin < 0 || g_net.maxs < 0)
339 return false; 346 return false;
340 unsigned bone_mask = aimbot_bone_mask();
341 if (!bone_mask)
342 return false;
343 int local = engine_get_local_player(); 347 int local = engine_get_local_player();
344 if (local <= 0) 348 if (local <= 0)
345 return false; 349 return false;
@@ -350,14 +354,11 @@ bool aimbot_apply(CUserCmd *cmd) {
350 *(int *)((uintptr_t)local_ent + g_net.health) <= 0) 354 *(int *)((uintptr_t)local_ent + g_net.health) <= 0)
351 return false; 355 return false;
352 356
353 QAngle view{cmd->viewangles[0], cmd->viewangles[1], 0.0f};
354
355 using Fn = int (*)(void *); 357 using Fn = int (*)(void *);
356 int hi = vfunc<Fn>(g_iface.entitylist, 6)(g_iface.entitylist); 358 int hi = vfunc<Fn>(g_iface.entitylist, 6)(g_iface.entitylist);
357 if (hi < 0 || hi > 4096) 359 if (hi < 0 || hi > 4096)
358 hi = 4096; 360 hi = 4096;
359 361
360 constexpr float MAX_FOV = 60.0f; // only things near the crosshair
361 struct Candidate { 362 struct Candidate {
362 int idx; 363 int idx;
363 float fov; 364 float fov;
@@ -398,10 +399,9 @@ bool aimbot_apply(CUserCmd *cmd) {
398 Vector approx{origin.x, origin.y, 399 Vector approx{origin.x, origin.y,
399 origin.z + maxz * ((bone_mask & (1u << 1)) ? 0.9f : 0.55f)}; 400 origin.z + maxz * ((bone_mask & (1u << 1)) ? 0.9f : 0.55f)};
400 float fov = getfov(view, angle_to(g_cam_eye, approx)); 401 float fov = getfov(view, angle_to(g_cam_eye, approx));
401 if (fov >= MAX_FOV) 402 if (fov >= AIM_MAX_FOV)
402 continue; 403 continue;
403 404
404 // keep candidates sorted by approximate angle, nearest first
405 int pos = ncands; 405 int pos = ncands;
406 while (pos > 0 && cands[pos - 1].fov > fov) 406 while (pos > 0 && cands[pos - 1].fov > fov)
407 pos--; 407 pos--;
@@ -418,15 +418,14 @@ bool aimbot_apply(CUserCmd *cmd) {
418 double now = esp_now(); 418 double now = esp_now();
419 if (now - last_none >= 2.0) { 419 if (now - last_none >= 2.0) {
420 last_none = now; 420 last_none = now;
421 logf("aimbot: no hostile target within %.0f deg", MAX_FOV); 421 logf("%s: no hostile target within %.0f deg", tag, AIM_MAX_FOV);
422 } 422 }
423 return false; 423 return false;
424 } 424 }
425 425
426 // Walk targets nearest-first. On each, pick the nearest selected hitbox
427 // point that passes vischeck; skip to the next target if all are blocked.
428 int best_idx = -1; 426 int best_idx = -1;
429 Vector best_head{}; 427 Vector best_point{};
428 float best_fov = 0.0f;
430 for (int ci = 0; ci < ncands && best_idx < 0; ci++) { 429 for (int ci = 0; ci < ncands && best_idx < 0; ci++) {
431 int idx = cands[ci].idx; 430 int idx = cands[ci].idx;
432 void *ent = entitylist_get(idx); 431 void *ent = entitylist_get(idx);
@@ -440,40 +439,55 @@ bool aimbot_apply(CUserCmd *cmd) {
440 float f = getfov(view, angle_to(g_cam_eye, pts[i])); 439 float f = getfov(view, angle_to(g_cam_eye, pts[i]));
441 if (f >= aim_fov) 440 if (f >= aim_fov)
442 continue; 441 continue;
443 if (aimbot_vischeck_enabled() && !is_visible(g_cam_eye, pts[i])) 442 if (vischeck && !is_visible(g_cam_eye, pts[i]))
444 continue; 443 continue;
445 aim_fov = f; 444 aim_fov = f;
446 aim_pt = pts[i]; 445 aim_pt = pts[i];
447 } 446 }
448 if (aim_fov <= MAX_FOV && aim_fov < 1e8f) { 447 if (aim_fov <= AIM_MAX_FOV && aim_fov < 1e8f) {
449 best_idx = idx; 448 best_idx = idx;
450 best_head = aim_pt; 449 best_point = aim_pt;
450 best_fov = aim_fov;
451 static int sel_logs = 0; 451 static int sel_logs = 0;
452 if (sel_logs < 5) { 452 if (sel_logs < 5) {
453 sel_logs++; 453 sel_logs++;
454 logf("aimbot: target idx=%d points=%d fov=%.2f vischeck=%d", idx, 454 logf("%s: target idx=%d points=%d fov=%.2f vischeck=%d", tag, idx,
455 npoints, aim_fov, (int)aimbot_vischeck_enabled()); 455 npoints, aim_fov, (int)vischeck);
456 } 456 }
457 } 457 }
458 } 458 }
459
460 if (best_idx < 0) { 459 if (best_idx < 0) {
461 static double last_vis = 0.0; 460 static double last_vis = 0.0;
462 double now = esp_now(); 461 double now = esp_now();
463 if (now - last_vis >= 2.0) { 462 if (now - last_vis >= 2.0) {
464 last_vis = now; 463 last_vis = now;
465 logf("aimbot: no visible aim point (vischeck=%d)", 464 logf("%s: no visible aim point (vischeck=%d)", tag, (int)vischeck);
466 (int)aimbot_vischeck_enabled());
467 } 465 }
468 return false; 466 return false;
469 } 467 }
468 out_idx = best_idx;
469 out_point = best_point;
470 out_fov = best_fov;
471 return true;
472}
470 473
471 QAngle desired = angle_to(g_cam_eye, best_head); 474bool aimbot_apply(CUserCmd *cmd) {
475 unsigned bone_mask = aimbot_bone_mask();
476 if (!bone_mask)
477 return false;
478 QAngle view{cmd->viewangles[0], cmd->viewangles[1], 0.0f};
479 int target = -1;
480 Vector point{};
481 float fov = 0.0f;
482 if (!select_aim_target(view, bone_mask, aimbot_vischeck_enabled(), "aimbot",
483 target, point, fov))
484 return false;
485 QAngle desired = angle_to(g_cam_eye, point);
472 static int want_logs = 0; 486 static int want_logs = 0;
473 if (want_logs < 10) { 487 if (want_logs < 10) {
474 want_logs++; 488 want_logs++;
475 logf("aimbot: aim=(%.1f %.1f %.1f) want=%.2f/%.2f", best_head.x, 489 logf("aimbot: target=%d aim=(%.1f %.1f %.1f) fov=%.2f want=%.2f/%.2f",
476 best_head.y, best_head.z, desired.x, desired.y); 490 target, point.x, point.y, point.z, fov, desired.x, desired.y);
477 } 491 }
478 float dp = desired.x - cmd->viewangles[0]; 492 float dp = desired.x - cmd->viewangles[0];
479 float dy = desired.y - cmd->viewangles[1]; 493 float dy = desired.y - cmd->viewangles[1];
@@ -499,15 +513,11 @@ bool aimbot_apply(CUserCmd *cmd) {
499 cmd->viewangles[0] = np; 513 cmd->viewangles[0] = np;
500 cmd->viewangles[1] = ny; 514 cmd->viewangles[1] = ny;
501 515
502 // cmd->viewangles drives usercmd/prediction, but the rendered camera can
503 // stay on the pre-hook angles. Also push the smoothed angles into the
504 // engine's view (IVEngineClient013 slot 20 = SetViewAngles).
505 if (g_iface.engine) { 516 if (g_iface.engine) {
506 QAngle out{np, ny, 0.0f}; 517 QAngle out{np, ny, 0.0f};
507 using SetViewFn = void (*)(void *, QAngle *); 518 using SetViewFn = void (*)(void *, QAngle *);
508 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &out); 519 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &out);
509 } 520 }
510
511 static int mod_logs = 0; 521 static int mod_logs = 0;
512 if (mod_logs < 10) { 522 if (mod_logs < 10) {
513 mod_logs++; 523 mod_logs++;
@@ -516,6 +526,46 @@ bool aimbot_apply(CUserCmd *cmd) {
516 return true; 526 return true;
517} 527}
518 528
529bool silent_aim_apply(CUserCmd *cmd) {
530 unsigned bone_mask = aimbot_bone_mask();
531 if (!bone_mask)
532 return false;
533 QAngle orig{g_cam_view.x, g_cam_view.y, g_cam_view.z};
534 QAngle view{orig.x, orig.y, 0.0f};
535 int target = -1;
536 Vector point{};
537 float fov = 0.0f;
538 if (!select_aim_target(view, bone_mask, true, "silentaim", target, point,
539 fov))
540 return false;
541 QAngle desired = angle_to(g_cam_eye, point);
542 float np = desired.x;
543 if (np > 89.0f) np = 89.0f;
544 if (np < -89.0f) np = -89.0f;
545 float ny = desired.y;
546 while (ny > 180.0f) ny -= 360.0f;
547 while (ny < -180.0f) ny += 360.0f;
548
549 cmd->viewangles[0] = np;
550 cmd->viewangles[1] = ny;
551 cmd->viewangles[2] = orig.z;
552
553 // The usercmd keeps the aim angles (shot/prediction); the rendered camera
554 // is restored to where the player was actually looking.
555 if (g_iface.engine) {
556 QAngle restore{orig.x, orig.y, orig.z};
557 using SetViewFn = void (*)(void *, QAngle *);
558 vfunc<SetViewFn>(g_iface.engine, 20)(g_iface.engine, &restore);
559 }
560 cmd->buttons |= IN_ATTACK;
561 static int logs = 0;
562 if (logs < 5) {
563 logs++;
564 logf("silentaim: fire idx=%d fov=%.2f aim=%.2f/%.2f", target, fov, np, ny);
565 }
566 return true;
567}
568
519bool triggerbot_apply(CUserCmd *cmd) { 569bool triggerbot_apply(CUserCmd *cmd) {
520 if (!g_iface.enginetrace || !g_iface.entitylist) 570 if (!g_iface.enginetrace || !g_iface.entitylist)
521 return false; 571 return false;
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index 7a7d32e..89d6b89 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -262,6 +262,13 @@ static void do_move(int seq) {
262 note_modified(cmd, flags, vel); 262 note_modified(cmd, flags, vel);
263 } 263 }
264 } 264 }
265
266 if (feature_active(FEAT_SILENTAIM)) {
267 if (silent_aim_apply(cmd)) {
268 const float *vel = (const float *)(e + g_net.velocity);
269 note_modified(cmd, flags, vel);
270 }
271 }
265} 272}
266 273
267// --------------------------------------------------------------------------- 274// ---------------------------------------------------------------------------
diff --git a/src/hl2h.h b/src/hl2h.h
index 28970b0..02be393 100644
--- a/src/hl2h.h
+++ b/src/hl2h.h
@@ -140,12 +140,14 @@ Vector angle_forward_vector(const QAngle &angles);
140float getfov(const QAngle &my_view, const QAngle &aim_ang); 140float getfov(const QAngle &my_view, const QAngle &aim_ang);
141bool aimbot_apply(CUserCmd *cmd); 141bool aimbot_apply(CUserCmd *cmd);
142bool triggerbot_apply(CUserCmd *cmd); 142bool triggerbot_apply(CUserCmd *cmd);
143bool silent_aim_apply(CUserCmd *cmd);
143enum FeatureId { 144enum FeatureId {
144 FEAT_BHOP = 0, 145 FEAT_BHOP = 0,
145 FEAT_ABH = 1, 146 FEAT_ABH = 1,
146 FEAT_ESP = 2, 147 FEAT_ESP = 2,
147 FEAT_AIMBOT = 3, 148 FEAT_AIMBOT = 3,
148 FEAT_TRIGGERBOT = 4 149 FEAT_TRIGGERBOT = 4,
150 FEAT_SILENTAIM = 5
149}; 151};
150enum EspOption { 152enum EspOption {
151 ESP_OPT_SHOW_NEUTRAL = 0, 153 ESP_OPT_SHOW_NEUTRAL = 0,
diff --git a/src/menu.cpp b/src/menu.cpp
index 585695c..11ed222 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -62,6 +62,7 @@ static FeatureState g_abh{true, 0};
62static FeatureState g_esp{true, 0}; 62static FeatureState g_esp{true, 0};
63static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu 63static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu
64static FeatureState g_triggerbot{true, 603}; // default Mouse4 64static FeatureState g_triggerbot{true, 603}; // default Mouse4
65static FeatureState g_silentaim{true, 602}; // default Mouse3
65 66
66// Aimbot bone checklist. Head defaults on (v1 behaviour). 67// Aimbot bone checklist. Head defaults on (v1 behaviour).
67enum { 68enum {
@@ -117,6 +118,9 @@ static MenuNode g_aimbot_smooth_node{NODE_VALUE, "Smoothness", false, 0, {}, nul
117static MenuNode g_triggerbot_feat{NODE_FEATURE, "Triggerbot", false, 1, {}, nullptr, nullptr, nullptr}; 118static MenuNode g_triggerbot_feat{NODE_FEATURE, "Triggerbot", false, 1, {}, nullptr, nullptr, nullptr};
118static MenuNode g_triggerbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_triggerbot.active, nullptr, nullptr}; 119static MenuNode g_triggerbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_triggerbot.active, nullptr, nullptr};
119static MenuNode g_triggerbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_triggerbot.bind, nullptr}; 120static MenuNode g_triggerbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_triggerbot.bind, nullptr};
121static MenuNode g_silentaim_feat{NODE_FEATURE, "Silent aim", false, 1, {}, nullptr, nullptr, nullptr};
122static MenuNode g_silentaim_active{NODE_TOGGLE, "Active", false, 0, {}, &g_silentaim.active, nullptr, nullptr};
123static MenuNode g_silentaim_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_silentaim.bind, nullptr};
120 124
121static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation 125static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation
122static int g_visible_count = 0; 126static int g_visible_count = 0;
@@ -142,6 +146,9 @@ static void build_tree() {
142 g_triggerbot_feat.children[0] = &g_triggerbot_active; 146 g_triggerbot_feat.children[0] = &g_triggerbot_active;
143 g_triggerbot_feat.children[1] = &g_triggerbot_bind; 147 g_triggerbot_feat.children[1] = &g_triggerbot_bind;
144 g_triggerbot_feat.child_count = 2; 148 g_triggerbot_feat.child_count = 2;
149 g_silentaim_feat.children[0] = &g_silentaim_active;
150 g_silentaim_feat.children[1] = &g_silentaim_bind;
151 g_silentaim_feat.child_count = 2;
145 for (int i = 0; i < ESP_OPT_COUNT; i++) 152 for (int i = 0; i < ESP_OPT_COUNT; i++)
146 g_esp_feat.children[i + 1] = &g_esp_opt_nodes[i]; 153 g_esp_feat.children[i + 1] = &g_esp_opt_nodes[i];
147 g_esp_feat.child_count = ESP_OPT_COUNT + 1; 154 g_esp_feat.child_count = ESP_OPT_COUNT + 1;
@@ -150,7 +157,8 @@ static void build_tree() {
150 g_root.children[2] = &g_esp_feat; 157 g_root.children[2] = &g_esp_feat;
151 g_root.children[3] = &g_aimbot_feat; 158 g_root.children[3] = &g_aimbot_feat;
152 g_root.children[4] = &g_triggerbot_feat; 159 g_root.children[4] = &g_triggerbot_feat;
153 g_root.child_count = 5; 160 g_root.children[5] = &g_silentaim_feat;
161 g_root.child_count = 6;
154} 162}
155 163
156static int g_depth[32]; // depth of each visible row (for indentation) 164static int g_depth[32]; // depth of each visible row (for indentation)
@@ -224,6 +232,8 @@ static void config_save() {
224 g_aim_bones[AIM_BONE_LLEG], g_aim_bones[AIM_BONE_RLEG]); 232 g_aim_bones[AIM_BONE_LLEG], g_aim_bones[AIM_BONE_RLEG]);
225 fprintf(f, "[triggerbot]\nactive=%d\nbind=%d\n", g_triggerbot.active, 233 fprintf(f, "[triggerbot]\nactive=%d\nbind=%d\n", g_triggerbot.active,
226 g_triggerbot.bind); 234 g_triggerbot.bind);
235 fprintf(f, "[silentaim]\nactive=%d\nbind=%d\n", g_silentaim.active,
236 g_silentaim.bind);
227 fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" 237 fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n"
228 "healthnum=%d\nname=%d\nskeleton=%d\nbox=%d\n", 238 "healthnum=%d\nname=%d\nskeleton=%d\nbox=%d\n",
229 g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL], 239 g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL],
@@ -253,6 +263,8 @@ static void config_load() {
253 cur = &g_aimbot; 263 cur = &g_aimbot;
254 else if (strstr(line, "[triggerbot]")) 264 else if (strstr(line, "[triggerbot]"))
255 cur = &g_triggerbot; 265 cur = &g_triggerbot;
266 else if (strstr(line, "[silentaim]"))
267 cur = &g_silentaim;
256 else 268 else
257 cur = nullptr; 269 cur = nullptr;
258 in_esp = (cur == &g_esp); 270 in_esp = (cur == &g_esp);
@@ -413,9 +425,10 @@ static bool key_pressed(int sc) {
413// feature gate queried from hl2h.cpp do_move(): feature must be Active AND 425// feature gate queried from hl2h.cpp do_move(): feature must be Active AND
414// its bind key held (always-on when unbound). 426// its bind key held (always-on when unbound).
415bool feature_active(int feature) { 427bool feature_active(int feature) {
416 static FeatureState *feats[5] = {&g_bhop, &g_abh, &g_esp, &g_aimbot, 428 static FeatureState *feats[6] = {&g_bhop, &g_abh, &g_esp,
417 &g_triggerbot}; 429 &g_aimbot, &g_triggerbot,
418 if (feature < 0 || feature > 4) 430 &g_silentaim};
431 if (feature < 0 || feature > 5)
419 return false; 432 return false;
420 FeatureState *f = feats[feature]; 433 FeatureState *f = feats[feature];
421 if (!f->active) 434 if (!f->active)
@@ -492,7 +505,8 @@ static void menu_handle_input() {
492 MenuNode *n = g_visible[g_selected]; 505 MenuNode *n = g_visible[g_selected];
493 if (n->bind_ptr) { 506 if (n->bind_ptr) {
494 // clear same bind from other features 507 // clear same bind from other features
495 FeatureState *features[] = {&g_bhop, &g_abh, &g_aimbot, &g_triggerbot}; 508 FeatureState *features[] = {&g_bhop, &g_abh, &g_aimbot, &g_triggerbot,
509 &g_silentaim};
496 for (auto *f : features) 510 for (auto *f : features)
497 if (&f->bind != n->bind_ptr && f->bind == i) 511 if (&f->bind != n->bind_ptr && f->bind == i)
498 f->bind = 0; 512 f->bind = 0;
@@ -707,11 +721,11 @@ void outer_draw() {
707 draw_text(270, 10 + i * 20, "[press key]"); 721 draw_text(270, 10 + i * 20, "[press key]");
708 else { 722 else {
709 /* stable name for current bind */ 723 /* stable name for current bind */
710 static char bn[4][32]; 724 static char bn[5][32];
711 static FeatureState *feats[] = {&g_bhop, &g_abh, &g_aimbot, 725 static FeatureState *feats[] = {&g_bhop, &g_abh, &g_aimbot,
712 &g_triggerbot}; 726 &g_triggerbot, &g_silentaim};
713 int fi = 0; 727 int fi = 0;
714 for (int k = 0; k < 4; k++) 728 for (int k = 0; k < 5; k++)
715 if (n->bind_ptr == &feats[k]->bind) 729 if (n->bind_ptr == &feats[k]->bind)
716 fi = k; 730 fi = k;
717 snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr)); 731 snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr));