Add dynamic box esp and cleanup code (#34)

Add dynamic box esp and cleanup code
This commit is contained in:
F1ssi0N 2018-04-04 17:42:06 +01:00 committed by GitHub
parent 7ce00987a0
commit 9c99ba9701
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 166 additions and 89 deletions

View File

@ -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() {

View File

@ -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();
}

View File

@ -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);
}
}
}

View File

@ -269,7 +269,7 @@ public:
};
template <>
class Convar<char *> : public ConvarBase {
class Convar<const char *> : public ConvarBase {
char *value;
public:

View File

@ -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];

View File

@ -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 {

View File

@ -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;
}

View File

@ -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
View 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

View File

@ -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 {

View File

@ -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) {

View File

@ -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