//====== Copyright � 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(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(NetMessageVtbl::Process, this); }; virtual bool ReadFromBuffer(bf_read* buffer) { return CallVFunc(NetMessageVtbl::ReadFromBuffer, this, buffer); } virtual bool WriteToBuffer(bf_write* buffer) { return CallVFunc(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(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(NetMessageVtbl::Process, this); }; virtual bool ReadFromBuffer(bf_read* buffer) { return CallVFunc(NetMessageVtbl::ReadFromBuffer, this, buffer); } virtual bool WriteToBuffer(bf_write* buffer) { return CallVFunc(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; }; /////////////////////////////////////////////////////////////////////////////////////// // Client messages: /////////////////////////////////////////////////////////////////////////////////////// class CLC_ClientTick : public CNetMessage { public: CLC_ClientTick() = default; CLC_ClientTick(int deltaTick, int stringTableTick) { void** pVFTable = reinterpret_cast(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(NetMessageVtbl::Process, this); }; virtual bool ReadFromBuffer(bf_read* buffer) { return CallVFunc(NetMessageVtbl::ReadFromBuffer, this, buffer); } virtual bool WriteToBuffer(bf_write* buffer) { return CallVFunc(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: }; /////////////////////////////////////////////////////////////////////////////////////// // Shared 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(g_pSVC_Print_VFTable)); LogConAdr("SVC_UserMessage::`vftable'", reinterpret_cast(g_pSVC_UserMessage_VFTable)); LogConAdr("SVC_ServerTick::`vftable'", reinterpret_cast(g_pSVC_ServerTick_VFTable)); LogConAdr("SVC_VoiceData::`vftable'", reinterpret_cast(g_pSVC_VoiceData_VFTable)); LogConAdr("SVC_PlaylistOverrides::`vftable'", reinterpret_cast(g_pSVC_PlaylistOverrides_VFTable)); LogConAdr("CLC_ClientTick::`vftable'", reinterpret_cast(g_pCLC_ClientTick_VFTable)); LogConAdr("CLC_SetPlaylistVarOverride::`vftable'", reinterpret_cast(g_pCLC_SetPlaylistVarOverride_VFTable)); LogConAdr("Base_CmdKeyValues::`vftable'", reinterpret_cast(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; }; ///////////////////////////////////////////////////////////////////////////////