Skip to content

Commit

Permalink
Engine Prediction by @RileyKun (#11)
Browse files Browse the repository at this point in the history
* 1

* 2

* 3

* 4

* 5

* 6

* 7

* 8

* who made this an int

---------

Co-authored-by: Viceroy <[email protected]>
  • Loading branch information
whohyno and Viceroyy authored Aug 9, 2024
1 parent 833e0b6 commit 31f1f3e
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 75 deletions.
8 changes: 5 additions & 3 deletions Fusion/Fusion.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<SupportJustMyCode>true</SupportJustMyCode>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
Expand Down Expand Up @@ -145,7 +145,7 @@
<WholeProgramOptimization>false</WholeProgramOptimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<SupportJustMyCode>true</SupportJustMyCode>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
Expand All @@ -170,6 +170,7 @@
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
Expand All @@ -196,6 +197,7 @@
<EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
Expand Down Expand Up @@ -650,4 +652,4 @@
</PropertyGroup>
<Error Condition="!Exists('..\packages\boost.1.85.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.85.0\build\boost.targets'))" />
</Target>
</Project>
</Project>
2 changes: 1 addition & 1 deletion Fusion/src/Features/Backtrack/Backtrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
80 changes: 34 additions & 46 deletions Fusion/src/Features/EnginePrediction/EnginePrediction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,72 @@

#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<int>::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<int>::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;

pLocal->SetCurrentCmd(nullptr);

*G::RandomSeed() = -1;

if (!bSimulated)
Simulate(pLocal, pCmd);
}
}
8 changes: 4 additions & 4 deletions Fusion/src/Features/EnginePrediction/EnginePrediction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
ADD_FEATURE(CEnginePrediction, EnginePrediction)
12 changes: 6 additions & 6 deletions Fusion/src/Hooks/ClientModeShared_CreateMove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
}
}
24 changes: 12 additions & 12 deletions Fusion/src/Hooks/NetChannel_SendDatagram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
return original;
}
7 changes: 6 additions & 1 deletion Fusion/src/SDK/Definitions/Main/CBaseCombatWeapon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const char*(__thiscall*)(void*)>(this, 331)(this);
}

bool HasAmmo()
{
return S::CBaseCombatWeapon_HasAmmo.As<bool(__thiscall*)(void*)>()(this);
}
};
};
11 changes: 10 additions & 1 deletion Fusion/src/SDK/Definitions/Main/CBasePlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<void(__thiscall*)(void*, const char*, int)>(this, 271)(this, ptr, subtype);
}

bool IsAlive()
{
return m_lifeState() == LIFE_ALIVE;
Expand Down Expand Up @@ -116,4 +125,4 @@ class CBasePlayer : public CBaseCombatCharacter
{
return S::CBasePlayer_GetAmmoCount.As<int(__fastcall*)(void*, int)>()(this, iAmmoType);
}
};
};
8 changes: 7 additions & 1 deletion Fusion/src/Utils/Memory/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ class CMemory
return vtable[index];
}

template<typename T>
inline T FindVFunc(void* vmt, size_t index)
{
return (*static_cast<T**>(vmt))[index];
}

inline std::uintptr_t RelToAbs(const std::uintptr_t address)
{
return *reinterpret_cast<std::int32_t*>(address + 0x3) + address + 0x7;
}
};

ADD_FEATURE_CUSTOM(CMemory, Memory, U)
ADD_FEATURE_CUSTOM(CMemory, Memory, U)

0 comments on commit 31f1f3e

Please sign in to comment.