diff --git a/CMakeLists.txt b/CMakeLists.txt index 6459f30b..625138e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ if (NOT ExternalDrawing) set(Visuals_EnforceStreamSafety 0) endif() -set(EnableProfiler 0 CACHE BOOL "Enable Profiler") +set(EnableProfiler 1 CACHE BOOL "Enable Profiler") set(EnableGUI 1 CACHE BOOL "Enable GUI") set(EnableIPC 1 CACHE BOOL "Enable IPC") set(DataPath "/opt/cathook/data" CACHE FILEPATH "Data location") @@ -100,13 +100,12 @@ endif() find_package(Git REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/external") find_package(SDL2 REQUIRED) - -find_package(Boost 1.76.0 EXACT) +find_package(Boost 1.76.5 EXACT) if (NOT ${Boost_FOUND}) set(BOOST_LIBS_OPTIONAL "" CACHE STRING "Boost libs to be compiled") add_subdirectory(external/boost-cmake) SET (BOOST_ROOT ${CMAKE_BINARY_DIR}/_deps/boost-src) - find_package(Boost 1.76.0 EXACT) + find_package(Boost 1.76.5 EXACT) include_directories(${Boost_INCLUDE_DIRS}) endif() @@ -167,7 +166,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-march=native -rdynamic -ggdb -Og") if (Internal_Symbolized) set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -ggdb -fvisibility=hidden -fvisibility-inlines-hidden") else() - set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -s -fvisibility=hidden -fvisibility-inlines-hidden") + set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -s -fmerge-all-constants -fdevirtualize-at-ltrans -fvisibility=hidden -fvisibility-inlines-hidden") endif() if (Force_CXX_23B) set(CMAKE_CXX_FLAGS "-std=gnu++2b ${CMAKE_CXX_FLAGS}") diff --git a/external/boost-cmake b/external/boost-cmake index 402df1a9..056b9dea 160000 --- a/external/boost-cmake +++ b/external/boost-cmake @@ -1 +1 @@ -Subproject commit 402df1a95f40357f9f42431c20bae58ceeb97223 +Subproject commit 056b9deae0526a033c5383d29268a1f67754e68b diff --git a/include/MiscTemporary.hpp b/include/MiscTemporary.hpp index e5fb36cc..a221e9ff 100755 --- a/include/MiscTemporary.hpp +++ b/include/MiscTemporary.hpp @@ -8,7 +8,7 @@ #include #include "common.hpp" #include "DetourHook.hpp" - +#include "inetmsghandler.h" #define MENU_COLOR (menu_color) // This is a temporary file to put code that needs moving/refactoring in. diff --git a/include/entitycache.hpp b/include/entitycache.hpp index bd5509db..e771e17f 100644 --- a/include/entitycache.hpp +++ b/include/entitycache.hpp @@ -24,6 +24,9 @@ #include "client_class.h" #include "Constants.hpp" #include +#include +#include + struct matrix3x4_t; class IClientEntity; @@ -60,7 +63,6 @@ constexpr int MAX_STRINGS = 16; #define HIGHEST_ENTITY (entity_cache::max) #define ENTITY(idx) (entity_cache::Get(idx)) -bool IsProjectileACrit(CachedEntity *ent); class CachedEntity { public: @@ -70,27 +72,27 @@ public: ~CachedEntity(); __attribute__((hot)) void Update(); + bool IsVisible(); - void Reset(); __attribute__((always_inline, hot, const)) IClientEntity *InternalEntity() const { return g_IEntityList->GetClientEntity(m_IDX); } - __attribute__((always_inline, hot, const)) inline bool Good() const + __attribute__((always_inline, hot, const)) bool Good() const { if (!RAW_ENT(this) || !RAW_ENT(this)->GetClientClass()->m_ClassID) return false; IClientEntity *const entity = InternalEntity(); return entity && !entity->IsDormant(); } - __attribute__((always_inline, hot, const)) inline bool Valid() const + __attribute__((always_inline, hot, const)) 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 + template __attribute__((always_inline, hot, const)) T &var(uintptr_t offset) const { return *reinterpret_cast(uintptr_t(RAW_ENT(this)) + offset); } @@ -109,7 +111,15 @@ public: { return RAW_ENT(this)->GetAbsOrigin(); }; - std::optional m_vecDormantOrigin(); + std::optional m_vecDormantOrigin() + { + if (!RAW_ENT(this)->IsDormant()) + return m_vecOrigin(); + auto vec = soundcache::GetSoundLocation(this->m_IDX); + if (vec) + return *vec; + return std::nullopt; + } int m_iTeam() { return NET_INT(RAW_ENT(this), netvar.iTeamNum); @@ -150,19 +160,18 @@ public: // Entity fields start here EntityType m_Type() { - EntityType ret = ENTITY_GENERIC; - int classid = m_iClassID(); + + int classid = m_iClassID(); if (classid == CL_CLASS(CTFPlayer)) - ret = ENTITY_PLAYER; + return ENTITY_PLAYER; else if (classid == CL_CLASS(CTFGrenadePipebombProjectile) || classid == CL_CLASS(CTFProjectile_Cleaver) || classid == CL_CLASS(CTFProjectile_Jar) || classid == CL_CLASS(CTFProjectile_JarMilk) || classid == CL_CLASS(CTFProjectile_Arrow) || classid == CL_CLASS(CTFProjectile_EnergyBall) || classid == CL_CLASS(CTFProjectile_EnergyRing) || classid == CL_CLASS(CTFProjectile_GrapplingHook) || classid == CL_CLASS(CTFProjectile_HealingBolt) || classid == CL_CLASS(CTFProjectile_Rocket) || classid == CL_CLASS(CTFProjectile_SentryRocket) || classid == CL_CLASS(CTFProjectile_BallOfFire) || classid == CL_CLASS(CTFProjectile_Flare)) - ret = ENTITY_PROJECTILE; + return ENTITY_PROJECTILE; else if (classid == CL_CLASS(CObjectTeleporter) || classid == CL_CLASS(CObjectSentrygun) || classid == CL_CLASS(CObjectDispenser)) - ret = ENTITY_BUILDING; + return ENTITY_BUILDING; else if (classid == CL_CLASS(CZombie) || classid == CL_CLASS(CTFTankBoss) || classid == CL_CLASS(CMerasmus) || classid == CL_CLASS(CMerasmusDancer) || classid == CL_CLASS(CEyeballBoss) || classid == CL_CLASS(CHeadlessHatman)) - ret = ENTITY_NPC; + return ENTITY_NPC; else - ret = ENTITY_GENERIC; - return ret; + return ENTITY_GENERIC; }; float m_flDistance() @@ -172,7 +181,12 @@ public: else return FLT_MAX; }; - + bool IsProjectileACrit(CachedEntity *ent) + { + if (ent->m_bGrenadeProjectile()) + return CE_BYTE(ent, netvar.Grenade_bCritical); + return CE_BYTE(ent, netvar.Rocket_bCritical); + } bool m_bCritProjectile() { if (m_Type() == EntityType::ENTITY_PROJECTILE) @@ -205,6 +219,19 @@ public: hitbox_cache::EntityHitboxCache hitboxes; player_info_s player_info{}; Averager velocity_averager{ 8 }; + void Reset() + { + m_bAnyHitboxVisible = false; + m_bVisCheckComplete = false; + m_lLastSeen = 0; + m_lSeenTicks = 0; + memset(&player_info, 0, sizeof(player_info_s)); + m_vecAcceleration.Zero(); + m_vecVOrigin.Zero(); + m_vecVelocity.Zero(); + m_fLastUpdate = 0; + } + bool was_dormant() { return RAW_ENT(this)->IsDormant(); @@ -222,16 +249,16 @@ namespace entity_cache extern u_int16_t max; extern u_int16_t previous_max; extern std::vector valid_ents; -extern std::unordered_map array; +extern boost::unordered_flat_map array; extern std::vector> proj_map; -extern std::vector player_cache; +extern std::vector player_cache; inline CachedEntity *Get(const u_int16_t &idx) { - auto iterator = array.find(idx); - if (iterator == array.end()) + auto test = array.find(idx); + if (test == array.end()) return nullptr; else - return &iterator->second; + return &test->second; } void dodgeProj(CachedEntity *proj_ptr); void Update(); diff --git a/include/entityhitboxcache.hpp b/include/entityhitboxcache.hpp index 599cbb67..3ee54940 100644 --- a/include/entityhitboxcache.hpp +++ b/include/entityhitboxcache.hpp @@ -30,35 +30,41 @@ struct CachedHitbox class EntityHitboxCache { -public: - - EntityHitboxCache() = default; - EntityHitboxCache(int in_IDX); - ~EntityHitboxCache(); - - CachedHitbox *GetHitbox(int id); - void Update(); - void InvalidateCache(); - bool VisibilityCheck(int id); - void Init(); - int GetNumHitboxes(); - void Reset(); - matrix3x4_t *GetBones(int numbones = -1); - - // for "fixing" bones to use the reconstructed ones - void UpdateBones(); - - int m_nNumHitboxes; - int hit_idx; - bool m_bModelSet; - bool m_bInit; - bool m_bSuccess; - model_t *m_pLastModel; +private: + int hit_idx; + bool m_bModelSet = false; + bool m_bInit = false; + bool m_bSuccess = false; + model_t *m_pLastModel = nullptr; CachedEntity *parent_ref; bool m_VisCheckValidationFlags[CACHE_MAX_HITBOXES]{ false }; bool m_VisCheck[CACHE_MAX_HITBOXES]{ false }; + void Init(); + +public: + EntityHitboxCache() = default; + EntityHitboxCache(int in_IDX) : hit_idx(in_IDX) + { + } + + CachedHitbox *GetHitbox(int id); + void InvalidateCache(); + bool VisibilityCheck(int id); + int GetNumHitboxes() + { + if (!m_bInit) + Init(); + if (!m_bSuccess) + return 0; + return m_nNumHitboxes; + } + matrix3x4_t *GetBones(int numbones = -1); + + // for "fixing" bones to use the reconstructed ones + void UpdateBones(); bool m_CacheValidationFlags[CACHE_MAX_HITBOXES]{ false }; + int m_nNumHitboxes = 0; std::vector m_CacheInternal; std::vector bones; diff --git a/include/hacks/Trigger.hpp b/include/hacks/Trigger.hpp index d0d8075a..5df0a757 100644 --- a/include/hacks/Trigger.hpp +++ b/include/hacks/Trigger.hpp @@ -19,7 +19,6 @@ bool IsTargetStateGood(CachedEntity *entity, std::optional std::string format(const Args &...args) extern const std::string classes[10]; extern const char *powerups[POWERUP_COUNT]; bool isTruce(); -bool GetPlayerInfo(int idx, player_info_s *info); + void setTruce(bool status); int GetPlayerForUserID(int userID); + +inline bool GetPlayerInfo(int idx, player_info_s *info) +{ + bool res = g_IEngine->GetPlayerInfo(idx, info); + if (!res) + return res; + + // First try parsing GUID, should always work unless a server is being malicious + try + { + std::string guid = info->guid; + guid = guid.substr(5, guid.length() - 6); + info->friendsID = std::stoul(guid.c_str()); + } + catch (...) + { + // Fix friends ID with player resource + info->friendsID = g_pPlayerResource->GetAccountID(idx); + } + return res; +} \ No newline at end of file diff --git a/include/soundcache.hpp b/include/soundcache.hpp index 04b2a8f9..8825d24b 100644 --- a/include/soundcache.hpp +++ b/include/soundcache.hpp @@ -6,6 +6,32 @@ namespace soundcache { -std::optional GetSoundLocation(int entid); -void cache_sound(const Vector *Origin, int source); + struct CSndInfo_t +{ + Vector m_pOrigin; +}; + +struct SoundStruct +{ + CSndInfo_t sound; + Timer last_update; +}; + +extern std::map sound_cache; +inline void cache_sound(const Vector *Origin, int source) +{ + // Just in case + if (!Origin) + return; + sound_cache[source].sound.m_pOrigin = *Origin; + sound_cache[source].last_update.update(); +} +inline std::optional GetSoundLocation(int entid) +{ + auto it = sound_cache.find(entid); + if (it == sound_cache.end()) + return std::nullopt; + return it->second.sound.m_pOrigin; +} + } // namespace soundcache diff --git a/src/SetupBonesReconst.cpp b/src/SetupBonesReconst.cpp index 63d833b9..5f79c24e 100644 --- a/src/SetupBonesReconst.cpp +++ b/src/SetupBonesReconst.cpp @@ -59,23 +59,16 @@ void GetSkeleton(IClientEntity *ent, CStudioHdr *pStudioHdr, Vector pos[], Quate boneSetup.AccumulatePose(pos, q, NET_INT(ent, netvar.m_nSequence), NET_FLOAT(ent, netvar.m_flCycle), 1.0, g_GlobalVars->curtime, *m_pIk); // sort the layers - int layer[MAX_OVERLAYS] = {}; - int i; - for (i = 0; i < m_AnimOverlay.Count(); i++) - { - layer[i] = MAX_OVERLAYS; - } - for (i = 0; i < m_AnimOverlay.Count(); i++) + static int layer[MAX_OVERLAYS]; + memset(layer,MAX_OVERLAYS,m_AnimOverlay.Count()*4); + for (int i = 0; i < m_AnimOverlay.Count(); i++) { CAnimationLayer &pLayer = m_AnimOverlay[i]; if ((pLayer.m_flWeight > 0) && pLayer.IsActive() && pLayer.m_nOrder >= 0 && pLayer.m_nOrder < m_AnimOverlay.Count()) { layer[pLayer.m_nOrder] = i; } - } - for (i = 0; i < m_AnimOverlay.Count(); i++) - { - if (layer[i] >= 0 && layer[i] < m_AnimOverlay.Count()) + if (layer[i] >= 0 && layer[i] < m_AnimOverlay.Count()) { CAnimationLayer &pLayer = m_AnimOverlay[layer[i]]; @@ -84,6 +77,7 @@ void GetSkeleton(IClientEntity *ent, CStudioHdr *pStudioHdr, Vector pos[], Quate boneSetup.AccumulatePose(pos, q, pLayer.m_nSequence, pLayer.m_flCycle, pLayer.m_flWeight, g_GlobalVars->curtime, *m_pIk); } } + if (m_pIk) { @@ -117,9 +111,8 @@ bool SetupBones(IClientEntity *ent, matrix3x4_t *pBoneToWorld, int boneMask) // EFL_SETTING_UP_BONES *entity_flags |= 1 << 3; - Vector pos[MAXSTUDIOBONES]; - Quaternion q[MAXSTUDIOBONES]; - + static Vector pos[MAXSTUDIOBONES]; + static Quaternion q[MAXSTUDIOBONES]; static uintptr_t m_pIK_offset = 0x568; Vector adjOrigin = ent->GetAbsOrigin(); diff --git a/src/entitycache.cpp b/src/entitycache.cpp index 8174bf67..4655c0c0 100644 --- a/src/entitycache.cpp +++ b/src/entitycache.cpp @@ -11,43 +11,6 @@ #include #include "soundcache.hpp" #include - -bool IsProjectileACrit(CachedEntity *ent) -{ - if (ent->m_bGrenadeProjectile()) - return CE_BYTE(ent, netvar.Grenade_bCritical); - return CE_BYTE(ent, netvar.Rocket_bCritical); -} - -CachedEntity::CachedEntity(u_int16_t idx) : m_IDX(idx), hitboxes(hitbox_cache::EntityHitboxCache{ idx }) -{ -#if PROXY_ENTITY != true - m_pEntity = nullptr; -#endif - m_fLastUpdate = 0.0f; -} - -inline void CachedEntity::Reset() -{ - m_bAnyHitboxVisible = false; - m_bVisCheckComplete = false; - m_lLastSeen = 0; - m_lSeenTicks = 0; - memset(&player_info, 0, sizeof(player_info_s)); - m_vecAcceleration.Zero(); - m_vecVOrigin.Zero(); - m_vecVelocity.Zero(); - m_fLastUpdate = 0; -} - -CachedEntity::~CachedEntity() -{ -} - -static settings::Float ve_window{ "debug.ve.window", "0" }; -static settings::Boolean ve_smooth{ "debug.ve.smooth", "true" }; -static settings::Int ve_averager_size{ "debug.ve.averaging", "0" }; - inline void CachedEntity::Update() { #if PROXY_ENTITY != true @@ -60,7 +23,7 @@ inline void CachedEntity::Update() m_lSeenTicks = 0; m_lLastSeen = 0; - hitboxes.Update(); + hitboxes.InvalidateCache(); m_bVisCheckComplete = false; @@ -68,6 +31,20 @@ inline void CachedEntity::Update() GetPlayerInfo(m_IDX, &player_info); } +inline CachedEntity::CachedEntity(u_int16_t idx) : m_IDX(idx), hitboxes(hitbox_cache::EntityHitboxCache{ idx }) +{ +#if PROXY_ENTITY != true + m_pEntity = nullptr; +#endif + m_fLastUpdate = 0.0f; +} +CachedEntity::~CachedEntity() +{ +} +static settings::Float ve_window{ "debug.ve.window", "0" }; +static settings::Boolean ve_smooth{ "debug.ve.smooth", "true" }; +static settings::Int ve_averager_size{ "debug.ve.averaging", "0" }; + // FIXME maybe disable this by default static settings::Boolean fast_vischeck{ "debug.fast-vischeck", "true" }; @@ -121,19 +98,9 @@ bool CachedEntity::IsVisible() return false; } - -std::optional CachedEntity::m_vecDormantOrigin() -{ - if (!RAW_ENT(this)->IsDormant()) - return m_vecOrigin(); - auto vec = soundcache::GetSoundLocation(this->m_IDX); - if (vec) - return *vec; - return std::nullopt; -} namespace entity_cache { -std::unordered_map array; +boost::unordered_flat_map array; std::vector valid_ents; std::vector> proj_map; std::vector player_cache; @@ -145,10 +112,8 @@ void Update() u_int16_t current_ents = g_IEntityList->NumberOfEntities(false); valid_ents.clear(); // Reserving isn't necessary as this doesn't reallocate it player_cache.clear(); - if (max >= MAX_ENTITIES) max = MAX_ENTITIES - 1; - if (previous_max == max && previous_ent == current_ents) { for (auto &[key, val] : array) @@ -171,8 +136,7 @@ void Update() { if (g_Settings.bInvalid || !(g_IEntityList->GetClientEntity(i)) || !(g_IEntityList->GetClientEntity(i)->GetClientClass()->m_ClassID)) continue; - if (array.find(i) == array.end()) - array.emplace(std::make_pair(i, CachedEntity{ i })); + array.try_emplace(i, CachedEntity{ i }); array[i].Update(); if (CE_GOOD((&array[i]))) diff --git a/src/entityhitboxcache.cpp b/src/entityhitboxcache.cpp index e1cc36ed..3c260d52 100644 --- a/src/entityhitboxcache.cpp +++ b/src/entityhitboxcache.cpp @@ -12,22 +12,6 @@ namespace hitbox_cache { -EntityHitboxCache::EntityHitboxCache(int in_IDX) : hit_idx(in_IDX) -{ - Reset(); -} -int EntityHitboxCache::GetNumHitboxes() -{ - if (!m_bInit) - Init(); - if (!m_bSuccess) - return 0; - return m_nNumHitboxes; -} - -EntityHitboxCache::~EntityHitboxCache() -{ -} void EntityHitboxCache::InvalidateCache() { @@ -41,11 +25,6 @@ void EntityHitboxCache::InvalidateCache() m_bSuccess = false; } -void EntityHitboxCache::Update() -{ - InvalidateCache(); -} - void EntityHitboxCache::Init() { model_t *model; @@ -183,23 +162,6 @@ matrix3x4_t *EntityHitboxCache::GetBones(int numbones) return bones.data(); } -void EntityHitboxCache::Reset() -{ - memset(m_VisCheck, 0, sizeof(bool) * CACHE_MAX_HITBOXES); - memset(m_VisCheckValidationFlags, 0, sizeof(bool) * CACHE_MAX_HITBOXES); - memset(m_CacheValidationFlags, 0, sizeof(bool) * CACHE_MAX_HITBOXES); - m_CacheInternal.clear(); - m_CacheInternal.shrink_to_fit(); - bones.clear(); - bones.shrink_to_fit(); - m_nNumHitboxes = 0; - m_bInit = false; - m_bModelSet = false; - m_bSuccess = false; - m_pLastModel = nullptr; - bones_setup = false; -} - CachedHitbox *EntityHitboxCache::GetHitbox(int id) { if (m_CacheValidationFlags[id]) @@ -238,11 +200,4 @@ CachedHitbox *EntityHitboxCache::GetHitbox(int id) return &m_CacheInternal[id]; } -void Update() -{ -} - -void Invalidate() -{ -} } // namespace hitbox_cache diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 3a35e5e8..563726ff 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -94,6 +94,121 @@ int slow_aim; float fov; bool enable; bool projectile_self_damage = false; +#if ENABLE_VISUALS +static settings::Boolean fov_draw{ "aimbot.fov-circle.enable", "0" }; +static settings::Float fovcircle_opacity{ "aimbot.fov-circle.opacity", "0.7" }; +#endif + +int PreviousX, PreviousY; +int CurrentX, CurrentY; + +float last_mouse_check = 0; +float stop_moving_time = 0; + +// Used to make rapidfire not knock your enemies out of range +unsigned last_target_ignore_timer = 0; +settings::Boolean ignore_cloak{ "aimbot.target.ignore-cloaked-spies", "1" }; +// Projectile info +bool projectile_mode{ false }; +float cur_proj_speed{ 0.0f }; +float cur_proj_grav{ 0.0f }; +float cur_proj_start_vel{ 0.0f }; + +bool shouldbacktrack_cache = false; +inline bool isHitboxMedium(int hitbox) +{ + switch (hitbox) + { + case 1: + case 2: + case 3: + case 4: + case 5: + return true; + + default: + return false; + } + + return false; +} +inline bool playerTeamCheck(CachedEntity *entity) + +{ + return (int) teammates == 2 || (entity->m_bEnemy() && !teammates) || (!entity->m_bEnemy() && teammates) || (CE_GOOD(LOCAL_W) && LOCAL_W->m_iClassID() == CL_CLASS(CTFCrossbow) && entity->m_iHealth() < entity->m_iMaxHealth()); +} +// Am I holding Hitman's Heatmaker ? +inline bool CarryingHeatmaker() +{ + return CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 752; +} +// A function to find the best hitbox for a target +inline int BestHitbox(CachedEntity *target) +{ + // Switch based apon the hitbox mode set by the user + switch (*hitbox_mode) + { + case 0: + // AUTO priority + return autoHitbox(target); + break; + case 1: + { // AUTO priority, return closest hitbox to crosshair + return ClosestHitbox(target); + } + break; + case 2: + { // STATIC priority, return a user chosen hitbox + return *hitbox; + } + break; + default: + break; + } + // Hitbox machine :b:roke + return -1; +} +inline float projectileHitboxSize(int projectile_size) +{ + switch (projectile_size) + { + case CL_CLASS(CTFRocketLauncher): + case CL_CLASS(CTFRocketLauncher_Mortar): + case CL_CLASS(CTFRocketLauncher_AirStrike): + case CL_CLASS(CTFRocketLauncher_DirectHit): + case CL_CLASS(CTFPipebombLauncher): + case CL_CLASS(CTFGrenadeLauncher): + case CL_CLASS(CTFCannon): + return 6.5f; + case CL_CLASS(CTFFlareGun): + case CL_CLASS(CTFFlareGun_Revenge): + case CL_CLASS(CTFDRGPomson): + return 3.0f; + case CL_CLASS(CTFSyringeGun): + case CL_CLASS(CTFCompoundBow): + return 2.0f; + default: + return 3.0f; + } +} +inline void updateShouldBacktrack() +{ + if (hacks::tf2::backtrack::hasData() || projectile_mode || !(*backtrackAimbot || force_backtrack_aimbot)) + shouldbacktrack_cache = false; + else + shouldbacktrack_cache = true; +} + +inline bool shouldBacktrack(CachedEntity *ent) +{ + if (!shouldbacktrack_cache) + return false; + else if (ent && ent->m_Type() != ENTITY_PLAYER) + return false; + else if (!tf2::backtrack::getGoodTicks(ent)) + return false; + return true; +} void spectatorUpdate() { switch (*specmode) @@ -126,11 +241,6 @@ void spectatorUpdate() } } -bool playerTeamCheck(CachedEntity *entity) - -{ - return (int) teammates == 2 || (entity->m_bEnemy() && !teammates) || (!entity->m_bEnemy() && teammates) || (CE_GOOD(LOCAL_W) && LOCAL_W->m_iClassID() == CL_CLASS(CTFCrossbow) && entity->m_iHealth() < entity->m_iMaxHealth()); -} #define GET_MIDDLE(c1, c2) (corners[c1] + corners[c2]) / 2.0f @@ -273,23 +383,6 @@ std::vector getHitpointsVischeck(CachedEntity *ent, int hitbox) return hitpoints; } -bool isHitboxMedium(int hitbox) -{ - switch (hitbox) - { - case 1: - case 2: - case 3: - case 4: - case 5: - return true; - - default: - return false; - } - - return false; -} // Get the best point to aim at for a given hitbox std::optional getBestHitpoint(CachedEntity *ent, int hitbox) { @@ -310,46 +403,9 @@ std::optional getBestHitpoint(CachedEntity *ent, int hitbox) return best_pos; } -#if ENABLE_VISUALS -static settings::Boolean fov_draw{ "aimbot.fov-circle.enable", "0" }; -static settings::Float fovcircle_opacity{ "aimbot.fov-circle.opacity", "0.7" }; -#endif -int PreviousX, PreviousY; -int CurrentX, CurrentY; -float last_mouse_check = 0; -float stop_moving_time = 0; -// Used to make rapidfire not knock your enemies out of range -unsigned last_target_ignore_timer = 0; -settings::Boolean ignore_cloak{ "aimbot.target.ignore-cloaked-spies", "1" }; -// Projectile info -bool projectile_mode{ false }; -float cur_proj_speed{ 0.0f }; -float cur_proj_grav{ 0.0f }; -float cur_proj_start_vel{ 0.0f }; - -bool shouldbacktrack_cache = false; - -void updateShouldBacktrack() -{ - if (hacks::tf2::backtrack::hasData() || projectile_mode || !(*backtrackAimbot || force_backtrack_aimbot)) - shouldbacktrack_cache = false; - else - shouldbacktrack_cache = true; -} - -bool shouldBacktrack(CachedEntity *ent) -{ - if (!shouldbacktrack_cache) - return false; - else if (ent && ent->m_Type() != ENTITY_PLAYER) - return false; - else if (!tf2::backtrack::getGoodTicks(ent)) - return false; - return true; -} // Reduce Backtrack lag by checking if the ticks hitboxes are within a reasonable FOV range bool validateTickFOV(tf2::backtrack::BacktrackData &tick) @@ -372,11 +428,6 @@ bool validateTickFOV(tf2::backtrack::BacktrackData &tick) return true; } -// Am I holding Hitman's Heatmaker ? -bool CarryingHeatmaker() -{ - return CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 752; -} void doAutoZoom(bool target_found) { @@ -1101,34 +1152,7 @@ bool IsTargetStateGood(CachedEntity *entity) return false; } -float projectileHitboxSize(int projectile_size) -{ - float projectile_hitbox_size = 6.3f; - switch (projectile_size) - { - case CL_CLASS(CTFRocketLauncher): - case CL_CLASS(CTFRocketLauncher_Mortar): - case CL_CLASS(CTFRocketLauncher_AirStrike): - case CL_CLASS(CTFRocketLauncher_DirectHit): - case CL_CLASS(CTFPipebombLauncher): - case CL_CLASS(CTFGrenadeLauncher): - case CL_CLASS(CTFCannon): - break; - case CL_CLASS(CTFFlareGun): - case CL_CLASS(CTFFlareGun_Revenge): - case CL_CLASS(CTFDRGPomson): - projectile_hitbox_size = 3; - break; - case CL_CLASS(CTFSyringeGun): - case CL_CLASS(CTFCompoundBow): - projectile_hitbox_size = 1; - break; - default: - break; - } - return projectile_hitbox_size; -} // A function to aim at a specific entitiy bool Aim(CachedEntity *entity) { @@ -1446,32 +1470,7 @@ int autoHitbox(CachedEntity *target) } return preferred; } -// A function to find the best hitbox for a target -int BestHitbox(CachedEntity *target) -{ - // Switch based apon the hitbox mode set by the user - switch (*hitbox_mode) - { - case 0: - // AUTO priority - return autoHitbox(target); - break; - case 1: - { // AUTO priority, return closest hitbox to crosshair - return ClosestHitbox(target); - } - break; - case 2: - { // STATIC priority, return a user chosen hitbox - return *hitbox; - } - break; - default: - break; - } - // Hitbox machine :b:roke - return -1; -} + // Function to find the closesnt hitbox to the crosshair for a given ent int ClosestHitbox(CachedEntity *target) diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp index f2e15b26..31a290a3 100644 --- a/src/hacks/AutoBackstab.cpp +++ b/src/hacks/AutoBackstab.cpp @@ -42,7 +42,7 @@ void ApplySwingHook() melee_range_hook.RestorePatch(); } -void RemoveSwingHook() +inline void RemoveSwingHook() { melee_range_hook.Shutdown(); } diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 43040d42..78da4beb 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -79,7 +79,7 @@ static settings::Boolean entity_id{ "esp.debug.id", "true" }; // Forward declarations void ResetEntityStrings(bool full_clear); -void AddEntityString(CachedEntity *entity, const std::string &string, const rgba_t &color = colors::empty); + // Entity Processing void __attribute__((fastcall)) ProcessEntity(CachedEntity *ent); void __attribute__((fastcall)) ProcessEntityPT(CachedEntity *ent); @@ -90,7 +90,6 @@ void __attribute__((fastcall)) DrawBox(CachedEntity *ent, const rgba_t &clr); void BoxCorners(int minx, int miny, int maxx, int maxy, const rgba_t &color, bool transparent); bool GetCollide(CachedEntity *ent); - // Storage vars for entities that need to be re-drawn std::vector> entities_need_repaint{}; @@ -123,12 +122,24 @@ public: Vector collide_min{ 0, 0, 0 }; bool transparent{ false }; }; -std::unordered_map data; +boost::unordered_flat_map data; // Dont fully understand struct but a guess is a group of something. // I will return once I have enough knowlage to reverse this. // NOTE: No idea on why we cant just use gethitbox and use the displacement on // that insted of having all this extra code. Shouldnt gethitbox use cached // hitboxes, if so it should be nicer on performance +// Use to add a esp string to an entity +inline void AddEntityString(CachedEntity *entity, const std::string &string, const rgba_t &color = colors::empty) +{ + ESPData &entity_data = data[entity]; + if (entity_data.string_count >= 15) + return; + entity_data.strings[entity_data.string_count].data = string; + entity_data.strings[entity_data.string_count].color = color; + entity_data.string_count++; + entity_data.needs_paint = true; +} + class bonelist_s { private: @@ -335,8 +346,9 @@ static void cm() // Get an entity from the loop tick and process it ProcessEntity(ent); hitboxUpdate(ent); + if (!data.contains(ent)) + data.emplace(ent, ESPData{}); - data.emplace(std::make_pair(ent, ESPData{})); if (data[ent].needs_paint) { // Checking this every tick is a waste of nanoseconds @@ -370,7 +382,9 @@ static void cm() ProcessEntity(ent_index); hitboxUpdate(ent_index); } - data.emplace(std::make_pair(ent_index, ESPData{})); + if (!data.contains(ent_index)) + data.emplace(ent_index, ESPData{}); + if (data[ent_index].needs_paint) { // Checking this every tick is a waste of nanoseconds @@ -1696,19 +1710,6 @@ bool GetCollide(CachedEntity *ent) // Impossible error, return false return false; } - -// Use to add a esp string to an entity -void AddEntityString(CachedEntity *entity, const std::string &string, const rgba_t &color) -{ - ESPData &entity_data = data[entity]; - if (entity_data.string_count >= 15) - return; - entity_data.strings[entity_data.string_count].data = string; - entity_data.strings[entity_data.string_count].color = color; - entity_data.string_count++; - entity_data.needs_paint = true; -} - // Function to reset entitys strings void ResetEntityStrings(bool full_clear) { @@ -1730,7 +1731,7 @@ void ResetEntityStrings(bool full_clear) } // Sets an entitys esp color -void SetEntityColor(CachedEntity *entity, const rgba_t &color) +inline void SetEntityColor(CachedEntity *entity, const rgba_t &color) { if (entity->m_IDX > 2047 || entity->m_IDX < 0) return; diff --git a/src/hacks/Trigger.cpp b/src/hacks/Trigger.cpp index 823d55e3..150e03b8 100644 --- a/src/hacks/Trigger.cpp +++ b/src/hacks/Trigger.cpp @@ -30,7 +30,7 @@ static settings::Boolean buildings_sentry{ "trigger.target.buildings-sentry", "t static settings::Boolean buildings_other{ "trigger.target.buildings-other", "true" }; static settings::Boolean stickybot{ "trigger.target.stickybombs", "false" }; static settings::Boolean teammates{ "trigger.target.teammates", "false" }; -static settings::Int max_range{ "trigger.target.max-range", "4096" }; +static settings::Float max_range{ "trigger.target.max-range", "4096" }; // Vars for usersettings @@ -38,7 +38,17 @@ float target_time = 0.0f; int last_hb_traced = 0; Vector forward; - +inline float EffectiveTargetingRange() +{ + if (GetWeaponMode() == weapon_melee) + return re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); + // Pyros only have so much untill their flames hit + else if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) + return 300.0f; + // If user has set a max range, then use their setting, + if (max_range) + return *max_range; +} // The main function of the triggerbot void CreateMove() { @@ -527,20 +537,7 @@ bool UpdateAimkey() } // Func to find value of how far to target ents -float EffectiveTargetingRange() -{ - if (GetWeaponMode() == weapon_melee) - return re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); - // Pyros only have so much untill their flames hit - else if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) - return 300.0f; - // If user has set a max range, then use their setting, - if (max_range) - return *max_range; - // else use a pre-set range - else - return 8012.0f; -} + // Helper functions to trace for hitboxes diff --git a/src/helpers.cpp b/src/helpers.cpp index 8b5619c8..cbb23b8c 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -1704,15 +1704,7 @@ float ATTRIB_HOOK_FLOAT(float base_value, const char *search_string, IClientEnti return AttribHookFloat_fn(base_value, search_string, ent, buffer, is_global_const_string); } -QAngle VectorToQAngle(Vector in) -{ - return *(QAngle *) ∈ -} -Vector QAngleToVector(QAngle in) -{ - return *(Vector *) ∈ -} void AimAt(Vector origin, Vector target, CUserCmd *cmd, bool compensate_punch) { @@ -1996,26 +1988,6 @@ int SharedRandomInt(unsigned iseed, const char *sharedname, int iMinVal, int iMa return g_pUniformStream->RandomInt(iMinVal, iMaxVal); } -bool GetPlayerInfo(int idx, player_info_s *info) -{ - bool res = g_IEngine->GetPlayerInfo(idx, info); - if (!res) - return res; - - // First try parsing GUID, should always work unless a server is being malicious - try - { - std::string guid = info->guid; - guid = guid.substr(5, guid.length() - 6); - info->friendsID = std::stoul(guid.c_str()); - } - catch (...) - { - // Fix friends ID with player resource - info->friendsID = g_pPlayerResource->GetAccountID(idx); - } - return res; -} int GetPlayerForUserID(int userID) { diff --git a/src/hooks/LevelInit.cpp b/src/hooks/LevelInit.cpp index 9c0fc8ed..e24c8534 100644 --- a/src/hooks/LevelInit.cpp +++ b/src/hooks/LevelInit.cpp @@ -51,6 +51,7 @@ DEFINE_HOOKED_METHOD(LevelInit, void, void *this_, const char *name) #endif hacks::shared::anti_anti_aim::resolver_map.clear(); g_IEngine->ClientCmd_Unrestricted("exec cat_matchexec"); + entity_cache::array.reserve(500); chat_stack::Reset(); original::LevelInit(this_, name); EC::run(EC::LevelInit); diff --git a/src/soundcache.cpp b/src/soundcache.cpp index 65dec491..f023a117 100644 --- a/src/soundcache.cpp +++ b/src/soundcache.cpp @@ -1,39 +1,21 @@ #include "common.hpp" #include "soundcache.hpp" -struct CSndInfo_t -{ - Vector m_pOrigin; -}; -struct SoundStruct -{ - CSndInfo_t sound; - Timer last_update; -}; - -static std::map sound_cache; namespace soundcache { constexpr unsigned int EXPIRETIME = 10000; -void cache_sound(const Vector *Origin, int source) -{ - // Just in case - if (!Origin) - return; - sound_cache[source].sound.m_pOrigin = *Origin; - sound_cache[source].last_update.update(); -} +std::map sound_cache; static void CreateMove() { if (CE_BAD(LOCAL_E)) return; CUtlVector sound_list; g_ISoundEngine->GetActiveSounds(sound_list); - for (auto i : sound_list) + for (const auto &i : sound_list) cache_sound(i.m_pOrigin, i.m_nSoundSource); for (auto it = sound_cache.cbegin(); it != sound_cache.cend();) @@ -45,14 +27,6 @@ static void CreateMove() } } -std::optional GetSoundLocation(int entid) -{ - auto it = sound_cache.find(entid); - if (it == sound_cache.end()) - return std::nullopt; - return it->second.sound.m_pOrigin; -} - static InitRoutine init([]() { EC::Register(EC::CreateMove, CreateMove, "CM_SoundCache"); EC::Register(