285 lines
6.8 KiB
C++
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);
|