2025-07-29 20:23:06 +03:00

188 lines
6.6 KiB
C++

#include "movement.h"
// used: sdk entity
#include "../../sdk/entity.h"
// used: cusercmd
#include "../../sdk/datatypes/usercmd.h"
// used: convars
#include "../../core/convars.h"
#include "../../sdk/interfaces/ienginecvar.h"
// used: cheat variables
#include "../../core/variables.h"
// movement correction angles
static QAngle_t angCorrectionView = {};
void F::MISC::MOVEMENT::OnMove(CUserCmd* pCmd, CBaseUserCmdPB* pBaseCmd, CCSPlayerController* pLocalController, C_CSPlayerPawn* pLocalPawn)
{
if (!pLocalController->IsPawnAlive())
return;
// check if player is in noclip or on ladder or in water
if (const int32_t nMoveType = pLocalPawn->GetMoveType(); nMoveType == MOVETYPE_NOCLIP || nMoveType == MOVETYPE_LADDER || pLocalPawn->GetWaterLevel() >= WL_WAIST)
return;
BunnyHop(pCmd, pBaseCmd, pLocalPawn);
AutoStrafe(pBaseCmd, pLocalPawn);
// loop through all tick commands
for (int nSubTick = 0; nSubTick < pCmd->csgoUserCmd.inputHistoryField.pRep->nAllocatedSize; nSubTick++)
{
CCSGOInputHistoryEntryPB* pInputEntry = pCmd->GetInputHistoryEntry(nSubTick);
if (pInputEntry == nullptr)
continue;
// save view angles for movement correction
angCorrectionView = pInputEntry->pViewAngles->angValue;
// movement correction & anti-untrusted
ValidateUserCommand(pCmd, pBaseCmd, pInputEntry);
}
}
void F::MISC::MOVEMENT::BunnyHop(CUserCmd* pCmd, CBaseUserCmdPB* pUserCmd, C_CSPlayerPawn* pLocalPawn)
{
if (!C_GET(bool, Vars.bAutoBHop) || CONVAR::sv_autobunnyhopping->value.i1)
return;
// update random seed
//MATH::fnRandomSeed(pUserCmd->nRandomSeed);
//// bypass of possible SMAC/VAC server anticheat detection
//if (static bool bShouldFakeJump = false; bShouldFakeJump)
//{
// pCmd->nButtons.nValue |= IN_JUMP;
// bShouldFakeJump = false;
//}
//// check is player want to jump
//else if (pCmd->nButtons.nValue & IN_JUMP)
//{
// // check is player on the ground
// if (pLocalPawn->GetFlags() & FL_ONGROUND)
// // note to fake jump at the next tick
// bShouldFakeJump = true;
// // check did random jump chance passed
// else if (MATH::fnRandomInt(0, 100) <= C_GET(int, Vars.nAutoBHopChance))
// pCmd->nButtons.nValue &= ~IN_JUMP;
//}
// im lazy so yea :D
if (pLocalPawn->GetFlags() & FL_ONGROUND)
{
pUserCmd->pInButtonState->SetBits(EButtonStatePBBits::BUTTON_STATE_PB_BITS_BUTTONSTATE1);
pUserCmd->pInButtonState->nValue &= ~IN_JUMP;
}
}
void F::MISC::MOVEMENT::AutoStrafe(CBaseUserCmdPB* pUserCmd, C_CSPlayerPawn* pLocalPawn)
{
if (!C_GET(bool, Vars.bAutoStrafe) || pLocalPawn->GetFlags() & FL_ONGROUND)
return;
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_LEFTMOVE);
pUserCmd->flSideMove = pUserCmd->nMousedX > 0 ? -1.0f : 1.0f; // a bit yanky, but works
}
void F::MISC::MOVEMENT::ValidateUserCommand(CUserCmd* pCmd, CBaseUserCmdPB* pUserCmd, CCSGOInputHistoryEntryPB* pInputEntry)
{
if (pUserCmd == nullptr)
return;
// clamp angle to avoid untrusted angle
if (C_GET(bool, Vars.bAntiUntrusted))
{
pInputEntry->SetBits(EInputHistoryBits::INPUT_HISTORY_BITS_VIEWANGLES);
if (pInputEntry->pViewAngles->angValue.IsValid())
{
pInputEntry->pViewAngles->angValue.Clamp();
pInputEntry->pViewAngles->angValue.z = 0.f;
}
else
{
pInputEntry->pViewAngles->angValue = {};
L_PRINT(LOG_WARNING) << CS_XOR("view angles have a NaN component, the value is reset");
}
}
MovementCorrection(pUserCmd, pInputEntry, angCorrectionView);
// correct movement buttons while player move have different to buttons values
// clear all of the move buttons states
pUserCmd->pInButtonState->SetBits(EButtonStatePBBits::BUTTON_STATE_PB_BITS_BUTTONSTATE1);
pUserCmd->pInButtonState->nValue &= (~IN_FORWARD | ~IN_BACK | ~IN_LEFT | ~IN_RIGHT);
// re-store buttons by active forward/side moves
if (pUserCmd->flForwardMove > 0.0f)
pUserCmd->pInButtonState->nValue |= IN_FORWARD;
else if (pUserCmd->flForwardMove < 0.0f)
pUserCmd->pInButtonState->nValue |= IN_BACK;
if (pUserCmd->flSideMove > 0.0f)
pUserCmd->pInButtonState->nValue |= IN_RIGHT;
else if (pUserCmd->flSideMove < 0.0f)
pUserCmd->pInButtonState->nValue |= IN_LEFT;
if (!pInputEntry->pViewAngles->angValue.IsZero())
{
const float flDeltaX = std::remainderf(pInputEntry->pViewAngles->angValue.x - angCorrectionView.x, 360.f);
const float flDeltaY = std::remainderf(pInputEntry->pViewAngles->angValue.y - angCorrectionView.y, 360.f);
float flPitch = CONVAR::m_pitch->value.fl;
float flYaw = CONVAR::m_yaw->value.fl;
float flSensitivity = CONVAR::sensitivity->value.fl;
if (flSensitivity == 0.0f)
flSensitivity = 1.0f;
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_MOUSEDX);
pUserCmd->nMousedX = static_cast<short>(flDeltaX / (flSensitivity * flPitch));
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_MOUSEDY);
pUserCmd->nMousedY = static_cast<short>(-flDeltaY / (flSensitivity * flYaw));
}
}
void F::MISC::MOVEMENT::MovementCorrection(CBaseUserCmdPB* pUserCmd, CCSGOInputHistoryEntryPB* pInputEntry, const QAngle_t& angDesiredViewPoint)
{
if (pUserCmd == nullptr)
return;
Vector_t vecForward = {}, vecRight = {}, vecUp = {};
angDesiredViewPoint.ToDirections(&vecForward, &vecRight, &vecUp);
// we don't attempt on forward/right roll, and on up pitch/yaw
vecForward.z = vecRight.z = vecUp.x = vecUp.y = 0.0f;
vecForward.NormalizeInPlace();
vecRight.NormalizeInPlace();
vecUp.NormalizeInPlace();
Vector_t vecOldForward = {}, vecOldRight = {}, vecOldUp = {};
pInputEntry->pViewAngles->angValue.ToDirections(&vecOldForward, &vecOldRight, &vecOldUp);
// we don't attempt on forward/right roll, and on up pitch/yaw
vecOldForward.z = vecOldRight.z = vecOldUp.x = vecOldUp.y = 0.0f;
vecOldForward.NormalizeInPlace();
vecOldRight.NormalizeInPlace();
vecOldUp.NormalizeInPlace();
const float flPitchForward = vecForward.x * pUserCmd->flForwardMove;
const float flYawForward = vecForward.y * pUserCmd->flForwardMove;
const float flPitchSide = vecRight.x * pUserCmd->flSideMove;
const float flYawSide = vecRight.y * pUserCmd->flSideMove;
const float flRollUp = vecUp.z * pUserCmd->flUpMove;
// solve corrected movement speed
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_FORWARDMOVE);
pUserCmd->flForwardMove = vecOldForward.x * flPitchSide + vecOldForward.y * flYawSide + vecOldForward.x * flPitchForward + vecOldForward.y * flYawForward + vecOldForward.z * flRollUp;
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_LEFTMOVE);
pUserCmd->flSideMove = vecOldRight.x * flPitchSide + vecOldRight.y * flYawSide + vecOldRight.x * flPitchForward + vecOldRight.y * flYawForward + vecOldRight.z * flRollUp;
pUserCmd->SetBits(EBaseCmdBits::BASE_BITS_UPMOVE);
pUserCmd->flUpMove = vecOldUp.x * flYawSide + vecOldUp.y * flPitchSide + vecOldUp.x * flYawForward + vecOldUp.y * flPitchForward + vecOldUp.z * flRollUp;
}