diff --git a/Fusion/Fusion.vcxproj b/Fusion/Fusion.vcxproj index 26a90fc..70eb5bb 100644 --- a/Fusion/Fusion.vcxproj +++ b/Fusion/Fusion.vcxproj @@ -116,8 +116,8 @@ NotSet false ProgramDatabase + MultiThreadedDebug true - MultiThreadedDebugDLL stdc17 @@ -145,7 +145,7 @@ false ProgramDatabase true - MultiThreadedDebugDLL + MultiThreadedDebug stdc17 @@ -170,6 +170,7 @@ NotSet ProgramDatabase false + MultiThreaded stdc17 @@ -196,6 +197,7 @@ AdvancedVectorExtensions2 ProgramDatabase false + MultiThreaded stdc17 @@ -650,4 +652,4 @@ - \ No newline at end of file + diff --git a/Fusion/src/Features/Backtrack/Backtrack.cpp b/Fusion/src/Features/Backtrack/Backtrack.cpp index 93e2e6f..d5e3040 100644 --- a/Fusion/src/Features/Backtrack/Backtrack.cpp +++ b/Fusion/src/Features/Backtrack/Backtrack.cpp @@ -263,7 +263,7 @@ void CBacktrack::CleanRecords() //const int iOldSize = pRecords.size(); - const int flDeadtime = I::GlobalVars->curtime + GetReal() - flMaxUnlag; // int ??? + const float flDeadtime = I::GlobalVars->curtime + GetReal() - flMaxUnlag; while (!mRecords[pEntity].empty()) { if (mRecords[pEntity].back().flSimTime >= flDeadtime) diff --git a/Fusion/src/Features/EnginePrediction/EnginePrediction.cpp b/Fusion/src/Features/EnginePrediction/EnginePrediction.cpp index 9565fca..b069b01 100644 --- a/Fusion/src/Features/EnginePrediction/EnginePrediction.cpp +++ b/Fusion/src/Features/EnginePrediction/EnginePrediction.cpp @@ -2,76 +2,67 @@ #include "../TickHandler/TickHandler.h" -int CEnginePrediction::GetTickbase(CUserCmd* pCmd, CTFPlayer* pLocal) +void CEnginePrediction::Start(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd) { - static int nTick = 0; - static CUserCmd* pLastCmd = nullptr; + if(!pLocal || !pLocal->IsAlive() || !pWeapon || !pCmd || !I::MoveHelper) + return; - if (pCmd) - { - if (!pLastCmd || pLastCmd->hasbeenpredicted) - nTick = pLocal->m_nTickBase(); - else - nTick++; - pLastCmd = pCmd; - } + m_nOldTickCount = I::GlobalVars->tickcount; + m_fOldCurrentTime = I::GlobalVars->curtime; + m_fOldFrameTime = I::GlobalVars->frametime; - return nTick; + pLocal->SetCurrentCmd(pCmd); + *G::RandomSeed() = MD5_PseudoRandom(pCmd->command_number) & std::numeric_limits::max(); + + I::GlobalVars->curtime = TICKS_TO_TIME(I::GlobalVars->tickcount); + I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.0f : TICK_INTERVAL; + + I::GameMovement->StartTrackPredictionErrors(pLocal); + + Simulate(pLocal, pWeapon, pCmd); } -void CEnginePrediction::Simulate(CTFPlayer* pLocal, CUserCmd* pCmd) +void CEnginePrediction::Simulate(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd) { - if (!pLocal || !pLocal->IsAlive() || !I::MoveHelper) + if (!pLocal || !pLocal->IsAlive() || !pWeapon || !I::MoveHelper) return; - pLocal->SetCurrentCmd(pCmd); - - *G::RandomSeed() = MD5_PseudoRandom(pCmd->command_number) & std::numeric_limits::max(); - - const int nOldTickBase = pLocal->m_nTickBase(); + nOldTickBase = pLocal->m_nTickBase(); const bool bOldIsFirstPrediction = I::Prediction->m_bFirstTimePredicted; const bool bOldInPrediction = I::Prediction->m_bInPrediction; I::Prediction->m_bFirstTimePredicted = false; I::Prediction->m_bInPrediction = true; + if(pCmd->weaponselect != NULL) + { + pLocal->SelectItem(pWeapon->GetName(), pCmd->weaponsubtype); + } + I::Prediction->SetLocalViewAngles(pCmd->viewangles); + pLocal->PreThink(); + pLocal->Think(); + I::Prediction->SetupMove(pLocal, pCmd, I::MoveHelper, &m_MoveData); I::GameMovement->ProcessMovement(pLocal, &m_MoveData); I::Prediction->FinishMove(pLocal, pCmd, &m_MoveData); - pLocal->m_nTickBase() = nOldTickBase; - I::Prediction->m_bFirstTimePredicted = bOldIsFirstPrediction; - I::Prediction->m_bInPrediction = bOldInPrediction; -} + pLocal->PostThink(); -void CEnginePrediction::Start(CTFPlayer* pLocal, CUserCmd* pCmd) -{ - if (!pLocal || !pLocal->IsAlive()) - return; - - m_nOldTickCount = I::GlobalVars->tickcount; - m_fOldCurrentTime = I::GlobalVars->curtime; - m_fOldFrameTime = I::GlobalVars->frametime; + I::GameMovement->FinishTrackPredictionErrors(pLocal); - I::GlobalVars->tickcount = GetTickbase(pCmd, pLocal); - I::GlobalVars->curtime = TICKS_TO_TIME(I::GlobalVars->tickcount); - I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.0f : TICK_INTERVAL; - - bSimulated = false; - if (F::Ticks.GetTicks(pLocal) && Vars::CL_Move::Doubletap::AntiWarp.Value && pLocal->OnSolid()) - return; // hopefully more accurate eyepos while dting - - bSimulated = true; - Simulate(pLocal, pCmd); + I::Prediction->m_bFirstTimePredicted = bOldIsFirstPrediction; + I::Prediction->m_bInPrediction = bOldInPrediction; } void CEnginePrediction::End(CTFPlayer* pLocal, CUserCmd* pCmd) { - if (!pLocal || !pLocal->IsAlive()) + if (!pLocal || !pLocal->IsAlive() || !I::MoveHelper) return; + pLocal->m_nTickBase() = nOldTickBase; + I::GlobalVars->tickcount = m_nOldTickCount; I::GlobalVars->curtime = m_fOldCurrentTime; I::GlobalVars->frametime = m_fOldFrameTime; @@ -79,7 +70,4 @@ void CEnginePrediction::End(CTFPlayer* pLocal, CUserCmd* pCmd) pLocal->SetCurrentCmd(nullptr); *G::RandomSeed() = -1; - - if (!bSimulated) - Simulate(pLocal, pCmd); -} \ No newline at end of file +} diff --git a/Fusion/src/Features/EnginePrediction/EnginePrediction.h b/Fusion/src/Features/EnginePrediction/EnginePrediction.h index c58a3ed..bee0109 100644 --- a/Fusion/src/Features/EnginePrediction/EnginePrediction.h +++ b/Fusion/src/Features/EnginePrediction/EnginePrediction.h @@ -7,18 +7,18 @@ class CEnginePrediction CMoveData m_MoveData = {}; private: - int GetTickbase(CUserCmd* pCmd, CTFPlayer* pLocal); - void Simulate(CTFPlayer* pLocal, CUserCmd* pCmd); + void Simulate(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd); int m_nOldTickCount = 0; + int nOldTickBase = 0; float m_fOldCurrentTime = 0.f; float m_fOldFrameTime = 0.f; bool bSimulated = false; public: - void Start(CTFPlayer* pLocal, CUserCmd* pCmd); + void Start(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd); void End(CTFPlayer* pLocal, CUserCmd* pCmd); }; -ADD_FEATURE(CEnginePrediction, EnginePrediction) \ No newline at end of file +ADD_FEATURE(CEnginePrediction, EnginePrediction) diff --git a/Fusion/src/Hooks/ClientModeShared_CreateMove.cpp b/Fusion/src/Hooks/ClientModeShared_CreateMove.cpp index 524f3c2..464fb94 100644 --- a/Fusion/src/Hooks/ClientModeShared_CreateMove.cpp +++ b/Fusion/src/Hooks/ClientModeShared_CreateMove.cpp @@ -105,20 +105,20 @@ MAKE_HOOK(ClientModeShared_CreateMove, U::Memory.GetVFunc(I::ClientModeShared, 2 // Run Features F::Misc.RunPre(pLocal, pCmd); - F::Backtrack.Run(pCmd); - F::Backtrack.BacktrackToCrosshair(pCmd); - - F::EnginePrediction.Start(pLocal, pCmd); + F::EnginePrediction.Start(pLocal, pWeapon, pCmd); { + F::Backtrack.Run(pCmd); + F::Backtrack.BacktrackToCrosshair(pCmd); const bool bAimRan = bSkip ? false : F::Aimbot.Run(pLocal, pWeapon, pCmd); if (!bAimRan && G::CanPrimaryAttack && G::IsAttacking && !F::AimbotProjectile.bLastTickCancel) F::Visuals.ProjectileTrace(pLocal, pWeapon, false); + + F::CritHack.Run(pLocal, pWeapon, pCmd); } F::EnginePrediction.End(pLocal, pCmd); F::PacketManip.Run(pLocal, pCmd, pSendPacket); F::Ticks.MovePost(pLocal, pCmd); - F::CritHack.Run(pLocal, pWeapon, pCmd); F::NoSpread.Run(pLocal, pWeapon, pCmd); F::Misc.RunPost(pLocal, pCmd, *pSendPacket); F::Resolver.CreateMove(); @@ -143,4 +143,4 @@ MAKE_HOOK(ClientModeShared_CreateMove, U::Memory.GetVFunc(I::ClientModeShared, 2 //const bool bShouldSkip = G::PSilentAngles || G::SilentAngles || G::AntiAim || G::AvoidingBackstab; //return bShouldSkip ? false : CALL_ORIGINAL(ecx, edx, input_sample_frametime, pCmd); return false; -} \ No newline at end of file +} diff --git a/Fusion/src/Hooks/NetChannel_SendDatagram.cpp b/Fusion/src/Hooks/NetChannel_SendDatagram.cpp index 13bfceb..7e4da3a 100644 --- a/Fusion/src/Hooks/NetChannel_SendDatagram.cpp +++ b/Fusion/src/Hooks/NetChannel_SendDatagram.cpp @@ -5,19 +5,19 @@ MAKE_SIGNATURE(NetChannel_SendDatagram, "engine.dll", "40 55 57 41 56 48 8D AC 24", 0x0); MAKE_HOOK(NetChannel_SendDatagram, S::NetChannel_SendDatagram(), int, __fastcall, - CNetChannel* netChannel, bf_write* datagram) + CNetChannel* netChannel, bf_write* datagram) { - if (!netChannel || datagram || netChannel->GetTimeSinceLastReceived() > TICK_INTERVAL * 2 || netChannel->IsTimingOut() || netChannel->IsLoopback()) - return CALL_ORIGINAL(netChannel, datagram); + if (!I::EngineClient->IsInGame() || !netChannel || datagram) + return CALL_ORIGINAL(netChannel, datagram); - F::Backtrack.bFakeLatency = H::Entities.GetLocal() && Vars::Backtrack::Enabled.Value && Vars::Backtrack::LatencyMode.Value == 1 || Vars::Backtrack::LatencyMode.Value == 2 && Vars::Backtrack::Latency.Value; - if (!F::Backtrack.bFakeLatency) - return CALL_ORIGINAL(netChannel, datagram); + F::Backtrack.bFakeLatency = Vars::Backtrack::LatencyMode.Value == 1 || Vars::Backtrack::LatencyMode.Value == 2 && Vars::Backtrack::Latency.Value; + if (!Vars::Backtrack::Enabled.Value || !F::Backtrack.bFakeLatency) + return CALL_ORIGINAL(netChannel, datagram); - const int nInSequenceNr = netChannel->m_nInSequenceNr, nInReliableState = netChannel->m_nInReliableState; - F::Backtrack.AdjustPing(netChannel); - const int original = CALL_ORIGINAL(netChannel, datagram); - netChannel->m_nInSequenceNr = nInSequenceNr, netChannel->m_nInReliableState = nInReliableState; + const int nInSequenceNr = netChannel->m_nInSequenceNr, nInReliableState = netChannel->m_nInReliableState; + F::Backtrack.AdjustPing(netChannel); + const int original = CALL_ORIGINAL(netChannel, datagram); + netChannel->m_nInSequenceNr = nInSequenceNr, netChannel->m_nInReliableState = nInReliableState; - return original; -} \ No newline at end of file + return original; +} diff --git a/Fusion/src/SDK/Definitions/Main/CBaseCombatWeapon.h b/Fusion/src/SDK/Definitions/Main/CBaseCombatWeapon.h index 11e83e4..8da03c7 100644 --- a/Fusion/src/SDK/Definitions/Main/CBaseCombatWeapon.h +++ b/Fusion/src/SDK/Definitions/Main/CBaseCombatWeapon.h @@ -22,8 +22,13 @@ class CBaseCombatWeapon : public CBaseAnimating NETVAR(m_iState, int, "CBaseCombatWeapon", "m_iState"); NETVAR(m_hOwner, EHANDLE, "CBaseCombatWeapon", "m_hOwner"); + const char* GetName() + { + return U::Memory.FindVFunc(this, 331)(this); + } + bool HasAmmo() { return S::CBaseCombatWeapon_HasAmmo.As()(this); } -}; \ No newline at end of file +}; diff --git a/Fusion/src/SDK/Definitions/Main/CBasePlayer.h b/Fusion/src/SDK/Definitions/Main/CBasePlayer.h index 201e6f0..d2d8302 100644 --- a/Fusion/src/SDK/Definitions/Main/CBasePlayer.h +++ b/Fusion/src/SDK/Definitions/Main/CBasePlayer.h @@ -81,6 +81,15 @@ class CBasePlayer : public CBaseCombatCharacter CONDGET(IsInWater, m_fFlags(), FL_INWATER); CONDGET(IsDucking, m_fFlags(), FL_DUCKING); + VIRTUAL(PreThink, void, void(__thiscall*)(void*), this, 260); + VIRTUAL(Think, void, void(__thiscall*)(void*), this, 174); + VIRTUAL(PostThink, void, void(__thiscall*)(void*), this, 261); + + void SelectItem(const char* ptr, int subtype) + { + U::Memory.FindVFunc(this, 271)(this, ptr, subtype); + } + bool IsAlive() { return m_lifeState() == LIFE_ALIVE; @@ -116,4 +125,4 @@ class CBasePlayer : public CBaseCombatCharacter { return S::CBasePlayer_GetAmmoCount.As()(this, iAmmoType); } -}; \ No newline at end of file +}; diff --git a/Fusion/src/Utils/Memory/Memory.h b/Fusion/src/Utils/Memory/Memory.h index 58fe271..03eea3d 100644 --- a/Fusion/src/Utils/Memory/Memory.h +++ b/Fusion/src/Utils/Memory/Memory.h @@ -15,10 +15,16 @@ class CMemory return vtable[index]; } + template + inline T FindVFunc(void* vmt, size_t index) + { + return (*static_cast(vmt))[index]; + } + inline std::uintptr_t RelToAbs(const std::uintptr_t address) { return *reinterpret_cast(address + 0x3) + address + 0x7; } }; -ADD_FEATURE_CUSTOM(CMemory, Memory, U) \ No newline at end of file +ADD_FEATURE_CUSTOM(CMemory, Memory, U)