#pragma once #include // used: MEM_PAD and virtual funcs #include "../utilities/memory.h" // used: CUtlBuffer #include "../sdk/datatypes/utlbuffer.h" // used: CBaseUserCmdPB #include "../sdk/datatypes/usercmd.h"; namespace CRC { struct CInButtonStateNoVTable { public: std::uint64_t nValue; std::uint64_t nValueChanged; std::uint64_t nValueScroll; }; struct SavedData_t { CInButtonStateNoVTable nButtons; QAngle_t angView; }; inline SavedData_t savedData; inline void Save(CBaseUserCmdPB* pBaseCmd) { if (pBaseCmd->pViewAngles != nullptr) savedData.angView = pBaseCmd->pViewAngles->angValue; savedData.nButtons.nValue = pBaseCmd->pInButtonState->nValue; savedData.nButtons.nValueChanged = pBaseCmd->pInButtonState->nValueChanged; savedData.nButtons.nValueScroll = pBaseCmd->pInButtonState->nValueScroll; } inline void Apply(CUserCmd* pCmd) { CBaseUserCmdPB* pBaseCmd = pCmd->csgoUserCmd.pBaseCmd; if (pBaseCmd == nullptr) return; pCmd->nButtons.nValue = savedData.nButtons.nValue; pCmd->nButtons.nValueChanged = savedData.nButtons.nValueChanged; pCmd->nButtons.nValueScroll = savedData.nButtons.nValueScroll; if (pBaseCmd->pViewAngles != nullptr) pBaseCmd->pViewAngles->angValue = savedData.angView; } inline bool CalculateCRC(CBaseUserCmdPB* pBaseCmd) { int nCalcualtedCRCSize = pBaseCmd->CalculateCmdCRCSize(); CUtlBuffer protobufBuffer(0, 0, 0); protobufBuffer.EnsureCapacity(nCalcualtedCRCSize + 1); using fnSerializePartialToArray = bool(__fastcall*)(CBaseUserCmdPB*, CUtlBuffer, int); static const fnSerializePartialToArray oSerializePartialToArray = reinterpret_cast(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 18 55 56 57 48 81 EC 90"))); #ifdef CS_PARANOID CS_ASSERT(oSerializePartialToArray != nullptr); #endif if (oSerializePartialToArray(pBaseCmd, protobufBuffer, nCalcualtedCRCSize)) { std::uintptr_t* pMessage = reinterpret_cast(I::MemAlloc->Alloc(0x18)); pBaseCmd->nCachedBits |= 1; auto nHasBits = static_cast(pBaseCmd->nHasBits & 0xFFFFFFFFFFFFFFFC); if ((pBaseCmd->nHasBits & 1) != 0) nHasBits = static_cast(nHasBits); using fnWriteMessage = void(__fastcall*)(std::uintptr_t*, CUtlBuffer, int); static const fnWriteMessage oWriteMessage = reinterpret_cast(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 10 48 89 6C 24 18 48 89 7C 24 20 41 56 48 83 EC 20 48 BF"))); #ifdef CS_PARANOID CS_ASSERT(oWriteMessage != nullptr); #endif using fnSetMessageData = std::string*(__fastcall*)(void*, std::uintptr_t*, void*); static const fnSetMessageData oSetMessageData = reinterpret_cast(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 20 55 56 57 48 83 EC 30 49"))); #ifdef CS_PARANOID CS_ASSERT(oSetMessageData != nullptr); #endif oWriteMessage(pMessage, protobufBuffer, nCalcualtedCRCSize); pBaseCmd->strMoveCrc = oSetMessageData(&pBaseCmd->strMoveCrc, pMessage, &nHasBits); I::MemAlloc->Free(pMessage); return true; } return false; } }