mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Engine: rebuild CClientState::ProcessCreateStringTable()
Rebuild CClientState::ProcessCreateStringTable() and add notes for multiple 'potential' exploit vectors that are currently in place. Also add wrappers for compressing/decompressing net packets.
This commit is contained in:
parent
ee64d07e5b
commit
f18a4c17a4
@ -185,6 +185,24 @@ public:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// server messages:
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
class SVC_CreateStringTable : public CNetMessage
|
||||
{
|
||||
public:
|
||||
const char* m_szTableName;
|
||||
int m_nMaxEntries;
|
||||
int m_nNumEntries;
|
||||
char m_bUserDataFixedSize;
|
||||
char _padding0[3];
|
||||
int m_nUserDataSize;
|
||||
int m_nUserDataSizeBits;
|
||||
int m_nDictFlags;
|
||||
int m_nLength;
|
||||
bf_read m_DataIn;
|
||||
bf_write m_DataOut;
|
||||
char m_bDataCompressed;
|
||||
char m_szTableNameBuffer[260];
|
||||
};
|
||||
|
||||
class SVC_Print : public CNetMessage
|
||||
{
|
||||
public:
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "tier0/frametask.h"
|
||||
#include "engine/common.h"
|
||||
#include "engine/host.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "engine/server/server.h"
|
||||
#endif // !CLIENT_DLL
|
||||
@ -173,6 +174,12 @@ bool CClientState::VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: processes string commands sent from server
|
||||
// Input : *thisptr -
|
||||
// *msg -
|
||||
// Output : true on success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::_ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg)
|
||||
{
|
||||
CClientState* const thisptr_ADJ = thisptr->GetShiftedBasePointer();
|
||||
@ -207,6 +214,99 @@ bool CClientState::_ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg)
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: create's string tables from string table data sent from server
|
||||
// Input : *thisptr -
|
||||
// *msg -
|
||||
// Output : true on success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::_ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* msg)
|
||||
{
|
||||
CClientState* const cl = thisptr->GetShiftedBasePointer();
|
||||
|
||||
if (!cl->IsConnected())
|
||||
return false;
|
||||
|
||||
CNetworkStringTableContainer* const container = cl->m_StringTableContainer;
|
||||
|
||||
// Must have a string table container at this point!
|
||||
if (!container)
|
||||
{
|
||||
Assert(0);
|
||||
|
||||
COM_ExplainDisconnection(true, "String table container missing.\n");
|
||||
v_Host_Disconnect(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
container->AllowCreation(true);
|
||||
const ssize_t startbit = msg->m_DataIn.GetNumBitsRead();
|
||||
|
||||
CNetworkStringTable* const table = (CNetworkStringTable*)container->CreateStringTable(false, msg->m_szTableName,
|
||||
msg->m_nMaxEntries, msg->m_nUserDataSize, msg->m_nUserDataSizeBits, msg->m_nDictFlags);
|
||||
|
||||
table->SetTick(cl->GetServerTickCount());
|
||||
CClientState__HookClientStringTable(cl, msg->m_szTableName);
|
||||
|
||||
if (msg->m_bDataCompressed)
|
||||
{
|
||||
// TODO[ AMOS ]: check sizes before proceeding to decode
|
||||
// the string tables
|
||||
unsigned int msgUncompressedSize = msg->m_DataIn.ReadLong();
|
||||
unsigned int msgCompressedSize = msg->m_DataIn.ReadLong();
|
||||
|
||||
size_t uncompressedSize = msgUncompressedSize;
|
||||
size_t compressedSize = msgCompressedSize;
|
||||
|
||||
bool bSuccess = false;
|
||||
|
||||
// TODO[ AMOS ]: this could do better. The engine does UINT_MAX-3
|
||||
// which doesn't look very great. Clamp to more reasonable values
|
||||
// than UINT_MAX-3 or UINT_MAX/2? The largest string tables sent
|
||||
// are settings layout string tables which are roughly 256KiB
|
||||
// compressed with LZSS. perhaps clamp this to something like 16MiB?
|
||||
if (msg->m_DataIn.TotalBytesAvailable() > 0 &&
|
||||
msgCompressedSize <= (unsigned int)msg->m_DataIn.TotalBytesAvailable() &&
|
||||
msgCompressedSize < UINT_MAX / 2 && msgUncompressedSize < UINT_MAX / 2)
|
||||
{
|
||||
// allocate buffer for uncompressed data, align to 4 bytes boundary
|
||||
uint8_t* const uncompressedBuffer = new uint8_t[PAD_NUMBER(msgUncompressedSize, 4)];
|
||||
uint8_t* const compressedBuffer = new uint8_t[PAD_NUMBER(msgCompressedSize, 4)];
|
||||
|
||||
msg->m_DataIn.ReadBytes(compressedBuffer, msgCompressedSize);
|
||||
|
||||
// uncompress data
|
||||
bSuccess = NET_BufferToBufferDecompress(compressedBuffer, compressedSize, uncompressedBuffer, uncompressedSize);
|
||||
bSuccess &= (uncompressedSize == msgUncompressedSize);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
bf_read data(uncompressedBuffer, (int)uncompressedSize);
|
||||
table->ParseUpdate(data, msg->m_nNumEntries);
|
||||
}
|
||||
|
||||
delete[] uncompressedBuffer;
|
||||
delete[] compressedBuffer;
|
||||
}
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
Assert(false);
|
||||
DevWarning(eDLL_T::CLIENT, "%s: Received malformed string table message!\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
table->ParseUpdate(msg->m_DataIn, msg->m_nNumEntries);
|
||||
}
|
||||
|
||||
container->AllowCreation(false);
|
||||
const ssize_t endbit = msg->m_DataIn.GetNumBitsRead();
|
||||
|
||||
return (endbit - startbit) == msg->m_nLength;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: get authentication token for current connection context
|
||||
// Input : *connectParams -
|
||||
@ -295,6 +395,7 @@ void VClientState::Detour(const bool bAttach) const
|
||||
DetourSetup(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing, bAttach);
|
||||
DetourSetup(&CClientState__ProcessStringCmd, &CClientState::_ProcessStringCmd, bAttach);
|
||||
DetourSetup(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick, bAttach);
|
||||
DetourSetup(&CClientState__ProcessCreateStringTable, &CClientState::_ProcessCreateStringTable, bAttach);
|
||||
DetourSetup(&CClientState__Connect, &CClientState::VConnect, bAttach);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "public/inetmsghandler.h"
|
||||
#include "public/isnapshotmgr.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "engine/networkstringtable.h"
|
||||
#include "engine/debugoverlay.h"
|
||||
#include "engine/clockdriftmgr.h"
|
||||
#include "engine/framesnapshot.h"
|
||||
@ -38,8 +39,10 @@ public: // Hook statics.
|
||||
static void VConnectionClosing(CClientState* thisptr, const char* szReason);
|
||||
static bool _ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg);
|
||||
static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg);
|
||||
static bool _ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* msg);
|
||||
static void VConnect(CClientState* thisptr, connectparams_t* connectParams);
|
||||
|
||||
|
||||
public:
|
||||
bool IsPaused() const;
|
||||
bool IsActive(void) const;
|
||||
@ -63,7 +66,12 @@ public:
|
||||
protected:
|
||||
FORCEINLINE CClientState* GetShiftedBasePointer(void)
|
||||
{
|
||||
char* const pShifted = reinterpret_cast<char*>(this) - 0x10; // Shifted due to compiler optimizations.
|
||||
// NOTE: you must check in the disassembler if the CClientState method
|
||||
// you detour is shifting the 'this' pointer with 16 bytes forward, if
|
||||
// so, you need to call this and use this pointer instead! The shifting
|
||||
// happens as part of a compiler optimization that truncated the vtable
|
||||
// pointers off so the 'this' pointer points directly to the class data
|
||||
char* const pShifted = reinterpret_cast<char*>(this) - 0x10;
|
||||
return reinterpret_cast<CClientState*>(pShifted);
|
||||
}
|
||||
|
||||
@ -123,7 +131,7 @@ public:
|
||||
_QWORD m_pServerClasses;
|
||||
int m_nServerClasses;
|
||||
int m_nServerClassBits;
|
||||
__int64 m_StringTableContainer;
|
||||
CNetworkStringTableContainer* m_StringTableContainer;
|
||||
char m_PersistenceData[98304];
|
||||
_BYTE m_bPersistenceBaselineRecvd;
|
||||
int m_nPersistenceBaselineEntries;
|
||||
@ -215,8 +223,11 @@ inline void(*CClientState__RunFrame)(CClientState* thisptr);
|
||||
inline void(*CClientState__Connect)(CClientState* thisptr, connectparams_t* connectParams);
|
||||
inline void(*CClientState__Disconnect)(CClientState* thisptr, bool bSendTrackingContext);
|
||||
inline void(*CClientState__ConnectionClosing)(CClientState* thisptr, const char* szReason);
|
||||
inline bool(*CClientState__HookClientStringTable)(CClientState* thisptr, const char* tableName);
|
||||
|
||||
inline bool(*CClientState__ProcessStringCmd)(CClientState* thisptr, NET_StringCmd* msg);
|
||||
inline bool(*CClientState__ProcessServerTick)(CClientState* thisptr, SVC_ServerTick* msg);
|
||||
inline bool(*CClientState__ProcessCreateStringTable)(CClientState* thisptr, SVC_CreateStringTable* msg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VClientState : public IDetour
|
||||
@ -227,8 +238,10 @@ class VClientState : public IDetour
|
||||
LogFunAdr("CClientState::Connect", CClientState__Connect);
|
||||
LogFunAdr("CClientState::Disconnect", CClientState__Disconnect);
|
||||
LogFunAdr("CClientState::ConnectionClosing", CClientState__ConnectionClosing);
|
||||
LogFunAdr("CClientState::HookClientStringTable", CClientState__HookClientStringTable);
|
||||
LogFunAdr("CClientState::ProcessStringCmd", CClientState__ProcessStringCmd);
|
||||
LogFunAdr("CClientState::ProcessServerTick", CClientState__ProcessServerTick);
|
||||
LogFunAdr("CClientState::ProcessCreateStringTable", CClientState__ProcessCreateStringTable);
|
||||
LogVarAdr("g_ClientState", g_pClientState);
|
||||
LogVarAdr("g_ClientState_Shifted", g_pClientState_Shifted);
|
||||
}
|
||||
@ -238,8 +251,10 @@ class VClientState : public IDetour
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 48 8B 32").GetPtr(CClientState__Connect);
|
||||
g_GameDll.FindPatternSIMD("40 56 57 41 54 41 55 41 57 48 83 EC 30 44 0F B6 FA").GetPtr(CClientState__Disconnect);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 0F 8E ?? ?? ?? ??").GetPtr(CClientState__ConnectionClosing);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B D9 48 8B FA 48 8B 89 ?? ?? ?? ?? 48 85 C9 0F 84 ?? ?? ?? ??").GetPtr(CClientState__HookClientStringTable);
|
||||
g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 80 B9 ?? ?? ?? ?? ?? 48 8B DA").GetPtr(CClientState__ProcessStringCmd);
|
||||
g_GameDll.FindPatternSIMD("40 57 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B F9 7C 66").GetPtr(CClientState__ProcessServerTick);
|
||||
g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 53 56 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??").GetPtr(CClientState__ProcessCreateStringTable);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
|
@ -57,6 +57,54 @@ int NET_SendDatagram(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: compresses the input buffer into the output buffer
|
||||
// Input : *dest -
|
||||
// *destLen -
|
||||
// *source -
|
||||
// sourceLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NET_BufferToBufferCompress(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen)
|
||||
{
|
||||
CLZSS lzss;
|
||||
uint32_t compLen = (uint32_t)sourceLen;
|
||||
|
||||
if (!lzss.CompressNoAlloc(source, (uint32_t)sourceLen, dest, &compLen))
|
||||
{
|
||||
memcpy(dest, source, sourceLen);
|
||||
|
||||
*destLen = sourceLen;
|
||||
return false;
|
||||
}
|
||||
|
||||
*destLen = compLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: decompresses the input buffer into the output buffer
|
||||
// Input : *source -
|
||||
// &sourceLen -
|
||||
// *dest -
|
||||
// destLen -
|
||||
// Output : true on success, false otherwise
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int NET_BufferToBufferDecompress(uint8_t* const source, size_t& sourceLen, uint8_t* const dest, const size_t destLen)
|
||||
{
|
||||
Assert(source);
|
||||
Assert(sourceLen);
|
||||
|
||||
CLZSS lzss;
|
||||
|
||||
if (lzss.IsCompressed(source))
|
||||
{
|
||||
return lzss.SafeUncompress(source, dest, (unsigned int)destLen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: safely decompresses the input buffer into the output buffer
|
||||
// Input : *lzss -
|
||||
@ -65,7 +113,7 @@ int NET_SendDatagram(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool
|
||||
// unBufSize -
|
||||
// Output : total decompressed bytes
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int NET_Decompress(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)
|
||||
unsigned int NET_BufferToBufferDecompress_LZSS(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)
|
||||
{
|
||||
return lzss->SafeUncompress(pInput, pOutput, unBufSize);
|
||||
}
|
||||
@ -301,7 +349,9 @@ void VNet::Detour(const bool bAttach) const
|
||||
DetourSetup(&v_NET_Config, &NET_Config, bAttach);
|
||||
DetourSetup(&v_NET_ReceiveDatagram, &NET_ReceiveDatagram, bAttach);
|
||||
DetourSetup(&v_NET_SendDatagram, &NET_SendDatagram, bAttach);
|
||||
DetourSetup(&v_NET_Decompress, &NET_Decompress, bAttach);
|
||||
|
||||
DetourSetup(&v_NET_BufferToBufferCompress, &NET_BufferToBufferCompress, bAttach);
|
||||
DetourSetup(&v_NET_BufferToBufferDecompress_LZSS, &NET_BufferToBufferDecompress_LZSS, bAttach);
|
||||
DetourSetup(&v_NET_PrintFunc, &NET_PrintFunc, bAttach);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ inline void(*v_NET_SetKey)(netkey_t* pKey, const char* szHash);
|
||||
inline void(*v_NET_Config)(void);
|
||||
inline bool(*v_NET_ReceiveDatagram)(int iSocket, netpacket_s* pInpacket, bool bRaw);
|
||||
inline int(*v_NET_SendDatagram)(SOCKET s, void* pPayload, int iLenght, netadr_t* pAdr, bool bEncrypted);
|
||||
inline unsigned int(*v_NET_Decompress)(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
inline bool(*v_NET_BufferToBufferCompress)(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen);
|
||||
inline unsigned int(*v_NET_BufferToBufferDecompress_LZSS)(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
inline void(*v_NET_PrintFunc)(const char* fmt, ...);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -35,6 +36,11 @@ void NET_GenerateKey();
|
||||
void NET_PrintFunc(const char* fmt, ...);
|
||||
void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow);
|
||||
|
||||
bool NET_BufferToBufferCompress(uint8_t* const dest, size_t* const destLen, uint8_t* const source, const size_t sourceLen);
|
||||
unsigned int NET_BufferToBufferDecompress(uint8_t* pInput, size_t& coBufsize, uint8_t* pOutput, const size_t unBufSize);
|
||||
|
||||
unsigned int NET_BufferToBufferDecompress_LZSS(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
|
||||
|
||||
bool NET_ReadMessageType(int* outType, bf_read* buffer);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -53,7 +59,8 @@ class VNet : public IDetour
|
||||
LogFunAdr("NET_SetKey", v_NET_SetKey);
|
||||
LogFunAdr("NET_ReceiveDatagram", v_NET_ReceiveDatagram);
|
||||
LogFunAdr("NET_SendDatagram", v_NET_SendDatagram);
|
||||
LogFunAdr("NET_Decompress", v_NET_Decompress);
|
||||
LogFunAdr("NET_BufferToBufferCompress", v_NET_BufferToBufferCompress);
|
||||
LogFunAdr("NET_BufferToBufferDecompress_LZSS", v_NET_BufferToBufferDecompress_LZSS);
|
||||
LogFunAdr("NET_PrintFunc", v_NET_PrintFunc);
|
||||
LogVarAdr("g_NetAdr", g_pNetAdr);
|
||||
LogVarAdr("g_NetKey", g_pNetKey);
|
||||
@ -66,7 +73,10 @@ class VNet : public IDetour
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 48 83 EC 20 48 8B F9 41 B8").GetPtr(v_NET_SetKey);
|
||||
g_GameDll.FindPatternSIMD("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr(v_NET_ReceiveDatagram);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 ?? ??").GetPtr(v_NET_SendDatagram);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 45 33 F6").GetPtr(v_NET_Decompress);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC 50 48 8B 05 ?? ?? ?? ?? 49 8B E9").GetPtr(v_NET_BufferToBufferCompress);
|
||||
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 45 33 F6").GetPtr(v_NET_BufferToBufferDecompress_LZSS);
|
||||
|
||||
g_GameDll.FindPatternSIMD("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48").GetPtr(v_NET_PrintFunc);
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
|
@ -9,19 +9,32 @@
|
||||
#define NETWORKSTRINGTABLE_H
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlhashtable.h"
|
||||
#include "tier1/bitbuf.h"
|
||||
#include "public/networkstringtabledefs.h"
|
||||
#include "client/client.h"
|
||||
|
||||
typedef int TABLEID;
|
||||
|
||||
class INetworkStringTable
|
||||
{
|
||||
INetworkStringTable* m_pVTable;
|
||||
};
|
||||
|
||||
class CNetworkStringTable : public INetworkStringTable
|
||||
{
|
||||
public:
|
||||
// Updating/Writing
|
||||
virtual bool WriteStringTable(bf_write& buf) = 0;
|
||||
virtual bool ReadStringTable(bf_read& buf) = 0;
|
||||
|
||||
virtual void ParseUpdate(bf_read& buf, int numStrings) = 0;
|
||||
|
||||
virtual pfnStringChanged GetCallback(void) = 0;
|
||||
|
||||
virtual int WriteUpdate(CClient* const client, bf_write& buf, int tickAck) = 0;
|
||||
virtual bool WriteBaselines(SVC_CreateStringTable& msg, char* msgBuffer, int msgBufferSize) = 0;
|
||||
|
||||
virtual void PurgeAllClientSide(void) = 0;
|
||||
virtual void EnableRollback(bool bState) = 0;
|
||||
|
||||
// TODO[ AMOS ]: there are a few more entries below in the vftable that
|
||||
// need to be mapped out, most of them set/get bit fields;
|
||||
// see [ r5apex_ds + 0x1329888 ]
|
||||
|
||||
TABLEID GetTableId(void) const;
|
||||
int GetMaxStrings(void) const;
|
||||
const char* GetTableName(void) const;
|
||||
@ -41,16 +54,20 @@ private:
|
||||
// !TODO
|
||||
};
|
||||
|
||||
class CNetworkStringTableContainer : public INetworkStringTable
|
||||
class CNetworkStringTableContainer : public INetworkStringTableContainer
|
||||
{
|
||||
public:
|
||||
static void WriteUpdateMessage(CNetworkStringTableContainer* thisp, CClient* client, unsigned int tick_ack, bf_write* msg);
|
||||
|
||||
// Guards so game .dll can't create tables at the wrong time
|
||||
inline void AllowCreation(bool state) { m_bAllowCreation = state; }
|
||||
|
||||
private:
|
||||
bool m_bAllowCreation; // create guard
|
||||
int m_nTickCount; // current tick
|
||||
bool m_bLocked; // currently locked?
|
||||
bool m_bEnableRollback; // enables rollback feature
|
||||
|
||||
CUtlVector < CNetworkStringTable* > m_Tables; // the string tables
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,22 @@ public:
|
||||
struct CS_INetChannelHandler : INetChannelHandler
|
||||
{};
|
||||
|
||||
enum netsocket_e
|
||||
{
|
||||
NS_CLIENT = 0, // client socket
|
||||
NS_SERVER, // server socket
|
||||
|
||||
// unknown as this seems unused in R5, but if the socket equals to this in
|
||||
// CServer::ConnectionlessPacketHandler() in case C2S_Challenge, the packet
|
||||
// sent back won't be encrypted
|
||||
NS_UNK0,
|
||||
|
||||
// used for chat room, communities, discord presence, EA/Origin, etc
|
||||
NS_PRESENCE,
|
||||
|
||||
MAX_SOCKETS // 4 in R5
|
||||
};
|
||||
|
||||
typedef struct netpacket_s
|
||||
{
|
||||
netadr_t from;
|
||||
|
76
r5dev/public/networkstringtabledefs.h
Normal file
76
r5dev/public/networkstringtabledefs.h
Normal file
@ -0,0 +1,76 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef NETWORKSTRINGTABLEDEFS_H
|
||||
#define NETWORKSTRINGTABLEDEFS_H
|
||||
|
||||
typedef int TABLEID;
|
||||
|
||||
#define INVALID_STRING_TABLE -1
|
||||
const unsigned short INVALID_STRING_INDEX = ( unsigned short )-1;
|
||||
|
||||
// table index is sent in log2( MAX_TABLES ) bits
|
||||
#define MAX_TABLES 32 // Table id is 4 bits
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class INetworkStringTable;
|
||||
|
||||
typedef void ( *pfnStringChanged )( void* object, INetworkStringTable* stringTable, int stringNumber, char const* newString, void const* newData );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Game .dll shared string table interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
class INetworkStringTable
|
||||
{
|
||||
public:
|
||||
virtual ~INetworkStringTable( void ) {};
|
||||
|
||||
// Table Info
|
||||
virtual const char *GetTableName( void ) const = 0;
|
||||
virtual TABLEID GetTableId( void ) const = 0;
|
||||
virtual int GetNumStrings( void ) const = 0;
|
||||
virtual int GetMaxStrings( void ) const = 0;
|
||||
virtual int GetEntryBits( void ) const = 0;
|
||||
|
||||
// Networking
|
||||
virtual void SetTick( int tick ) = 0;
|
||||
virtual bool ChangedSinceTick( int tick ) const = 0;
|
||||
|
||||
// Accessors (length -1 means don't change user data if string already exits)
|
||||
virtual int AddString( bool bIsServer, const char *value, int length = -1, const void *userdata = 0 ) = 0;
|
||||
virtual int AddString( const char* value ) = 0;
|
||||
|
||||
virtual const char* GetString( int stringNumber ) = 0;
|
||||
|
||||
virtual int Unused0( void ) = 0; // returns -1
|
||||
virtual int Unused1( void ) const = 0; // returns -1
|
||||
virtual int Unused2( void ) const = 0; // returns 0
|
||||
|
||||
virtual void SetStringUserData( int stringNumber, int length, const void *userdata ) = 0;
|
||||
virtual const void* GetStringUserData( int stringNumber, int* length ) = 0;
|
||||
};
|
||||
|
||||
class INetworkStringTableContainer
|
||||
{
|
||||
public:
|
||||
virtual ~INetworkStringTableContainer( void ) {};
|
||||
|
||||
// table creation/destruction
|
||||
virtual INetworkStringTable *CreateStringTable( bool createTableMemory, const char *tableName, int maxentries, int userdatafixedsize = 0, int userdatanetworkbits = 0, int dictFlags = 0 ) = 0;
|
||||
virtual void RemoveAllTables( void ) = 0;
|
||||
|
||||
// table infos
|
||||
virtual INetworkStringTable *FindTable( const char *tableName ) const = 0;
|
||||
virtual INetworkStringTable *GetTable( TABLEID stringTable ) const = 0;
|
||||
virtual int GetNumTables( void ) const = 0;
|
||||
|
||||
virtual void SetAllowClientSideAddString( INetworkStringTable *table, bool bAllowClientSideAddString ) = 0;
|
||||
};
|
||||
|
||||
#endif // NETWORKSTRINGTABLEDEFS_H
|
Loading…
x
Reference in New Issue
Block a user