Add dynamic box esp and cleanup code (#34)
Add dynamic box esp and cleanup code
This commit is contained in:
parent
7ce00987a0
commit
9c99ba9701
@ -22,6 +22,8 @@
|
||||
|
||||
#include "utils/profiler.hh"
|
||||
|
||||
static Convar<bool> 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() {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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<const char *> doghook_esp_enemy{"doghook_esp_enemy", "FF0000FF", nullptr};
|
||||
static Convar<const char *> 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<Engine>()->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<EntList>()->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ public:
|
||||
};
|
||||
|
||||
template <>
|
||||
class Convar<char *> : public ConvarBase {
|
||||
class Convar<const char *> : public ConvarBase {
|
||||
char *value;
|
||||
|
||||
public:
|
||||
|
@ -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 <cstdarg>
|
||||
|
||||
void text(FontHandle h, Color c, math::Vector p, const char *format, ...) {
|
||||
profiler_profile_function();
|
||||
if (is_surface()) {
|
||||
|
||||
char buffer[1024];
|
||||
|
@ -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 {
|
||||
|
@ -77,11 +77,6 @@ std::pair<math::Vector, math::Vector> 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;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include "signature.hh"
|
||||
|
||||
#include "utils/hex.hh"
|
||||
|
||||
#if doghook_platform_linux()
|
||||
#include <dirent.h>
|
||||
#include <elf.h>
|
||||
@ -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<u8 *>(cur);
|
||||
if (!pat[2]) return first;
|
||||
if (*reinterpret_cast<const u16 *>(pat) == '\?\?' ||
|
||||
|
27
src/utils/hex.hh
Normal file
27
src/utils/hex.hh
Normal file
@ -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
|
@ -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 {
|
||||
|
@ -9,42 +9,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <x86intrin.h>
|
||||
|
||||
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<ProfileNode *> 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) {
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user