From b24671c10eee7faebc946b16173b7961c93ab196 Mon Sep 17 00:00:00 2001 From: bencat07 Date: Sun, 2 Jun 2019 15:30:32 +0200 Subject: [PATCH] add buggy sound esp (Crashes at some parts right now) --- include/core/interfaces.hpp | 2 + include/entitycache.hpp | 9 ++++ include/playerresource.h | 1 + include/soundcache.hpp | 13 ++++++ src/CMakeLists.txt | 1 + src/core/interfaces.cpp | 2 + src/hacks/ESP.cpp | 85 ++++++++++++++++++++++++++++--------- src/playerresource.cpp | 15 +++++++ src/soundcache.cpp | 33 ++++++++++++++ src/visual/drawing.cpp | 13 +++++- 10 files changed, 153 insertions(+), 21 deletions(-) create mode 100644 include/soundcache.hpp create mode 100644 src/soundcache.cpp diff --git a/include/core/interfaces.hpp b/include/core/interfaces.hpp index a0496080..8f68da5d 100644 --- a/include/core/interfaces.hpp +++ b/include/core/interfaces.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace vgui { @@ -60,6 +61,7 @@ extern CHud *g_CHUD; extern ISteamClient *g_ISteamClient; extern ISteamFriends *g_ISteamFriends; extern IVEngineClient013 *g_IEngine; +extern IEngineSound *g_ISoundEngine; extern vgui::ISurface *g_ISurface; extern vgui::IPanel *g_IPanel; extern IClientEntityList *g_IEntityList; diff --git a/include/entitycache.hpp b/include/entitycache.hpp index 6a04aae9..28917113 100644 --- a/include/entitycache.hpp +++ b/include/entitycache.hpp @@ -53,6 +53,8 @@ struct mstudiobbox_t; #define CE_GOOD(entity) (entity && !g_Settings.bInvalid && entity->Good()) #define CE_BAD(entity) (!CE_GOOD(entity)) +#define CE_VALID(entity) (entity && !g_Settings.bInvalid && entity->Valid()) +#define CE_INVALID(entity) (!CE_VALID(entity)) #define IDX_GOOD(idx) (idx >= 0 && idx <= HIGHEST_ENTITY && idx < MAX_ENTITIES) #define IDX_BAD(idx) !IDX_GOOD(idx) @@ -82,6 +84,13 @@ public: IClientEntity *const entity = InternalEntity(); return entity && !entity->IsDormant(); } + __attribute__((always_inline, hot, const)) inline bool Valid() const + { + if (!RAW_ENT(this) || !RAW_ENT(this)->GetClientClass()->m_ClassID) + return false; + IClientEntity *const entity = InternalEntity(); + return entity; + } template __attribute__((always_inline, hot, const)) inline T &var(uintptr_t offset) const { return *reinterpret_cast(uintptr_t(RAW_ENT(this)) + offset); diff --git a/include/playerresource.h b/include/playerresource.h index c42cf99d..12e605de 100755 --- a/include/playerresource.h +++ b/include/playerresource.h @@ -14,6 +14,7 @@ class TFPlayerResource public: void Update(); int GetMaxHealth(CachedEntity *player); + int GetHealth(CachedEntity *player); int GetMaxBuffedHealth(CachedEntity *player); int GetClass(CachedEntity *player); int GetTeam(int idx); diff --git a/include/soundcache.hpp b/include/soundcache.hpp new file mode 100644 index 00000000..cf40b55b --- /dev/null +++ b/include/soundcache.hpp @@ -0,0 +1,13 @@ +#include "common.hpp" +struct CSndInfo_t +{ + Vector m_pOrigin; + int m_nSoundSource; +}; + +struct SoundStruct +{ + CSndInfo_t sound; + Timer last_update; +}; +extern std::map sound_cache; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d85a600..a8ed7562 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,7 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/angles.cpp" "${CMAKE_CURRENT_LIST_DIR}/prediction.cpp" "${CMAKE_CURRENT_LIST_DIR}/projlogging.cpp" "${CMAKE_CURRENT_LIST_DIR}/sconvars.cpp" + "${CMAKE_CURRENT_LIST_DIR}/soundcache.cpp" "${CMAKE_CURRENT_LIST_DIR}/targethelper.cpp" "${CMAKE_CURRENT_LIST_DIR}/textfile.cpp" "${CMAKE_CURRENT_LIST_DIR}/textmode.cpp" diff --git a/src/core/interfaces.cpp b/src/core/interfaces.cpp index ac061d87..a30adf65 100644 --- a/src/core/interfaces.cpp +++ b/src/core/interfaces.cpp @@ -22,6 +22,7 @@ IVModelRender *g_IVModelRender = nullptr; ISteamClient *g_ISteamClient = nullptr; ISteamFriends *g_ISteamFriends = nullptr; IVEngineClient013 *g_IEngine = nullptr; +IEngineSound *g_ISoundEngine = nullptr; vgui::ISurface *g_ISurface = nullptr; vgui::IPanel *g_IPanel = nullptr; IClientEntityList *g_IEntityList = nullptr; @@ -87,6 +88,7 @@ void CreateInterfaces() { g_ICvar = BruteforceInterface("VEngineCvar", sharedobj::vstdlib()); g_IEngine = BruteforceInterface("VEngineClient", sharedobj::engine()); + g_ISoundEngine = BruteforceInterface("IEngineSoundClient", sharedobj::engine()); g_AppID = g_IEngine->GetAppID(); g_IEntityList = BruteforceInterface("VClientEntityList", sharedobj::client()); g_ISteamClient = BruteforceInterface("SteamClient", sharedobj::steamclient(), 17); diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index d548c447..768397c0 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -10,6 +10,7 @@ #include #include #include "common.hpp" +#include "soundcache.hpp" namespace hacks::shared::esp { @@ -192,7 +193,7 @@ struct bonelist_s return; // ent->m_bBonesSetup = false; - Vector displacement = RAW_ENT(ent)->GetAbsOrigin() - ent->m_vecOrigin(); + Vector displacement = {}; const auto &bones = ent->hitboxes.GetBones(); DrawBoneList(bones, leg_r, 3, color, displacement); DrawBoneList(bones, leg_l, 3, color, displacement); @@ -260,7 +261,7 @@ static void cm() { // Get an entity from the loop tick and process it CachedEntity *ent = ENTITY(i); - if (CE_BAD(ent)) + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) continue; ProcessEntity(ent); // Update Bones @@ -369,8 +370,17 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) PROF_SECTION(PT_esp_process_entity); // Check to prevent crashes - if (CE_BAD(ent)) + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) return; + // Dormant + bool dormant = false; + if (RAW_ENT(ent)->IsDormant()) + { + auto ent_cache = sound_cache[ent->m_IDX]; + if (ent_cache.last_update.check(10000) || ent_cache.sound.m_pOrigin.IsZero()) + return; + dormant = true; + } int classid = ent->m_iClassID(); EntityType type = ent->m_Type(); @@ -384,8 +394,12 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) fg = ent_data.color = colors::EntityF(ent); // Check if entity is on screen, then save screen position if true + Vector position = ent->m_vecOrigin(); + // Dormant + if (dormant) + position = sound_cache[ent->m_IDX].sound.m_pOrigin; static Vector screen, origin_screen; - if (!draw::EntityCenterToScreen(ent, screen) && !draw::WorldToScreen(ent->m_vecOrigin(), origin_screen)) + if (!draw::EntityCenterToScreen(ent, screen) && !draw::WorldToScreen(position, origin_screen)) return; // Reset the collide cache @@ -410,7 +424,7 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) // Get world to screen Vector scn; - draw::WorldToScreen(ent->m_vecOrigin(), scn); + draw::WorldToScreen(position, scn); // Draw a line draw::Line(scn.x, scn.y, width - scn.x, height - scn.y, fg, 0.5f); @@ -747,8 +761,15 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) { if (!enable) return; // Esp enable check - if (CE_BAD(ent)) - return; // CE_BAD check to prevent crashes + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) + return; // CE_INVALID check to prevent crashes + // Dormant + if (RAW_ENT(ent)->IsDormant()) + { + auto ent_cache = sound_cache[ent->m_IDX]; + if (ent_cache.last_update.check(10000) || ent_cache.sound.m_pOrigin.IsZero()) + return; + } if (max_dist && ent->m_flDistance() > *max_dist) return; int classid = ent->m_iClassID(); @@ -1096,7 +1117,10 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // Health esp if ((int) show_health == 1 || (int) show_health == 3) { - AddEntityString(ent, format(ent->m_iHealth(), '/', ent->m_iMaxHealth(), " HP"), colors::Health(ent->m_iHealth(), ent->m_iMaxHealth())); + if (RAW_ENT(ent)->IsDormant()) + AddEntityString(ent, "?/? HP", colors::black); + else + AddEntityString(ent, format(ent->m_iHealth(), '/', ent->m_iMaxHealth(), " HP"), colors::Health(ent->m_iHealth(), ent->m_iMaxHealth())); } IF_GAME(IsTF()) { @@ -1113,7 +1137,7 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) if (eid >= 32 && eid <= HIGHEST_ENTITY) { CachedEntity *weapon = ENTITY(eid); - if (!CE_BAD(weapon) && weapon->m_iClassID() == CL_CLASS(CWeaponMedigun) && weapon) + if (!CE_INVALID(weapon) && weapon->m_iClassID() == CL_CLASS(CWeaponMedigun) && weapon) { if (CE_INT(weapon, netvar.iItemDefinitionIndex) != 998) { @@ -1169,6 +1193,9 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // Jarated if (HasCondition(ent)) AddEntityString(ent, "*JARATED*", colors::yellow); + // Dormant + if (CE_VALID(ent) && RAW_ENT(ent)->IsDormant()) + AddEntityString(ent, "*DORMANT*", colors::red); } } // Hoovy Esp @@ -1180,7 +1207,7 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) if (IDX_GOOD(widx)) { CachedEntity *weapon = ENTITY(widx); - if (CE_GOOD(weapon)) + if (CE_VALID(weapon)) { if (show_weapon) { @@ -1201,12 +1228,21 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // Draw 3D box around player/building void _FASTCALL Draw3DBox(CachedEntity *ent, const rgba_t &clr) { - if (CE_BAD(ent)) + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) return; - const Vector &origin = RAW_ENT(ent)->GetCollideable()->GetCollisionOrigin(); - Vector mins = RAW_ENT(ent)->GetCollideable()->OBBMins(); - Vector maxs = RAW_ENT(ent)->GetCollideable()->OBBMaxs(); + Vector origin = RAW_ENT(ent)->GetCollideable()->GetCollisionOrigin(); + Vector mins = RAW_ENT(ent)->GetCollideable()->OBBMins(); + Vector maxs = RAW_ENT(ent)->GetCollideable()->OBBMaxs(); + // Dormant + if (RAW_ENT(ent)->IsDormant()) + { + auto ent_cache = sound_cache[ent->m_IDX]; + if (!ent_cache.last_update.check(10000) && !ent_cache.sound.m_pOrigin.IsZero()) + origin = ent_cache.sound.m_pOrigin; + else + return; + } // Create a array for storing box points Vector corners[8]; // World vectors @@ -1262,7 +1298,7 @@ void _FASTCALL DrawBox(CachedEntity *ent, const rgba_t &clr) PROF_SECTION(PT_esp_drawbox); // Check if ent is bad to prevent crashes - if (CE_BAD(ent)) + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) return; // Get our collidable bounds @@ -1332,8 +1368,8 @@ bool GetCollide(CachedEntity *ent) { PROF_SECTION(PT_esp_getcollide); - // Null + Dormant check to prevent crashing - if (CE_BAD(ent)) + // Null check to prevent crashing + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) return false; // Grab esp data @@ -1344,9 +1380,18 @@ bool GetCollide(CachedEntity *ent) { // Get collision center, max, and mins - const Vector &origin = RAW_ENT(ent)->GetCollideable()->GetCollisionOrigin(); - Vector mins = RAW_ENT(ent)->GetCollideable()->OBBMins() + origin; - Vector maxs = RAW_ENT(ent)->GetCollideable()->OBBMaxs() + origin; + Vector origin = RAW_ENT(ent)->GetCollideable()->GetCollisionOrigin(); + // Dormant + if (RAW_ENT(ent)->IsDormant()) + { + auto ent_cache = sound_cache[ent->m_IDX]; + if (!ent_cache.last_update.check(10000) && !ent_cache.sound.m_pOrigin.IsZero()) + origin = ent_cache.sound.m_pOrigin; + else + return false; + } + Vector mins = RAW_ENT(ent)->GetCollideable()->OBBMins() + origin; + Vector maxs = RAW_ENT(ent)->GetCollideable()->OBBMaxs() + origin; // Create a array for storing box points Vector points_r[8]; // World vectors diff --git a/src/playerresource.cpp b/src/playerresource.cpp index 45d8ac67..e2cdae4d 100755 --- a/src/playerresource.cpp +++ b/src/playerresource.cpp @@ -25,6 +25,21 @@ void TFPlayerResource::Update() } } +int TFPlayerResource::GetHealth(CachedEntity *player) +{ + IClientEntity *ent; + int idx; + /* :thinking */ + IF_GAME(!IsTF()) return 100; + ent = g_IEntityList->GetClientEntity(entity); + if (!ent || ent->GetClientClass()->m_ClassID != RCC_PLAYERRESOURCE) + return 0; + idx = player->m_IDX; + if (idx >= 64 || idx < 0) + return 0; + return *(int *) ((unsigned) ent + netvar.m_iHealth_Resource + 4 * idx); +} + int TFPlayerResource::GetMaxHealth(CachedEntity *player) { IClientEntity *ent; diff --git a/src/soundcache.cpp b/src/soundcache.cpp new file mode 100644 index 00000000..d76ea7ba --- /dev/null +++ b/src/soundcache.cpp @@ -0,0 +1,33 @@ +#include "common.hpp" + +struct CSndInfo_t +{ + Vector m_pOrigin; + int m_nSoundSource; +}; + +struct SoundStruct +{ + CSndInfo_t sound; + Timer last_update; +}; +std::map sound_cache; + +void CreateMove() +{ + if (CE_BAD(LOCAL_E)) + return; + CUtlVector sound_list; + g_ISoundEngine->GetActiveSounds(sound_list); + for (auto i : sound_list) + { + sound_cache[i.m_nSoundSource].sound.m_pOrigin = *i.m_pOrigin; + sound_cache[i.m_nSoundSource].sound.m_nSoundSource = sound_cache[i.m_nSoundSource].sound.m_nSoundSource; + sound_cache[i.m_nSoundSource].last_update.update(); + } +} +static InitRoutine init([]() { + EC::Register(EC::CreateMove, CreateMove, "CM_SoundCache"); + EC::Register( + EC::LevelInit, []() { sound_cache.clear(); }, "soundcache_levelinit"); +}); diff --git a/src/visual/drawing.cpp b/src/visual/drawing.cpp index a0868d7a..626ee438 100644 --- a/src/visual/drawing.cpp +++ b/src/visual/drawing.cpp @@ -23,6 +23,7 @@ #include #include #include +#include "soundcache.hpp" // String -> Wstring #include @@ -395,10 +396,20 @@ bool EntityCenterToScreen(CachedEntity *entity, Vector &out) Vector world, min, max; bool succ; - if (CE_BAD(entity)) + if (CE_INVALID(entity)) return false; RAW_ENT(entity)->GetRenderBounds(min, max); world = RAW_ENT(entity)->GetAbsOrigin(); + + // Dormant + if (RAW_ENT(entity)->IsDormant()) + { + auto ent_cache = sound_cache[entity->m_IDX]; + if (!ent_cache.last_update.check(10000) && ent_cache.sound.m_pOrigin.IsZero()) + world = ent_cache.sound.m_pOrigin; + else + return false; + } world.z += (min.z + max.z) / 2; succ = draw::WorldToScreen(world, out); return succ;