From 8a5264e5671607390cb5d78c2e6fdb28a32c562d Mon Sep 17 00:00:00 2001 From: rei-2 <174158077+rei-2@users.noreply.github.com> Date: Thu, 23 Jan 2025 12:02:12 -0500 Subject: [PATCH] fixes to melee aim always include at least 1 bt record if we can --- .../Aimbot/AimbotGlobal/AimbotGlobal.h | 2 +- .../Aimbot/AimbotHitscan/AimbotHitscan.cpp | 14 ++-- .../Aimbot/AimbotMelee/AimbotMelee.cpp | 83 ++++++++----------- .../Features/Aimbot/AimbotMelee/AimbotMelee.h | 2 +- Amalgam/src/Features/Backtrack/Backtrack.cpp | 64 +++++++------- Amalgam/src/Features/Backtrack/Backtrack.h | 4 +- .../src/Hooks/CBasePlayer_ItemPostFrame.cpp | 3 - Amalgam/src/SDK/Definitions/Main/CModel.h | 6 +- 8 files changed, 80 insertions(+), 98 deletions(-) diff --git a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.h b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.h index 51e3afda..48e4efa6 100644 --- a/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.h +++ b/Amalgam/src/Features/Aimbot/AimbotGlobal/AimbotGlobal.h @@ -25,7 +25,7 @@ struct Target_t int m_nPriority = 0; int m_nAimedHitbox = -1; - TickRecord m_Tick = {}; + TickRecord m_tRecord = {}; bool m_bBacktrack = false; }; diff --git a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp index ec4d03bb..c6ac4d66 100644 --- a/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotHitscan/AimbotHitscan.cpp @@ -306,13 +306,13 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p }; int iReturn = false; - for (auto& pTick : vRecords) + for (auto& tRecord : vRecords) { bool bRunPeekCheck = flSpread && (Vars::Aimbot::General::PeekDTOnly.Value ? F::Ticks.GetTicks(pWeapon) : true) && Vars::Aimbot::General::HitscanPeek.Value; if (target.m_TargetType == ETargetType::Player || target.m_TargetType == ETargetType::Sentry) { - auto aBones = pTick.m_BoneMatrix.m_aBones; + auto aBones = tRecord.m_BoneMatrix.m_aBones; if (!aBones) continue; @@ -423,9 +423,9 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p } if (bWillHit) { - flPreferredRecord = pTick.m_flSimTime; + flPreferredRecord = tRecord.m_flSimTime; - target.m_Tick = pTick; + target.m_tRecord = tRecord; target.m_vPos = vTransformed; target.m_nAimedHitbox = pair.second; if (target.m_TargetType == ETargetType::Player) @@ -483,7 +483,7 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p target.m_vAngleTo = vAngles; if (RayToOBB(vEyePos, vForward, vMins, vMaxs, transform)) // for the time being, no vischecks against other hitboxes { - target.m_Tick = pTick; + target.m_tRecord = tRecord; target.m_vPos = vTransformed; return true; } @@ -743,7 +743,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC F::Resolver.Aimbot(target.m_pEntity->As(), target.m_nAimedHitbox == HITBOX_HEAD); if (target.m_bBacktrack) - pCmd->tick_count = TIME_TO_TICKS(target.m_Tick.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp); + pCmd->tick_count = TIME_TO_TICKS(target.m_tRecord.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp); bool bLine = Vars::Visuals::Bullet::Enabled.Value; bool bBoxes = Vars::Visuals::Hitbox::Enabled.Value & Vars::Visuals::Hitbox::EnabledEnum::OnShot; @@ -757,7 +757,7 @@ void CAimbotHitscan::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pC G::LineStorage.push_back({ { pLocal->GetShootPos(), target.m_vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true }); if (bBoxes) { - auto vBoxes = F::Visuals.GetHitboxes(target.m_Tick.m_BoneMatrix.m_aBones, target.m_pEntity->As(), {}, target.m_nAimedHitbox); + auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As(), {}, target.m_nAimedHitbox); G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end()); } } diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index f19895f0..dddf444c 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -258,28 +258,20 @@ bool CAimbotMelee::CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEy return true; } -int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque newRecords) +int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque& vSimRecords) { if (Vars::Aimbot::General::Ignore.Value & Vars::Aimbot::General::IgnoreEnum::Unsimulated && H::Entities.GetChoke(target.m_pEntity->entindex()) > Vars::Aimbot::General::TickTolerance.Value) return false; float flHull = SDK::AttribHookValue(18, "melee_bounds_multiplier", pWeapon); - float flRange = pWeapon->GetSwingRange(pLocal); + float flRange = SDK::AttribHookValue(pWeapon->GetSwingRange(pLocal), "melee_range_multiplier", pWeapon); if (pLocal->m_flModelScale() > 1.0f) { flRange *= pLocal->m_flModelScale(); - flRange *= pLocal->m_flModelScale(); - flRange *= pLocal->m_flModelScale(); + flHull *= pLocal->m_flModelScale(); } - flRange = SDK::AttribHookValue(flRange, "melee_range_multiplier", pWeapon); - if (flHull <= 0.f || flRange <= 0.f) - return false; - - static Vec3 vSwingMins = { -flHull, -flHull, -flHull }; - static Vec3 vSwingMaxs = { flHull, flHull, flHull }; - - CGameTrace trace = {}; - CTraceFilterHitscan filter = {}; filter.pSkip = pLocal; + Vec3 vSwingMins = { -flHull, -flHull, -flHull }; + Vec3 vSwingMaxs = { flHull, flHull, flHull }; std::deque vRecords; { @@ -319,50 +311,44 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe } } } - if (!newRecords.empty()) + if (!vSimRecords.empty()) { - for (TickRecord& pTick : newRecords) + for (TickRecord& tRecord : vSimRecords) { vRecords.pop_back(); - vRecords.push_front({ pTick.m_flSimTime, {}, pTick.m_vOrigin }); + vRecords.push_front({ tRecord.m_flSimTime, {}, tRecord.m_vOrigin, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs() }); } - for (TickRecord& pTick : vRecords) - pTick.m_flSimTime -= TICKS_TO_TIME(newRecords.size()); + for (TickRecord& tRecord : vRecords) + tRecord.m_flSimTime -= TICKS_TO_TIME(vSimRecords.size()); } - std::deque validRecords = target.m_TargetType == ETargetType::Player ? F::Backtrack.GetValidRecords(&vRecords, pLocal, true) : vRecords; - if (!Vars::Backtrack::Enabled.Value && !validRecords.empty()) - validRecords = { validRecords.front() }; + vRecords = target.m_TargetType == ETargetType::Player ? F::Backtrack.GetValidRecords(&vRecords, pLocal, true) : vRecords; + if (!Vars::Backtrack::Enabled.Value && !vRecords.empty()) + vRecords = { vRecords.front() }; - // this might be retarded - const float flTargetPos = (target.m_pEntity->m_vecMaxs().z - target.m_pEntity->m_vecMins().z) * 65.f / 82.f; - const float flLocalPos = (pLocal->m_vecMaxs().z - pLocal->m_vecMins().z) * 65.f / 82.f; - const Vec3 vDiff = { 0, 0, std::min(flTargetPos, flLocalPos) }; - - auto originTolerance = [target](float flTolerance) - { - target.m_pEntity->m_vecMins() += flTolerance; - target.m_pEntity->m_vecMaxs() -= flTolerance; - }; - - // account for origin tolerance - originTolerance(0.125f); - - for (auto& pTick : validRecords) + CGameTrace trace = {}; + CTraceFilterHitscan filter = {}; filter.pSkip = pLocal; + for (auto& tRecord : vRecords) { - const Vec3 vRestore = target.m_pEntity->GetAbsOrigin(); - target.m_pEntity->SetAbsOrigin(pTick.m_vOrigin); + Vec3 vRestoreOrigin = target.m_pEntity->GetAbsOrigin(); + Vec3 vRestoreMins = target.m_pEntity->m_vecMins(); + Vec3 vRestoreMaxs = target.m_pEntity->m_vecMaxs(); - target.m_vPos = pTick.m_vOrigin + vDiff; + target.m_pEntity->SetAbsOrigin(tRecord.m_vOrigin); + target.m_pEntity->m_vecMins() = tRecord.m_vMins + 0.125f; // account for origin tolerance + target.m_pEntity->m_vecMaxs() = tRecord.m_vMaxs - 0.125f; + + Vec3 vDiff = { 0, 0, std::clamp(vEyePos.z - tRecord.m_vOrigin.z, target.m_pEntity->m_vecMins().z, target.m_pEntity->m_vecMaxs().z) }; + target.m_vPos = tRecord.m_vOrigin + vDiff; target.m_vAngleTo = Aim(G::CurrentUserCmd->viewangles, Math::CalcAngle(vEyePos, target.m_vPos)); Vec3 vForward; Math::AngleVectors(target.m_vAngleTo, &vForward); Vec3 vTraceEnd = vEyePos + (vForward * flRange); - SDK::Trace(vEyePos, vTraceEnd, MASK_SHOT | CONTENTS_GRATE, &filter, &trace); + SDK::TraceHull(vEyePos, vTraceEnd, {}, {}, MASK_SOLID, &filter, &trace); bool bReturn = trace.m_pEnt && trace.m_pEnt == target.m_pEntity; if (!bReturn) { - SDK::TraceHull(vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SHOT | CONTENTS_GRATE, &filter, &trace); + SDK::TraceHull(vEyePos, vTraceEnd, vSwingMins, vSwingMaxs, MASK_SOLID, &filter, &trace); bReturn = trace.m_pEnt && trace.m_pEnt == target.m_pEntity; } @@ -374,14 +360,15 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe bReturn = false; } - target.m_pEntity->SetAbsOrigin(vRestore); + target.m_pEntity->SetAbsOrigin(vRestoreOrigin); + target.m_pEntity->m_vecMins() = vRestoreMins; + target.m_pEntity->m_vecMaxs() = vRestoreMaxs; if (bReturn) { - target.m_Tick = pTick; + target.m_tRecord = tRecord; target.m_bBacktrack = target.m_TargetType == ETargetType::Player /*&& Vars::Backtrack::Enabled.Value*/; - originTolerance(-0.125f); return true; } else if (Vars::Aimbot::General::AimType.Value == Vars::Aimbot::General::AimTypeEnum::Smooth) @@ -393,14 +380,10 @@ int CAimbotMelee::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWe SDK::Trace(vEyePos, vTraceEnd, MASK_SHOT | CONTENTS_GRATE, &filter, &trace); if (trace.m_pEnt && trace.m_pEnt == target.m_pEntity) - { - originTolerance(-0.125f); return 2; - } } } - originTolerance(-0.125f); return false; } @@ -508,7 +491,7 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd if (G::Attacking == 1) { if (target.m_bBacktrack) - pCmd->tick_count = TIME_TO_TICKS(target.m_Tick.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp); + pCmd->tick_count = TIME_TO_TICKS(target.m_tRecord.m_flSimTime) + TIME_TO_TICKS(F::Backtrack.m_flFakeInterp); // bug: fast old records seem to be progressively more unreliable ? } @@ -525,7 +508,7 @@ void CAimbotMelee::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd G::LineStorage.push_back({ { vEyePos, target.m_vPos }, I::GlobalVars->curtime + 5.f, Vars::Colors::Bullet.Value, true }); if (bBoxes) { - auto vBoxes = F::Visuals.GetHitboxes(target.m_Tick.m_BoneMatrix.m_aBones, target.m_pEntity->As()); + auto vBoxes = F::Visuals.GetHitboxes(target.m_tRecord.m_BoneMatrix.m_aBones, target.m_pEntity->As()); G::BoxStorage.insert(G::BoxStorage.end(), vBoxes.begin(), vBoxes.end()); } if (bPath) diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h index 840321fc..cfdfb72b 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.h @@ -14,7 +14,7 @@ class CAimbotMelee std::unordered_map>& pRecordMap, std::unordered_map>& mPaths); bool CanBackstab(CBaseEntity* pTarget, CTFPlayer* pLocal, Vec3 vEyeAngles); - int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque newRecords); + int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Vec3 vEyePos, std::deque& vSimRecords); Vec3 Aim(Vec3 vCurAngle, Vec3 vToAngle, int iMethod = Vars::Aimbot::General::AimType.Value); void Aim(CUserCmd* pCmd, Vec3& vAngle); diff --git a/Amalgam/src/Features/Backtrack/Backtrack.cpp b/Amalgam/src/Features/Backtrack/Backtrack.cpp index 527b7ec4..0c77160e 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.cpp +++ b/Amalgam/src/Features/Backtrack/Backtrack.cpp @@ -92,20 +92,6 @@ void CBacktrack::UpdateDatagram() -bool CBacktrack::WithinRewind(const TickRecord& record) -{ - auto pNetChan = I::EngineClient->GetNetChannelInfo(); - if (!pNetChan) - return false; - - const float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING); - const int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value; - - const float flDelta = flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(record.m_flSimTime)); - - return fabsf(flDelta) < float(Vars::Backtrack::Window.Value) / 1000; -} - std::deque* CBacktrack::GetRecords(CBaseEntity* pEntity) { if (m_mRecords[pEntity].empty()) @@ -116,22 +102,43 @@ std::deque* CBacktrack::GetRecords(CBaseEntity* pEntity) std::deque CBacktrack::GetValidRecords(std::deque* pRecords, CTFPlayer* pLocal, bool bDistance) { - std::deque validRecords = {}; - if (!pRecords) - return validRecords; + std::deque vRecords = {}; + if (!pRecords || pRecords->empty()) + return vRecords; - for (auto& pTick : *pRecords) + auto pNetChan = I::EngineClient->GetNetChannelInfo(); + if (!pNetChan) + return vRecords; + + float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING); + int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value; + + for (auto& tRecord : *pRecords) { - if (!WithinRewind(pTick)) + float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(tRecord.m_flSimTime))); + if (flDelta > float(Vars::Backtrack::Window.Value) / 1000) continue; - validRecords.push_back(pTick); + vRecords.push_back(tRecord); } - if (pLocal) + if (vRecords.empty()) + { // make sure there is at least 1 record + float flMinDelta = 0.2f; + for (auto& tRecord : *pRecords) + { + float flDelta = fabsf(flCorrect - TICKS_TO_TIME(iServerTick - TIME_TO_TICKS(tRecord.m_flSimTime))); + if (flDelta > flMinDelta) + continue; + + flMinDelta = flDelta; + vRecords = { tRecord }; + } + } + else if (pLocal && vRecords.size() > 1) { if (bDistance) - std::sort(validRecords.begin(), validRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool + std::sort(vRecords.begin(), vRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool { if (Vars::Backtrack::PreferOnShot.Value && a.m_bOnShot != b.m_bOnShot) return a.m_bOnShot > b.m_bOnShot; @@ -140,14 +147,7 @@ std::deque CBacktrack::GetValidRecords(std::deque* pReco }); else { - auto pNetChan = I::EngineClient->GetNetChannelInfo(); - if (!pNetChan) - return validRecords; - - const float flCorrect = std::clamp(pNetChan->GetLatency(FLOW_OUTGOING) + ROUND_TO_TICKS(m_flFakeInterp) + ROUND_TO_TICKS(m_flFakeLatency), 0.f, m_flMaxUnlag) - pNetChan->GetLatency(FLOW_OUTGOING); - const int iServerTick = m_iTickCount + G::AnticipatedChoke + Vars::Backtrack::Offset.Value; - - std::sort(validRecords.begin(), validRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool + std::sort(vRecords.begin(), vRecords.end(), [&](const TickRecord& a, const TickRecord& b) -> bool { if (Vars::Backtrack::PreferOnShot.Value && a.m_bOnShot != b.m_bOnShot) return a.m_bOnShot > b.m_bOnShot; @@ -159,7 +159,7 @@ std::deque CBacktrack::GetValidRecords(std::deque* pReco } } - return validRecords; + return vRecords; } @@ -177,6 +177,8 @@ void CBacktrack::MakeRecords() pPlayer->m_flSimulationTime(), *reinterpret_cast(H::Entities.GetBones(pPlayer->entindex())), pPlayer->m_vecOrigin(), + pPlayer->m_vecMins(), + pPlayer->m_vecMaxs(), m_mDidShoot[pPlayer->entindex()] }; diff --git a/Amalgam/src/Features/Backtrack/Backtrack.h b/Amalgam/src/Features/Backtrack/Backtrack.h index 62a0b2e4..497ef5a3 100644 --- a/Amalgam/src/Features/Backtrack/Backtrack.h +++ b/Amalgam/src/Features/Backtrack/Backtrack.h @@ -28,14 +28,14 @@ struct TickRecord float m_flSimTime = 0.f; BoneMatrix m_BoneMatrix = {}; Vec3 m_vOrigin = {}; + Vec3 m_vMins = {}; + Vec3 m_vMaxs = {}; bool m_bOnShot = false; bool m_bInvalid = false; }; class CBacktrack { - bool WithinRewind(const TickRecord& record); - void SendLerp(); void UpdateDatagram(); void MakeRecords(); diff --git a/Amalgam/src/Hooks/CBasePlayer_ItemPostFrame.cpp b/Amalgam/src/Hooks/CBasePlayer_ItemPostFrame.cpp index 714d5e20..db2bfba2 100644 --- a/Amalgam/src/Hooks/CBasePlayer_ItemPostFrame.cpp +++ b/Amalgam/src/Hooks/CBasePlayer_ItemPostFrame.cpp @@ -36,10 +36,7 @@ MAKE_HOOK(CBasePlayer_ItemPostFrame, S::CBasePlayer_ItemPostFrame(), void, return CALL_ORIGINAL(rcx); } - //SDK::Output("CBasePlayer_ItemPostFrame", std::format("{}; {}, {}, {}; {:#x}", TIME_TO_TICKS(pLocal->m_flNextAttack() - I::GlobalVars->curtime) == 31, I::GlobalVars->curtime - pWeapon->m_flTimeWeaponIdle(), I::GlobalVars->curtime - pLocal->m_flNextAttack(), I::GlobalVars->curtime - pWeapon->m_flNextPrimaryAttack(), uintptr_t(_ReturnAddress())).c_str()); CALL_ORIGINAL(rcx); pWeapon->IncrementAmmo(); pWeapon->m_bReloadedThroughAnimEvent() = true; - - //SDK::Output("CBasePlayer_ItemPostFrame", ""); } \ No newline at end of file diff --git a/Amalgam/src/SDK/Definitions/Main/CModel.h b/Amalgam/src/SDK/Definitions/Main/CModel.h index edf3dc4b..5d4d8067 100644 --- a/Amalgam/src/SDK/Definitions/Main/CModel.h +++ b/Amalgam/src/SDK/Definitions/Main/CModel.h @@ -58,7 +58,7 @@ struct Ray_t void Init(Vector const& start, Vector const& end) { m_Delta = end - start; - m_IsSwept = (m_Delta.LengthSqr() != 0); + m_IsSwept = m_Delta.LengthSqr() != 0; m_Extents.Set(); m_IsRay = true; m_StartOffset.Set(); @@ -68,10 +68,10 @@ struct Ray_t void Init(Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs) { m_Delta = end - start; - m_IsSwept = (m_Delta.LengthSqr() != 0); + m_IsSwept = m_Delta.LengthSqr() != 0; m_Extents = maxs - mins; m_Extents *= 0.5f; - m_IsRay = (m_Extents.LengthSqr() < 1e-6); + m_IsRay = m_Extents.LengthSqr() == 0; m_StartOffset = mins + maxs; m_StartOffset *= 0.5f; m_Start = start + m_StartOffset;