From 9c99ba97014ae09a91f1e4fefeec78751a065f66 Mon Sep 17 00:00:00 2001 From: F1ssi0N Date: Wed, 4 Apr 2018 17:42:06 +0100 Subject: [PATCH] Add dynamic box esp and cleanup code (#34) Add dynamic box esp and cleanup code --- src/doghook.cc | 4 +++ src/modules/aimbot.cc | 5 ++- src/modules/esp.cc | 75 ++++++++++++++++++++++++++++++++++--------- src/sdk/convar.hh | 2 +- src/sdk/draw.cc | 5 ++- src/sdk/draw.hh | 15 ++++++++- src/sdk/player.cc | 7 +--- src/sdk/signature.cc | 23 +++---------- src/utils/hex.hh | 27 ++++++++++++++++ src/utils/math.hh | 20 ++++++++++++ src/utils/profiler.cc | 59 +++++++++++++--------------------- src/utils/profiler.hh | 13 +++++--- 12 files changed, 166 insertions(+), 89 deletions(-) create mode 100644 src/utils/hex.hh diff --git a/src/doghook.cc b/src/doghook.cc index f00e1ad..9836f3a 100644 --- a/src/doghook.cc +++ b/src/doghook.cc @@ -22,6 +22,8 @@ #include "utils/profiler.hh" +static Convar doghook_profiling_enabled{"doghook_profiling_enabled", false, nullptr}; + // Singleton for doing init / deinit of doghook // and dealing with hooks from gamesystem @@ -115,6 +117,7 @@ public: // make sure that the profiler is inited first profiler::init(); + doghook_profiling_enabled = profiler::profiling_enabled(); // make sure that the netvars are initialised // becuase their dynamic initialiser could be after the @@ -162,6 +165,7 @@ public: // HOWEVER: it might be better to do this at frame_end() void update([[maybe_unused]] float frametime) override { if (inited != true) return; + profiler::set_profiling_enabled(doghook_profiling_enabled); } Doghook() { diff --git a/src/modules/aimbot.cc b/src/modules/aimbot.cc index d6a2fbb..78c3fad 100644 --- a/src/modules/aimbot.cc +++ b/src/modules/aimbot.cc @@ -281,13 +281,12 @@ auto find_targets() { finished_target(Target{e, pos}); // Now that we have a target break! - // TOOD: maybe we shouldnt do this?? - break; + // TODO: only do this when we want to do speedy targets! + //break; } } } - // TODO: remove me sort_targets(); } diff --git a/src/modules/esp.cc b/src/modules/esp.cc index cf9a53f..102a626 100644 --- a/src/modules/esp.cc +++ b/src/modules/esp.cc @@ -2,9 +2,11 @@ #include "esp.hh" +#include "sdk/convar.hh" #include "sdk/draw.hh" #include "sdk/entity.hh" #include "sdk/player.hh" +#include "utils/hex.hh" #include "utils/profiler.hh" @@ -14,18 +16,19 @@ namespace esp { draw::FontHandle f = -1; +// TODO: do this in a stack based method instead of recursing! void show_nodes_recursive(profiler::ProfileNode *node, math::Vector &pos) { profiler_profile_function(); if (node->parent != nullptr) { - auto parent_time = node->parent->t.milliseconds(); + auto parent_cycles = node->parent->t.cycles(); - auto percentage = node->t.milliseconds() / parent_time * 100; + auto percentage = float(node->t.cycles()) / parent_cycles * 100; // Print yourself first - draw::text(f, {255, 255, 255, 255}, pos, "%s: %f %f%", node->name, node->t.milliseconds(), percentage); + draw::text(f, {255, 255, 255, 255}, pos, "%s: %llu %f %f%", node->name, node->t.cycles(), node->t.milliseconds(), percentage); } else { - draw::text(f, {255, 255, 255, 255}, pos, "%s: %f", node->name, node->t.milliseconds()); + draw::text(f, {255, 255, 255, 255}, pos, "%s: %d %f", node->name, node->t.cycles(), node->t.milliseconds()); } // now print children @@ -41,6 +44,9 @@ void show_nodes(profiler::ProfileNode *node, math::Vector pos) { show_nodes_recursive(node, pos); } +static Convar doghook_esp_enemy{"doghook_esp_enemy", "FF0000FF", nullptr}; +static Convar doghook_esp_friendly{"doghook_esp_friend", "00FF00FF", nullptr}; + void paint() { profiler_profile_function(); @@ -51,33 +57,70 @@ void paint() { f = draw::register_font("Tahoma", 17); } - //draw::filled_rect({255, 0, 0, 255}, {500, 500, 0}, {1000, 1000, 0}); - draw::text(f, {255, 0, 0, 255}, {0, 0, 0}, "DOGHOOK:tm: :joy: :joy: :jo3: :nice:"); show_nodes(profiler::find_root_node(), {0, 100, 0}); if (IFace()->in_game() == false) return; + auto local_player = Player::local(); + + auto local_player_team = local_player->team(); + + auto friendly_color = draw::Color(hex::dword(doghook_esp_friendly.to_string())); + auto enemy_color = draw::Color(hex::dword(doghook_esp_enemy.to_string())); + for (auto e : IFace()->get_range()) { if (e->is_valid() == false) continue; if (auto player = e->to_player()) { + + if (!player->alive()) continue; + + auto player_color = player->team() == local_player_team ? friendly_color : enemy_color; + auto world_space_centre = player->world_space_centre(); - // auto player_min_screen = draw::world_to_screen(render_bounds.first); - // auto player_max_screen = draw::world_to_screen(render_bounds.second); - - // if (player_min_screen != math::Vector::invalid() && player_max_screen != math::Vector::invalid()) { - // draw::filled_rect({255, 255, 255, 255}, player_min_screen, player_max_screen); - // } - math::Vector screen_space_centre; if (draw::world_to_screen(world_space_centre, screen_space_centre)) { - //draw::filled_rect({255, 255, 255, 255}, screen_space_centre + math::Vector{-2, -2, -2}, screen_space_centre + math::Vector{2, 2, 2}); auto info = player->info(); - if (info.user_id != -1 && player->alive()) - draw::text(f, {255, 255, 255, 255}, screen_space_centre, "%s", info.name); + if (info.user_id != -1) + draw::text(f, player_color, screen_space_centre, "%s", info.name); + } + + // These boxes are funky and they need to be transformed better... + { + auto collision = player->collision_bounds(); + + auto origin = player->origin(); + + auto min = collision.first + origin; + auto max = collision.second + origin; + + math::Vector point_list[] = { + {min.x, min.y, min.z}, + {min.x, max.y, min.z}, + {max.x, max.y, min.z}, + {max.x, min.y, min.z}, + {max.x, max.y, max.z}, + {min.x, max.y, max.z}, + {min.x, min.y, max.z}, + {max.x, min.y, max.z}, + }; + + draw::world_to_screen(point_list[0], min); + max = min; + + bool visible = true; + for (u32 i = 1; i < 8; i++) { + math::Vector new_point; + draw::world_to_screen(point_list[i], new_point); + + min = min.min(new_point); + max = max.max(new_point); + } + + draw::outlined_rect(player_color, min, max); } } } diff --git a/src/sdk/convar.hh b/src/sdk/convar.hh index 9b5dce4..069e488 100644 --- a/src/sdk/convar.hh +++ b/src/sdk/convar.hh @@ -269,7 +269,7 @@ public: }; template <> -class Convar : public ConvarBase { +class Convar : public ConvarBase { char *value; public: diff --git a/src/sdk/draw.cc b/src/sdk/draw.cc index 7934b40..d1901e4 100644 --- a/src/sdk/draw.cc +++ b/src/sdk/draw.cc @@ -11,6 +11,8 @@ #include "sdk.hh" #include "vfunc.hh" +#include "utils/profiler.hh" + namespace sdk::draw { class Surface { @@ -34,7 +36,7 @@ public: } void set_font_color(int r, int g, int b, int a) { - return_virtual_func(set_font_color, 19, 18, 18, 0, r, b, g, a); + return_virtual_func(set_font_color, 19, 18, 18, 0, r, g, b, a); } void set_text_pos(int x, int y) { @@ -157,6 +159,7 @@ FontHandle register_font(const char *font_name, u32 size) { #include void text(FontHandle h, Color c, math::Vector p, const char *format, ...) { + profiler_profile_function(); if (is_surface()) { char buffer[1024]; diff --git a/src/sdk/draw.hh b/src/sdk/draw.hh index 7bc8670..fcb56f6 100644 --- a/src/sdk/draw.hh +++ b/src/sdk/draw.hh @@ -7,8 +7,21 @@ namespace sdk { namespace draw { -struct Color { +class Color { +public: u8 r, g, b, a; + + Color() = default; + Color(const Color &c) = default; + explicit Color(u32 c) { + auto array = (u8 *)&c; + r = array[3]; + g = array[2]; + b = array[1]; + a = array[0]; + } + Color(u8 r, u8 g, u8 b, u8 a) : r(r), g(g), b(b), a(a) { + } }; enum class RenderTarget { diff --git a/src/sdk/player.cc b/src/sdk/player.cc index c27d92f..9c6b0e2 100644 --- a/src/sdk/player.cc +++ b/src/sdk/player.cc @@ -77,11 +77,6 @@ std::pair Player::render_bounds() { func.invoke(ret.first, ret.second); - auto origin = this->origin(); - - ret.first += origin; - ret.second += origin; - return ret; } @@ -89,7 +84,7 @@ math::Vector Player::world_space_centre() { auto bounds = render_bounds(); auto centre = origin(); - centre.z = (bounds.first.z + bounds.second.z) / 2; + centre.z += (bounds.first.z + bounds.second.z) / 2; return centre; } diff --git a/src/sdk/signature.cc b/src/sdk/signature.cc index 0c0dfdb..f519bf9 100644 --- a/src/sdk/signature.cc +++ b/src/sdk/signature.cc @@ -2,6 +2,8 @@ #include "signature.hh" +#include "utils/hex.hh" + #if doghook_platform_linux() #include #include @@ -12,24 +14,7 @@ #endif using namespace signature; - -static constexpr auto in_range(char x, char a, char b) { - return (x >= a && x <= b); -} - -static constexpr auto get_bits(char x) { - if (in_range((x & (~0x20)), 'A', 'F')) { - return (x & (~0x20)) - 'A' + 0xa; - } else if (in_range(x, '0', '9')) { - return x - '0'; - } else { - return 0; - } -} - -static constexpr auto get_byte(const char *x) { - return get_bits(x[0]) << 4 | get_bits(x[1]); -} +using namespace hex; static u8 *find_pattern_internal(uptr start, uptr end, const char *pattern) { u8 *first = 0; @@ -38,7 +23,7 @@ static u8 *find_pattern_internal(uptr start, uptr end, const char *pattern) { for (uptr cur = start; cur < end; cur += 1) { if (!*pat) return first; - if (*(u8 *)pat == '\?' || *(u8 *)cur == get_byte(pat)) { + if (*(u8 *)pat == '\?' || *(u8 *)cur == byte(pat)) { if (first == 0) first = reinterpret_cast(cur); if (!pat[2]) return first; if (*reinterpret_cast(pat) == '\?\?' || diff --git a/src/utils/hex.hh b/src/utils/hex.hh new file mode 100644 index 0000000..1c207a3 --- /dev/null +++ b/src/utils/hex.hh @@ -0,0 +1,27 @@ +#pragma once + +namespace hex { +static constexpr auto in_range(char x, char a, char b) { + return (x >= a && x <= b); +} + +static constexpr auto get_bits(char x) { + if (in_range((x & (~0x20)), 'A', 'F')) { + return (x & (~0x20)) - 'A' + 0xa; + } else if (in_range(x, '0', '9')) { + return x - '0'; + } else { + return 0; + } +} + +static constexpr auto byte(const char *x) { + return get_bits(x[0]) << 4 | get_bits(x[1]); +} +static constexpr auto word(const char *x) { + return byte(x) << 8 | byte(x + 2); +} +static constexpr auto dword(const char *x) { + return word(x) << 16 | word(x + 4); +} +} // namespace hex diff --git a/src/utils/math.hh b/src/utils/math.hh index 206a501..3fcaf93 100644 --- a/src/utils/math.hh +++ b/src/utils/math.hh @@ -174,6 +174,26 @@ public: return ret; } + + inline auto min(const Vector &other) const { + Vector ret; + + ret.x = x < other.x ? x : other.x; + ret.y = y < other.y ? y : other.y; + ret.z = z < other.z ? z : other.z; + + return ret; + } + + inline auto max(const Vector &other) const { + Vector ret; + + ret.x = x > other.x ? x : other.x; + ret.y = y > other.y ? y : other.y; + ret.z = z > other.z ? z : other.z; + + return ret; + } }; class Matrix3x4 { diff --git a/src/utils/profiler.cc b/src/utils/profiler.cc index c37fe77..c7f6621 100644 --- a/src/utils/profiler.cc +++ b/src/utils/profiler.cc @@ -9,42 +9,6 @@ #include #include #include - -class TimeVal { -public: - TimeVal() {} - TimeVal &operator=(const TimeVal &other) { - tv = other.tv; - return *this; - } - - inline double operator-(const TimeVal &left) { - u64 left_us = (u64)left.tv.tv_sec * 1000000 + left.tv.tv_usec; - u64 right_us = (u64)tv.tv_sec * 1000000 + tv.tv_usec; - u64 diff_us = left_us - right_us; - return diff_us / 1000000; - } - - timeval tv; -}; - -static inline double timeval_sub(const timeval &left, const timeval &right) { - auto right_us = (u64)right.tv_sec * 1000000 + right.tv_usec; - auto left_us = (u64)left.tv_sec * 1000000 + left.tv_usec; - - // dont question it - auto diff = right_us - left_us; - return diff / 1000000; -} -// Positive diff of 2 u64s -static inline u64 diff(u64 v1, u64 v2) { - i64 d = v1 - v2; - if (d >= 0) - return d; - else - return -d; -} - #endif namespace profiler { @@ -114,6 +78,18 @@ u64 Timer::sample() { // Calculate the clockspeed on init init_time(Timer::calculate_clock_speed()); +#ifdef _DEBUG +bool enable_profiling = true; +#else +bool enable_profiling = false; +#endif + +bool profiling_enabled() { return enable_profiling; } +void set_profiling_enabled(bool s) { enable_profiling = s; } + +// TODO: using this flat based structure means that we cant have a 2 nodes for the same location +// Take the function draw::test, it may be called from multiple places, but there is only 1 timer for it +// This means that the timer will be wrong for that function / may not show up in the graph properly... std::vector nodes; ProfileNode *find_node(u32 id) { @@ -147,12 +123,13 @@ void enter_node(u32 id, const char *name) { current_nodes.push(find_root_node()); } + if (!enable_profiling) return; + // TODO: maybe we should try and search for nodes that we know are children first?? auto current_node = current_nodes.top(); auto node = find_node(id); if (node == nullptr) { - node = new ProfileNode(); node->parent = current_nodes.top(); @@ -166,6 +143,12 @@ void enter_node(u32 id, const char *name) { nodes.push_back(node); } + if (current_node != node) + // If we arent the child of the current node then add us + if (std::find(current_node->children.begin(), current_node->children.end(), node) == current_node->children.end()) { + current_node->children.push_back(node); + } + if (node->recursions == 0) { node->t.start(); node->recursions = 1; @@ -179,6 +162,8 @@ void enter_node(u32 id, const char *name) { void exit_node() { if (current_nodes.size() < 1) return; // we clearly arent inited yet... + if (!enable_profiling) return; + auto node = current_nodes.top(); if (node->recursions == 1) { diff --git a/src/utils/profiler.hh b/src/utils/profiler.hh index a7e8027..98f1102 100644 --- a/src/utils/profiler.hh +++ b/src/utils/profiler.hh @@ -51,6 +51,9 @@ public: void enter_node(u32 id, const char *name); void exit_node(); +bool profiling_enabled(); +void set_profiling_enabled(bool s); + // access all nodes via index (returns nullptr at end of array) ProfileNode *node(u32 index); ProfileNode *find_root_node(); @@ -66,7 +69,7 @@ public: ~ProfileScope() { exit_node(); }; }; -#ifdef _DEBUG +//#ifdef _DEBUG #if _MSC_VER #define profiler_profile_function() \ auto __ProfileScope##__LINE__ = profiler::ProfileScope(__FUNCTION__) @@ -76,9 +79,9 @@ public: #endif #define profiler_profile_scope(name) \ auto __ProfileScope##__LINE__ = profiler::ProfileScope("/" name) -#else -#define profiler_profile_function() -#define profiler_profile_scope(name) -#endif +//#else +//#define profiler_profile_function() +//#define profiler_profile_scope(name) +//#endif } // namespace profiler