diff --git a/.gitmodules b/.gitmodules index 9ec01a35..84ae995f 100755 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "ucccccp"] path = external/ucccccp url = https://github.com/nullworks/ucccccp.git +[submodule "external/co-library"] + path = external/co-library + url = https://github.com/nullworks/co-library.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5468a864..ce8916c5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_BUILD_TYPE_VALUES}) cmake_minimum_required(VERSION 3.0) project(cathook VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 17) add_library(cathook SHARED "") set(GameSpecific 1 CACHE BOOL "Build for specific target game (As opposed to universal, but slower, lib)") @@ -31,6 +33,7 @@ set(Textmode 0 CACHE BOOL "Various textmode-only features for bots") set(EnableTextmodeStdin 0 CACHE BOOL "Textmode Stdin -> Console bridge (EXPERIMENTAL)") set(EnableWarnings 1 CACHE BOOL "Enable compile warnings") set(EnableNullGraphics 0 CACHE BOOL "Enable experimental textmode hooks (CRASHES)") +set(EnableOnlineFeatures 1 CACHE BOOL "Enable online features (WIP)") if(NOT EnableVisuals) set(EnableGUI 0) @@ -62,6 +65,11 @@ if(EnableIPC) target_link_libraries(cathook SimpleIPC) endif() +if(EnableOnlineFeatures) + add_subdirectory(external/co-library) + target_link_libraries(cathook co-library) +endif() + if(EnableVisuals) add_subdirectory(external/libglez) target_include_directories(cathook PRIVATE include/visual) diff --git a/TODO b/TODO index ea8386eb..56928a71 100755 --- a/TODO +++ b/TODO @@ -1,8 +1,3 @@ -// TODO - MUST do before merging into master (unless removed). - -1. Re-add radar and emoji esp -2. Locate most of the crashes - //==================================================================================================// //Big TODO list for cathook // //Organized by Julianacat // diff --git a/external/co-library b/external/co-library new file mode 160000 index 00000000..393948a6 --- /dev/null +++ b/external/co-library @@ -0,0 +1 @@ +Subproject commit 393948a6bf7ee4a62f5a3bd82d94c05d4bc405aa diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 744abdef..588f81d7 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -39,7 +39,8 @@ target_sources(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}/velocity.hpp" "${CMAKE_CURRENT_LIST_DIR}/votelogger.hpp" "${CMAKE_CURRENT_LIST_DIR}/MiscTemporary.hpp" - "${CMAKE_CURRENT_LIST_DIR}/Options.hpp") + "${CMAKE_CURRENT_LIST_DIR}/Options.hpp" + "${CMAKE_CURRENT_LIST_DIR}/PlayerTools.hpp") target_include_directories(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}") @@ -50,6 +51,7 @@ add_subdirectory(hacks) add_subdirectory(hooks) add_subdirectory(reclasses) add_subdirectory(sdk) +add_subdirectory(online) if(EnableVisuals) add_subdirectory(visual) diff --git a/include/PlayerTools.hpp b/include/PlayerTools.hpp new file mode 100644 index 00000000..c26a2f38 --- /dev/null +++ b/include/PlayerTools.hpp @@ -0,0 +1,43 @@ +/* + Created on 23.06.18. +*/ + +#pragma once + +#include "config.h" +#include + +#if ENABLE_VISUALS +#include +#endif + +class CachedEntity; + +namespace player_tools +{ + +enum class IgnoreReason +{ + DO_NOT_IGNORE, + IS_HOOVY, + IS_TAUNTING, + LOCAL_PLAYER_LIST, + ONLINE_NO_TARGET, + ONLINE_FRIENDLY_SOFTWARE, + DEVELOPER, + OTHER +}; + +IgnoreReason shouldTargetSteamId(unsigned id); +IgnoreReason shouldTarget(CachedEntity *player); + +bool shouldAlwaysRenderEspSteamId(unsigned id); +bool shouldAlwaysRenderEsp(CachedEntity *entity); + +#if ENABLE_VISUALS +std::optional forceEspColorSteamId(unsigned id); +std::optional forceEspColor(CachedEntity *entity); +#endif + +void onKilledBy(CachedEntity *entity); +} \ No newline at end of file diff --git a/include/globals.h b/include/globals.h index b626eeaf..801e09cf 100755 --- a/include/globals.h +++ b/include/globals.h @@ -23,7 +23,6 @@ extern ConVar *cl_interpolate; extern CatVar event_log; extern CatVar cathook; // Master switch -extern CatVar ignore_taunting; extern bool *bSendPackets; extern CatVar show_antiaim; extern CatVar force_thirdperson; diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp index 0534c7f0..6ae0667d 100644 --- a/include/hacks/Backtrack.hpp +++ b/include/hacks/Backtrack.hpp @@ -13,17 +13,19 @@ namespace hacks::shared::backtrack { struct BacktrackData { - int tickcount; - Vector hitboxpos; - Vector min; - Vector max; - Vector origin; - float viewangles; + int tickcount{ 0 }; + Vector hitboxpos{ 0.0f, 0.0f, 0.0f }; + Vector min{ 0.0f, 0.0f, 0.0f }; + Vector max{ 0.0f, 0.0f, 0.0f }; + Vector origin{ 0.0f, 0.0f, 0.0f }; + float viewangles{ 0.0f }; + float simtime{ 0.0f }; + Vector entorigin{ 0.0f, 0.0f, 0.0f }; }; struct BestTickData { - int tickcount; - int tick; + int tickcount{ 0 }; + int tick{ 0 }; bool operator<(const BestTickData &rhs) const { return tickcount < rhs.tickcount; @@ -54,6 +56,7 @@ typedef boost::circular_buffer_space_optimized circular_buf; extern circular_buf sequences; extern CatVar latency; extern CatVar enable; +extern int ticks; extern BacktrackData headPositions[32][66]; extern BestTickData sorted_ticks[66]; } diff --git a/include/hacks/Trigger.hpp b/include/hacks/Trigger.hpp index 5aa54f96..1f5a74aa 100755 --- a/include/hacks/Trigger.hpp +++ b/include/hacks/Trigger.hpp @@ -15,6 +15,7 @@ namespace hacks::shared::triggerbot { void CreateMove(); +CachedEntity *FindEntInSight(float range); bool ShouldShoot(); bool IsTargetStateGood(CachedEntity *entity); CachedEntity *FindEntInSight(float range); diff --git a/include/hoovy.hpp b/include/hoovy.hpp index f0d7eb34..b9b52259 100755 --- a/include/hoovy.hpp +++ b/include/hoovy.hpp @@ -7,5 +7,7 @@ #pragma once +class CachedEntity; + void UpdateHoovyList(); bool IsHoovy(CachedEntity *entity); diff --git a/include/online/CMakeLists.txt b/include/online/CMakeLists.txt new file mode 100644 index 00000000..a08e5342 --- /dev/null +++ b/include/online/CMakeLists.txt @@ -0,0 +1,2 @@ +target_sources(cathook PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/Online.hpp") \ No newline at end of file diff --git a/include/online/Online.hpp b/include/online/Online.hpp new file mode 100644 index 00000000..3876af8d --- /dev/null +++ b/include/online/Online.hpp @@ -0,0 +1,39 @@ +/* + Created on 23.06.18. +*/ + +#pragma once + +#include +#include +#include +#include + +namespace online +{ + +struct user_data +{ + bool is_anonymous{ false }; + bool is_using_friendly_software{ false }; + bool is_steamid_verified{ false }; + std::string username{}; + std::vector shown_groups{}; + std::string software_name{}; + bool has_software{ false }; + bool no_target{ false }; + bool is_developer{}; +#if ENABLE_VISUALS + bool has_color{ false }; + colors::rgba_t color{}; + bool rainbow{ false }; +#endif +}; + +/* + * Identify unidentified users, send online status, etc + */ +void update(); + +user_data *getUserData(unsigned steamId); +} \ No newline at end of file diff --git a/include/reclasses/C_BaseEntity.hpp b/include/reclasses/C_BaseEntity.hpp old mode 100755 new mode 100644 index 941d53e3..a121bfed --- a/include/reclasses/C_BaseEntity.hpp +++ b/include/reclasses/C_BaseEntity.hpp @@ -8,6 +8,7 @@ #pragma once #include "reclasses.hpp" +#include "copypasted/CSignature.h" namespace re { @@ -27,5 +28,15 @@ public: static int placeholder = 0; return placeholder; } + inline static int SetAbsOrigin(IClientEntity *self, Vector const &origin) + { + typedef int (*SetAbsOrigin_t)(IClientEntity *, Vector const &); + uintptr_t addr = gSignatures.GetClientSignature( + "55 89 E5 57 56 53 83 EC ? 8B 5D ? 8B 75 ? 89 1C 24 E8 ? ? ? ? F3 " + "0F 10 06"); + SetAbsOrigin_t SetAbsOrigin_fn = SetAbsOrigin_t(addr); + + return SetAbsOrigin_fn(self, origin); + } }; } diff --git a/include/visual/colors.hpp b/include/visual/colors.hpp old mode 100755 new mode 100644 index 416e2575..ea947dd3 --- a/include/visual/colors.hpp +++ b/include/visual/colors.hpp @@ -48,6 +48,8 @@ struct rgba_t constexpr rgba_t(float _r, float _g, float _b, float _a = 1.0f) : r(_r), g(_g), b(_b), a(_a){}; + explicit rgba_t(const char hex[6]); + constexpr operator glez::rgba() const { return *reinterpret_cast(this); @@ -76,6 +78,16 @@ struct rgba_t } }; +constexpr bool operator==(const rgba_t &lhs, const rgba_t &rhs) +{ + return rhs.r == lhs.r && rhs.g == lhs.g && rhs.b == lhs.b && rhs.a == lhs.a; +} + +constexpr bool operator!=(const rgba_t &lhs, const rgba_t &rhs) +{ + return !(lhs == rhs); +} + constexpr rgba_t FromRGBA8(float r, float g, float b, float a) { return rgba_t{ r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 944a3379..291c9552 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,8 @@ target_sources(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}/velocity.cpp" "${CMAKE_CURRENT_LIST_DIR}/votelogger.cpp" "${CMAKE_CURRENT_LIST_DIR}/MiscTemporary.cpp" - "${CMAKE_CURRENT_LIST_DIR}/Options.cpp") + "${CMAKE_CURRENT_LIST_DIR}/Options.cpp" + "${CMAKE_CURRENT_LIST_DIR}/PlayerTools.cpp") add_subdirectory(core) add_subdirectory(classinfo) @@ -41,6 +42,7 @@ add_subdirectory(hacks) add_subdirectory(hooks) add_subdirectory(reclasses) add_subdirectory(sdk) +add_subdirectory(online) if(EnableVisuals) add_subdirectory(visual) diff --git a/src/PlayerTools.cpp b/src/PlayerTools.cpp new file mode 100644 index 00000000..395404a7 --- /dev/null +++ b/src/PlayerTools.cpp @@ -0,0 +1,171 @@ +/* + Created on 23.06.18. +*/ + +#include +#include +#include +#include +#include +#include "PlayerTools.hpp" +#include "entitycache.hpp" + +static std::unordered_map betrayal_list{}; + +static CatCommand forgive_all("pt_forgive_all", "Clear betrayal list", + []() { betrayal_list.clear(); }); + +namespace settings +{ + +static CatVar online_notarget(CV_SWITCH, "pt_ignore_notarget", "1", + "Ignore notarget", + "Ignore online players with notarget role"); +static CatVar hoovy(CV_SWITCH, "pt_ignore_hoovy", "1", "Ignore hoovy"); +static CatVar online_friendly_software(CV_SWITCH, "pt_ignore_friendly_software", + "1", "Ignore friendly software", + "Ignore CO-compatible software"); +static CatVar online_only_verified(CV_SWITCH, "pt_ignore_only_verified", "0", + "Only ignore verified", + "If online checks are enabled, only apply " + "ignore if SteamID is verified (not " + "recommended right now)"); +static CatVar online_anonymous(CV_SWITCH, "pt_ignore_anonymous", "1", + "Ignore anonymous", + "Apply ignore checks to anonymous accounts too"); +static CatVar betrayal_limit( + CV_INT, "pt_betrayal_limit", "3", "Betrayal limit", + "Stop ignoring a player after N kills while you ignored them"); +static CatVar taunting(CV_SWITCH, "pt_ignore_taunting", "1", "Ignore taunting", + "Don't shoot taunting players"); +} + +namespace player_tools +{ + +IgnoreReason shouldTargetSteamId(unsigned id) +{ + if (id == 0) + return IgnoreReason::DO_NOT_IGNORE; + + if (settings::betrayal_limit) + { + if (betrayal_list[id] > int(settings::betrayal_limit)) + return IgnoreReason::DO_NOT_IGNORE; + } + + auto &pl = playerlist::AccessData(id); + if (playerlist::IsFriendly(pl.state)) + return IgnoreReason::LOCAL_PLAYER_LIST; + + auto *co = online::getUserData(id); + if (co) + { + bool check_verified = + !settings::online_only_verified || co->is_steamid_verified; + bool check_anonymous = settings::online_anonymous || !co->is_anonymous; + + if (check_verified && check_anonymous) + { + if (settings::online_notarget && co->no_target) + return IgnoreReason::ONLINE_NO_TARGET; + if (settings::online_friendly_software && + co->is_using_friendly_software) + return IgnoreReason::ONLINE_FRIENDLY_SOFTWARE; + } + // Always check developer status, no exceptions + if (co->is_developer) + return IgnoreReason::DEVELOPER; + } + + return IgnoreReason::DO_NOT_IGNORE; +} +IgnoreReason shouldTarget(CachedEntity *entity) +{ + if (entity->m_Type() == ENTITY_PLAYER) + { + if (settings::hoovy && IsHoovy(entity)) + return IgnoreReason::IS_HOOVY; + if (settings::taunting && HasCondition(entity)) + return IgnoreReason::IS_TAUNTING; + + return shouldTargetSteamId(entity->player_info.friendsID); + } + + return IgnoreReason::DO_NOT_IGNORE; +} + +bool shouldAlwaysRenderEspSteamId(unsigned id) +{ + if (id == 0) + return false; + + auto &pl = playerlist::AccessData(id); + if (pl.state != playerlist::k_EState::DEFAULT) + return true; + + auto *co = online::getUserData(id); + if (co) + return true; + + return false; +} +bool shouldAlwaysRenderEsp(CachedEntity *entity) +{ + if (entity->m_Type() == ENTITY_PLAYER) + { + return shouldAlwaysRenderEspSteamId(entity->player_info.friendsID); + } + + return false; +} + +#if ENABLE_VISUALS +std::optional forceEspColorSteamId(unsigned id) +{ + if (id == 0) + return std::nullopt; + + auto pl = playerlist::Color(id); + if (pl != colors::empty) + return std::optional{ pl }; + + auto *co = online::getUserData(id); + if (co) + { + if (co->has_color) + return std::optional{ co->color }; + if (co->rainbow) + return std::optional{ colors::RainbowCurrent() }; + } + + return std::nullopt; +} +std::optional forceEspColor(CachedEntity *entity) +{ + if (entity->m_Type() == ENTITY_PLAYER) + { + return forceEspColorSteamId(entity->player_info.friendsID); + } + + return std::nullopt; +} +#endif + +void onKilledBy(unsigned id) +{ + auto reason = shouldTargetSteamId(id); + if (reason != IgnoreReason::DO_NOT_IGNORE) + { + // We ignored the gamer, but they still shot us + if (betrayal_list.find(id) == betrayal_list.end()) + betrayal_list[id] = 0; + betrayal_list[id]++; + } +} + +void onKilledBy(CachedEntity *entity) +{ + onKilledBy(entity->player_info.friendsID); +} +} \ No newline at end of file diff --git a/src/entityhitboxcache.cpp b/src/entityhitboxcache.cpp index f9e09cc6..c0324ad4 100644 --- a/src/entityhitboxcache.cpp +++ b/src/entityhitboxcache.cpp @@ -47,8 +47,8 @@ void EntityHitboxCache::Update() { InvalidateCache(); if (CE_BAD(parent_ref)) - if (GetHitbox(0)) - return; + if (GetHitbox(0)) + return; } void EntityHitboxCache::Init() diff --git a/src/globals.cpp b/src/globals.cpp index a0999d5a..d9f80a15 100755 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -33,8 +33,6 @@ CatVar force_name(CV_STRING, "name", "", "Force name"); CatVar cathook(CV_SWITCH, "enabled", "1", "CatHook enabled", "Disabling this completely disables cathook (can be re-enabled)"); -CatVar ignore_taunting(CV_SWITCH, "ignore_taunting", "1", "Ignore taunting", - "Aimbot/Triggerbot won't attack taunting enemies"); // CatVar send_packets(CV_SWITCH, "sendpackets", "1", "Send packets", "Internal // use"); CatVar show_antiaim(CV_SWITCH, "thirdperson_angles", "1", "Real TP angles", diff --git a/src/hack.cpp b/src/hack.cpp index 2416049c..1d203214 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -532,6 +532,13 @@ free(logname);*/ #if ENABLE_VISUALS hacks::shared::esp::Init(); #endif +#if not ENABLE_VISUALS + hack::command_stack().push("exec cat_autoexec_textmode"); +#endif + hack::command_stack().push("exec cat_autoexec"); + hack::command_stack().push("cat_killsay_reload"); + hack::command_stack().push("cat_spam_reload"); + logging::Info("Clearing initializer stack"); while (!init_stack().empty()) { @@ -540,12 +547,6 @@ free(logname);*/ } logging::Info("Initializer stack done"); -#if not ENABLE_VISUALS - hack::command_stack().push("exec cat_autoexec_textmode"); -#endif - hack::command_stack().push("exec cat_autoexec"); - hack::command_stack().push("cat_killsay_reload"); - hack::command_stack().push("cat_spam_reload"); hack::initialized = true; } diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 80d8d60d..3ab44c20 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include "common.hpp" namespace hacks::shared::aimbot @@ -60,8 +62,6 @@ static CatVar static CatVar ignore_vaccinator( CV_SWITCH, "aimbot_ignore_vaccinator", "1", "Ignore Vaccinator", "Hitscan weapons won't fire if enemy is vaccinated against bullets"); -static CatVar ignore_hoovy(CV_SWITCH, "aimbot_ignore_hoovy", "0", - "Ignore Hoovies", "Aimbot won't attack hoovies"); static CatVar ignore_cloak(CV_SWITCH, "aimbot_ignore_cloak", "1", "Ignore cloaked", "Don't aim at invisible enemies"); static CatVar ignore_deadringer(CV_SWITCH, "aimbot_ignore_deadringer", "1", @@ -175,7 +175,101 @@ bool projectileAimbotRequired; // This array will store calculated projectile/hitscan predictions // for current frame, to avoid performing them again AimbotCalculatedData_s calculated_data_array[2048]{}; +bool BacktrackAimbot() +{ + if (!hacks::shared::backtrack::enable) + return false; + + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !CanShoot()) + return false; + + if (zoomed_only && !g_pLocalPlayer->bZoomed && + !(g_pUserCmd->buttons & IN_ATTACK)) + return false; + + int iBestTarget = hacks::shared::backtrack::iBestTarget; + if (iBestTarget == -1) + { + + float bestscr = 999.0f; + for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + { + if (i == g_pLocalPlayer->entity_idx) + continue; + CachedEntity *it = ENTITY(i); + if (CE_BAD(it) || !it->m_bAlivePlayer() || + it->m_Type() != ENTITY_PLAYER) + continue; + if (it->m_iTeam() == LOCAL_E->m_iTeam()) + continue; + if (!hacks::shared::backtrack::headPositions[iBestTarget][0].hitboxpos.z) + continue; + if (!it->hitboxes.GetHitbox(0)) + continue; + if (IsPlayerInvisible(it) && ignore_cloak) + continue; + float scr = + GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, + it->hitboxes.GetHitbox(0)->center); + if (scr < bestscr) + { + iBestTarget = it->m_IDX; + bestscr = scr; + } + } + if (iBestTarget == -1) + return true; + + }; + + for (int t = 0; t < hacks::shared::backtrack::ticks; ++t) + hacks::shared::backtrack::sorted_ticks[t] = + hacks::shared::backtrack::BestTickData{ hacks::shared::backtrack::headPositions[iBestTarget][t].tickcount, t }; + std::sort(hacks::shared::backtrack::sorted_ticks, hacks::shared::backtrack::sorted_ticks + hacks::shared::backtrack::ticks); + int tickcnt = 0; + + for (auto i : hacks::shared::backtrack::headPositions[iBestTarget]) + { + bool good_tick = false; + for (int j = 0; j < 12; ++j) + if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick) + good_tick = true; + tickcnt++; + if (!i.hitboxpos.z) + continue; + if (!good_tick) + continue; + if (!IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxpos)) + continue; + float scr = abs(g_pLocalPlayer->v_OrigViewangles.y - i.viewangles); + + CachedEntity *tar = ENTITY(iBestTarget); + // ok just in case + if (CE_BAD(tar)) + continue; + Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles); + float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime); + angles.y = i.viewangles; + simtime = i.simtime; + g_pUserCmd->tick_count = i.tickcount; + Vector tr = (i.hitboxpos - g_pLocalPlayer->v_Eye); + Vector angles2; + VectorAngles(tr, angles2); + // Clamping is important + fClampAngle(angles2); + // Slow aim + if (slow_aim) + DoSlowAim(angles2); + else if (silent) + g_pLocalPlayer->bUseSilentAngles = true; + // Set angles + g_pUserCmd->viewangles = angles2; + g_pUserCmd->buttons |= IN_ATTACK; + return true; + } + return true; +} // The main "loop" of the aimbot. void CreateMove() { @@ -226,6 +320,8 @@ void CreateMove() cur_proj_grav = float(proj_gravity); } + if (BacktrackAimbot()) + return; // Refresh our best target CachedEntity *target_entity = RetrieveBestTarget(aimkey_status); if (CE_BAD(target_entity) || !foundTarget) @@ -574,8 +670,11 @@ bool IsTargetStateGood(CachedEntity *entity) } } - // Taunting - if (ignore_taunting && HasCondition(entity)) + // Some global checks + if (player_tools::shouldTarget(entity) != + player_tools::IgnoreReason::DO_NOT_IGNORE) + return false; + if (hacks::shared::catbot::should_ignore_player(entity)) return false; // Invulnerable players, ex: uber, bonk if (IsPlayerInvulnerable(entity)) @@ -605,19 +704,7 @@ bool IsTargetStateGood(CachedEntity *entity) HasCondition(entity)) return false; } - // Friendly player - if (playerlist::IsFriendly(playerlist::AccessData(entity).state)) - return false; - IF_GAME(IsTF()) - { - // Hoovys - if (ignore_hoovy && IsHoovy(entity)) - { - return false; - } - } - if (hacks::shared::catbot::should_ignore_player(entity)) - return false; + // Preform hitbox prediction int hitbox = BestHitbox(entity); AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; diff --git a/src/hacks/Announcer.cpp b/src/hacks/Announcer.cpp old mode 100755 new mode 100644 index 09d9bd4a..fa08b588 --- a/src/hacks/Announcer.cpp +++ b/src/hacks/Announcer.cpp @@ -177,4 +177,3 @@ void shutdown() g_IEventManager2->RemoveListener(&listener()); } } - diff --git a/src/hacks/AntiAim.cpp b/src/hacks/AntiAim.cpp index 6f17899b..703723f9 100644 --- a/src/hacks/AntiAim.cpp +++ b/src/hacks/AntiAim.cpp @@ -15,29 +15,20 @@ CatVar communicate(CV_SWITCH, "identify", "0", "identify", "Auto identify for other cathook users"); CatVar enabled(CV_SWITCH, "aa_enabled", "0", "Anti-Aim", "Master AntiAim switch"); -static CatVar trueang(CV_SWITCH, "aa_realfakes", "0", "Real fakes", - "Do real fakeangles (Unresolveable)"); static CatVar yaw(CV_FLOAT, "aa_yaw", "0.0", "Yaw", "Static yaw (left/right)", 360.0); static CatVar pitch(CV_FLOAT, "aa_pitch", "-89.0", "Pitch", "Static pitch (up/down)", -89.0, 89.0); -static CatVar yaw_real(CV_FLOAT, "aa_yaw_real", "0.0", "Real Yaw", - "Static yaw (left/right)", 360.0); -static CatVar pitch_real(CV_FLOAT, "aa_pitch_real", "-89.0", "Real Pitch", - "Static pitch (up/down)", -89.0, 89.0); static CatEnum yaw_mode_enum({ "KEEP", "STATIC", "JITTER", "BIGRANDOM", "RANDOM", "SPIN", "OFFSETKEEP", "EDGE", "HECK", - "FAKESIDEWAYS" }); + "FAKESIDEWAYS", "FAKERIGHT", "FAKELEFT", + "FAKEFUCK" }); static CatEnum pitch_mode_enum({ "KEEP", "STATIC", "JITTER", "RANDOM", "FLIP", "FAKEFLIP", "FAKEUP", "FAKEDOWN", "FAKECENTER", "UP", "DOWN", "HECK" }); CatVar yaw_mode(yaw_mode_enum, "aa_yaw_mode", "0", "Yaw mode", "Yaw mode"); static CatVar pitch_mode(pitch_mode_enum, "aa_pitch_mode", "0", "Pitch mode", "Pitch mode"); -static CatVar true_yaw_mode(yaw_mode_enum, "aa_yaw_mode_real", "0", - "The Real Yaw", "Yaw mode"); -static CatVar true_pitch_mode(pitch_mode_enum, "aa_pitch_mode_real", "0", - "The Real Pitch", "Pitch mode"); static CatVar roll(CV_FLOAT, "aa_roll", "0", "Roll", "Roll angle (viewangles.z)", -180, 180); static CatVar @@ -72,37 +63,16 @@ bool aaaa_key_pressed = false; float GetAAAAPitch() { - if (!trueang) + switch ((int) aaaa_mode) { - switch ((int) aaaa_mode) - { - case 0: - return aaaa_stage ? -271 : -89; - case 1: - return aaaa_stage ? 271 : 89; - default: - break; - } - return 0; - } - else - { - if (*bSendPackets == true) - { - switch ((int) aaaa_mode) - { - case 0: - return aaaa_stage ? -271 : -89; - case 1: - return aaaa_stage ? 271 : 89; - default: - break; - } - } - else if (*bSendPackets == false) - return g_pUserCmd->viewangles.x; - return 0; + case 0: + return aaaa_stage ? -271 : -89; + case 1: + return aaaa_stage ? 271 : 89; + default: + break; } + return 0; } float GetAAAATimerLength() @@ -419,12 +389,13 @@ void ProcessUserCmd(CUserCmd *cmd) if (!ShouldAA(cmd)) return; static bool angstate = true; - if (trueang) + if ((int) yaw_mode >= 9) angstate = !angstate; + else + angstate = true; if (!LOCAL_E->m_bAlivePlayer()) angstate = true; - if (lagexploit::ExploitActive() || g_pUserCmd->buttons & IN_ATTACK || - g_pUserCmd->buttons & IN_ATTACK2) + if (g_pUserCmd->buttons & IN_ATTACK || g_pUserCmd->buttons & IN_ATTACK2) angstate = true; *bSendPackets = angstate; float &p = cmd->viewangles.x; @@ -438,180 +409,103 @@ void ProcessUserCmd(CUserCmd *cmd) g_pLocalPlayer->bUseSilentAngles = true; return; } - if (!*bSendPackets) - switch ((int) true_yaw_mode) - { - case 1: // FIXED - y = (float) yaw_real; - break; - case 2: // JITTER - if (flip) - y += 90; - else - y -= 90; - break; - case 3: // BIGRANDOM - y = RandFloatRange(-65536.0f, 65536.0f); - clamp = false; - break; - case 4: // RANDOM - y = RandFloatRange(-180.0f, 180.0f); - break; - case 5: // SPIN - cur_yaw += (float) spin; - if (cur_yaw > 180) - cur_yaw = -180; - if (cur_yaw < -180) - cur_yaw = 180; - y = cur_yaw; - break; - case 6: // OFFSETKEEP - y += (float) yaw_real; - break; - case 7: // Edge - // Attemt to find an edge and if found, edge - if (findEdge(y)) - y = useEdge(y); - break; - case 8: - FuckYaw(y); - clamp = false; - break; - default: - break; - } - if (*bSendPackets) - switch ((int) yaw_mode) - { - case 1: // FIXED - y = (float) yaw; - break; - case 2: // JITTER - if (flip) - y += 90; - else - y -= 90; - break; - case 3: // BIGRANDOM - y = RandFloatRange(-65536.0f, 65536.0f); - clamp = false; - break; - case 4: // RANDOM - y = RandFloatRange(-180.0f, 180.0f); - break; - case 5: // SPIN - cur_yaw += (float) spin; - if (cur_yaw > 180) - cur_yaw = -180; - if (cur_yaw < -180) - cur_yaw = 180; - y = cur_yaw; - break; - case 6: // OFFSETKEEP - y += (float) yaw; - break; - case 7: // Edge - // Attemt to find an edge and if found, edge - if (findEdge(y)) - y = useEdge(y); - break; - case 8: - FuckYaw(y); - clamp = false; - break; - default: - break; - } - if (yaw_mode == 9) + switch ((int) yaw_mode) + { + case 1: // FIXED + y = (float) yaw; + break; + case 2: // JITTER + if (flip) + y += 90; + else + y -= 90; + break; + case 3: // BIGRANDOM + y = RandFloatRange(-65536.0f, 65536.0f); + clamp = false; + break; + case 4: // RANDOM + y = RandFloatRange(-180.0f, 180.0f); + break; + case 5: // SPIN + cur_yaw += (float) spin; + if (cur_yaw > 180) + cur_yaw = -180; + if (cur_yaw < -180) + cur_yaw = 180; + y = cur_yaw; + break; + case 6: // OFFSETKEEP + y += (float) yaw; + break; + case 7: // Edge + // Attemt to find an edge and if found, edge + if (findEdge(y)) + y = useEdge(y); + break; + case 8: + FuckYaw(y); + clamp = false; + break; + case 9: y += *bSendPackets ? 90.0f : -90.0f; - if (!*bSendPackets) - switch (int(true_pitch_mode)) - { - case 1: - p = float(pitch_real); - break; - case 2: - if (flip) - p += 30.0f; - else - p -= 30.0f; - break; - case 3: - p = RandFloatRange(-89.0f, 89.0f); - break; - case 4: - p = flip ? 89.0f : -89.0f; - break; - case 5: - p = flip ? 271.0f : -271.0f; - clamp = false; - break; - case 6: - p = -271.0f; - clamp = false; - break; - case 7: - p = 271.0f; - clamp = false; - break; - case 8: - p = -3256.0f; - clamp = false; - break; - case 9: - p = -89.0f; - break; - case 10: - p = 89.0f; - break; - case 11: - FuckPitch(p); - clamp = false; - } - if (*bSendPackets) - switch (int(pitch_mode)) - { - case 1: - p = float(pitch); - break; - case 2: - if (flip) - p += 30.0f; - else - p -= 30.0f; - break; - case 3: - p = RandFloatRange(-89.0f, 89.0f); - break; - case 4: - p = flip ? 89.0f : -89.0f; - break; - case 5: - p = flip ? 271.0f : -271.0f; - clamp = false; - break; - case 6: - p = -271.0f; - clamp = false; - break; - case 7: - p = 271.0f; - clamp = false; - break; - case 8: - p = -3256.0f; - clamp = false; - break; - case 9: - p = -89.0f; - break; - case 10: - p = 89.0f; - break; - case 11: - FuckPitch(p); - clamp = false; - } + break; + case 10: + y += *bSendPackets ? 0.0f : 90.0f; + break; + case 11: + y += *bSendPackets ? 0.0f : -90.0f; + break; + case 12: + if (*bSendPackets) + FuckYaw(y); + break; + default: + break; + } + switch (int(pitch_mode)) + { + case 1: + p = float(pitch); + break; + case 2: + if (flip) + p += 30.0f; + else + p -= 30.0f; + break; + case 3: + p = RandFloatRange(-89.0f, 89.0f); + break; + case 4: + p = flip ? 89.0f : -89.0f; + break; + case 5: + p = flip ? 271.0f : -271.0f; + clamp = false; + break; + case 6: + p = -271.0f; + clamp = false; + break; + case 7: + p = 271.0f; + clamp = false; + break; + case 8: + p = -3256.0f; + clamp = false; + break; + case 9: + p = -89.0f; + break; + case 10: + p = 89.0f; + break; + case 11: + FuckPitch(p); + clamp = false; + } flip = !flip; if (clamp) fClampAngle(cmd->viewangles); diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp index 3fd55f16..1cef380d 100644 --- a/src/hacks/AutoBackstab.cpp +++ b/src/hacks/AutoBackstab.cpp @@ -37,7 +37,8 @@ void CreateMove() return; if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFKnife)) return; - if (CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_bReadyToBackstab)) + if (!hacks::shared::backtrack::enable && + CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_bReadyToBackstab)) g_pUserCmd->buttons |= IN_ATTACK; else { @@ -46,22 +47,34 @@ void CreateMove() if (hacks::shared::backtrack::iBestTarget == -1) return; int iBestTarget = hacks::shared::backtrack::iBestTarget; - int BestTick = hacks::shared::backtrack::BestTick; - - float scr = - abs(g_pLocalPlayer->v_OrigViewangles.y - - hacks::shared::backtrack::headPositions[iBestTarget][BestTick] - .viewangles); - - if (scr < 40.0f && - hacks::shared::backtrack::headPositions[iBestTarget][BestTick] - .origin.DistTo(g_pLocalPlayer->v_Eye) <= - re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W))) + int tickcnt = 0; + for (auto i : hacks::shared::backtrack::headPositions[iBestTarget]) { - g_pUserCmd->tick_count = - hacks::shared::backtrack::headPositions[iBestTarget][BestTick] - .tickcount; - g_pUserCmd->buttons |= IN_ATTACK; + bool good_tick = false; + for (int j = 0; j < 12; ++j) + if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick) + good_tick = true; + tickcnt++; + if (!good_tick) + continue; + + float scr = abs(g_pLocalPlayer->v_OrigViewangles.y - i.viewangles); + + if (scr <= 90.0f && + i.origin.DistTo(g_pLocalPlayer->v_Eye) <= + re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W))) + { + CachedEntity *tar = ENTITY(iBestTarget); + // ok just in case + if (CE_BAD(tar)) + continue; + Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles); + float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime); + angles.y = i.viewangles; + g_pUserCmd->tick_count = i.tickcount; + g_pUserCmd->buttons |= IN_ATTACK; + break; + } } } } diff --git a/src/hacks/AutoDeadringer.cpp b/src/hacks/AutoDeadringer.cpp index 22afeeb8..b5406f9e 100644 --- a/src/hacks/AutoDeadringer.cpp +++ b/src/hacks/AutoDeadringer.cpp @@ -50,10 +50,13 @@ void CreateMove() return; if (CE_BAD(LOCAL_E)) return; + if (g_pLocalPlayer->clazz != tf_spy) + return; if (CE_BYTE(LOCAL_E, netvar.m_bFeignDeathReady)) return; - if (HasCondition(LOCAL_E) || HasCondition(LOCAL_E)) - return; + if (HasCondition(LOCAL_E) || + HasCondition(LOCAL_E)) + return; if (CE_INT(LOCAL_E, netvar.iHealth) < (int) trigger_health && NearbyEntities() > 1) g_pUserCmd->buttons |= IN_ATTACK2; @@ -64,6 +67,10 @@ void CreateMove() continue; if (!IsProjectile(ent) && !ent->m_bGrenadeProjectile()) continue; + if (!ent->m_bEnemy()) + continue; + if (ent->m_Type() != ENTITY_PROJECTILE) + continue; if (ent->m_bCritProjectile() && ent->m_flDistance() <= 1000.0f) g_pUserCmd->buttons |= IN_ATTACK2; if (ent->m_flDistance() < 300.0f) diff --git a/src/hacks/AutoDetonator.cpp b/src/hacks/AutoDetonator.cpp index cedf1381..2e68c7b6 100644 --- a/src/hacks/AutoDetonator.cpp +++ b/src/hacks/AutoDetonator.cpp @@ -5,6 +5,7 @@ * Author: nullifiedcat & Lighty */ +#include #include "common.hpp" namespace hacks::tf::autodetonator @@ -53,20 +54,17 @@ bool IsTarget(CachedEntity *ent) // Dont detonate on dead players if (!ent->m_bAlivePlayer()) return false; - // Dont detonate on friendly players - if (playerlist::IsFriendly(playerlist::AccessData(ent).state)) - return false; + // Global checks + if (player_tools::shouldTarget(ent) != + player_tools::IgnoreReason::DO_NOT_IGNORE) + return false; IF_GAME(IsTF()) { // Dont target invulnerable players, ex: uber, bonk if (IsPlayerInvulnerable(ent)) return false; - // If settings allow, ignore taunting players - if (ignore_taunting && HasCondition(ent)) - return false; - // If settings allow, dont target cloaked players if (legit && IsPlayerInvisible(ent)) return false; diff --git a/src/hacks/AutoHeal.cpp b/src/hacks/AutoHeal.cpp index 81039558..183254e4 100644 --- a/src/hacks/AutoHeal.cpp +++ b/src/hacks/AutoHeal.cpp @@ -351,29 +351,31 @@ bool IsPopped() bool ShouldChargePlayer(int idx) { CachedEntity *target = ENTITY(idx); - const int health = target->m_iHealth(); + const int health = target->m_iHealth(); if (float(pop_uber_percent) > 0) { - const float pophealth = target->m_iMaxHealth() * (float(pop_uber_percent) / 100); + const float pophealth = + target->m_iMaxHealth() * (float(pop_uber_percent) / 100); if (health < pophealth) return true; } else { - const float damage_accum_duration = - g_GlobalVars->curtime - data[idx].accum_damage_start; - if (!data[idx].accum_damage_start) + const float damage_accum_duration = + g_GlobalVars->curtime - data[idx].accum_damage_start; + if (!data[idx].accum_damage_start) + return false; + if (health > 30 && data[idx].accum_damage < 45) + return false; + const float dd = + ((float) data[idx].accum_damage / damage_accum_duration); + if (dd > 40) + { + return true; + } + if (health < 30 && data[idx].accum_damage > 10) + return true; return false; - if (health > 30 && data[idx].accum_damage < 45) - return false; - const float dd = ((float) data[idx].accum_damage / damage_accum_duration); - if (dd > 40) - { - return true; - } - if (health < 30 && data[idx].accum_damage > 10) - return true; - return false; } return false; } diff --git a/src/hacks/AutoSticky.cpp b/src/hacks/AutoSticky.cpp index 10db1ca5..d7a93d5b 100644 --- a/src/hacks/AutoSticky.cpp +++ b/src/hacks/AutoSticky.cpp @@ -7,6 +7,7 @@ #include "common.hpp" #include +#include namespace hacks::tf::autosticky { @@ -58,8 +59,10 @@ bool IsTarget(CachedEntity *ent) // Dont detonate on dead players if (!ent->m_bAlivePlayer()) return false; - // Dont detonate on friendly players - if (playerlist::IsFriendly(playerlist::AccessData(ent).state)) + + // Global checks + if (player_tools::shouldTarget(ent) != + player_tools::IgnoreReason::DO_NOT_IGNORE) return false; IF_GAME(IsTF()) diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index 5d2965da..7e89a200 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -25,8 +25,8 @@ static CatEnum slots_enum({ "All", "Primary", "Secondary", "Melee", static CatVar slots(slots_enum, "backtrack_slots", "0", "Enabled Slots", "Select what slots backtrack should be enabled on."); -BacktrackData headPositions[32][66]; -BestTickData sorted_ticks[66]; +BacktrackData headPositions[32][66]{}; +BestTickData sorted_ticks[66]{}; int highesttick[32]{}; int lastincomingsequencenumber = 0; static bool shouldDrawBt; @@ -69,10 +69,11 @@ int ticks = 12; void Init() { for (int i = 0; i < 32; i++) - for (int j = 0; j < 66; j++) - headPositions[i][j] = BacktrackData{ - 0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } - }; + for (int j = 0; j < 66; j++) + headPositions[i][j] = + BacktrackData{ 0, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, 0, + 0, { 0, 0, 0 } }; if (!installed) { latency.InstallChangeCallback( @@ -115,7 +116,8 @@ void Run() { for (BacktrackData &btd : headPositions[i]) btd = BacktrackData{ 0, { 0, 0, 0 }, { 0, 0, 0 }, - { 0, 0, 0 }, { 0, 0, 0 }, 0 }; + { 0, 0, 0 }, { 0, 0, 0 }, 0, + 0, { 0, 0, 0 } }; continue; } if (pEntity->m_iTeam() == LOCAL_E->m_iTeam()) @@ -131,10 +133,12 @@ void Run() NET_VECTOR(RAW_ENT(pEntity), netvar.m_angEyeAngles).y; float viewangles = (_viewangles > 180) ? _viewangles - 360 : _viewangles; + float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime); Vector hitbox_spine = pEntity->hitboxes.GetHitbox(3)->center; + Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin(); headPositions[i][cmd->command_number % ticks] = - BacktrackData{ cmd->tick_count, hitboxpos, min, max, - hitbox_spine, viewangles }; + BacktrackData{ cmd->tick_count, hitboxpos, min, max, + hitbox_spine, viewangles, simtime, ent_orig }; float FOVDistance = GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, hitboxpos); float distance = g_pLocalPlayer->v_Eye.DistTo(hitbox_spine); @@ -189,7 +193,18 @@ void Run() BestTick = bestTick; if (cmd->buttons & IN_ATTACK) - cmd->tick_count = headPositions[iBestTarget][bestTick].tickcount; + { + CachedEntity *tar = ENTITY(iBestTarget); + // ok just in case + if (CE_BAD(tar)) + return; + auto i = headPositions[iBestTarget][bestTick]; + cmd->tick_count = i.tickcount; + Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles); + float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime); + angles.y = i.viewangles; + simtime = i.simtime; + } } } void Draw() diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 51bc4483..8832b27e 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include "common.hpp" namespace hacks::shared::esp @@ -146,6 +148,14 @@ static CatVar entity_model(CV_SWITCH, "esp_model_name", "0", "Model name ESP", static CatVar entity_id(CV_SWITCH, "esp_entity_id", "1", "Entity ID", "Used with Entity ESP. Shows entityID"); +// Online +static CatVar online(CV_SWITCH, "esp_online", "1", "Show online info", + "Username, etc"); +static CatVar online_groups(CV_SWITCH, "esp_online_groups", "1", + "Show online groups", "Admin, developer, etc"); +static CatVar online_software(CV_SWITCH, "esp_online_software", "1", + "Show software", "cathook, lmaobox, etc"); + // CatVar draw_hitbox(CV_SWITCH, "esp_hitbox", "1", "Draw Hitbox"); // Unknown @@ -349,7 +359,7 @@ void CreateMove() ProcessEntity(ent); // Update Bones if (i <= 32) - ent->hitboxes.GetHitbox(0); + ent->hitboxes.GetHitbox(0); // Dont know what this check is for if (data[i].string_count) { @@ -1153,10 +1163,13 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) if (!g_IEngine->GetPlayerInfo(ent->m_IDX, &info)) return; + online::user_data *data = + online ? online::getUserData(info.friendsID) : nullptr; + // TODO, check if u can just use "ent->m_bEnemy()" instead of m_iTeam // Legit mode handling if (legit && ent->m_iTeam() != g_pLocalPlayer->team && - playerlist::IsDefault(info.friendsID)) + playerlist::IsDefault(info.friendsID) && !(data)) { if (IsPlayerInvisible(ent)) return; // Invis check @@ -1168,6 +1181,24 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // return; } + if (data) + { + AddEntityString(ent, "CO: " + data->username, colors::yellow); + if (data->is_steamid_verified) + AddEntityString(ent, "Verified SteamID", colors::green); + if (online_groups) + for (auto &s : data->shown_groups) + AddEntityString(ent, s, colors::orange); + if (online_software && data->has_software) + { + if (data->is_using_friendly_software) + AddEntityString(ent, "Software: " + data->software_name); + else + AddEntityString(ent, "Software: " + data->software_name, + colors::red); + } + } + // Powerup handling if (powerup_esp) { @@ -1178,7 +1209,7 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // Dont understand reasoning for this check if (ent->m_bEnemy() || teammates || - !playerlist::IsDefault(info.friendsID)) + player_tools::shouldAlwaysRenderEsp(ent)) { // Playername diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index 29381d56..a0ebe9ef 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -65,8 +65,8 @@ static const int crumb_limit = 64; // limit int follow_target = 0; bool inited; -Timer lastTaunt{}; //time since taunt was last executed, used to avoid kicks -std::array afkTicks; //for how many ms the player hasn't been moving +Timer lastTaunt{}; // time since taunt was last executed, used to avoid kicks +std::array afkTicks; // for how many ms the player hasn't been moving void checkAFK() { @@ -234,7 +234,9 @@ void WorldTick() continue; if (entity->m_bEnemy()) continue; - if (afk && afkTicks[i].check(int(afktime))) //don't follow target that was determined afk + if (afk && + afkTicks[i].check(int( + afktime))) // don't follow target that was determined afk continue; if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) continue; @@ -277,7 +279,7 @@ void WorldTick() continue; // ooooo, a target follow_target = i; - afkTicks[i].update(); //set afk time to 0 + afkTicks[i].update(); // set afk time to 0 } } // last check for entity before we continue @@ -294,7 +296,7 @@ void WorldTick() follow_target = 0; return; } - //check if target is afk + // check if target is afk if (afk) { if (afkTicks[follow_target].check(int(afktime))) @@ -302,7 +304,6 @@ void WorldTick() follow_target = 0; return; } - } // if(!checkPath()) //wip do not merge if you see this @@ -345,9 +346,11 @@ void WorldTick() } } - //moved because its worthless otherwise - if (sync_taunt && HasCondition(followtar) && lastTaunt.test_and_set(1000)) { - g_IEngine->ClientCmd("taunt"); + // moved because its worthless otherwise + if (sync_taunt && HasCondition(followtar) && + lastTaunt.test_and_set(1000)) + { + g_IEngine->ClientCmd("taunt"); } // Follow the crumbs when too far away, or just starting to follow diff --git a/src/hacks/Trigger.cpp b/src/hacks/Trigger.cpp index 2e1f1c12..c302f412 100644 --- a/src/hacks/Trigger.cpp +++ b/src/hacks/Trigger.cpp @@ -9,6 +9,7 @@ #include #include "common.hpp" #include +#include namespace hacks::shared::triggerbot { @@ -79,43 +80,57 @@ int last_hb_traced = 0; Vector forward; bool CanBacktrack() { - int target = hacks::shared::backtrack::iBestTarget; - int BestTick = hacks::shared::backtrack::BestTick; - auto min = hacks::shared::backtrack::headPositions[target][BestTick].min; - auto max = hacks::shared::backtrack::headPositions[target][BestTick].max; - if (!min.x && !max.x) - return false; - - // Get the min and max for the hitbox - Vector minz(std::min(min.x, max.x), std::min(min.y, max.y), - std::min(min.z, max.z)); - Vector maxz(std::max(min.x, max.x), std::max(min.y, max.y), - std::max(min.z, max.z)); - - // Shrink the hitbox here - Vector size = maxz - minz; - Vector smod = size * 0.05f * (int) accuracy; - - // Save the changes to the vectors - minz += smod; - maxz -= smod; - - // Trace and test if it hits the smaller hitbox, if it fails - // we - // return false - Vector hit; - - if (!IsVectorVisible(g_pLocalPlayer->v_Eye, minz) && - !IsVectorVisible(g_pLocalPlayer->v_Eye, maxz)) + int target = hacks::shared::backtrack::iBestTarget; + int tickcnt = 0; + for (auto i : hacks::shared::backtrack::headPositions[target]) { - return true; - } - if (CheckLineBox(minz, maxz, g_pLocalPlayer->v_Eye, forward, hit)) - { - g_pUserCmd->tick_count = - hacks::shared::backtrack::headPositions[target][BestTick].tickcount; - g_pUserCmd->buttons |= IN_ATTACK; - return false; + bool good_tick = false; + for (int j = 0; j < 12; ++j) + if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick) + good_tick = true; + tickcnt++; + if (!good_tick) + continue; + auto min = i.min; + auto max = i.max; + if (!min.x && !max.x) + continue; + + // Get the min and max for the hitbox + Vector minz(fminf(min.x, max.x), fminf(min.y, max.y), + fminf(min.z, max.z)); + Vector maxz(fmaxf(min.x, max.x), fmaxf(min.y, max.y), + fmaxf(min.z, max.z)); + + // Shrink the hitbox here + Vector size = maxz - minz; + Vector smod = size * 0.05f * (int) accuracy; + + // Save the changes to the vectors + minz += smod; + maxz -= smod; + + // Trace and test if it hits the smaller hitbox, if it fails + // we + // return false + Vector hit; + + if (!IsVectorVisible(g_pLocalPlayer->v_Eye, minz) && + !IsVectorVisible(g_pLocalPlayer->v_Eye, maxz)) + continue; + if (CheckLineBox(minz, maxz, g_pLocalPlayer->v_Eye, forward, hit)) + { + CachedEntity *tar = ENTITY(target); + // ok just in case + if (CE_BAD(tar)) + continue; + Vector &angles = NET_VECTOR(tar, netvar.m_angEyeAngles); + float &simtime = NET_FLOAT(tar, netvar.m_flSimulationTime); + angles.y = i.viewangles; + g_pUserCmd->tick_count = i.tickcount; + g_pUserCmd->buttons |= IN_ATTACK; + return false; + } } return true; } @@ -141,7 +156,7 @@ void CreateMove() CachedEntity *ent = FindEntInSight(EffectiveTargetingRange()); // Check if can backtrack, shoot if we can - if (!CanBacktrack()) + if (!CanBacktrack() || hacks::shared::backtrack::enable) return; // Check if dormant or null to prevent crashes @@ -272,6 +287,11 @@ bool IsTargetStateGood(CachedEntity *entity) if (!entity->m_bEnemy() && !teammates) return false; + // Global checks + if (player_tools::shouldTarget(entity) != + player_tools::IgnoreReason::DO_NOT_IGNORE) + return false; + IF_GAME(IsTF()) { // If settings allow waiting for charge, and current charge cant @@ -291,9 +311,6 @@ bool IsTargetStateGood(CachedEntity *entity) return false; } } - // If settings allow, ignore taunting players - if (ignore_taunting && HasCondition(entity)) - return false; // Dont target invulnerable players, ex: uber, bonk if (IsPlayerInvulnerable(entity)) return false; @@ -307,17 +324,6 @@ bool IsTargetStateGood(CachedEntity *entity) HasCondition(entity)) return false; } - // Dont target players marked as friendly - if (playerlist::IsFriendly(playerlist::AccessData(entity).state)) - return false; - IF_GAME(IsTF()) - { - // If settings allow, ignore hoovys - if (ignore_hoovy && IsHoovy(entity)) - { - return false; - } - } // Head hitbox detection if (HeadPreferable(entity)) @@ -339,12 +345,12 @@ bool IsTargetStateGood(CachedEntity *entity) if (hb) { // Get the min and max for the hitbox - Vector minz(std::min(hb->min.x, hb->max.x), - std::min(hb->min.y, hb->max.y), - std::min(hb->min.z, hb->max.z)); - Vector maxz(std::max(hb->min.x, hb->max.x), - std::max(hb->min.y, hb->max.y), - std::max(hb->min.z, hb->max.z)); + Vector minz(fminf(hb->min.x, hb->max.x), + fminf(hb->min.y, hb->max.y), + fminf(hb->min.z, hb->max.z)); + Vector maxz(fmaxf(hb->min.x, hb->max.x), + fmaxf(hb->min.y, hb->max.y), + fmaxf(hb->min.z, hb->max.z)); // Shrink the hitbox here Vector size = maxz - minz; @@ -623,25 +629,17 @@ bool UpdateAimkey() float EffectiveTargetingRange() { if (GetWeaponMode() == weapon_melee) - { return re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); - // Pyros only have so much untill their flames hit - } + // Pyros only have so much untill their flames hit else if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) - { - return 185.0f; - } + return 200.0f; // If user has set a max range, then use their setting, if (max_range) - { return (float) max_range; - // else use a pre-set range - } + // else use a pre-set range else - { return 8012.0f; - } } // Helper functions to trace for hitboxes diff --git a/src/hacks/ac/antiaim.cpp b/src/hacks/ac/antiaim.cpp old mode 100755 new mode 100644 index 5b9a430a..1312097c --- a/src/hacks/ac/antiaim.cpp +++ b/src/hacks/ac/antiaim.cpp @@ -74,4 +74,3 @@ void Event(KeyValues *event) { } } - diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 5fffe5c7..b42da318 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -89,7 +89,8 @@ void RunEnginePrediction(IClientEntity *ent, CUserCmd *ucmd) #else #define antikick_time 90 #endif -const char *cmds[7] = {"use", "voicecommand", "spec_next", "spec_prev", "spec_player", "invprev", "invnext"}; +const char *cmds[7] = { "use", "voicecommand", "spec_next", "spec_prev", + "spec_player", "invprev", "invnext" }; namespace hooked_methods { DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, @@ -338,14 +339,14 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, if (engine_pred) engine_prediction::RunEnginePrediction(RAW_ENT(LOCAL_E), g_pUserCmd); - { - PROF_SECTION(CM_aimbot); - hacks::shared::aimbot::CreateMove(); - } { PROF_SECTION(CM_backtracc); hacks::shared::backtrack::Run(); } + { + PROF_SECTION(CM_aimbot); + hacks::shared::aimbot::CreateMove(); + } IF_GAME(IsTF2()) { PROF_SECTION(CM_antibackstab); @@ -537,12 +538,12 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, { for (int i = 0; i < 7800; i += sizeof(cmds[nextdata])) { - senddata.m_szCommand = cmds[nextdata]; + senddata.m_szCommand = cmds[nextdata]; ch->SendNetMsg(senddata); if (nextdata == 6) - nextdata = 0; + nextdata = 0; else - nextdata++; + nextdata++; } ch->Transmit(); } @@ -581,12 +582,12 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, for (int i = 0; i < 7800 + additionallag; i += sizeof(cmds[nextdata])) { - senddata.m_szCommand = cmds[nextdata]; + senddata.m_szCommand = cmds[nextdata]; ch->SendNetMsg(senddata, false); if (nextdata == 6) - nextdata = 0; + nextdata = 0; else - nextdata++; + nextdata++; } ch->Transmit(); } @@ -595,11 +596,11 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, { for (int i = 0; i < (int) serverlag_amount; i++) { - senddata.m_szCommand = cmds[nextdata]; + senddata.m_szCommand = cmds[nextdata]; if (nextdata == 6) - nextdata = 0; + nextdata = 0; else - nextdata++; + nextdata++; ch->SendNetMsg(senddata, false); } ch->Transmit(); diff --git a/src/hooks/Paint.cpp b/src/hooks/Paint.cpp index 6e1fc4a7..5fd4d6cb 100644 --- a/src/hooks/Paint.cpp +++ b/src/hooks/Paint.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "common.hpp" #include "hitrate.hpp" #include "hack.hpp" @@ -31,6 +32,7 @@ DEFINE_HOOKED_METHOD(Paint, void, IEngineVGui *this_, PaintMode_t mode) { hitrate::Update(); } + online::update(); #if ENABLE_IPC static Timer nametimer{}; if (nametimer.test_and_set(1000 * 10)) diff --git a/src/online/CMakeLists.txt b/src/online/CMakeLists.txt new file mode 100644 index 00000000..ecbbb1c2 --- /dev/null +++ b/src/online/CMakeLists.txt @@ -0,0 +1,2 @@ +target_sources(cathook PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/Online.cpp") \ No newline at end of file diff --git a/src/online/Online.cpp b/src/online/Online.cpp new file mode 100644 index 00000000..c15de102 --- /dev/null +++ b/src/online/Online.cpp @@ -0,0 +1,333 @@ +/* + Created on 23.06.18. +*/ + +#include +#include + +#include +#include +#include +#include + +#undef null + +#include +#include +#include +#include + +namespace online +{ + +void saveApiKeyAndHost(std::string host); +void claimSteamId(); + +static co::OnlineService cathookOnlineService{}; +static std::unordered_map> data{}; +static std::unordered_map identify_queue{}; +static Timer identify_timer{}; +static bool identify_stale{ false }; +static std::string api_key{}; + +static CatVar enable(CV_SWITCH, "online", "1", "Enable online features"); +static CatCommand login("online_login", "Login", [](const CCommand &args) { + if (args.ArgC() != 3) + { + logging::Info("\nUsage: online_login \"\"\nKey will " + "be saved in your data folder"); + return; + } + std::string host(args.Arg(2)); + logging::Info("[CO] Host = %s", host.c_str()); + try + { + cathookOnlineService.setHost(host); + } + catch (std::exception &ex) + { + logging::Info("[CO] Error setting host: %s", ex.what()); + return; + } + std::string key(args.Arg(1)); + try + { + cathookOnlineService.login( + key, [key, host](co::ApiCallResult result, + std::optional me) { + if (result == co::ApiCallResult::OK) + { + logging::Info("[CO] Successfully logged in. Welcome, %s", + me->username.c_str()); + api_key = key; + saveApiKeyAndHost(host); + claimSteamId(); + } + else + { + logging::Info("[CO] There was an error logging in: code %d", + result); + } + }); + } + catch (std::exception &ex) + { + logging::Info("[CO] Exception: %s", ex.what()); + } +}); +static CatCommand flush("online_flush_cache", "Flush player cache", + [](const CCommand &args) { + data.clear(); + identify_queue.clear(); + identify_stale = true; + }); + +// INTERNAL METHODS + +void claimSteamId() +{ + auto id = g_ISteamUser->GetSteamID(); + logging::Info("[CO] Claiming SteamID %u", id.GetAccountID()); + try + { + cathookOnlineService.gameStartup(id.GetAccountID()); + } + catch (std::exception &ex) + { + logging::Info("[CO] Exception: %s", ex.what()); + } +} + +bool tryLoadApiKeyAndHost() +{ + std::ifstream keyfile(DATA_PATH "/api_key", std::ios::in); + if (keyfile) + { + std::string host{}; + keyfile >> api_key >> host; + if (!api_key.empty() && !host.empty()) + { + try + { + cathookOnlineService.setHost(host); + } + catch (std::exception &ex) + { + logging::Info("Error while setting host: %s", ex.what()); + } + return true; + } + } + return false; +} + +void saveApiKeyAndHost(std::string host) +{ + std::ofstream keyfile(DATA_PATH "/api_key", std::ios::out); + if (!keyfile) + { + logging::Info("[CO] Something went wrong while saving API key"); + return; + } + keyfile << api_key << '\n' << host << '\n'; +} + +void queueUserForIdentification(unsigned steamId) +{ + + identify_queue[steamId] = false; + identify_timer.update(); + identify_stale = true; +} + +void markSteamIdNonOnline(unsigned id) +{ + logging::Info("[CO] %u - not online", id); + data[id] = std::nullopt; +} + +void processOnlineIdentity(unsigned id, co::identified_user &user) +{ + logging::Info("[CO] %u - online", id); + user_data udata{}; + udata.username = user.username; + udata.is_anonymous = (user.username == "anonymous"); + udata.is_steamid_verified = user.steamid_verified; + for (auto &i : user.groups) + { + if (i.display_name.has_value()) + udata.shown_groups.push_back(*i.display_name); + if (i.name == "notarget") + udata.no_target = true; + if (i.name == "owner" || i.name == "contributor") + { + udata.is_developer = true; +#if ENABLE_VISUALS + udata.rainbow = true; +#endif + } + } +#if ENABLE_VISUALS + if (user.color.has_value()) + { + udata.has_color = true; + udata.color = colors::rgba_t(user.color->c_str()); + } +#endif + if (user.uses_software.has_value()) + { + udata.has_software = true; + udata.is_using_friendly_software = user.uses_software->friendly; + udata.software_name = user.uses_software->name; + } + data[id] = std::move(udata); +} + +void processIdentifyResponse(std::vector input, + co::identified_user_group &group) +{ + logging::Info( + "[CO] Processing identify response containing %u / %u entries", + group.users.size(), input.size()); + for (auto i : input) + { + auto u = group.users.find(i); + if (u == group.users.end()) + markSteamIdNonOnline(i); + else + processOnlineIdentity(i, (*u).second); + + identify_queue.erase(i); + logging::Info("[CO] Removed %u from identify queue, left %u\n", i, + identify_queue.size()); + } +} + +void sendIdentifyRequest() +{ + std::vector steamIds{}; + auto it = identify_queue.begin(); + // Create a list of up to 32 steamId's + for (int i = 0; i < 32 && it != identify_queue.end(); ++i, ++it) + { + if (!it->second) + { + it->second = true; + steamIds.push_back(it->first); + } + } + logging::Info("[CO] Sending identify request for %u players", + steamIds.size()); + try + { + cathookOnlineService.userIdentify( + steamIds, + (std::function)>) [steamIds]( + co::ApiCallResult result, + std::optional group) { + if (result == co::ApiCallResult::OK) + { + processIdentifyResponse(steamIds, *group); + } + else + { + logging::Info("[CO] Something went wrong while identifying " + "%u players: code %d", + steamIds.size(), result); + for (auto i : steamIds) + { + identify_queue[i] = false; + } + identify_stale = true; + } + }); + } + catch (std::exception &ex) + { + logging::Info("[CO] Exception: %s", ex.what()); + } +} + +InitRoutine init([]() { + cathookOnlineService.setErrorHandler((std::function) []( + std::string error) { logging::Info("[CO] Error: %s", error.c_str()); }); + if (tryLoadApiKeyAndHost()) + { + logging::Info("[CO] API key loaded successfully"); + try + { + cathookOnlineService.login( + api_key, [](co::ApiCallResult result, + std::optional me) { + if (result == co::ApiCallResult::OK) + { + logging::Info( + "[CO] Successfully logged in. Welcome, %s", + me->username.c_str()); + claimSteamId(); + } + else + { + logging::Info( + "[CO] There was an error logging in: code %d", + result); + } + }); + } + catch (std::exception &ex) + { + logging::Info("[CO] Exception: %s", ex.what()); + } + } +}); + +// EXTERNAL METHODS + +void update() +{ + if (!enable) + return; + // Only send a request after 3 seconds passed since last unknown steamId was + // added to the queue + if (!api_key.empty() && identify_stale && identify_timer.check(3000) && + !identify_queue.empty()) + { + sendIdentifyRequest(); + identify_stale = false; + } + try + { + cathookOnlineService.processPendingCalls(); + } + catch (std::exception &ex) + { + logging::Info("[CO] Exception: %s", ex.what()); + } +} + +user_data *getUserData(unsigned steamId) +{ + if (!enable) + return nullptr; + + if (!steamId) + return nullptr; + + auto it = data.find(steamId); + // User not identified + if (it == data.end()) + { + // Queue user for identification + if (identify_queue.find(steamId) == identify_queue.end()) + queueUserForIdentification(steamId); + return nullptr; + } + // SteamID belongs to online user + if (it->second.has_value()) + return &*it->second; + // SteamID does not belong to online user + return nullptr; +} +} \ No newline at end of file diff --git a/src/visual/EffectChams.cpp b/src/visual/EffectChams.cpp index eb13fcea..66ebb9ee 100644 --- a/src/visual/EffectChams.cpp +++ b/src/visual/EffectChams.cpp @@ -8,6 +8,7 @@ #include #include #include "common.hpp" +#include "Backtrack.hpp" // static CatVar chams_experimental(CV_SWITCH, "chams_effect", "0", // "Experimental Chams"); @@ -320,29 +321,28 @@ void EffectChams::RenderChamsRecursive(IClientEntity *entity) void EffectChams::RenderChams(IClientEntity *entity) { CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); - if (ShouldRenderChams(entity)) + if (ShouldRenderChams(entity)) + { + rgba_t color = ChamsColor(entity); + rgba_t color_2 = color * 0.6f; + if (!legit) { - rgba_t color = ChamsColor(entity); - rgba_t color_2 = color * 0.6f; - if (!legit) - { - mat_unlit_z->AlphaModulate(1.0f); - ptr->DepthRange(0.0f, 0.01f); - g_IVRenderView->SetColorModulation(color_2); - g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit_z - : mat_lit_z); + mat_unlit_z->AlphaModulate(1.0f); + ptr->DepthRange(0.0f, 0.01f); + g_IVRenderView->SetColorModulation(color_2); + g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit_z + : mat_lit_z); - RenderChamsRecursive(entity); - } + RenderChamsRecursive(entity); + } - if (legit || !singlepass) - { - mat_unlit->AlphaModulate(1.0f); - g_IVRenderView->SetColorModulation(color); - ptr->DepthRange(0.0f, 1.0f); - g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit - : mat_lit); - RenderChamsRecursive(entity); + if (legit || !singlepass) + { + mat_unlit->AlphaModulate(1.0f); + g_IVRenderView->SetColorModulation(color); + ptr->DepthRange(0.0f, 1.0f); + g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit : mat_lit); + RenderChamsRecursive(entity); } } } diff --git a/src/visual/colors.cpp b/src/visual/colors.cpp index ea4a2555..325d259e 100644 --- a/src/visual/colors.cpp +++ b/src/visual/colors.cpp @@ -5,6 +5,8 @@ * Author: nullifiedcat */ +#include +#include #include "common.hpp" static CatVar user_red_blue(CV_INT, "esp_color_red_b", "0", "Red Team: Blue", @@ -130,9 +132,10 @@ rgba_t colors::EntityF(CachedEntity *ent) else if (ent->m_iTeam() == TEAM_RED) result = red_v; } - plclr = playerlist::Color(ent); - if (plclr.a) - result = plclr; + + auto o = player_tools::forceEspColor(ent); + if (o.has_value()) + return *o; } } @@ -144,3 +147,30 @@ rgba_t colors::RainbowCurrent() return colors::FromHSL(fabs(sin(g_GlobalVars->curtime / 2.0f)) * 360.0f, 0.85f, 0.9f); } + +static unsigned char hexToChar(char i) +{ + if (i >= '0' && i <= '9') + return i - '0'; + if (i >= 'a' && i <= 'f') + return i - 'a' + 10; + if (i >= 'A' && i <= 'F') + return i - 'A' + 10; + return 0; +} + +static unsigned int hexToByte(char hi, char lo) +{ + return (hexToChar(hi) << 4) | (hexToChar(lo)); +} + +colors::rgba_t::rgba_t(const char hex[6]) +{ + auto ri = hexToByte(hex[0], hex[1]); + auto gi = hexToByte(hex[2], hex[3]); + auto bi = hexToByte(hex[4], hex[5]); + r = float(ri) / 255.0f; + g = float(gi) / 255.0f; + b = float(bi) / 255.0f; + a = 1.0f; +} diff --git a/src/visual/menu/ncc/Menu.cpp b/src/visual/menu/ncc/Menu.cpp index b614341b..97af5040 100644 --- a/src/visual/menu/ncc/Menu.cpp +++ b/src/visual/menu/ncc/Menu.cpp @@ -308,8 +308,6 @@ static const std::string list_tf2 = R"( "aimbot_ignore_cloak" "aimbot_ignore_deadringer" "aimbot_ignore_vaccinator" - "ignore_taunting" - "aimbot_ignore_hoovy" "aimbot_teammates" ] "Auto Heal" [ @@ -598,11 +596,6 @@ static const std::string list_tf2 = R"( "Anti-Aim" [ "Anti-Aim Menu" "aa_enabled" - "aa_realfakes" - "aa_pitch_real" - "aa_yaw_real" - "aa_pitch_mode_real" - "aa_yaw_mode_real" "aa_pitch" "aa_yaw" "aa_pitch_mode"