mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Only block 'CLC_SetPlaylistVarOverride' messages when cheats are disabled. The server still needs to be able to override client playlist vars (using 'SVC_PlaylistOverrides'). This isn't a problem, as on any disconnect, the client will reload its own bundled copy.
512 lines
17 KiB
C++
512 lines
17 KiB
C++
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======//
|
||
//
|
||
// Purpose:
|
||
//
|
||
// $NoKeywords: $
|
||
//=============================================================================//
|
||
|
||
#pragma once
|
||
#include "tier1/bitbuf.h"
|
||
#include "public/inetchannel.h"
|
||
#include "public/inetmessage.h"
|
||
#include "public/inetmsghandler.h"
|
||
|
||
#define HUD_PRINTNOTIFY 1
|
||
#define HUD_PRINTCONSOLE 2
|
||
#define HUD_PRINTTALK 3
|
||
#define HUD_PRINTCENTER 4
|
||
|
||
//-------------------------------------------------------------------------------------
|
||
// Forward declarations
|
||
//-------------------------------------------------------------------------------------
|
||
class CNetChan;
|
||
class SVC_Print;
|
||
class SVC_UserMessage;
|
||
class SVC_PlaylistOverrides;
|
||
class CLC_SetPlaylistVarOverride;
|
||
class Base_CmdKeyValues;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// MM_HEARTBEAT
|
||
//-------------------------------------------------------------------------
|
||
//inline CMemory MM_Heartbeat__ToString; // server HeartBeat? (baseserver.cpp).
|
||
|
||
//-------------------------------------------------------------------------
|
||
// SVC_Print
|
||
//-------------------------------------------------------------------------
|
||
inline bool(*SVC_Print_Process)(SVC_Print* thisptr);
|
||
inline void* g_pSVC_Print_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// SVC_UserMessage
|
||
//-------------------------------------------------------------------------
|
||
inline bool(*SVC_UserMessage_Process)(SVC_UserMessage* thisptr);
|
||
inline void* g_pSVC_UserMessage_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// SVC_ServerTick
|
||
//-------------------------------------------------------------------------
|
||
inline void* g_pSVC_ServerTick_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// SVC_VoiceData
|
||
//-------------------------------------------------------------------------
|
||
inline void* g_pSVC_VoiceData_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// SVC_PlaylistOverrides
|
||
//-------------------------------------------------------------------------
|
||
inline void* g_pSVC_PlaylistOverrides_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// CLC_ClientTick
|
||
//-------------------------------------------------------------------------
|
||
inline void* g_pCLC_ClientTick_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// CLC_SetPlaylistVarOverride
|
||
//-------------------------------------------------------------------------
|
||
inline bool(*CLC_SetPlaylistVarOverride_ReadFromBuffer)(CLC_SetPlaylistVarOverride* thisptr, bf_read* buffer);
|
||
inline bool(*CLC_SetPlaylistVarOverride_WriteToBuffer)(CLC_SetPlaylistVarOverride* thisptr, bf_write* buffer);
|
||
inline void* g_pCLC_SetPlaylistVarOverride_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Base_CmdKeyValues
|
||
//-------------------------------------------------------------------------
|
||
inline bool(*Base_CmdKeyValues_ReadFromBuffer)(Base_CmdKeyValues* thisptr, bf_read* buffer);
|
||
inline bool(*Base_CmdKeyValues_WriteToBuffer)(Base_CmdKeyValues* thisptr, bf_write* buffer);
|
||
inline void* g_pBase_CmdKeyValues_VFTable = nullptr;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Enumeration of the INetMessage class
|
||
//-------------------------------------------------------------------------
|
||
enum NetMessageVtbl
|
||
{
|
||
Destructor = 0,
|
||
SetNetChannel,
|
||
SetReliable,
|
||
Process,
|
||
ReadFromBuffer,
|
||
WriteToBuffer,
|
||
IsReliable,
|
||
GetGroup,
|
||
GetType,
|
||
GetName,
|
||
GetNetChannel,
|
||
ToString,
|
||
GetSize
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Enumeration of netmessage types
|
||
//-------------------------------------------------------------------------
|
||
enum NetMessageType
|
||
{
|
||
net_StringCmd = 3,
|
||
net_SetConVar = 4,
|
||
net_SignonState = 5,
|
||
net_MTXUserMsg = 6,
|
||
|
||
svc_ServerInfo = 7,
|
||
svc_SendTable = 8,
|
||
svc_ClassInfo = 9,
|
||
svc_SetPause = 10,
|
||
svc_Playlists = 11,
|
||
svc_CreateStringTable = 12,
|
||
svc_UpdateStringTable = 13,
|
||
svc_VoiceData = 14,
|
||
svc_DurangoVoiceData = 15,
|
||
svc_Print = 16,
|
||
svc_Sounds = 17,
|
||
svc_FixAngle = 18,
|
||
svc_CrosshairAngle = 19,
|
||
svc_GrantClientSidePickup = 20,
|
||
svc_ServerTick = 22,
|
||
svc_PersistenceDefFile = 23,
|
||
svc_UseCachedPersistenceDefFile = 24,
|
||
svc_PersistenceBaseline = 25,
|
||
svc_PersistenceUpdateVar = 26,
|
||
svc_PersistenceNotifySaved = 27,
|
||
svc_DLCNotifyOwnership = 28,
|
||
svc_MatchmakingETAs = 29,
|
||
svc_MatchmakingStatus = 30,
|
||
svc_MTXUserInfo = 31,
|
||
svc_PlaylistChange = 32,
|
||
svc_SetTeam = 33,
|
||
svc_PlaylistOverrides = 34,
|
||
svc_AntiCheat = 35,
|
||
svc_AntiCheatChallenge = 36,
|
||
svc_UserMessage = 37,
|
||
svc_Snapshot = 40,
|
||
svc_TempEntities = 41,
|
||
svc_Menu = 42,
|
||
svc_CmdKeyValues = 43,
|
||
svc_DatatableChecksum = 44,
|
||
|
||
clc_ClientInfo = 45,
|
||
clc_Move = 46,
|
||
clc_VoiceData = 47,
|
||
clc_DurangoVoiceData = 48,
|
||
clc_FileCRCCheck = 50,
|
||
clc_LoadingProgress = 52,
|
||
clc_PersistenceRequestSave = 53,
|
||
clc_PersistenceClientToken = 54,
|
||
clc_SetClientEntitlements = 55,
|
||
clc_SetPlaylistVarOverride = 56,
|
||
clc_ClaimClientSidePickup = 57,
|
||
clc_CmdKeyValues = 59,
|
||
clc_ClientTick = 60,
|
||
clc_ClientSayText = 61,
|
||
clc_PINTelemetryData = 62,
|
||
clc_AntiCheat = 63,
|
||
clc_AntiCheatChallenge = 64,
|
||
clc_GamepadMsg = 65,
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Enumeration of netmessage groups
|
||
//-------------------------------------------------------------------------
|
||
enum NetMessageGroup
|
||
{
|
||
NoReplay = 2,
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
class CNetMessage : public INetMessage
|
||
{
|
||
public:
|
||
int m_nGroup;
|
||
bool m_bReliable;
|
||
CNetChan* m_NetChannel;
|
||
INetMessageHandler* m_pMessageHandler;
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
// server messages:
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
class SVC_Print : public CNetMessage
|
||
{
|
||
public:
|
||
virtual ~SVC_Print() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) = 0;
|
||
virtual void SetReliable(bool state) = 0;
|
||
|
||
virtual bool Process(void) = 0; bool ProcessImpl(void);
|
||
|
||
virtual bool ReadFromBuffer(bf_read* buffer) = 0;
|
||
virtual bool WriteToBuffer(bf_write* buffer) = 0;
|
||
|
||
virtual bool IsReliable(void) const = 0;
|
||
|
||
virtual int GetGroup(void) const = 0;
|
||
virtual int GetType(void) const = 0;
|
||
virtual const char* GetName(void) const = 0;
|
||
virtual CNetChan* GetNetChannel(void) const = 0;
|
||
virtual const char* ToString(void) const = 0;
|
||
virtual size_t GetSize(void) const = 0;
|
||
|
||
const void* m_pData;
|
||
const char* m_szText;
|
||
private:
|
||
char m_szTextBuffer[2048];
|
||
};
|
||
|
||
class SVC_UserMessage : public CNetMessage
|
||
{
|
||
public:
|
||
virtual ~SVC_UserMessage() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) = 0;
|
||
virtual void SetReliable(bool state) = 0;
|
||
|
||
virtual bool Process(void) = 0; bool ProcessImpl(void);
|
||
|
||
virtual bool ReadFromBuffer(bf_read* buffer) = 0;
|
||
virtual bool WriteToBuffer(bf_write* buffer) = 0;
|
||
|
||
virtual bool IsReliable(void) const = 0;
|
||
|
||
virtual int GetGroup(void) const = 0;
|
||
virtual int GetType(void) const = 0;
|
||
virtual const char* GetName(void) const = 0;
|
||
virtual CNetChan* GetNetChannel(void) const = 0;
|
||
virtual const char* ToString(void) const = 0;
|
||
virtual size_t GetSize(void) const = 0;
|
||
|
||
int m_nMsgType;
|
||
int m_nLength; // data length in bits
|
||
bf_read m_DataIn;
|
||
bf_write m_DataOut;
|
||
};
|
||
|
||
class SVC_ServerTick : public CNetMessage
|
||
{
|
||
public:
|
||
SVC_ServerTick() = default;
|
||
SVC_ServerTick(int tick, float hostFrametime, float hostFrametime_stddeviation, uint8_t cpuPercent)
|
||
{
|
||
void** pVFTable = reinterpret_cast<void**>(this);
|
||
*pVFTable = g_pSVC_ServerTick_VFTable;
|
||
|
||
m_bReliable = false;
|
||
m_NetChannel = nullptr;
|
||
m_NetTick.m_nServerTick = tick;
|
||
m_NetTick.m_nClientTick = tick;
|
||
|
||
m_NetTick.m_flHostFrameTime = hostFrametime;
|
||
m_NetTick.m_flHostFrameTimeStdDeviation = hostFrametime_stddeviation;
|
||
m_NetTick.m_nServerCPU = cpuPercent;
|
||
};
|
||
|
||
virtual ~SVC_ServerTick() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; }
|
||
virtual void SetReliable(bool state) { m_bReliable = state; };
|
||
|
||
virtual bool Process(void)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::Process, this);
|
||
};
|
||
virtual bool ReadFromBuffer(bf_read* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::ReadFromBuffer, this, buffer);
|
||
}
|
||
virtual bool WriteToBuffer(bf_write* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::WriteToBuffer, this, buffer);
|
||
}
|
||
|
||
virtual bool IsReliable(void) const { return m_bReliable; };
|
||
|
||
virtual int GetGroup(void) const { return m_nGroup; };
|
||
virtual int GetType(void) const { return NetMessageType::svc_ServerTick; };
|
||
virtual const char* GetName(void) const { return "svc_ServerTick"; };
|
||
virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; };
|
||
virtual const char* ToString(void) const
|
||
{
|
||
static char szBuf[4096];
|
||
V_snprintf(szBuf, sizeof(szBuf), "%s: server tick %i", this->GetName(), m_NetTick.m_nServerTick);
|
||
|
||
return szBuf;
|
||
};
|
||
virtual size_t GetSize(void) const { return sizeof(SVC_ServerTick); };
|
||
|
||
nettick_t m_NetTick;
|
||
};
|
||
|
||
struct SVC_VoiceData : public CNetMessage
|
||
{
|
||
public:
|
||
SVC_VoiceData() = default;
|
||
SVC_VoiceData(int senderClient, int nBytes, char* data)
|
||
{
|
||
void** pVFTable = reinterpret_cast<void**>(this);
|
||
*pVFTable = g_pSVC_VoiceData_VFTable;
|
||
|
||
m_bReliable = false;
|
||
m_NetChannel = nullptr;
|
||
|
||
m_nFromClient = senderClient;
|
||
m_nLength = nBytes; // length in bits
|
||
m_DataOut = data;
|
||
|
||
m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer
|
||
};
|
||
|
||
virtual ~SVC_VoiceData() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; }
|
||
virtual void SetReliable(bool state) { m_bReliable = state; };
|
||
|
||
virtual bool Process(void)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::Process, this);
|
||
};
|
||
virtual bool ReadFromBuffer(bf_read* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::ReadFromBuffer, this, buffer);
|
||
}
|
||
virtual bool WriteToBuffer(bf_write* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::WriteToBuffer, this, buffer);
|
||
}
|
||
|
||
virtual bool IsReliable(void) const { return m_bReliable; };
|
||
|
||
virtual int GetGroup(void) const { return m_nGroup; };
|
||
virtual int GetType(void) const { return NetMessageType::svc_VoiceData; };
|
||
virtual const char* GetName(void) const { return "svc_VoiceData"; };
|
||
virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; };
|
||
virtual const char* ToString(void) const
|
||
{
|
||
static char szBuf[4096];
|
||
V_snprintf(szBuf, sizeof(szBuf), "%s: client %i, bytes %i", this->GetName(), m_nFromClient, ((m_nLength + 7) >> 3));
|
||
|
||
return szBuf;
|
||
};
|
||
virtual size_t GetSize(void) const { return sizeof(SVC_VoiceData); };
|
||
|
||
int m_nFromClient;
|
||
int m_nLength;
|
||
bf_read m_DataIn;
|
||
void* m_DataOut;
|
||
};
|
||
|
||
class SVC_PlaylistOverrides : public CNetMessage
|
||
{
|
||
private:
|
||
int m_nMsgType;
|
||
int m_nLength; // data length in bits
|
||
bf_read m_DataIn;
|
||
bf_write m_DataOut;
|
||
};
|
||
|
||
class CLC_ClientTick : public CNetMessage
|
||
{
|
||
public:
|
||
CLC_ClientTick() = default;
|
||
CLC_ClientTick(int deltaTick, int stringTableTick)
|
||
{
|
||
void** pVFTable = reinterpret_cast<void**>(this);
|
||
*pVFTable = g_pCLC_ClientTick_VFTable;
|
||
|
||
m_bReliable = false;
|
||
m_NetChannel = nullptr;
|
||
|
||
m_nDeltaTick = deltaTick;
|
||
m_nStringTableTick = stringTableTick;
|
||
};
|
||
|
||
virtual ~CLC_ClientTick() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; }
|
||
virtual void SetReliable(bool state) { m_bReliable = state; };
|
||
|
||
virtual bool Process(void)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::Process, this);
|
||
};
|
||
virtual bool ReadFromBuffer(bf_read* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::ReadFromBuffer, this, buffer);
|
||
}
|
||
virtual bool WriteToBuffer(bf_write* buffer)
|
||
{
|
||
return CallVFunc<bool>(NetMessageVtbl::WriteToBuffer, this, buffer);
|
||
}
|
||
|
||
virtual bool IsReliable(void) const { return m_bReliable; };
|
||
|
||
virtual int GetGroup(void) const { return m_nGroup; };
|
||
virtual int GetType(void) const { return NetMessageType::clc_ClientTick; };
|
||
virtual const char* GetName(void) const { return "clc_ClientTick"; };
|
||
virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; };
|
||
virtual const char* ToString(void) const
|
||
{
|
||
static char szBuf[4096];
|
||
V_snprintf(szBuf, sizeof(szBuf), "%s: client tick %i", this->GetName(), m_nDeltaTick);
|
||
|
||
return szBuf;
|
||
};
|
||
virtual size_t GetSize(void) const { return sizeof(CLC_ClientTick); };
|
||
|
||
int m_nDeltaTick;
|
||
int m_nStringTableTick;
|
||
};
|
||
|
||
class CLC_SetPlaylistVarOverride : public CNetMessage
|
||
{
|
||
public:
|
||
static bool ReadFromBufferImpl(CLC_SetPlaylistVarOverride* thisptr, bf_read* buffer);
|
||
static bool WriteToBufferImpl(CLC_SetPlaylistVarOverride* thisptr, bf_write* buffer);
|
||
|
||
private:
|
||
// !TODO:
|
||
};
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
// Client messages:
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
struct NET_StringCmd : CNetMessage
|
||
{
|
||
const char* cmd;
|
||
char buffer[1024];
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
// This message is subclassed by 'SVC_CmdKeyValues' and 'CLC_CmdKeyValues'
|
||
class Base_CmdKeyValues : public CNetMessage
|
||
{
|
||
public:
|
||
virtual ~Base_CmdKeyValues() {};
|
||
|
||
virtual void SetNetChannel(CNetChan* netchan) = 0;
|
||
virtual void SetReliable(bool state) = 0;
|
||
|
||
virtual bool Process(void) = 0;
|
||
|
||
virtual bool ReadFromBuffer(bf_read* buffer) = 0;
|
||
static bool ReadFromBufferImpl(Base_CmdKeyValues* thisptr, bf_read* buffer);
|
||
|
||
virtual bool WriteToBuffer(bf_write* buffer) = 0;
|
||
static bool WriteToBufferImpl(Base_CmdKeyValues* thisptr, bf_write* buffer);
|
||
|
||
virtual bool IsReliable(void) const = 0;
|
||
|
||
virtual int GetGroup(void) const = 0;
|
||
virtual int GetType(void) const = 0;
|
||
virtual const char* GetName(void) const = 0;
|
||
virtual CNetChan* GetNetChannel(void) const = 0;
|
||
virtual const char* ToString(void) const = 0;
|
||
virtual size_t GetSize(void) const = 0;
|
||
|
||
int m_nMsgType;
|
||
int m_nLength; // data length in bits
|
||
bf_read m_DataIn;
|
||
bf_write m_DataOut;
|
||
};
|
||
|
||
bool ShouldReplayMessage(const CNetMessage* msg);
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
class V_NetMessages : public IDetour
|
||
{
|
||
virtual void GetAdr(void) const
|
||
{
|
||
LogConAdr("SVC_Print::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_Print_VFTable));
|
||
LogConAdr("SVC_UserMessage::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_UserMessage_VFTable));
|
||
LogConAdr("SVC_ServerTick::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_ServerTick_VFTable));
|
||
LogConAdr("SVC_VoiceData::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_VoiceData_VFTable));
|
||
LogConAdr("SVC_PlaylistOverrides::`vftable'", reinterpret_cast<uintptr_t>(g_pSVC_PlaylistOverrides_VFTable));
|
||
LogConAdr("CLC_ClientTick::`vftable'", reinterpret_cast<uintptr_t>(g_pCLC_ClientTick_VFTable));
|
||
LogConAdr("CLC_SetPlaylistVarOverride::`vftable'", reinterpret_cast<uintptr_t>(g_pCLC_SetPlaylistVarOverride_VFTable));
|
||
LogConAdr("Base_CmdKeyValues::`vftable'", reinterpret_cast<uintptr_t>(g_pBase_CmdKeyValues_VFTable));
|
||
//LogFunAdr("MM_Heartbeat::ToString", MM_Heartbeat__ToString.GetPtr());
|
||
}
|
||
virtual void GetFun(void) const
|
||
{
|
||
//MM_Heartbeat__ToString = g_GameDll.FindPatternSIMD("48 83 EC 38 E8 ?? ?? ?? ?? 3B 05 ?? ?? ?? ??");
|
||
// 48 83 EC 38 E8 ? ? ? ? 3B 05 ? ? ? ?
|
||
}
|
||
virtual void GetVar(void) const { }
|
||
virtual void GetCon(void) const
|
||
{
|
||
// We get the actual address of the vftable here, not the class instance.
|
||
g_pSVC_Print_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_Print@@");
|
||
g_pSVC_UserMessage_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_UserMessage@@");
|
||
g_pSVC_ServerTick_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_ServerTick@@");
|
||
g_pSVC_VoiceData_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_VoiceData@@");
|
||
g_pSVC_PlaylistOverrides_VFTable = g_GameDll.GetVirtualMethodTable(".?AVSVC_PlaylistOverrides@@");
|
||
g_pCLC_ClientTick_VFTable = g_GameDll.GetVirtualMethodTable(".?AVCLC_ClientTick@@");
|
||
g_pCLC_SetPlaylistVarOverride_VFTable = g_GameDll.GetVirtualMethodTable(".?AVCLC_SetPlaylistVarOverride@@");
|
||
g_pBase_CmdKeyValues_VFTable = g_GameDll.GetVirtualMethodTable(".?AVBase_CmdKeyValues@@");
|
||
}
|
||
virtual void Attach(void) const;
|
||
virtual void Detach(void) const;
|
||
};
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|