2025-07-25 22:49:56 +03:00

285 lines
6.8 KiB
C++

#pragma once
#include "qAngles.h"
#include "Utils/Memory.h"
#include "Utils/Defines.h"
#include "Utils/cVector.h"
enum ECommandButtons : std::uint64_t
{
IN_ATTACK = 1 << 0,
IN_JUMP = 1 << 1,
IN_DUCK = 1 << 2,
IN_FORWARD = 1 << 3,
IN_BACK = 1 << 4,
IN_USE = 1 << 5,
IN_LEFT = 1 << 7,
IN_RIGHT = 1 << 8,
IN_MOVELEFT = 1 << 9,
IN_MOVERIGHT = 1 << 10,
IN_SECOND_ATTACK = 1 << 11,
IN_RELOAD = 1 << 13,
IN_SPRINT = 1 << 16,
IN_JOYAUTOSPRINT = 1 << 17,
IN_SHOWSCORES = 1ULL << 33,
IN_ZOOM = 1ULL << 34,
IN_LOOKATWEAPON = 1ULL << 35
};
// compiled protobuf messages and looked at what bits are used in them
enum ESubtickMoveStepBits : std::uint32_t
{
MOVESTEP_BITS_BUTTON = 0x1U,
MOVESTEP_BITS_PRESSED = 0x2U,
MOVESTEP_BITS_WHEN = 0x4U,
MOVESTEP_BITS_ANALOG_FORWARD_DELTA = 0x8U,
MOVESTEP_BITS_ANALOG_LEFT_DELTA = 0x10U
};
enum EInputHistoryBits : std::uint32_t
{
INPUT_HISTORY_BITS_VIEWANGLES = 0x1U,
INPUT_HISTORY_BITS_SHOOTPOSITION = 0x2U,
INPUT_HISTORY_BITS_TARGETHEADPOSITIONCHECK = 0x4U,
INPUT_HISTORY_BITS_TARGETABSPOSITIONCHECK = 0x8U,
INPUT_HISTORY_BITS_TARGETANGCHECK = 0x10U,
INPUT_HISTORY_BITS_CL_INTERP = 0x20U,
INPUT_HISTORY_BITS_SV_INTERP0 = 0x40U,
INPUT_HISTORY_BITS_SV_INTERP1 = 0x80U,
INPUT_HISTORY_BITS_PLAYER_INTERP = 0x100U,
INPUT_HISTORY_BITS_RENDERTICKCOUNT = 0x200U,
INPUT_HISTORY_BITS_RENDERTICKFRACTION = 0x400U,
INPUT_HISTORY_BITS_PLAYERTICKCOUNT = 0x800U,
INPUT_HISTORY_BITS_PLAYERTICKFRACTION = 0x1000U,
INPUT_HISTORY_BITS_FRAMENUMBER = 0x2000U,
INPUT_HISTORY_BITS_TARGETENTINDEX = 0x4000U
};
enum EButtonStatePBBits : uint32_t
{
BUTTON_STATE_PB_BITS_BUTTONSTATE1 = 0x1U,
BUTTON_STATE_PB_BITS_BUTTONSTATE2 = 0x2U,
BUTTON_STATE_PB_BITS_BUTTONSTATE3 = 0x4U
};
enum EBaseCmdBits : std::uint32_t
{
BASE_BITS_MOVE_CRC = 0x1U,
BASE_BITS_BUTTONPB = 0x2U,
BASE_BITS_VIEWANGLES = 0x4U,
BASE_BITS_COMMAND_NUMBER = 0x8U,
BASE_BITS_CLIENT_TICK = 0x10U,
BASE_BITS_FORWARDMOVE = 0x20U,
BASE_BITS_LEFTMOVE = 0x40U,
BASE_BITS_UPMOVE = 0x80U,
BASE_BITS_IMPULSE = 0x100U,
BASE_BITS_WEAPON_SELECT = 0x200U,
BASE_BITS_RANDOM_SEED = 0x400U,
BASE_BITS_MOUSEDX = 0x800U,
BASE_BITS_MOUSEDY = 0x1000U,
BASE_BITS_CONSUMED_SERVER_ANGLE = 0x2000U,
BASE_BITS_CMD_FLAGS = 0x4000U,
BASE_BITS_ENTITY_HANDLE = 0x8000U
};
enum ECSGOUserCmdBits : std::uint32_t
{
CSGOUSERCMD_BITS_BASECMD = 0x1U,
CSGOUSERCMD_BITS_LEFTHAND = 0x2U,
CSGOUSERCMD_BITS_ATTACK3START = 0x4U,
CSGOUSERCMD_BITS_ATTACK1START = 0x8U,
CSGOUSERCMD_BITS_ATTACK2START = 0x10U
};
template <typename T>
struct RepeatedPtrField_t
{
struct Rep_t
{
int nAllocatedSize;
T* tElements[(2147483647 - 2 * sizeof(int)) / sizeof(void*)];
};
void* pArena;
int nCurrentSize;
int nTotalSize;
Rep_t* pRep;
};
class CBasePB
{
public:
MEM_PAD(0x8); // 0x0 VTABLE
std::uint32_t nHasBits; // 0x8
std::uint64_t nCachedBits; // 0xC
void SetBits(std::uint64_t nBits)
{
// @note: you don't need to check if the bits are already set as bitwise OR will not change the value if the bit is already set
nCachedBits |= nBits;
}
};
static_assert(sizeof(CBasePB) == 0x18);
class CMsgQAngle : public CBasePB
{
public:
QAngle_t angValue; // 0x18
};
static_assert(sizeof(CMsgQAngle) == 0x28);
class CMsgVector : public CBasePB
{
public:
Vector4D_t vecValue; // 0x18
};
static_assert(sizeof(CMsgVector) == 0x28);
class CCSGOInterpolationInfoPB : public CBasePB
{
public:
float flFraction; // 0x18
int nSrcTick; // 0x1C
int nDstTick; // 0x20
};
static_assert(sizeof(CCSGOInterpolationInfoPB) == 0x28);
class CCSGOInputHistoryEntryPB : public CBasePB
{
public:
CMsgQAngle* pViewAngles; // 0x18
CMsgVector* pShootPosition; // 0x20
CMsgVector* pTargetHeadPositionCheck; // 0x28
CMsgVector* pTargetAbsPositionCheck; // 0x30
CMsgQAngle* pTargetAngPositionCheck; // 0x38
CCSGOInterpolationInfoPB* cl_interp; // 0x40
CCSGOInterpolationInfoPB* sv_interp0; // 0x48
CCSGOInterpolationInfoPB* sv_interp1; // 0x50
CCSGOInterpolationInfoPB* player_interp; // 0x58
int nRenderTickCount; // 0x60
float flRenderTickFraction; // 0x64
int nPlayerTickCount; // 0x68
float flPlayerTickFraction; // 0x6C
int nFrameNumber; // 0x70
int nTargetEntIndex; // 0x74
};
static_assert(sizeof(CCSGOInputHistoryEntryPB) == 0x78);
struct CInButtonStatePB : CBasePB
{
std::uint64_t nValue;
std::uint64_t nValueChanged;
std::uint64_t nValueScroll;
};
static_assert(sizeof(CInButtonStatePB) == 0x30);
struct CSubtickMoveStep : CBasePB
{
public:
std::uint64_t nButton;
bool bPressed;
float flWhen;
float flAnalogForwardDelta;
float flAnalogLeftDelta;
};
static_assert(sizeof(CSubtickMoveStep) == 0x30);
class CBaseUserCmdPB : public CBasePB
{
public:
RepeatedPtrField_t<CSubtickMoveStep> subtickMovesField;
std::string* strMoveCrc;
CInButtonStatePB* pInButtonState;
CMsgQAngle* pViewAngles;
std::int32_t nLegacyCommandNumber;
std::int32_t nClientTick;
float flForwardMove;
float flSideMove;
float flUpMove;
std::int32_t nImpulse;
std::int32_t nWeaponSelect;
std::int32_t nRandomSeed;
std::int32_t nMousedX;
std::int32_t nMousedY;
std::uint32_t nConsumedServerAngleChanges;
std::int32_t nCmdFlags;
std::uint32_t nPawnEntityHandle;
int CalculateCmdCRCSize()
{
return M::CallVFunc<int, 7U>(this);
}
};
static_assert(sizeof(CBaseUserCmdPB) == 0x80);
class CCSGOUserCmdPB
{
public:
std::uint32_t nHasBits;
std::uint64_t nCachedSize;
RepeatedPtrField_t<CCSGOInputHistoryEntryPB> inputHistoryField;
CBaseUserCmdPB* pBaseCmd;
bool bLeftHandDesired;
std::int32_t nAttack3StartHistoryIndex;
std::int32_t nAttack1StartHistoryIndex;
std::int32_t nAttack2StartHistoryIndex;
// @note: this function is used to check if the bits are set and set them if they are not
void CheckAndSetBits(std::uint32_t nBits)
{
if (!(nHasBits & nBits))
nHasBits |= nBits;
}
};
static_assert(sizeof(CCSGOUserCmdPB) == 0x40);
struct CInButtonState
{
public:
MEM_PAD(0x8) // 0x0 VTABLE
std::uint64_t nValue; // 0x8
std::uint64_t nValueChanged; // 0x10
std::uint64_t nValueScroll; // 0x18
};
static_assert(sizeof(CInButtonState) == 0x20);
class CUserCmd
{
public:
MEM_PAD(0x8); // 0x0 VTABLE
MEM_PAD(0x10); // TODO: find out what this is, added 14.08.2024
CCSGOUserCmdPB csgoUserCmd; // 0x18
CInButtonState nButtons; // 0x58
MEM_PAD(0x20); // 0x78
CCSGOInputHistoryEntryPB* GetInputHistoryEntry(int nIndex)
{
if (nIndex >= csgoUserCmd.inputHistoryField.pRep->nAllocatedSize || nIndex >= csgoUserCmd.inputHistoryField.nCurrentSize)
return nullptr;
return csgoUserCmd.inputHistoryField.pRep->tElements[nIndex];
}
void SetSubTickAngle(const QAngle_t& angView)
{
for (int i = 0; i < this->csgoUserCmd.inputHistoryField.pRep->nAllocatedSize; i++)
{
CCSGOInputHistoryEntryPB* pInputEntry = this->GetInputHistoryEntry(i);
if (!pInputEntry || !pInputEntry->pViewAngles)
continue;
pInputEntry->pViewAngles->angValue = angView;
pInputEntry->SetBits(EInputHistoryBits::INPUT_HISTORY_BITS_VIEWANGLES);
}
}
};
static_assert(sizeof(CUserCmd) == 0x98);