From 59c12526a0b62d222b243fbbfadb0cb309f417a0 Mon Sep 17 00:00:00 2001 From: rei-2 <174158077+rei-2@users.noreply.github.com> Date: Mon, 11 May 2026 22:39:26 -0400 Subject: [PATCH] move anticheat compatibility --- Amalgam/Amalgam.vcxproj | 3 + Amalgam/Amalgam.vcxproj.filters | 3 + .../Aimbot/AimbotHitscan/AimbotHitscan.cpp | 3 +- .../Aimbot/AimbotMelee/AimbotMelee.cpp | 3 +- .../AimbotProjectile/AimbotProjectile.cpp | 3 +- .../AntiCheatCompatibility.cpp | 123 ++++++++++++++++++ .../AntiCheatCompatibility.h | 33 +++++ Amalgam/src/Features/Backtrack/Backtrack.cpp | 11 +- Amalgam/src/Features/CritHack/CritHack.cpp | 7 +- Amalgam/src/Features/Misc/Misc.cpp | 19 +-- .../NoSpreadHitscan/NoSpreadHitscan.cpp | 4 + .../Features/PacketManip/AntiAim/AntiAim.cpp | 3 +- Amalgam/src/Features/Ticks/Ticks.cpp | 3 +- Amalgam/src/Features/Visuals/Visuals.cpp | 33 ++++- Amalgam/src/Features/Visuals/Visuals.h | 2 + .../CEngineClient_GetScreenAspectRatio.cpp | 10 ++ Amalgam/src/Hooks/CHLClient_CreateMove.cpp | 103 +-------------- Amalgam/src/Hooks/CNetChannel_SendNetMsg.cpp | 61 ++------- .../src/SDK/Definitions/Main/INetMessage.h | 2 +- 19 files changed, 242 insertions(+), 187 deletions(-) create mode 100644 Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.cpp create mode 100644 Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.h create mode 100644 Amalgam/src/Hooks/CEngineClient_GetScreenAspectRatio.cpp diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj index 8b1a94d6..9370a237 100644 --- a/Amalgam/Amalgam.vcxproj +++ b/Amalgam/Amalgam.vcxproj @@ -913,6 +913,7 @@ + @@ -964,6 +965,7 @@ + @@ -1222,6 +1224,7 @@ + diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters index f53d8c83..5a53a07b 100644 --- a/Amalgam/Amalgam.vcxproj.filters +++ b/Amalgam/Amalgam.vcxproj.filters @@ -205,6 +205,8 @@ + + @@ -620,6 +622,7 @@ + diff --git a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp index 5fb0b538..82b6635a 100644 --- a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp @@ -6,6 +6,7 @@ #include "../../NoSpread/NoSpread.h" #include "../../Simulation/MovementSimulation/MovementSimulation.h" #include "../../Visuals/Visuals.h" +#include "../../AntiCheatCompatibility/AntiCheatCompatibility.h" static inline std::vector GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) { @@ -616,7 +617,7 @@ bool CAimbotHitscan::Aim(const Vec3& vCurAngle, Vec3 vToAngle, Vec3& vOut, int i break; } - //if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value) + //if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || F::AntiCheatCompatibility.Active()) Math::ClampAngles(vOut); return bReturn; } diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index 1c781747..728b274e 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -5,6 +5,7 @@ #include "../../EnginePrediction/EnginePrediction.h" #include "../../Ticks/Ticks.h" #include "../../Visuals/Visuals.h" +#include "../../AntiCheatCompatibility/AntiCheatCompatibility.h" static inline bool AimFriendlyBuilding(CBaseObject* pBuilding) { @@ -463,7 +464,7 @@ bool CAimbotMelee::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& vOut, break; } - if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value) + if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || F::AntiCheatCompatibility.Active()) Math::ClampAngles(vOut); return bReturn; } diff --git a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp index 12a624ca..8f7cb41a 100644 --- a/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotProjectile/AimbotProjectile.cpp @@ -5,6 +5,7 @@ #include "../../EnginePrediction/EnginePrediction.h" #include "../../World/World.h" #include "../AutoAirblast/AutoAirblast.h" +#include "../../AntiCheatCompatibility/AntiCheatCompatibility.h" #include //#define SPLASH_DEBUG1 // trace splash visualization @@ -1759,7 +1760,7 @@ bool CAimbotProjectile::Aim(const Vec3& vCurAngle, const Vec3& vToAngle, Vec3& v break; } - if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || Vars::Misc::Game::AntiCheatCompatibility.Value) + if (iMethod != Vars::Aimbot::General::AimTypeEnum::Silent || F::AntiCheatCompatibility.Active()) Math::ClampAngles(vOut); return bReturn; } diff --git a/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.cpp b/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.cpp new file mode 100644 index 00000000..bd8bdd10 --- /dev/null +++ b/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.cpp @@ -0,0 +1,123 @@ +#include "AntiCheatCompatibility.h" + +#include "../Backtrack/Backtrack.h" +#include "../Misc/Misc.h" + +void CAntiCheatCompatibility::CreateMove(CUserCmd* pCmd, bool* pSendPacket) +{ + if (!Active()) + return; + + Math::ClampAngles(pCmd->viewangles); // shouldn't happen, but failsafe + + m_vHistory.emplace_front(pCmd->viewangles, pCmd->buttons & IN_ATTACK, pCmd->buttons & IN_ATTACK2, *pSendPacket); + if (m_vHistory.size() > 5) + m_vHistory.pop_back(); + if (m_vHistory.size() < 3) + return; + + // prevent trigger checks, though this shouldn't happen ordinarily + if (!m_vHistory[0].m_bAttack1 && m_vHistory[1].m_bAttack1 && !m_vHistory[2].m_bAttack1) + pCmd->buttons |= IN_ATTACK; + if (!m_vHistory[0].m_bAttack2 && m_vHistory[1].m_bAttack2 && !m_vHistory[2].m_bAttack2) + pCmd->buttons |= IN_ATTACK2; + + // don't care if we are actually attacking or not, a miss is less important than a detection + if (m_vHistory[0].m_bAttack1 || m_vHistory[1].m_bAttack1 || m_vHistory[2].m_bAttack1) + { + // prevent silent aim checks + if (Math::CalcFov(m_vHistory[0].m_vAngle, m_vHistory[1].m_vAngle) > PSILENT_EPSILON + && Math::CalcFov(m_vHistory[0].m_vAngle, m_vHistory[2].m_vAngle) < REAL_EPSILON) + { + pCmd->viewangles = m_vHistory[1].m_vAngle.LerpAngle(m_vHistory[0].m_vAngle, 0.5f); + if (Math::CalcFov(pCmd->viewangles, m_vHistory[2].m_vAngle) < REAL_EPSILON) + pCmd->viewangles = m_vHistory[0].m_vAngle + Vec3(0.f, REAL_EPSILON * 2); + m_vHistory[0].m_vAngle = pCmd->viewangles; + m_vHistory[0].m_bSendingPacket = *pSendPacket = m_vHistory[1].m_bSendingPacket; + } + + // prevent aim snap checks + if (m_vHistory.size() == 5) + { + float flDelta01 = Math::CalcFov(m_vHistory[0].m_vAngle, m_vHistory[1].m_vAngle); + float flDelta12 = Math::CalcFov(m_vHistory[1].m_vAngle, m_vHistory[2].m_vAngle); + float flDelta23 = Math::CalcFov(m_vHistory[2].m_vAngle, m_vHistory[3].m_vAngle); + float flDelta34 = Math::CalcFov(m_vHistory[3].m_vAngle, m_vHistory[4].m_vAngle); + + if ((flDelta12 > SNAP_SIZE_EPSILON && flDelta23 < SNAP_NOISE_EPSILON && m_vHistory[2].m_vAngle != m_vHistory[3].m_vAngle + || flDelta23 > SNAP_SIZE_EPSILON && flDelta12 < SNAP_NOISE_EPSILON && m_vHistory[1].m_vAngle != m_vHistory[2].m_vAngle) + && flDelta01 < SNAP_NOISE_EPSILON && m_vHistory[0].m_vAngle != m_vHistory[1].m_vAngle + && flDelta34 < SNAP_NOISE_EPSILON && m_vHistory[3].m_vAngle != m_vHistory[4].m_vAngle) + { + pCmd->viewangles.y += SNAP_NOISE_EPSILON * 2; + m_vHistory[0].m_vAngle = pCmd->viewangles; + m_vHistory[0].m_bSendingPacket = *pSendPacket = m_vHistory[1].m_bSendingPacket; + } + } + } +} + +void CAntiCheatCompatibility::RespondCvarValue(INetMessage& msg) +{ + if (!Active()) + return; + + auto pMsg = reinterpret_cast(&msg); + if (!pMsg->m_szCvarName) + return; + + auto pConVar = H::ConVars.FindVar(pMsg->m_szCvarName); + if (!pConVar) + return; + + switch (FNV1A::Hash32(pMsg->m_szCvarName)) + { + case FNV1A::Hash32Const("cl_interp"): + if (F::Backtrack.m_flSentInterp != -1.f) + m_sValue = std::to_string(std::min(F::Backtrack.m_flSentInterp, 0.1f)); + else + m_sValue = pConVar->GetString(); + break; + case FNV1A::Hash32Const("cl_interp_ratio"): + m_sValue = "1"; + break; + case FNV1A::Hash32Const("cl_cmdrate"): + if (F::Misc.m_iWishCmdrate != -1) + m_sValue = std::to_string(F::Misc.m_iWishCmdrate); + else + m_sValue = pConVar->GetString(); + break; + case FNV1A::Hash32Const("cl_updaterate"): + if (F::Misc.m_iWishUpdaterate != -1) + m_sValue = std::to_string(F::Misc.m_iWishUpdaterate); + else + m_sValue = pConVar->GetString(); + break; + case FNV1A::Hash32Const("mat_dxlevel"): + m_sValue = pConVar->GetString(); + break; + default: + m_sValue = pConVar->m_pParent->m_pszDefaultValue; + } + pMsg->m_szCvarValue = m_sValue.c_str(); + + SDK::Output("Convar spoof", std::format("{}: {} ({})", pMsg->m_szCvarName, pMsg->m_szCvarValue, msg.ToString()).c_str(), Vars::Menu::Theme::Accent.Value, Vars::Debug::Logging.Value); +} + +void CAntiCheatCompatibility::BunnyHop(CUserCmd* pCmd, bool bCurGrounded, bool bLastGrounded) +{ + if (!Active()) + return; + + // prevent more than 9 bhops occurring. if a server has this under that threshold they're retarded anyways + if (bCurGrounded) + { + if (!bLastGrounded && pCmd->buttons & IN_JUMP) + m_iJumps++; + else + m_iJumps = 0; + + if (m_iJumps > 9) + pCmd->buttons &= ~IN_JUMP; + } +} \ No newline at end of file diff --git a/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.h b/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.h new file mode 100644 index 00000000..dd8ed273 --- /dev/null +++ b/Amalgam/src/Features/AntiCheatCompatibility/AntiCheatCompatibility.h @@ -0,0 +1,33 @@ +#pragma once +#include "../../SDK/SDK.h" + +#define MATH_EPSILON (1.f / 16) +#define PSILENT_EPSILON (1.f - MATH_EPSILON) +#define REAL_EPSILON (0.1f + MATH_EPSILON) +#define SNAP_SIZE_EPSILON (10.f - MATH_EPSILON) +#define SNAP_NOISE_EPSILON (0.5f + MATH_EPSILON) + +struct CmdHistory_t +{ + Vec3 m_vAngle; + bool m_bAttack1; + bool m_bAttack2; + bool m_bSendingPacket; +}; + +class CAntiCheatCompatibility +{ +private: + std::deque m_vHistory; + std::string m_sValue = ""; + int m_iJumps = 0; + +public: + void CreateMove(CUserCmd* pCmd, bool* pSendPacket); + void BunnyHop(CUserCmd* pCmd, bool bCurGrounded, bool bLastGrounded); + void RespondCvarValue(INetMessage& msg); + + inline bool Active() { return Vars::Misc::Game::AntiCheatCompatibility.Value; } +}; + +ADD_FEATURE(CAntiCheatCompatibility, AntiCheatCompatibility); \ No newline at end of file diff --git a/Amalgam/src/Features/Backtrack/Backtrack.cpp b/Amalgam/src/Features/Backtrack/Backtrack.cpp index f8008bb3..c871d2ed 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.cpp +++ b/Amalgam/src/Features/Backtrack/Backtrack.cpp @@ -2,6 +2,7 @@ #include "../PacketManip/FakeLag/FakeLag.h" #include "../Ticks/Ticks.h" +#include "../AntiCheatCompatibility/AntiCheatCompatibility.h" void CBacktrack::Reset() { @@ -30,7 +31,7 @@ float CBacktrack::GetWishFake() float CBacktrack::GetWishLerp() { - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) return std::clamp(Vars::Backtrack::Interp.Value / 1000.f, G::Lerp, 0.1f); return std::clamp(Vars::Backtrack::Interp.Value / 1000.f, G::Lerp, m_flMaxUnlag); @@ -43,7 +44,7 @@ float CBacktrack::GetFakeLatency() float CBacktrack::GetFakeInterp() { - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) return std::min(m_flFakeInterp, 0.1f); return m_flFakeInterp; @@ -66,7 +67,7 @@ int CBacktrack::GetAnticipatedChoke(int iMethod) void CBacktrack::CreateMove(CUserCmd* pCmd) { - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) return; // correct tick_count for fakeinterp / nointerp @@ -152,7 +153,7 @@ std::vector CBacktrack::GetValidRecords(std::vector& v float flCorrect = std::clamp(GetReal(MAX_FLOWS, false) + ROUND_TO_TICKS(GetFakeInterp()), 0.f, m_flMaxUnlag) + flTimeMod; int iServerTick = m_iTickCount + TIME_TO_TICKS(GetReal(FLOW_OUTGOING)) + GetAnticipatedChoke() + Vars::Backtrack::Offset.Value; - if (!Vars::Misc::Game::AntiCheatCompatibility.Value && GetWindow()) + if (!F::AntiCheatCompatibility.Active() && GetWindow()) { for (auto pRecord : vRecords) { @@ -197,7 +198,7 @@ std::vector CBacktrack::GetValidRecords(std::vector& v float flBDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(b->m_flSimTime)); return fabsf(flADelta) < fabsf(flBDelta); }); - } + } return vReturn; } diff --git a/Amalgam/src/Features/CritHack/CritHack.cpp b/Amalgam/src/Features/CritHack/CritHack.cpp index 62722669..8b557bd5 100644 --- a/Amalgam/src/Features/CritHack/CritHack.cpp +++ b/Amalgam/src/Features/CritHack/CritHack.cpp @@ -1,6 +1,7 @@ #include "CritHack.h" #include "../Ticks/Ticks.h" +#include "../AntiCheatCompatibility/AntiCheatCompatibility.h" #define WEAPON_RANDOM_RANGE 10000 #define TF_DAMAGE_CRIT_MULTIPLIER 3.0f @@ -359,7 +360,7 @@ void CCritHack::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) if (iRequest == CritRequestEnum::Any) return; - if (!Vars::Misc::Game::AntiCheatCompatibility.Value) + if (!F::AntiCheatCompatibility.Active()) { if (int iCommand = GetCritCommand(pWeapon, pCmd->command_number, iRequest == CritRequestEnum::Crit)) { @@ -382,7 +383,7 @@ int CCritHack::PredictCmdNum(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd { auto fGetCmdNum = [&](int iCommandNumber) { - if (!pWeapon || !pLocal->IsAlive() || !I::EngineClient->IsInGame() || Vars::Misc::Game::AntiCheatCompatibility.Value + if (!pWeapon || !pLocal->IsAlive() || !I::EngineClient->IsInGame() || F::AntiCheatCompatibility.Active() || pLocal->IsCritBoosted() || pWeapon->m_flCritTime() > I::GlobalVars->curtime || !WeaponCanCrit(pWeapon)) return iCommandNumber; @@ -641,7 +642,7 @@ void CCritHack::Draw(CTFPlayer* pLocal) float flTickBase = TICKS_TO_TIME(pLocal->m_nTickBase()); - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) H::Draw.StringOutlined(fFont, x, y += nTall, Vars::Colors::IndicatorTextBad.Value, Vars::Menu::Theme::Background.Value, align, "Anticheat compatibility"); if (pLocal->IsCritBoosted()) diff --git a/Amalgam/src/Features/Misc/Misc.cpp b/Amalgam/src/Features/Misc/Misc.cpp index 0fa6ecc3..ace72360 100644 --- a/Amalgam/src/Features/Misc/Misc.cpp +++ b/Amalgam/src/Features/Misc/Misc.cpp @@ -4,6 +4,7 @@ #include "../Ticks/Ticks.h" #include "../Players/PlayerUtils.h" #include "../Aimbot/AutoRocketJump/AutoRocketJump.h" +#include "../AntiCheatCompatibility/AntiCheatCompatibility.h" void CMisc::RunPre(CTFPlayer* pLocal, CUserCmd* pCmd) { @@ -68,21 +69,7 @@ void CMisc::AutoJump(CTFPlayer* pLocal, CUserCmd* pCmd) if (!(pCmd->buttons & IN_JUMP) && bCurGrounded && !bLastAttempted) pCmd->buttons |= IN_JUMP; } - - if (Vars::Misc::Game::AntiCheatCompatibility.Value) - { // prevent more than 9 bhops occurring. if a server has this under that threshold they're retarded anyways - static int iJumps = 0; - if (bCurGrounded) - { - if (!bLastGrounded && pCmd->buttons & IN_JUMP) - iJumps++; - else - iJumps = 0; - - if (iJumps > 9) - pCmd->buttons &= ~IN_JUMP; - } - } + F::AntiCheatCompatibility.BunnyHop(pCmd, bCurGrounded, bLastGrounded); bLastAttempted = pCmd->buttons & IN_JUMP; } @@ -366,7 +353,7 @@ void CMisc::FastMovement(CTFPlayer* pLocal, CUserCmd* pCmd) case 1: { if ((pLocal->IsDucking() ? !Vars::Misc::Movement::DuckSpeed.Value : !Vars::Misc::Movement::FastAccelerate.Value) - || Vars::Misc::Game::AntiCheatCompatibility.Value + || F::AntiCheatCompatibility.Active() || G::Attacking == 1 || F::Ticks.m_bDoubletap || F::Ticks.m_bSpeedhack || F::Ticks.m_bRecharge || G::AntiAim) return; diff --git a/Amalgam/src/Features/NoSpread/NoSpreadHitscan/NoSpreadHitscan.cpp b/Amalgam/src/Features/NoSpread/NoSpreadHitscan/NoSpreadHitscan.cpp index 37e3be81..d87b03dd 100644 --- a/Amalgam/src/Features/NoSpread/NoSpreadHitscan/NoSpreadHitscan.cpp +++ b/Amalgam/src/Features/NoSpread/NoSpreadHitscan/NoSpreadHitscan.cpp @@ -1,6 +1,7 @@ #include "NoSpreadHitscan.h" #include "../../Ticks/Ticks.h" +#include "../../AntiCheatCompatibility/AntiCheatCompatibility.h" #include #include @@ -26,6 +27,9 @@ bool CNoSpreadHitscan::ShouldRun(CTFWeaponBase* pWeapon) : !Vars::Aimbot::General::NoSpread.Value || !I::EngineClient->IsInGame()) return false; + if (F::AntiCheatCompatibility.Active()) + return false; + return true; } diff --git a/Amalgam/src/Features/PacketManip/AntiAim/AntiAim.cpp b/Amalgam/src/Features/PacketManip/AntiAim/AntiAim.cpp index c9b60c4e..672cf0cd 100644 --- a/Amalgam/src/Features/PacketManip/AntiAim/AntiAim.cpp +++ b/Amalgam/src/Features/PacketManip/AntiAim/AntiAim.cpp @@ -4,6 +4,7 @@ #include "../../Players/PlayerUtils.h" #include "../../Misc/Misc.h" #include "../../Aimbot/AutoRocketJump/AutoRocketJump.h" +#include "../../AntiCheatCompatibility/AntiCheatCompatibility.h" bool CAntiAim::AntiAimOn() { @@ -240,7 +241,7 @@ void CAntiAim::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, bo vAngles.x = iAntiBackstab != 2 ? GetPitch(pCmd->viewangles.x) : pCmd->viewangles.x; vAngles.y = !iAntiBackstab ? GetYaw(pLocal, pCmd, bSendPacket) : pCmd->viewangles.y; - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) Math::ClampAngles(vAngles); SDK::FixMovement(pCmd, vAngles); pCmd->viewangles.x = vAngles.x; diff --git a/Amalgam/src/Features/Ticks/Ticks.cpp b/Amalgam/src/Features/Ticks/Ticks.cpp index 37d91967..eb96a17a 100644 --- a/Amalgam/src/Features/Ticks/Ticks.cpp +++ b/Amalgam/src/Features/Ticks/Ticks.cpp @@ -4,6 +4,7 @@ #include "../EnginePrediction/EnginePrediction.h" #include "../Aimbot/AutoRocketJump/AutoRocketJump.h" #include "../Backtrack/Backtrack.h" +#include "../AntiCheatCompatibility/AntiCheatCompatibility.h" void CTicks::Reset() { @@ -239,7 +240,7 @@ void CTicks::MoveManage() static auto sv_maxusrcmdprocessticks = H::ConVars.FindVar("sv_maxusrcmdprocessticks"); m_iMaxUsrCmdProcessTicks = sv_maxusrcmdprocessticks->GetInt(); - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) m_iMaxUsrCmdProcessTicks = std::min(m_iMaxUsrCmdProcessTicks, 8); m_iMaxShift = m_iMaxUsrCmdProcessTicks - std::max(m_iMaxUsrCmdProcessTicks - Vars::Doubletap::RechargeLimit.Value, 0) - (F::AntiAim.YawOn() ? F::AntiAim.AntiAimTicks() : 0); m_iMaxShift = std::max(m_iMaxShift, 1); diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp index 95892d8a..5fd11d21 100644 --- a/Amalgam/src/Features/Visuals/Visuals.cpp +++ b/Amalgam/src/Features/Visuals/Visuals.cpp @@ -9,6 +9,7 @@ #include "../Spectate/Spectate.h" #include "../CritHack/CritHack.h" #include "../Ticks/Ticks.h" +#include "FakeAngle/FakeAngle.h" #include "../World/World.h" MAKE_SIGNATURE(UTIL_PlayerByIndex, "server.dll", "48 83 EC ? 8B D1 85 C9 7E ? 48 8B 05", 0x0); @@ -1189,12 +1190,6 @@ void CVisuals::CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) if (Vars::Visuals::Effects::SpellFootsteps.Value && (F::Ticks.m_bDoubletap || F::Ticks.m_bWarp)) pLocal->FireEvent(pLocal->GetAbsOrigin(), QAngle(), 7001, nullptr); - static auto r_aspectratio = H::ConVars.FindVar("r_aspectratio"); - static float flOldRatio = 0.f; - float flNewRatio = Vars::Visuals::UI::AspectRatio.Value; - if (flNewRatio != flOldRatio) - r_aspectratio->SetValue(flOldRatio = flNewRatio); - DrawHitboxes(2); #ifdef WORLD_DEBUG @@ -1242,4 +1237,30 @@ void CVisuals::CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon) } } #endif +} + +void CVisuals::LocalAnimations(CTFPlayer* pLocal, CUserCmd* pCmd, bool bSendPacket) +{ + m_vAngles.push_back(pCmd->viewangles); + + auto pAnimState = pLocal->m_PlayerAnimState(); + if (!bSendPacket || !pAnimState) + return; + + float flOldFrametime = I::GlobalVars->frametime; + float flOldCurtime = I::GlobalVars->curtime; + I::GlobalVars->frametime = TICK_INTERVAL; + I::GlobalVars->curtime = TICKS_TO_TIME(pLocal->m_nTickBase()); + for (auto& vAngle : m_vAngles) + { + if (pLocal->IsTaunting() && pLocal->m_bAllowMoveDuringTaunt()) + pLocal->m_flTauntYaw() = vAngle.y; + pAnimState->Update(pAnimState->m_flEyeYaw = vAngle.y, vAngle.x); + pLocal->FrameAdvance(TICK_INTERVAL); + } + I::GlobalVars->frametime = flOldFrametime; + I::GlobalVars->curtime = flOldCurtime; + m_vAngles.clear(); + + F::FakeAngle.Run(pLocal); } \ No newline at end of file diff --git a/Amalgam/src/Features/Visuals/Visuals.h b/Amalgam/src/Features/Visuals/Visuals.h index 0d1aa392..9a9344ae 100644 --- a/Amalgam/src/Features/Visuals/Visuals.h +++ b/Amalgam/src/Features/Visuals/Visuals.h @@ -44,6 +44,7 @@ private: std::unordered_map m_mProjectiles = {}; std::vector m_vSightLines = {}; std::vector m_vPickups = {}; + std::vector m_vAngles = {}; #ifdef DEBUG_TEXT std::vector m_vDebugText = {}; @@ -78,6 +79,7 @@ public: void RestoreWorldModulation(); void CreateMove(CTFPlayer* pLocal, CTFWeaponBase* pWeapon); + void LocalAnimations(CTFPlayer* pLocal, CUserCmd* pCmd, bool bSendPacket); }; ADD_FEATURE(CVisuals, Visuals); \ No newline at end of file diff --git a/Amalgam/src/Hooks/CEngineClient_GetScreenAspectRatio.cpp b/Amalgam/src/Hooks/CEngineClient_GetScreenAspectRatio.cpp new file mode 100644 index 00000000..d812402b --- /dev/null +++ b/Amalgam/src/Hooks/CEngineClient_GetScreenAspectRatio.cpp @@ -0,0 +1,10 @@ +#include "../SDK/SDK.h" + +MAKE_HOOK(CEngineClient_GetScreenAspectRatio, U::Memory.GetVirtual(I::EngineClient, 95), float, + void* rcx) +{ + if (Vars::Visuals::UI::AspectRatio.Value) + return Vars::Visuals::UI::AspectRatio.Value; + + return CALL_ORIGINAL(rcx); +} \ No newline at end of file diff --git a/Amalgam/src/Hooks/CHLClient_CreateMove.cpp b/Amalgam/src/Hooks/CHLClient_CreateMove.cpp index bead961f..09f33f42 100644 --- a/Amalgam/src/Hooks/CHLClient_CreateMove.cpp +++ b/Amalgam/src/Hooks/CHLClient_CreateMove.cpp @@ -13,23 +13,10 @@ #include "../Features/Visuals/Visuals.h" #include "../Features/Visuals/FakeAngle/FakeAngle.h" #include "../Features/Spectate/Spectate.h" - -#define MATH_EPSILON (1.f / 16) -#define PSILENT_EPSILON (1.f - MATH_EPSILON) -#define REAL_EPSILON (0.1f + MATH_EPSILON) -#define SNAP_SIZE_EPSILON (10.f - MATH_EPSILON) -#define SNAP_NOISE_EPSILON (0.5f + MATH_EPSILON) +#include "../Features/AntiCheatCompatibility/AntiCheatCompatibility.h" MAKE_SIGNATURE(IHasGenericMeter_GetMeterMultiplier, "client.dll", "F3 0F 10 81 ? ? ? ? C3 CC CC CC CC CC CC CC 48 85 D2", 0x0); -struct CmdHistory_t -{ - Vec3 m_vAngle; - bool m_bAttack1; - bool m_bAttack2; - bool m_bSendingPacket; -}; - static inline void UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd) { G::PSilentAngles = G::SilentAngles = G::Attacking = G::Throwing = false; @@ -144,90 +131,6 @@ static inline void UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm G::CanHeadshot = pWeapon->CanHeadshot() || pWeapon->AmbassadorCanHeadshot(TICKS_TO_TIME(pLocal->m_nTickBase())); } -static inline void LocalAnimations(CTFPlayer* pLocal, CUserCmd* pCmd, bool bSendPacket) -{ - static std::vector vAngles = {}; - vAngles.push_back(pCmd->viewangles); - auto pAnimState = pLocal->m_PlayerAnimState(); - if (bSendPacket && pAnimState) - { - float flOldFrametime = I::GlobalVars->frametime; - float flOldCurtime = I::GlobalVars->curtime; - I::GlobalVars->frametime = TICK_INTERVAL; - I::GlobalVars->curtime = TICKS_TO_TIME(pLocal->m_nTickBase()); - for (auto& vAngle : vAngles) - { - if (pLocal->IsTaunting() && pLocal->m_bAllowMoveDuringTaunt()) - pLocal->m_flTauntYaw() = vAngle.y; - pAnimState->Update(pAnimState->m_flEyeYaw = vAngle.y, vAngle.x); - pLocal->FrameAdvance(TICK_INTERVAL); - } - I::GlobalVars->frametime = flOldFrametime; - I::GlobalVars->curtime = flOldCurtime; - vAngles.clear(); - - F::FakeAngle.Run(pLocal); - } -} - -static inline void AntiCheatCompatibility(CUserCmd* pCmd, bool* pSendPacket) -{ - if (!Vars::Misc::Game::AntiCheatCompatibility.Value) - return; - - Math::ClampAngles(pCmd->viewangles); // shouldn't happen, but failsafe - - static std::deque vHistory; - vHistory.emplace_front(pCmd->viewangles, pCmd->buttons & IN_ATTACK, pCmd->buttons & IN_ATTACK2, *pSendPacket); - if (vHistory.size() > 5) - vHistory.pop_back(); - - if (vHistory.size() < 3) - return; - - // prevent trigger checks, though this shouldn't happen ordinarily - if (!vHistory[0].m_bAttack1 && vHistory[1].m_bAttack1 && !vHistory[2].m_bAttack1) - pCmd->buttons |= IN_ATTACK; - if (!vHistory[0].m_bAttack2 && vHistory[1].m_bAttack2 && !vHistory[2].m_bAttack2) - pCmd->buttons |= IN_ATTACK2; - - // don't care if we are actually attacking or not, a miss is less important than a detection - if (vHistory[0].m_bAttack1 || vHistory[1].m_bAttack1 || vHistory[2].m_bAttack1) - { - // prevent silent aim checks - if (Math::CalcFov(vHistory[0].m_vAngle, vHistory[1].m_vAngle) > PSILENT_EPSILON - && Math::CalcFov(vHistory[0].m_vAngle, vHistory[2].m_vAngle) < REAL_EPSILON) - { - pCmd->viewangles = vHistory[1].m_vAngle.LerpAngle(vHistory[0].m_vAngle, 0.5f); - if (Math::CalcFov(pCmd->viewangles, vHistory[2].m_vAngle) < REAL_EPSILON) - pCmd->viewangles = vHistory[0].m_vAngle + Vec3(0.f, REAL_EPSILON * 2); - vHistory[0].m_vAngle = pCmd->viewangles; - vHistory[0].m_bSendingPacket = *pSendPacket = vHistory[1].m_bSendingPacket; - } - - // prevent aim snap checks - if (vHistory.size() == 5) - { - float flDelta01 = Math::CalcFov(vHistory[0].m_vAngle, vHistory[1].m_vAngle); - float flDelta12 = Math::CalcFov(vHistory[1].m_vAngle, vHistory[2].m_vAngle); - float flDelta23 = Math::CalcFov(vHistory[2].m_vAngle, vHistory[3].m_vAngle); - float flDelta34 = Math::CalcFov(vHistory[3].m_vAngle, vHistory[4].m_vAngle); - - if (( - flDelta12 > SNAP_SIZE_EPSILON && flDelta23 < SNAP_NOISE_EPSILON && vHistory[2].m_vAngle != vHistory[3].m_vAngle - || flDelta23 > SNAP_SIZE_EPSILON && flDelta12 < SNAP_NOISE_EPSILON && vHistory[1].m_vAngle != vHistory[2].m_vAngle - ) - && flDelta01 < SNAP_NOISE_EPSILON && vHistory[0].m_vAngle != vHistory[1].m_vAngle - && flDelta34 < SNAP_NOISE_EPSILON && vHistory[3].m_vAngle != vHistory[4].m_vAngle) - { - pCmd->viewangles.y += SNAP_NOISE_EPSILON * 2; - vHistory[0].m_vAngle = pCmd->viewangles; - vHistory[0].m_bSendingPacket = *pSendPacket = vHistory[1].m_bSendingPacket; - } - } - } -} - MAKE_HOOK(CHLClient_CreateMove, U::Memory.GetVirtual(I::Client, 21), void, void* rcx, int sequence_number, float input_sample_frametime, bool active) { @@ -263,8 +166,8 @@ MAKE_HOOK(CHLClient_CreateMove, U::Memory.GetVirtual(I::Client, 21), void, F::NoSpreadHitscan.AskForPlayerPerf(); F::EnginePrediction.End(pLocal, pCmd); - AntiCheatCompatibility(pCmd, pSendPacket); - LocalAnimations(pLocal, pCmd, *pSendPacket); + F::AntiCheatCompatibility.CreateMove(pCmd, pSendPacket); + F::Visuals.LocalAnimations(pLocal, pCmd, *pSendPacket); G::Choking = !*pSendPacket; G::LastUserCmd = pCmd; diff --git a/Amalgam/src/Hooks/CNetChannel_SendNetMsg.cpp b/Amalgam/src/Hooks/CNetChannel_SendNetMsg.cpp index 4d0d300d..0ff1b3fd 100644 --- a/Amalgam/src/Hooks/CNetChannel_SendNetMsg.cpp +++ b/Amalgam/src/Hooks/CNetChannel_SendNetMsg.cpp @@ -3,6 +3,7 @@ #include "../Features/Ticks/Ticks.h" #include "../Features/Backtrack/Backtrack.h" #include "../Features/Misc/Misc.h" +#include "../Features/AntiCheatCompatibility/AntiCheatCompatibility.h" MAKE_SIGNATURE(CNetChannel_SendNetMsg, "engine.dll", "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 48 8B F1 45 0F B6 F1", 0x0); @@ -26,7 +27,7 @@ MAKE_HOOK(CNetChannel_SendNetMsg, S::CNetChannel_SendNetMsg(), bool, case FNV1A::Hash32Const("cl_interp"): if (F::Backtrack.m_flSentInterp != -1.f) strncpy_s(localCvar->Value, std::to_string(F::Backtrack.m_flSentInterp).c_str(), MAX_OSPATH); - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) { try { float flValue = std::stof(localCvar->Value); strncpy_s(localCvar->Value, std::to_string(std::min(flValue, 0.1f)).c_str(), MAX_OSPATH); @@ -35,7 +36,7 @@ MAKE_HOOK(CNetChannel_SendNetMsg, S::CNetChannel_SendNetMsg(), bool, case FNV1A::Hash32Const("cl_cmdrate"): if (F::Misc.m_iWishCmdrate != -1) strncpy_s(localCvar->Value, std::to_string(F::Misc.m_iWishCmdrate).c_str(), MAX_OSPATH); - if (Vars::Misc::Game::AntiCheatCompatibility.Value) + if (F::AntiCheatCompatibility.Active()) { try { int iValue = std::stof(localCvar->Value); strncpy_s(localCvar->Value, std::to_string(std::max(iValue, 10)).c_str(), MAX_OSPATH); @@ -65,57 +66,11 @@ MAKE_HOOK(CNetChannel_SendNetMsg, S::CNetChannel_SendNetMsg(), bool, } break; } - case clc_VoiceData: - // stop lag with voice chat - bVoice = true; - break; case clc_RespondCvarValue: - if (Vars::Misc::Game::AntiCheatCompatibility.Value) - { - auto pMsg = reinterpret_cast(&msg); - if (!pMsg) break; - - auto cvarName = reinterpret_cast(pMsg[6]); - if (!cvarName) break; - - auto pConVar = H::ConVars.FindVar(cvarName); - if (!pConVar) break; - - static std::string sValue = ""; - switch (FNV1A::Hash32(cvarName)) - { - case FNV1A::Hash32Const("cl_interp"): - if (F::Backtrack.m_flSentInterp != -1.f) - sValue = std::to_string(std::min(F::Backtrack.m_flSentInterp, 0.1f)); - else - sValue = pConVar->GetString(); - break; - case FNV1A::Hash32Const("cl_interp_ratio"): - sValue = "1"; - break; - case FNV1A::Hash32Const("cl_cmdrate"): - if (F::Misc.m_iWishCmdrate != -1) - sValue = std::to_string(F::Misc.m_iWishCmdrate); - else - sValue = pConVar->GetString(); - break; - case FNV1A::Hash32Const("cl_updaterate"): - if (F::Misc.m_iWishUpdaterate != -1) - sValue = std::to_string(F::Misc.m_iWishUpdaterate); - else - sValue = pConVar->GetString(); - break; - case FNV1A::Hash32Const("mat_dxlevel"): - sValue = pConVar->GetString(); - break; - default: - sValue = pConVar->m_pParent->m_pszDefaultValue; - } - pMsg[7] = uintptr_t(sValue.c_str()); - - SDK::Output("Convar spoof", msg.ToString(), Vars::Menu::Theme::Accent.Value, Vars::Debug::Logging.Value); - } + { + F::AntiCheatCompatibility.RespondCvarValue(msg); break; + } case clc_Move: { const auto pMsg = reinterpret_cast(&msg); @@ -163,6 +118,10 @@ MAKE_HOOK(CNetChannel_SendNetMsg, S::CNetChannel_SendNetMsg(), bool, return true; } + case clc_VoiceData: + // stop lag with voice chat + bVoice = true; + break; } return CALL_ORIGINAL(pNetChan, msg, bForceReliable, bVoice); diff --git a/Amalgam/src/SDK/Definitions/Main/INetMessage.h b/Amalgam/src/SDK/Definitions/Main/INetMessage.h index f374809e..11f4a41f 100644 --- a/Amalgam/src/SDK/Definitions/Main/INetMessage.h +++ b/Amalgam/src/SDK/Definitions/Main/INetMessage.h @@ -276,7 +276,7 @@ public: int m_eStatusCode; -private: +public: char m_szCvarNameBuffer[256]; char m_szCvarValueBuffer[256]; };