From 9b9659e152d2b4342023fc7f4d2b67faa1ac8b60 Mon Sep 17 00:00:00 2001 From: whitehai11 Date: Wed, 5 Aug 2026 16:42:17 +0200 Subject: [PATCH] Add configurable triggerbot (mode/key/delay/hold, hitbox filter, scoped-only, indicator) --- .../AndromedaClient/Features/CMisc/CMisc.cpp | 182 +++++++++++++++++- .../AndromedaClient/Features/CMisc/CMisc.hpp | 14 ++ .../AndromedaClient/GUI/CAndromedaMenu.cpp | 55 ++++++ .../AndromedaClient/Settings/Settings.hpp | 16 ++ .../GameClient/CL_Trace.cpp | 36 ++++ .../GameClient/CL_Trace.hpp | 7 + 6 files changed, 309 insertions(+), 1 deletion(-) diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.cpp index b04da16..ed50e5f 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.cpp @@ -1,5 +1,6 @@ #include "CMisc.hpp" +#include #include #include #include @@ -18,7 +19,11 @@ #include #include +#include +#include +#include #include +#include #include @@ -91,7 +96,7 @@ auto CMisc::OnClientOutput() -> void const auto ObserverMode = pObserverServices->m_iObserverMode(); - if ( ObserverMode != 4 && ObserverMode != 5 ) + if ( ObserverMode != OBS_MODE_IN_EYE && ObserverMode != OBS_MODE_CHASE ) continue; if ( pObserverServices->m_hObserverTarget() != LocalPawnHandle ) @@ -109,6 +114,20 @@ auto CMisc::OnClientOutput() -> void } } + if ( Settings::Triggerbot::Active && Settings::Triggerbot::DrawIndicator ) + { + if ( m_bTargetInCrosshair ) + { + const auto DisplaySize = ImGui::GetIO().DisplaySize; + + const ImVec2 Center( DisplaySize.x * 0.5f , DisplaySize.y * 0.5f ); + + const ImColor IndicatorColor = m_bTriggerFiring ? ImColor( 0 , 255 , 0 ) : ImColor( 255 , 200 , 0 ); + + GetRenderStackSystem()->DrawCircleFilled( Center , 3.f , IndicatorColor ); + } + } + if ( Settings::Misc::Hitmarker ) { if ( m_HitTime.time_since_epoch().count() > 0 ) @@ -137,6 +156,9 @@ auto CMisc::OnCreateMove( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void if ( !pUserCmd ) return; + if ( Settings::Triggerbot::Active ) + RunTriggerbot( pInput , pUserCmd ); + if ( Settings::Misc::Bunnyhop ) { auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn(); @@ -170,6 +192,164 @@ auto CMisc::OnCreateMove( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void } } +auto CMisc::RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void +{ + auto Reset = [ & ]() + { + m_bTriggerShooting = false; + m_TriggerArmTime = {}; + m_ShotStartTime = {}; + + m_bTargetInCrosshair = false; + m_bTriggerFiring = false; + }; + + auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn(); + + if ( !pLocalPawn || !pLocalPawn->IsAlive() ) + { + Reset(); + return; + } + + const auto WeaponType = GetCL_Weapons()->GetLocalWeaponType(); + + const bool bIsGun = WeaponType == CSWeaponType_t::WEAPONTYPE_PISTOL || + WeaponType == CSWeaponType_t::WEAPONTYPE_SUBMACHINEGUN || + WeaponType == CSWeaponType_t::WEAPONTYPE_RIFLE || + WeaponType == CSWeaponType_t::WEAPONTYPE_SHOTGUN || + WeaponType == CSWeaponType_t::WEAPONTYPE_SNIPER_RIFLE || + WeaponType == CSWeaponType_t::WEAPONTYPE_MACHINEGUN || + WeaponType == CSWeaponType_t::WEAPONTYPE_TASER; + + if ( !bIsGun ) + { + Reset(); + return; + } + + if ( Settings::Triggerbot::ScopedOnly ) + { + if ( WeaponType == CSWeaponType_t::WEAPONTYPE_SNIPER_RIFLE && !pLocalPawn->m_bIsScoped() ) + { + Reset(); + return; + } + } + + bool bShouldRun = false; + + switch ( Settings::Triggerbot::Mode ) + { + case 1: + { + bShouldRun = true; + } + break; + + case 2: + { + const bool bKeyDown = ( GetAsyncKeyState( Settings::Triggerbot::Key ) & 0x8000 ) != 0; + + if ( bKeyDown && !m_bTriggerKeyDown ) + m_bTriggerToggledOn = !m_bTriggerToggledOn; + + m_bTriggerKeyDown = bKeyDown; + + bShouldRun = m_bTriggerToggledOn; + } + break; + + default: + { + const bool bKeyDown = ( GetAsyncKeyState( Settings::Triggerbot::Key ) & 0x8000 ) != 0; + + bShouldRun = bKeyDown; + } + break; + } + + if ( !bShouldRun ) + { + Reset(); + return; + } + + const auto Result = GetCL_Trace()->TraceToHitGroup( pInput ); + + auto* pTargetPawn = reinterpret_cast( Result.pHitEntity ); + + bool bTargetValid = false; + + if ( pTargetPawn && pTargetPawn->IsPlayerPawn() && pTargetPawn != pLocalPawn && pTargetPawn->IsAlive() ) + { + if ( !Settings::Triggerbot::IgnoreTeammates || pTargetPawn->m_iTeamNum() != pLocalPawn->m_iTeamNum() ) + { + switch ( Result.nHitGroup ) + { + case 1: bTargetValid = Settings::Triggerbot::Hitbox_Head; break; + case 2: bTargetValid = Settings::Triggerbot::Hitbox_Chest; break; + case 3: bTargetValid = Settings::Triggerbot::Hitbox_Stomach; break; + case 4: + case 5: bTargetValid = Settings::Triggerbot::Hitbox_Arms; break; + case 6: + case 7: bTargetValid = Settings::Triggerbot::Hitbox_Legs; break; + default: bTargetValid = true; break; + } + } + } + + m_bTargetInCrosshair = bTargetValid; + + if ( !bTargetValid ) + { + m_bTriggerShooting = false; + m_TriggerArmTime = {}; + m_ShotStartTime = {}; + + m_bTriggerFiring = false; + + return; + } + + const auto Now = std::chrono::steady_clock::now(); + + const auto DelayMs = std::chrono::milliseconds( std::max( 0 , Settings::Triggerbot::Delay ) ); + const auto HoldMs = std::chrono::milliseconds( std::max( 0 , Settings::Triggerbot::HoldTime ) ); + + if ( !m_bTriggerShooting ) + { + if ( m_TriggerArmTime.time_since_epoch().count() == 0 ) + m_TriggerArmTime = Now; + + if ( ( Now - m_TriggerArmTime ) >= DelayMs ) + { + m_bTriggerShooting = true; + m_ShotStartTime = Now; + m_TriggerArmTime = {}; + } + } + else + { + if ( ( Now - m_ShotStartTime ) >= HoldMs ) + { + m_bTriggerShooting = false; + m_TriggerArmTime = Now; + } + } + + if ( m_bTriggerShooting ) + { + GetCL_Bypass()->SetAttack( pUserCmd , true ); + + m_bTriggerFiring = true; + } + else + { + m_bTriggerFiring = false; + } +} + auto CMisc::OnFrameStageNotify( int FrameStage ) -> void { if ( FrameStage != 6 ) diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.hpp index 3396fd2..5f0b80c 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Features/CMisc/CMisc.hpp @@ -3,6 +3,7 @@ #include #include +#include class CCSGOInput; class CUserCmd; @@ -27,9 +28,22 @@ public: virtual void OnFrameStageNotify( int FrameStage ) override; virtual void OnFireEventClientSide( IGameEvent* pGameEvent ) override; +private: + auto RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void; + private: std::chrono::steady_clock::time_point m_HitTime{}; std::chrono::steady_clock::time_point m_HitSoundTime{}; + +private: + bool m_bTriggerToggledOn = false; + bool m_bTriggerKeyDown = false; + bool m_bTriggerShooting = false; + std::chrono::steady_clock::time_point m_TriggerArmTime{}; + std::chrono::steady_clock::time_point m_ShotStartTime{}; + + std::atomic_bool m_bTargetInCrosshair = false; + std::atomic_bool m_bTriggerFiring = false; }; auto GetMisc() -> CMisc*; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp index 45ced8e..f59d6cc 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp @@ -350,6 +350,61 @@ auto CAndromedaMenu::RenderMiscPanel() -> void Checkbox( "Hitmarker" , Settings::Misc::Hitmarker ); Checkbox( "Hit Sound" , Settings::Misc::HitSound ); + + ImGui::SeparatorText( "Triggerbot" ); + + Checkbox( "Triggerbot" , Settings::Triggerbot::Active ); + + if ( Settings::Triggerbot::Active ) + { + const char* TriggerModeItems[] = + { + "Hold Key" , "Always" , "Toggle" + }; + + Combo( "Mode" , Settings::Triggerbot::Mode , TriggerModeItems , IM_ARRAYSIZE( TriggerModeItems ) ); + + static const char* TriggerKeyItems[] = + { + "Alt" , "Shift" , "Ctrl" , "Mouse 4" , "Mouse 5" , "Q" , "E" , "F" , "X" , "C" , "V" , "B" , "Space" + }; + + static const int TriggerKeys[] = + { + VK_MENU , VK_SHIFT , VK_CONTROL , 0x04 , 0x05 , 0x51 , 0x45 , 0x46 , 0x58 , 0x43 , 0x56 , 0x42 , VK_SPACE + }; + + int iKeyIdx = 0; + + for ( int i = 0; i < IM_ARRAYSIZE( TriggerKeys ); i++ ) + { + if ( TriggerKeys[ i ] == Settings::Triggerbot::Key ) + { + iKeyIdx = i; + break; + } + } + + if ( Combo( "Key" , iKeyIdx , TriggerKeyItems , IM_ARRAYSIZE( TriggerKeyItems ) ) ) + Settings::Triggerbot::Key = TriggerKeys[ iKeyIdx ]; + + SliderInt( "Delay (ms)" , Settings::Triggerbot::Delay , 0 , 300 ); + SliderInt( "Hold Time (ms)" , Settings::Triggerbot::HoldTime , 0 , 200 ); + + ImGui::Separator(); + + Checkbox( "Nur gescoped (Sniper)" , Settings::Triggerbot::ScopedOnly ); + Checkbox( "Teammates ignorieren" , Settings::Triggerbot::IgnoreTeammates ); + Checkbox( "Fadenkreuz-Indikator" , Settings::Triggerbot::DrawIndicator ); + + ImGui::Separator(); + + Checkbox( "Kopf" , Settings::Triggerbot::Hitbox_Head ); + Checkbox( "Brust" , Settings::Triggerbot::Hitbox_Chest ); + Checkbox( "Bauch" , Settings::Triggerbot::Hitbox_Stomach ); + Checkbox( "Arme" , Settings::Triggerbot::Hitbox_Arms ); + Checkbox( "Beine" , Settings::Triggerbot::Hitbox_Legs ); + } } auto CAndromedaMenu::RenderConfigPanel() -> void diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp index 52d658d..47c4437 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp @@ -52,6 +52,22 @@ namespace Settings inline auto Hitmarker = true; inline auto HitSound = true; } + namespace Triggerbot + { + inline auto Active = false; + inline auto Mode = 0; // 0 = Hold Key, 1 = Always, 2 = Toggle + inline auto Key = VK_MENU; // Alt + inline auto Delay = 50; // ms + inline auto HoldTime = 30; // ms + inline auto ScopedOnly = false; + inline auto IgnoreTeammates = true; + inline auto Hitbox_Head = true; + inline auto Hitbox_Chest = true; + inline auto Hitbox_Stomach = true; + inline auto Hitbox_Arms = false; + inline auto Hitbox_Legs = false; + inline auto DrawIndicator = true; + } namespace Colors { namespace Visual diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp index 749c0cb..9981a7c 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.cpp @@ -84,6 +84,42 @@ auto CL_Trace::TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity* return nullptr; } +auto CL_Trace::TraceToHitGroup( CCSGOInput* pInput ) -> TriggerTraceResult_t +{ + TriggerTraceResult_t Result; + + auto pLocalPlayerPawn = GetCL_Players()->GetLocalPlayerPawn(); + + if ( !pLocalPlayerPawn || !pInput ) + return Result; + + Vector3 vForward; + + Ray_t Ray; + CGameTrace GameTrace; + CTraceFilter Filter( 0x1C1003 , pLocalPlayerPawn , 3 , 15 ); + + const auto vStart = GetCL_Players()->GetLocalEyeOrigin(); + QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 ); + + Math::AngleVectors( ViewAngles , vForward ); + + vForward *= 8192.f; + + const auto vEnd = vStart + vForward; + + if ( IGamePhysicsQuery_TraceShape( SDK::Pointers::CVPhys2World() , Ray , vStart , vEnd , &Filter , &GameTrace ) ) + { + if ( GameTrace.pHitEntity && GameTrace.pHitBox ) + { + Result.pHitEntity = GameTrace.pHitEntity; + Result.nHitGroup = GameTrace.pHitBox->nGroupId; + } + } + + return Result; +} + auto GetCL_Trace() -> CL_Trace* { return &g_CL_Trace; diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp index b6bb3d0..b6fb02b 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/GameClient/CL_Trace.hpp @@ -11,11 +11,18 @@ class Vector3; class CCSGOInput; class C_BaseEntity; +struct TriggerTraceResult_t +{ + C_BaseEntity* pHitEntity = nullptr; + int nHitGroup = 0; +}; + class CL_Trace final { public: auto TraceToBoneEntity( CCSGOInput* pInput , const QAngle* AngleCorrection , QAngle* ViewAngleCorrection ) -> std::pair; auto TraceToEntityEndPos( const Vector3* vEnd ) -> C_BaseEntity*; + auto TraceToHitGroup( CCSGOInput* pInput ) -> TriggerTraceResult_t; }; auto GetCL_Trace() -> CL_Trace*;