From e6f45aaa9b41c42a56b74be0f073f719d5cc9ca5 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 15 Aug 2022 02:59:41 +0200 Subject: [PATCH] CBitBuf improvements * Use proper types reflecting assembly from the engine in 'CBitRead::Seek' (some values are 64bit, either changed by Respawn or the compiler used by Respawn). * Confirmed changes made to NETMSG_TYPE_BITS (now 511 instead of 255) and NETMSG_LENGTH_BITS (now 12 which is 511 max instead of 255). * Confirmed msg HUD types. * Enforce NET_MIN_MESSAGE on 'SVC_UserMessage::Process'. * Remove unnecessary padding and add proper symbols where padding was actually used. --- r5dev/common/netmessages.cpp | 10 ++++++---- r5dev/common/netmessages.h | 11 +++++------ r5dev/engine/net.h | 7 +++++++ r5dev/tier1/bitbuf.cpp | 10 +++++----- r5dev/tier1/bitbuf.h | 8 ++------ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/r5dev/common/netmessages.cpp b/r5dev/common/netmessages.cpp index 77c4a5da..c180d47c 100644 --- a/r5dev/common/netmessages.cpp +++ b/r5dev/common/netmessages.cpp @@ -9,6 +9,7 @@ // /////////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" +#include "engine/net.h" #include "common/netmessages.h" bool SVC_Print::Process() @@ -24,13 +25,14 @@ bool SVC_Print::Process() bool SVC_UserMessage::Process() { bf_read buf = m_DataIn; - UserMessages type = (UserMessages)buf.ReadByte(); + int type = buf.ReadByte(); - if (type == UserMessages::TextMsg) + if (type == HUD_PRINTCONSOLE || + type == HUD_PRINTCENTER) { - char text[256]; + char text[MAX_USER_MSG_DATA]; buf.ReadString(text, sizeof(text)); - if (strnlen_s(text, sizeof(text)) > 0) + if (strnlen_s(text, sizeof(text)) >= NET_MIN_MESSAGE) { DevMsg(eDLL_T::SERVER, text); } diff --git a/r5dev/common/netmessages.h b/r5dev/common/netmessages.h index 6306d273..74ab7ddb 100644 --- a/r5dev/common/netmessages.h +++ b/r5dev/common/netmessages.h @@ -2,10 +2,10 @@ #include "tier1/bitbuf.h" #include "public/inetmsghandler.h" -enum class UserMessages : int -{ - TextMsg = 0x2 -}; +#define HUD_PRINTNOTIFY 1 +#define HUD_PRINTCONSOLE 2 +#define HUD_PRINTTALK 3 +#define HUD_PRINTCENTER 4 class INetMessage { @@ -17,7 +17,6 @@ class CNetMessage : public INetMessage public: int m_nGroup; bool m_bReliable; - char padding[3]; void* m_NetChannel; }; @@ -26,7 +25,7 @@ class SVC_Print : public CNetMessage, IServerMessageHandler public: bool Process(); - char padding[8]; + const void* m_pData; const char* m_szText; private: char m_szTextBuffer[2048]; diff --git a/r5dev/engine/net.h b/r5dev/engine/net.h index e5244749..c2cd859f 100644 --- a/r5dev/engine/net.h +++ b/r5dev/engine/net.h @@ -6,6 +6,13 @@ #define FRAGMENT_BITS 8 #define FRAGMENT_SIZE (1< SVC_LASTMSG (6 in Valve Source). +#define NETMSG_LENGTH_BITS 12 // 512 bytes (11 in Valve Source, 256 bytes). +#define NET_MIN_MESSAGE 5 // Even connectionless packets require int32 value (-1) + 1 byte content + /* ==== CNETCHAN ======================================================================================================================================================== */ inline CMemory p_NET_Init; inline auto v_NET_Init = p_NET_Init.RCast(); diff --git a/r5dev/tier1/bitbuf.cpp b/r5dev/tier1/bitbuf.cpp index f4ae292d..310c9dfb 100644 --- a/r5dev/tier1/bitbuf.cpp +++ b/r5dev/tier1/bitbuf.cpp @@ -189,7 +189,7 @@ bool CBitRead::ReadString(char* pStr, int maxLen, bool bLine, int* pOutNumChars) return !IsOverflowed() && !bTooSmall; } -bool CBitRead::Seek(int nPosition) +bool CBitRead::Seek(size_t nPosition) { bool bSucc = true; if (nPosition < 0 || nPosition > m_nDataBits) @@ -198,10 +198,10 @@ bool CBitRead::Seek(int nPosition) bSucc = false; nPosition = m_nDataBits; } - int nHead = m_nDataBytes & 3; // non-multiple-of-4 bytes at head of buffer. We put the "round off" + size_t nHead = m_nDataBytes & 3; // non-multiple-of-4 bytes at head of buffer. We put the "round off" // at the head to make reading and detecting the end efficient. - int nByteOfs = nPosition / 8; + size_t nByteOfs = nPosition / 8; if ((m_nDataBytes < 4) || (nHead && (nByteOfs < nHead))) { // partial first dword @@ -220,7 +220,7 @@ bool CBitRead::Seek(int nPosition) } else { - int nAdjPosition = nPosition - (nHead << 3); + ssize_t nAdjPosition = nPosition - (nHead << 3); m_pDataIn = reinterpret_cast ( reinterpret_cast(m_pData) + ((nAdjPosition / 32) << 2) + nHead); if (m_pData) @@ -239,7 +239,7 @@ bool CBitRead::Seek(int nPosition) return bSucc; } -void CBitRead::StartReading(const void* pData, int nBytes, int iStartBit, int nBits) +void CBitRead::StartReading(const void* pData, size_t nBytes, size_t iStartBit, size_t nBits) { // Make sure it's dword aligned and padded. assert(((unsigned long)pData & 3) == 0); diff --git a/r5dev/tier1/bitbuf.h b/r5dev/tier1/bitbuf.h index 97291296..783a6b4b 100644 --- a/r5dev/tier1/bitbuf.h +++ b/r5dev/tier1/bitbuf.h @@ -14,7 +14,6 @@ typedef enum //----------------------------------------------------------------------------- // Used for serialization //----------------------------------------------------------------------------- -#pragma pack(push,1) class CBitBuffer { public: @@ -27,11 +26,9 @@ public: //////////////////////////////////// const char* m_pDebugName; uint8_t m_bOverflow; - char gap_0x11[7]; size_t m_nDataBits; size_t m_nDataBytes; }; -#pragma pack(pop) class CBitRead : public CBitBuffer { @@ -46,9 +43,8 @@ public: int ReadChar(); bool ReadString(char* pStr, int bufLen, bool bLine = false, int* pOutNumChars = nullptr); - void StartReading(const void* pData, int nBytes, int iStartBit = 0, int nBits = -1); - - bool Seek(int nPosition); + void StartReading(const void* pData, size_t nBytes, size_t iStartBit = 0, size_t nBits = -1); + bool Seek(size_t nPosition); //////////////////////////////////// uint32_t m_nInBufWord;