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];
};