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 c82918e..fb5e3eb 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 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -479,6 +480,9 @@ auto CMisc::OnCreateMove( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void if ( Settings::Triggerbot::Active ) RunTriggerbot( pInput , pUserCmd ); + if ( Settings::Ragebot::Active ) + RunRagebot( pInput , pUserCmd ); + if ( Settings::Misc::Bunnyhop ) { auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn(); @@ -1335,6 +1339,246 @@ auto CMisc::RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void } } +auto CMisc::CalculateRagebotFov( const QAngle& ViewAngles , const QAngle& AimAngles ) -> float +{ + const float flPitch = std::fabsf( Math::AngleNormalize( AimAngles.m_x - ViewAngles.m_x ) ); + const float flYaw = std::fabsf( Math::AngleNormalize( AimAngles.m_y - ViewAngles.m_y ) ); + + return std::sqrtf( flPitch * flPitch + flYaw * flYaw ); +} + +auto CMisc::RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void +{ + m_bRagebotFiring = false; + + auto* pLocalPawn = GetCL_Players()->GetLocalPlayerPawn(); + + if ( !pLocalPawn || !pLocalPawn->IsAlive() ) + 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 ) + return; + + bool bShouldRun = false; + + switch ( Settings::Ragebot::Mode ) + { + case 1: + { + bShouldRun = true; + } + break; + + case 2: + { + const bool bKeyDown = ( GetAsyncKeyState( Settings::Ragebot::Key ) & 0x8000 ) != 0; + + if ( bKeyDown && !m_bRagebotKeyDown ) + m_bRagebotToggledOn = !m_bRagebotToggledOn; + + m_bRagebotKeyDown = bKeyDown; + + bShouldRun = m_bRagebotToggledOn; + } + break; + + default: + { + const bool bKeyDown = ( GetAsyncKeyState( Settings::Ragebot::Key ) & 0x8000 ) != 0; + + bShouldRun = bKeyDown; + } + break; + } + + if ( !bShouldRun ) + return; + + auto* pWeapon = GetCL_Weapons()->GetLocalActiveWeapon(); + + if ( !pWeapon ) + return; + + const float flInaccuracy = C_CSWeaponBaseGun_GetInaccuracy( pWeapon , nullptr , nullptr ); + const float flSpread = C_CSWeaponBaseGun_GetSpread( pWeapon ); + const int iItemDefIdx = GetCL_Weapons()->GetLocalWeaponDefinitionIndex(); + + const Vector3 vEyeOrigin = GetCL_Players()->GetLocalEyeOrigin(); + + const QAngle ViewAngles = *CCSGOInput_GetViewAngles( pInput , 0 ); + + C_CSPlayerPawn* pBestPawn = nullptr; + QAngle BestAngles; + float flBestFov = 9999.f; + + const auto& CachedVec = GetEntityCache()->GetCachedEntity(); + + std::scoped_lock Lock( GetEntityCache()->GetLock() ); + + for ( const auto& CachedEntity : *CachedVec ) + { + if ( CachedEntity.m_Type != CachedEntity_t::PLAYER_CONTROLLER ) + continue; + + auto* pEntity = CachedEntity.m_Handle.Get(); + + if ( !pEntity ) + continue; + + auto* pController = reinterpret_cast( pEntity ); + + if ( pController == GetCL_Players()->GetLocalPlayerController() ) + continue; + + auto* pPawn = pController->m_hPawn().Get(); + + if ( !pPawn || !pPawn->IsPlayerPawn() || pPawn == pLocalPawn || !pPawn->IsAlive() ) + continue; + + if ( Settings::Ragebot::IgnoreTeammates && pPawn->m_iTeamNum() == pLocalPawn->m_iTeamNum() ) + continue; + + const char* szBoneName = "head_0"; + + switch ( Settings::Ragebot::Hitbox ) + { + case 0: szBoneName = "head_0"; break; + case 2: szBoneName = "spine_3"; break; + case 3: szBoneName = "pelvis"; break; + case 4: szBoneName = "ankle_l"; break; + default: szBoneName = "pelvis"; break; + } + + const Vector3 vAimPoint = GetCL_Bones()->GetBonePositionByName( pPawn , szBoneName ); + + if ( vAimPoint.IsZero() ) + continue; + + Vector3 vDelta = vAimPoint - vEyeOrigin; + + if ( vDelta.Length() < 0.01f ) + continue; + + if ( Settings::Ragebot::VisibleOnly && !GetCL_VisibleCheck()->IsBoneVisible( pPawn , vAimPoint ) ) + continue; + + QAngle AimAngles; + Math::VectorAngles( vDelta.Normalized() , AimAngles ); + + if ( Settings::Ragebot::Recoil ) + { + const auto& PunchCache = pLocalPawn->m_aimPunchCache(); + + if ( PunchCache.Count() > 0 ) + { + constexpr float k_PunchScale = 2.f; + + AimAngles.m_x -= PunchCache[ 0 ].m_x * k_PunchScale; + AimAngles.m_y -= PunchCache[ 0 ].m_y * k_PunchScale; + } + } + + if ( Settings::Ragebot::NoSpread ) + { + constexpr float k_RadToDeg = 180.f / 3.14159265358979f; + + for ( auto i = 0; i < 3; i++ ) + { + int iTick = 0; + + if ( pUserCmd && pUserCmd->cmd.base().has_client_tick() ) + iTick = pUserCmd->cmd.base().client_tick(); + + const auto iSeed = static_cast( GetSpreadSeed( AimAngles , iTick ) ); + + const auto sv = CalculateSeedSpread( iSeed + 1 , flInaccuracy , flSpread , iItemDefIdx ); + + AimAngles.m_x -= sv.y * k_RadToDeg; + AimAngles.m_y += sv.x * k_RadToDeg; + } + } + + Math::NormalizeAngles( AimAngles ); + Math::ClampAngles( AimAngles ); + + const float flFov = CalculateRagebotFov( ViewAngles , AimAngles ); + + if ( flFov > static_cast( Settings::Ragebot::FOV ) ) + continue; + + if ( flFov < flBestFov ) + { + flBestFov = flFov; + pBestPawn = pPawn; + BestAngles = AimAngles; + } + } + + if ( !pBestPawn ) + return; + + if ( Settings::Ragebot::Hitchance > 0 ) + { + const float flHitchance = CalculateHitchance( pInput , pBestPawn , BestAngles , Settings::Ragebot::HitchanceSamples ); + + if ( ( flHitchance * 100.f ) < static_cast( Settings::Ragebot::Hitchance ) ) + return; + } + + if ( Settings::Ragebot::AutoStop ) + { + const Vector3 Velocity = pLocalPawn->m_vecVelocity(); + + const float flSpeed = Velocity.Length2D(); + + if ( flSpeed > 5.f ) + { + constexpr float k_Pi = 3.14159265358979f; + + const float flVelYaw = std::atan2f( Velocity.m_y , Velocity.m_x ) * ( 180.f / k_Pi ); + + float flDelta = flVelYaw - ViewAngles.m_y; + + while ( flDelta > 180.f ) + flDelta -= 360.f; + + while ( flDelta < -180.f ) + flDelta += 360.f; + + auto& uButtons = pUserCmd->button_states.buttonstate1; + + if ( flDelta > -45.f && flDelta <= 45.f ) + uButtons |= IN_BACK; + else if ( flDelta > 45.f && flDelta <= 135.f ) + uButtons |= IN_MOVELEFT; + else if ( flDelta > 135.f || flDelta <= -135.f ) + uButtons |= IN_FORWARD; + else + uButtons |= IN_MOVERIGHT; + + pUserCmd->cmd.mutable_base()->mutable_buttons_pb()->set_buttonstate1( uButtons ); + } + } + + GetCL_Bypass()->SetViewAngles( &BestAngles , pInput , pUserCmd ); + + if ( Settings::Ragebot::AutoFire ) + { + GetCL_Bypass()->SetAttack( pUserCmd , true ); + m_bRagebotFiring = true; + } +} + static thread_local std::mt19937 g_TriggerRng( std::random_device{}() ); auto CMisc::CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float 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 36cd088..02bccaa 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 @@ -35,8 +35,10 @@ public: private: auto RunTriggerbot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void; + auto RunRagebot( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void; auto CalculateHitchance( CCSGOInput* pInput , C_CSPlayerPawn* pTarget , const QAngle& ViewAngles , const int Samples ) -> float; auto CalculateSeedDirection( CCSGOInput* pInput , CUserCmd* pUserCmd , Vector3* vOutDirection ) -> bool; + auto CalculateRagebotFov( const QAngle& ViewAngles , const QAngle& AimAngles ) -> float; auto RunMovement( CCSGOInput* pInput , CUserCmd* pUserCmd ) -> void; auto RunAutoStrafe( CCSGOInput* pInput , CUserCmd* pUserCmd , C_CSPlayerPawn* pLocalPawn , bool bOnGround ) -> void; @@ -77,6 +79,10 @@ private: bool m_bRightHeld = false; bool m_bForwardHeld = false; bool m_bBackHeld = false; + + std::atomic_bool m_bRagebotFiring = false; + bool m_bRagebotKeyDown = false; + bool m_bRagebotToggledOn = 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 45b204e..1eb8843 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.cpp @@ -72,6 +72,18 @@ auto CAndromedaMenu::OnRenderMenu() -> void ImGui::EndTabItem(); } + if ( ImGui::BeginTabItem( "Legitbot" ) ) + { + RenderLegitbotPanel(); + ImGui::EndTabItem(); + } + + if ( ImGui::BeginTabItem( "Ragebot" ) ) + { + RenderRagebotPanel(); + ImGui::EndTabItem(); + } + if ( ImGui::BeginTabItem( "Misc" ) ) { RenderMiscPanel(); @@ -367,7 +379,10 @@ auto CAndromedaMenu::RenderMiscPanel() -> void Checkbox( "Hitmarker" , Settings::Misc::Hitmarker ); Checkbox( "Hit Sound" , Settings::Misc::HitSound ); +} +auto CAndromedaMenu::RenderLegitbotPanel() -> void +{ ImGui::SeparatorText( "Triggerbot" ); Checkbox( "Triggerbot" , Settings::Triggerbot::Active ); @@ -436,6 +451,72 @@ auto CAndromedaMenu::RenderMiscPanel() -> void } } +auto CAndromedaMenu::RenderRagebotPanel() -> void +{ + ImGui::SeparatorText( "Ragebot" ); + + Checkbox( "Enabled" , Settings::Ragebot::Active ); + + if ( Settings::Ragebot::Active ) + { + const char* RageModeItems[] = + { + "Hold Key" , "Always" , "Toggle" + }; + + Combo( "Mode" , Settings::Ragebot::Mode , RageModeItems , IM_ARRAYSIZE( RageModeItems ) ); + + static const char* RageKeyItems[] = + { + "Alt" , "Shift" , "Ctrl" , "Mouse 4" , "Mouse 5" , "Q" , "E" , "F" , "X" , "C" , "V" , "B" , "Space" + }; + + static const int RageKeys[] = + { + 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( RageKeys ); i++ ) + { + if ( RageKeys[ i ] == Settings::Ragebot::Key ) + { + iKeyIdx = i; + break; + } + } + + if ( Combo( "Key" , iKeyIdx , RageKeyItems , IM_ARRAYSIZE( RageKeyItems ) ) ) + Settings::Ragebot::Key = RageKeys[ iKeyIdx ]; + + const char* HitboxItems[] = + { + "Head" , "Nearest" , "Chest" , "Stomach" , "Legs" + }; + + Combo( "Hitbox" , Settings::Ragebot::Hitbox , HitboxItems , IM_ARRAYSIZE( HitboxItems ) ); + + SliderInt( "FOV" , Settings::Ragebot::FOV , 1 , 180 ); + + ImGui::Separator(); + + Checkbox( "NoSpread" , Settings::Ragebot::NoSpread ); + Checkbox( "Auto Fire" , Settings::Ragebot::AutoFire ); + Checkbox( "Auto Stop" , Settings::Ragebot::AutoStop ); + Checkbox( "Recoil Control" , Settings::Ragebot::Recoil ); + Checkbox( "Teammates ignorieren" , Settings::Ragebot::IgnoreTeammates ); + Checkbox( "Nur sichtbar" , Settings::Ragebot::VisibleOnly ); + + ImGui::Separator(); + + SliderInt( "Hitchance (%)" , Settings::Ragebot::Hitchance , 0 , 100 , Settings::Ragebot::Hitchance > 0 ? "%d%%" : "%d (aus)" ); + + if ( Settings::Ragebot::Hitchance > 0 ) + SliderInt( "Hitchance Samples" , Settings::Ragebot::HitchanceSamples , 16 , 128 ); + } +} + auto CAndromedaMenu::RenderConfigPanel() -> void { ImGui::SeparatorText( "Menu" ); diff --git a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.hpp b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.hpp index 727bc23..b013de8 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/GUI/CAndromedaMenu.hpp @@ -16,6 +16,8 @@ private: auto RenderMusicPanel() -> void; auto RenderConfigPanel() -> void; auto RenderMiscPanel() -> void; + auto RenderLegitbotPanel() -> void; + auto RenderRagebotPanel() -> void; private: auto Checkbox( const char* szLabel , bool& bValue ) -> bool; 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 f5b85f9..ef4aca4 100644 --- a/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp +++ b/Andromeda-CS2-Base/Andromeda-CS2-Base/AndromedaClient/Settings/Settings.hpp @@ -88,6 +88,22 @@ namespace Settings inline auto HitchanceSamples = 64; inline auto SeedTrigger = false; // deterministic: only fire if the real bullet (current random_seed) would hit } + namespace Ragebot + { + inline auto Active = false; + inline auto Mode = 0; // 0 = Hold Key, 1 = Always, 2 = Toggle + inline auto Key = VK_MENU; // Alt + inline auto Hitbox = 0; // 0 = Head, 1 = Nearest, 2 = Chest, 3 = Stomach, 4 = Legs + inline auto FOV = 10; // degrees + inline auto Hitchance = 70; // percent, 0 = off + inline auto HitchanceSamples = 64; + inline auto AutoFire = true; + inline auto AutoStop = true; + inline auto NoSpread = true; + inline auto Recoil = true; + inline auto IgnoreTeammates = true; + inline auto VisibleOnly = true; + } namespace Colors { namespace Visual