From 6feb41c285db95b25c278c965a932db8a34ea50b Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 2 Apr 2022 02:48:54 +0200 Subject: [PATCH] Partial CNetChan class rebuild and implementation (see description) * Adapt codebase to new class to reduce rune-like code. * Fixed several bugs where the global CClient pointer was used instead of the instance in question to issue bans and display information about a certain client in CBanSystem and Pylon. * Upgraded CBanSystem and Pylon to use IPv6 instead (including IPv4 mapped IPv6 addresses). This breaks all existing banlist files! All bans have to be re-issued or the existing file has to be updated to use IPv4 mapped IPv6 addresses and renamed to 'banlist.json', and moved to the root of the 'platform' folder. --- r5dev/common/netmessages.h | 27 +++ r5dev/core/init.cpp | 4 +- r5dev/core/stdafx.h | 4 + r5dev/engine/baseclient.cpp | 4 +- r5dev/engine/baseclient.h | 45 ++-- r5dev/engine/baseserver.cpp | 12 +- r5dev/engine/host_state.cpp | 6 +- r5dev/engine/net.cpp | 178 +++++++++++++++- r5dev/engine/net.h | 71 +++++++ r5dev/engine/net_chan.cpp | 295 +++++++++++++------------- r5dev/engine/net_chan.h | 225 ++++++++++++++------ r5dev/gameui/IBrowser.cpp | 6 +- r5dev/networksystem/pylon.cpp | 2 +- r5dev/public/bansystem.cpp | 64 ++---- r5dev/public/include/inetchannel.h | 13 ++ r5dev/public/utility.cpp | 6 +- r5dev/server/IVEngineServer.cpp | 35 +-- r5dev/server/server.cpp | 28 +-- r5dev/server/server.h | 14 +- r5dev/tier0/completion.cpp | 137 ++++-------- r5dev/tier1/NetAdr2.h | 58 +++-- r5dev/tier1/bitbuf.cpp | 75 +++++++ r5dev/tier1/bitbuf.h | 40 ++++ r5dev/tier1/utlmemory.h | 20 ++ r5dev/tier1/utlvector.h | 23 ++ r5dev/vproj/clientsdk.vcxproj | 5 + r5dev/vproj/clientsdk.vcxproj.filters | 15 ++ r5dev/vproj/dedicated.vcxproj | 5 + r5dev/vproj/dedicated.vcxproj.filters | 15 ++ r5dev/vproj/gamesdk.vcxproj | 6 + r5dev/vproj/gamesdk.vcxproj.filters | 18 ++ 31 files changed, 995 insertions(+), 461 deletions(-) create mode 100644 r5dev/public/include/inetchannel.h create mode 100644 r5dev/tier1/bitbuf.cpp create mode 100644 r5dev/tier1/bitbuf.h create mode 100644 r5dev/tier1/utlmemory.h create mode 100644 r5dev/tier1/utlvector.h diff --git a/r5dev/common/netmessages.h b/r5dev/common/netmessages.h index 8d6ceb77..a26288d7 100644 --- a/r5dev/common/netmessages.h +++ b/r5dev/common/netmessages.h @@ -1,5 +1,32 @@ #pragma once +struct CNetMessage +{ + void* iNetMessageVTable; + int m_nGroup; + bool m_bReliable; + char padding[3]; + void* m_NetChannel; +}; + +struct VecNetMessages +{ + CNetMessage** items; + int64_t m_nAllocationCount; + int64_t m_nGrowSize; + int m_Size; + int padding_; +}; + +struct VecNetDataFragments +{ + void** items; + int64_t m_nAllocationCount; + int64_t m_nGrowSize; + int m_Size; + int padding_; +}; + namespace { //------------------------------------------------------------------------- diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 7ce2fb8a..91405a72 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -144,7 +144,7 @@ void Systems_Init() #endif // DEDICATED || GAMEDLL_S3 //CModelLoader_Attach(); - CNetChan_Attach(); + NET_Attach(); ConCommand_Attach(); IConVar_Attach(); CKeyValueSystem_Attach(); @@ -245,7 +245,7 @@ void Systems_Shutdown() #endif // DEDICATED || GAMEDLL_S3 //CModelLoader_Detach(); - CNetChan_Detach(); + NET_Detach(); ConCommand_Detach(); IConVar_Detach(); CKeyValueSystem_Detach(); diff --git a/r5dev/core/stdafx.h b/r5dev/core/stdafx.h index 32a6a2b7..66d08fd1 100644 --- a/r5dev/core/stdafx.h +++ b/r5dev/core/stdafx.h @@ -64,6 +64,10 @@ #include "tier0/platform.h" #include "common/pseudodefs.h" +// Common type declarations to reduce code verbosity. +using std::string; +using std::vector; + #if !defined(SDKLAUNCHER) && !defined (NETCONSOLE) namespace { diff --git a/r5dev/engine/baseclient.cpp b/r5dev/engine/baseclient.cpp index ab34161d..664d7326 100644 --- a/r5dev/engine/baseclient.cpp +++ b/r5dev/engine/baseclient.cpp @@ -55,7 +55,7 @@ PERSISTENCE CBaseClient::GetPersistenceState(void) const //--------------------------------------------------------------------------------- // Purpose: gets the net channel of this client //--------------------------------------------------------------------------------- -void* CBaseClient::GetNetChan(void) const +CNetChan* CBaseClient::GetNetChan(void) const { return m_NetChannel; } @@ -96,7 +96,7 @@ void CBaseClient::SetPersistenceState(PERSISTENCE nPersistenceState) // Purpose: sets the net channel of this client // !TODO : Remove this and rebuild INetChannel //--------------------------------------------------------------------------------- -void CBaseClient::SetNetChan(void* pNetChan) +void CBaseClient::SetNetChan(CNetChan* pNetChan) { m_NetChannel = pNetChan; } diff --git a/r5dev/engine/baseclient.h b/r5dev/engine/baseclient.h index 3c3907a1..7baf2114 100644 --- a/r5dev/engine/baseclient.h +++ b/r5dev/engine/baseclient.h @@ -1,5 +1,6 @@ #pragma once #include "common/protocol.h" +#include "engine/net_chan.h" #include "server/IVEngineServer.h" //----------------------------------------------------------------------------- @@ -19,12 +20,12 @@ public: std::int64_t GetOriginID(void) const; SIGNONSTATE GetSignonState(void) const; PERSISTENCE GetPersistenceState(void) const; - void* GetNetChan(void) const; + CNetChan* GetNetChan(void) const; void SetUserID(std::int32_t nUserID); void SetOriginID(std::int64_t nOriginID); void SetSignonState(SIGNONSTATE nSignonState); void SetPersistenceState(PERSISTENCE nPersistenceState); - void SetNetChan(void* pNetChan); // !TODO: HACK! + void SetNetChan(CNetChan* pNetChan); // !TODO: HACK! bool IsConnected(void) const; bool IsSpawned(void) const; bool IsActive(void) const; @@ -37,28 +38,28 @@ public: private: // [ PIXIE ]: AMOS PLEASE VERIFY STRUCT INTEGRITY FOR EARLIER SEASONS. THERE WAS A PADDING AFTER ORIGINID BEFORE. - char pad_0000[16]; //0x0000 - std::int32_t m_nUserID; //0x0010 - char pad_0014[844]; //0x0014 - void* m_ConVars; //0x0360 This is a KeyValue*! - char pad_0368[8]; //0x0368 - CBaseServer* m_Server; //0x0370 - char pad_0378[40]; //0x0378 - void* m_NetChannel; //0x03A0 - char pad_03A8[8]; //0x03A8 - SIGNONSTATE m_nSignonState; //0x03B0 - std::int32_t m_nDeltaTick; //0x03B4 - std::int64_t m_nOriginID; //0x03B8 - char pad_03C0[480]; //0x03C0 - bool m_bFakePlayer; //0x05A0 - bool m_bReceivedPacket; //0x05A1 - bool m_bLowViolence; //0x05A2 - bool m_bFullyAuthenticated; //0x05A3 - char pad_05A4[24]; //0x05A4 + char pad_0000[16]; //0x0000 + std::int32_t m_nUserID; //0x0010 + char pad_0014[844]; //0x0014 + void* m_ConVars; //0x0360 This is a KeyValue*! + char pad_0368[8]; //0x0368 + CBaseServer* m_Server; //0x0370 + char pad_0378[40]; //0x0378 + CNetChan* m_NetChannel; //0x03A0 + char pad_03A8[8]; //0x03A8 + SIGNONSTATE m_nSignonState; //0x03B0 + std::int32_t m_nDeltaTick; //0x03B4 + std::int64_t m_nOriginID; //0x03B8 + char pad_03C0[480]; //0x03C0 + bool m_bFakePlayer; //0x05A0 + bool m_bReceivedPacket; //0x05A1 + bool m_bLowViolence; //0x05A2 + bool m_bFullyAuthenticated; //0x05A3 + char pad_05A4[24]; //0x05A4 PERSISTENCE m_nPersistenceState; //0x05BC - char pad_05C0[302676]; //0x05C0 + char pad_05C0[302676]; //0x05C0 std::int32_t m_LastMovementTick; //0x4A414 - char pad_4A418[168]; //0x4A418 + char pad_4A418[168]; //0x4A418 }; #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) static_assert(sizeof(CBaseClient) == 0x4A440); diff --git a/r5dev/engine/baseserver.cpp b/r5dev/engine/baseserver.cpp index 466731fc..8c25dc5d 100644 --- a/r5dev/engine/baseserver.cpp +++ b/r5dev/engine/baseserver.cpp @@ -23,11 +23,11 @@ int CBaseServer::GetNumHumanPlayers(void) const int nHumans = 0; for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++) { - CBaseClient* client = g_pClient->GetClient(i); - if (!client) + CBaseClient* pClient = g_pClient->GetClient(i); + if (!pClient) continue; - if (client->IsHumanPlayer()) + if (pClient->IsHumanPlayer()) nHumans++; } @@ -43,11 +43,11 @@ int CBaseServer::GetNumFakeClients(void) const int nBots = 0; for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++) { - CBaseClient* client = g_pClient->GetClient(i); - if (!client) + CBaseClient* pClient = g_pClient->GetClient(i); + if (!pClient) continue; - if (client->IsConnected() && client->IsFakeClient()) + if (pClient->IsConnected() && pClient->IsFakeClient()) nBots++; } diff --git a/r5dev/engine/host_state.cpp b/r5dev/engine/host_state.cpp index 3c0a67ca..f5312171 100644 --- a/r5dev/engine/host_state.cpp +++ b/r5dev/engine/host_state.cpp @@ -17,9 +17,9 @@ #else // #include "engine/cl_rcon.h" #endif // DEDICATED +#include "engine/net.h" #include "engine/gl_screen.h" #include "engine/host_state.h" -#include "engine/net_chan.h" #include "engine/sys_engine.h" #include "engine/sys_utils.h" #include "engine/cmodel_bsp.h" @@ -159,14 +159,14 @@ FORCEINLINE void CHostState::Setup(void) const std::thread think(&CHostState::Think, this); think.detach(); - *reinterpret_cast(m_bRestrictServerCommands) = true; // Restrict commands. + *m_bRestrictServerCommands = true; // Restrict commands. ConCommandBase* disconnect = g_pCVar->FindCommandBase("disconnect"); disconnect->AddFlags(FCVAR_SERVER_CAN_EXECUTE); // Make sure server is not restricted to this. g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1); if (net_userandomkey->GetBool()) { - HNET_GenerateKey(); + NET_GenerateKey(); } #ifdef DEDICATED diff --git a/r5dev/engine/net.cpp b/r5dev/engine/net.cpp index 74a05f2c..c66a8c5d 100644 --- a/r5dev/engine/net.cpp +++ b/r5dev/engine/net.cpp @@ -6,6 +6,147 @@ #include "core/stdafx.h" #include "engine/net.h" +#ifndef NETCONSOLE +#include "core/logdef.h" +#include "tier0/cvar.h" +#include "tier0/completion.h" +#include "mathlib/color.h" +#include "engine/sys_utils.h" +#include "engine/net.h" +#include "engine/net_chan.h" +#ifndef CLIENT_DLL +#include "engine/baseclient.h" +#endif // !CLIENT_DLL +#endif // !NETCONSOLE + +#ifndef NETCONSOLE +//----------------------------------------------------------------------------- +// Purpose: shutdown netchannel +//----------------------------------------------------------------------------- +void NET_ShutDown(void* thisptr, const char* szReason, std::uint8_t a1, char a2) +{ +#if !defined (GAMEDLL_S0) || !defined (GAMEDLL_S1) // !TEMP UNTIL CHOSTSTATE IS BUILD AGNOSTIC! // + DownloadPlaylists_f_CompletionFunc(); // Re-load playlist from disk after getting disconnected from the server. +#endif // !GAMEDLL_S0 || !GAMEDLL_S1 + v_NET_Shutdown(thisptr, szReason, a1, a2); +} + +//----------------------------------------------------------------------------- +// Purpose: hook and log the receive datagram +//----------------------------------------------------------------------------- +bool NET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bRaw) +{ + bool result = v_NET_ReceiveDatagram(iSocket, pInpacket, bRaw); + if (result) + { + // Log received packet data. + HexDump("[+] NET_ReceiveDatagram", 0, &pInpacket->data[NULL], pInpacket->wiresize); + } + return result; +} + +//----------------------------------------------------------------------------- +// Purpose: hook and log the send datagram +//----------------------------------------------------------------------------- +void* NET_SendDatagram(SOCKET s, const char* szPayload, int iLenght, int nFlags) +{ + void* result = v_NET_SendDatagram(s, szPayload, iLenght, nFlags); + if (result) + { + // Log transmitted packet data. + HexDump("[+] NET_SendDatagram", 0, szPayload, iLenght); + } + return result; +} + +//----------------------------------------------------------------------------- +// Purpose: sets the user specified encryption key +//----------------------------------------------------------------------------- +void NET_SetKey(std::string svNetKey) +{ + g_szNetKey.clear(); + g_szNetKey = svNetKey; + + DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); + DevMsg(eDLL_T::ENGINE, "] NET_KEY ----------------------------------------------------\n"); + DevMsg(eDLL_T::ENGINE, "] BASE64: %s%s%s\n", g_svGreyB.c_str(), g_szNetKey.c_str(), g_svReset.c_str()); + DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); + + v_NET_SetKey(g_pNetKey, g_szNetKey.c_str()); +} + +//----------------------------------------------------------------------------- +// Purpose: calculates and sets the encryption key +//----------------------------------------------------------------------------- +void NET_GenerateKey() +{ + g_szNetKey.clear(); + net_userandomkey->SetValue(1); + + BCRYPT_ALG_HANDLE hAlgorithm; + if (BCryptOpenAlgorithmProvider(&hAlgorithm, L"RNG", 0, 0) < 0) + { + Error(eDLL_T::ENGINE, "Failed to open rng algorithm\n"); + return; + } + unsigned char pBuffer[0x10u]; + if (BCryptGenRandom(hAlgorithm, pBuffer, 0x10u, 0) < 0) + { + Error(eDLL_T::ENGINE, "Failed to generate random data\n"); + return; + } + + for (int i = 0; i < 0x10u; i++) + { + g_szNetKey += pBuffer[i]; + } + + g_szNetKey = Base64Encode(g_szNetKey); + + DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); + DevMsg(eDLL_T::ENGINE, "] NET_KEY ----------------------------------------------------\n"); + DevMsg(eDLL_T::ENGINE, "] BASE64: %s%s%s\n", g_svGreyB.c_str(), g_szNetKey.c_str(), g_svReset.c_str()); + DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); + + v_NET_SetKey(g_pNetKey, g_szNetKey.c_str()); +} + +//----------------------------------------------------------------------------- +// Purpose: hook and log the client's signonstate to the console +//----------------------------------------------------------------------------- +void NET_PrintFunc(const char* fmt, ...) +{ + static char buf[1024]; + + va_list args; + va_start(args, fmt); + + vsnprintf(buf, sizeof(buf), fmt, args); + + buf[sizeof(buf) - 1] = 0; + va_end(args); + + DevMsg(eDLL_T::CLIENT, "%s", buf); +} + +//----------------------------------------------------------------------------- +// Purpose: disconnect the client and shutdown netchannel +//----------------------------------------------------------------------------- +void NET_DisconnectClient(CBaseClient* pClient, int nIndex, const char* szReason, uint8_t unk1, char unk2) +{ +#ifndef CLIENT_DLL + if (!pClient || std::strlen(szReason) == NULL || !pClient->GetNetChan()) + { + return; + } + + v_NET_Shutdown(pClient->GetNetChan(), szReason, unk1, unk2); // Shutdown netchan. + pClient->SetNetChan(nullptr); // Null netchan. + CBaseClient_Clear(pClient); // Reset CClient instance for client. + g_bIsPersistenceVarSet[nIndex] = false; // Reset Persistence var. +#endif // !CLIENT_DLL +} +#endif // !NETCONSOLE //----------------------------------------------------------------------------- // Purpose: returns the WSA error code @@ -59,6 +200,41 @@ const char* NET_ErrorString(int iCode) case WSATRY_AGAIN : return "WSATRY_AGAIN"; case WSANO_RECOVERY : return "WSANO_RECOVERY"; case WSANO_DATA : return "WSANO_DATA"; - default : return "UNKNOWN ERROR"; + default : return "UNKNOWN_ERROR"; } } + +#ifndef NETCONSOLE +/////////////////////////////////////////////////////////////////////////////// +void NET_Attach() +{ + DetourAttach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc); +#ifndef DEDICATED + DetourAttach((LPVOID*)&v_NET_Shutdown, &NET_ShutDown); +#endif +} + +void NET_Detach() +{ + DetourDetach((LPVOID*)&v_NET_PrintFunc, &NET_PrintFunc); +#ifndef DEDICATED + DetourDetach((LPVOID*)&v_NET_Shutdown, &NET_ShutDown); +#endif +} + +void NET_Trace_Attach() +{ + DetourAttach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram); + DetourAttach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram); +} + +void NET_Trace_Detach() +{ + DetourDetach((LPVOID*)&v_NET_ReceiveDatagram, &NET_ReceiveDatagram); + DetourDetach((LPVOID*)&v_NET_SendDatagram, &NET_SendDatagram); +} + +/////////////////////////////////////////////////////////////////////////////// +std::string g_szNetKey = "WDNWLmJYQ2ZlM0VoTid3Yg=="; +std::uintptr_t g_pNetKey = g_mGameDll.StringSearch("client:NetEncryption_NewKey").FindPatternSelf("48 8D ? ? ? ? ? 48 3B", ADDRESS::Direction::UP, 300).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(); +#endif // !NETCONSOLE diff --git a/r5dev/engine/net.h b/r5dev/engine/net.h index 20627996..1adf9d31 100644 --- a/r5dev/engine/net.h +++ b/r5dev/engine/net.h @@ -1,3 +1,74 @@ #pragma once +#ifndef NETCONSOLE +#include "engine/net_chan.h" +#define MAX_STREAMS 2 +#define FRAGMENT_BITS 8 +#define FRAGMENT_SIZE (1<m_Name + 1; } //----------------------------------------------------------------------------- -// Purpose: hook and log the receive datagram +// Purpose: gets the netchannel address +// Output : const char* //----------------------------------------------------------------------------- -bool HNET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bRaw) +const char* CNetChan::GetAddress(void) const { - bool result = NET_ReceiveDatagram(iSocket, pInpacket, bRaw); - if (result) + char szAdr[INET6_ADDRSTRLEN]{}; + inet_ntop(AF_INET6, &this->remote_address.adr, szAdr, INET6_ADDRSTRLEN); + return szAdr; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel data rate +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetDataRate(void) const +{ + return this->m_Rate; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel buffer size (NET_FRAMES_BACKUP) +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetBufferSize(void) const +{ + return NET_FRAMES_BACKUP; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel latency +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetLatency(int flow) const +{ + return this->m_DataFlow[flow].latency; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel average choke +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetAvgChoke(int flow) const +{ + return this->m_DataFlow[flow].avgchoke; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel average latency +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetAvgLatency(int flow) const +{ + return this->m_DataFlow[flow].avglatency; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel average loss +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetAvgLoss(int flow) const +{ + return this->m_DataFlow[flow].avgloss; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel average packets +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetAvgPackets(int flow) const +{ + return this->m_DataFlow[flow].avgpacketspersec; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel average data +// Input : flow - +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetAvgData(int flow) const +{ + return this->m_DataFlow[flow].avgbytespersec; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel total data +// Input : flow - +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetTotalData(int flow) const +{ + return this->m_DataFlow[flow].totalbytes; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel total packets +// Input : flow - +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetTotalPackets(int flow) const +{ + return this->m_DataFlow[flow].totalpackets; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel sequence number +// Input : flow - +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetSequenceNr(int flow) const +{ + if (flow == FLOW_OUTGOING) { - // Log received packet data - HexDump("[+] NET_ReceiveDatagram", 0, &pInpacket->data[NULL], pInpacket->wiresize); + return this->m_nOutSequenceNr; } - return result; -} - -//----------------------------------------------------------------------------- -// Purpose: hook and log the send datagram -//----------------------------------------------------------------------------- -void* HNET_SendDatagram(SOCKET s, const char* szPayload, int iLenght, int nFlags) -{ - void* result = NET_SendDatagram(s, szPayload, iLenght, nFlags); - if (result) + else if (flow == FLOW_INCOMING) { - // Log transmitted packet data - HexDump("[+] NET_SendDatagram", 0, szPayload, iLenght); - } - return result; -} - -//----------------------------------------------------------------------------- -// Purpose: sets the user specified encryption key -//----------------------------------------------------------------------------- -void HNET_SetKey(std::string svNetKey) -{ - g_szNetKey.clear(); - g_szNetKey = svNetKey; - - DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); - DevMsg(eDLL_T::ENGINE, "] NET_KEY ----------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "] BASE64: %s%s%s\n", g_svGreyB.c_str(), g_szNetKey.c_str(), g_svReset.c_str()); - DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); - - NET_SetKey(g_pNetKey, g_szNetKey.c_str()); -} - -//----------------------------------------------------------------------------- -// Purpose: calculates and sets the encryption key -//----------------------------------------------------------------------------- -void HNET_GenerateKey() -{ - g_szNetKey.clear(); - net_userandomkey->SetValue(1); - - BCRYPT_ALG_HANDLE hAlgorithm; - if (BCryptOpenAlgorithmProvider(&hAlgorithm, L"RNG", 0, 0) < 0) - { - Error(eDLL_T::ENGINE, "Failed to open rng algorithm\n"); - return; - } - unsigned char pBuffer[0x10u]; - if (BCryptGenRandom(hAlgorithm, pBuffer, 0x10u, 0) < 0) - { - Error(eDLL_T::ENGINE, "Failed to generate random data\n"); - return; + return this->m_nInSequenceNr; } - for (int i = 0; i < 0x10u; i++) - { - g_szNetKey += pBuffer[i]; - } - - g_szNetKey = Base64Encode(g_szNetKey); - - DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); - DevMsg(eDLL_T::ENGINE, "] NET_KEY ----------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "] BASE64: %s%s%s\n", g_svGreyB.c_str(), g_szNetKey.c_str(), g_svReset.c_str()); - DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); - - NET_SetKey(g_pNetKey, g_szNetKey.c_str()); + return NULL; } //----------------------------------------------------------------------------- -// Purpose: hook and log the client's signonstate to the console +// Purpose: gets the netchannel connect time +// Output : double //----------------------------------------------------------------------------- -void HNET_PrintFunc(const char* fmt, ...) +double CNetChan::GetConnectTime(void) const { - static char buf[1024]; - - va_list args; - va_start(args, fmt); - - vsnprintf(buf, sizeof(buf), fmt, args); - - buf[sizeof(buf) -1] = 0; - va_end(args); - - DevMsg(eDLL_T::CLIENT, "%s", buf); + return this->connect_time; } //----------------------------------------------------------------------------- -// Purpose: disconnect the client and shutdown netchannel +// Purpose: gets the netchannel timeout +// Output : float //----------------------------------------------------------------------------- -void NET_DisconnectClient(CBaseClient* pClient, int nIndex, const char* szReason, uint8_t unk1, char unk2) +float CNetChan::GetTimeoutSeconds(void) const { -#ifndef CLIENT_DLL - if (!pClient) // Client valid? - { - return; - } - - if (std::strlen(szReason) == NULL) // Is reason null? - { - return; - } - - if (!pClient->GetNetChan()) // NC even existent? - { - return; - } - - NET_Shutdown(pClient->GetNetChan(), szReason, unk1, unk2); // Shutdown netchan. - pClient->SetNetChan(nullptr); // Null netchan. - CBaseClient_Clear(pClient); // Reset CClient instance for client. - g_bIsPersistenceVarSet[nIndex] = false; // Reset Persistence var. -#endif // !CLIENT_DLL + return this->m_Timeout; } -/////////////////////////////////////////////////////////////////////////////// -void CNetChan_Attach() +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel socket +// Output : int +//----------------------------------------------------------------------------- +int CNetChan::GetSocket(void) const { - DetourAttach((LPVOID*)&NET_PrintFunc, &HNET_PrintFunc); -#ifndef DEDICATED - DetourAttach((LPVOID*)&NET_Shutdown, &HNET_ShutDown); -#endif + return this->m_Socket; } -void CNetChan_Detach() +//----------------------------------------------------------------------------- +// Purpose: checks if the reliable stream is overflowed +// Output : true if overflowed, false otherwise +//----------------------------------------------------------------------------- +bool CNetChan::IsOverflowed(void) const { - DetourDetach((LPVOID*)&NET_PrintFunc, &HNET_PrintFunc); -#ifndef DEDICATED - DetourDetach((LPVOID*)&NET_Shutdown, &HNET_ShutDown); -#endif + return this->m_StreamReliable.IsOverflowed(); } - -void CNetChan_Trace_Attach() -{ - DetourAttach((LPVOID*)&NET_ReceiveDatagram, &HNET_ReceiveDatagram); - DetourAttach((LPVOID*)&NET_SendDatagram, &HNET_SendDatagram); -} - -void CNetChan_Trace_Detach() -{ - DetourDetach((LPVOID*)&NET_ReceiveDatagram, &HNET_ReceiveDatagram); - DetourDetach((LPVOID*)&NET_SendDatagram, &HNET_SendDatagram); -} - -/////////////////////////////////////////////////////////////////////////////// -std::string g_szNetKey = "WDNWLmJYQ2ZlM0VoTid3Yg=="; -std::uintptr_t g_pNetKey = g_mGameDll.StringSearch("client:NetEncryption_NewKey").FindPatternSelf("48 8D ? ? ? ? ? 48 3B", ADDRESS::Direction::UP, 300).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr(); diff --git a/r5dev/engine/net_chan.h b/r5dev/engine/net_chan.h index e944e643..f25f226a 100644 --- a/r5dev/engine/net_chan.h +++ b/r5dev/engine/net_chan.h @@ -1,70 +1,167 @@ -#pragma once -#include "common/protocol.h" -#include "tier1/NetAdr2.h" +//=============================================================================// +// +// Purpose: +// +//=============================================================================// +#ifndef NET_CHAN_H +#define NET_CHAN_H + +#include "tier1/bitbuf.h" +#include "tier1/NetAdr2.h" +#include "tier1/utlmemory.h" +#include "common/netmessages.h" +#include "common/protocol.h" +#include "public/include/inetchannel.h" + +#define NET_FRAMES_BACKUP 128 +#define NET_LEN_CHANNELNAME 32 +#define NET_FRAMES_MASK (NET_FRAMES_BACKUP-1) + +//----------------------------------------------------------------------------- +// Purpose: forward declarations +//----------------------------------------------------------------------------- class CBaseClient; -namespace +//----------------------------------------------------------------------------- +struct netframe_t { - /* ==== CNETCHAN ======================================================================================================================================================== */ -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2) - ADDRESS p_NET_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x54\x41\x56\x41\x57\x48\x81\xEC\xC0\x01\x00", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); - void*(*NET_Init)(char a1) = (void* (*)(char))p_NET_Init.GetPtr(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC C0 01 00*/ - - ADDRESS p_NET_Shutdown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x6C\x24\x18\x56\x57\x41\x56\x48\x83\xEC\x30\x83\xB9\xD8", "xxxxxxxxxxxxxxxx"); - void (*NET_Shutdown)(void* thisptr, const char* a0, std::uint8_t a1, char a2) = (void (*)(void*, const char*, std::uint8_t, char))p_NET_Shutdown.GetPtr(); /*48 89 6C 24 18 56 57 41 56 48 83 EC 30 83 B9 D8*/ -#elif defined (GAMEDLL_S3) - ADDRESS p_NET_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x54\x41\x56\x41\x57\x48\x81\xEC\xF0\x01\x00", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); - void* (*NET_Init)(char a1) = (void* (*)(char))p_NET_Init.GetPtr(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 81 EC F0 01 00*/ - - ADDRESS p_NET_Shutdown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x6C\x24\x18\x56\x57\x41\x56\x48\x83\xEC\x30\x83\xB9\xD0", "xxxxxxxxxxxxxxxx"); - void (*NET_Shutdown)(void* thisptr, const char* szReason, std::uint8_t a1, char a2) = (void (*)(void*, const char*, std::uint8_t, char))p_NET_Shutdown.GetPtr(); /*48 89 6C 24 18 56 57 41 56 48 83 EC 30 83 B9 D0*/ -#endif - ADDRESS p_NET_SetKey = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\xF9\x41\xB8", "xxxxxxxxxxxxxxxxxxxxxxxxx"); - void (*NET_SetKey)(std::uintptr_t pKey, const char* szHash) = (void (*)(std::uintptr_t, const char*))p_NET_SetKey.GetPtr(); /*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*/ - - ADDRESS p_NET_ReceiveDatagram = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xEB", "xxxxxxxxxxxxxxxxxxxxxxxxx"); - bool (*NET_ReceiveDatagram)(int iSocket, netpacket_s* pInpacket, bool bRaw) = (bool (*)(int, netpacket_s*, bool))p_NET_ReceiveDatagram.GetPtr(); /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/ - - ADDRESS p_NET_SendDatagram = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x81\xEC\x00\x05\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxx?xxx"); - void*(*NET_SendDatagram)(SOCKET s, const char* szPayload, int iLenght, int nFlags) = (void*(*)(SOCKET, const char*, int, int))p_NET_SendDatagram.GetPtr(); /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/ - - ADDRESS p_NET_PrintFunc = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x54\x24\x10\x4C\x89\x44\x24\x18\x4C\x89\x4C\x24\x20\xC3\x48", "xxxxxxxxxxxxxxxxx"); - void (*NET_PrintFunc)(const char* fmt) = (void(*)(const char*))p_NET_PrintFunc.GetPtr(); /*48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48*/ -} - -/////////////////////////////////////////////////////////////////////////////// -bool HNET_ReceiveDatagram(int iSocket, netpacket_s* pInpacket, bool bRaw); -void* HNET_SendDatagram(SOCKET s, const char* szPayload, int iLenght, int nFlags); -void HNET_SetKey(std::string svNetKey); -void HNET_GenerateKey(); -void HNET_PrintFunc(const char* fmt, ...); -void NET_DisconnectClient(CBaseClient* pClient, int nIndex, const char* szReason, std::uint8_t unk1, char unk2); - -void CNetChan_Attach(); -void CNetChan_Detach(); -void CNetChan_Trace_Attach(); -void CNetChan_Trace_Detach(); - -/////////////////////////////////////////////////////////////////////////////// -extern std::string g_szNetKey; -extern std::uintptr_t g_pNetKey; - -/////////////////////////////////////////////////////////////////////////////// -class HNetChan : public IDetour -{ - virtual void debugp() - { - std::cout << "| FUN: NET_Init : 0x" << std::hex << std::uppercase << p_NET_Init.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: NET_Shutdown : 0x" << std::hex << std::uppercase << p_NET_Shutdown.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: NET_SetKey : 0x" << std::hex << std::uppercase << p_NET_SetKey.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: NET_ReceiveDatagram : 0x" << std::hex << std::uppercase << p_NET_ReceiveDatagram.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: NET_SendDatagram : 0x" << std::hex << std::uppercase << p_NET_SendDatagram.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: NET_PrintFunc : 0x" << std::hex << std::uppercase << p_NET_PrintFunc.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| VAR: g_pNetKey : 0x" << std::hex << std::uppercase << g_pNetKey << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; - } + float one; + float two; + float three; + float four; + float five; + float six; }; -/////////////////////////////////////////////////////////////////////////////// -REGISTER(HNetChan); +//----------------------------------------------------------------------------- +struct __declspec(align(8)) netflow_t +{ + float nextcompute; + float avgbytespersec; + float avgpacketspersec; + float avgloss; + float avgchoke; + float avglatency; + float latency; + int64_t totalpackets; + int64_t totalbytes; + netframe_t frames[NET_FRAMES_BACKUP]; + netframe_t current_frame; +}; + +//----------------------------------------------------------------------------- +struct __declspec(align(4)) dataFragments_t +{ + char* data; + int64_t block_size; + bool m_bIsCompressed; + uint8_t gap11[7]; + int64_t m_nRawSize; + bool m_bFirstFragment; + bool m_bLastFragment; + bool m_bIsOutbound; + int transferID; + int m_nTransferSize; + int m_nCurrentOffset; +}; + +//----------------------------------------------------------------------------- +enum EBufType +{ + BUF_RELIABLE = 0, + BUF_UNRELIABLE, + BUF_VOICE +}; + +//----------------------------------------------------------------------------- +class __declspec(align(8)) CNetChan +{ +public: + const char* GetName(void) const; + const char* GetAddress(void) const; + int GetDataRate(void) const; + int GetBufferSize(void) const; + + float GetLatency(int flow) const; + float GetAvgChoke(int flow) const; + float GetAvgLatency(int flow) const; + float GetAvgLoss(int flow) const; + float GetAvgPackets(int flow) const; + float GetAvgData(int flow) const; + + int GetTotalData(int flow) const; + int GetTotalPackets(int flow) const; + int GetSequenceNr(int flow) const; + + float GetTimeoutSeconds(void) const; + double GetConnectTime(void) const; + int GetSocket(void) const; + + bool IsOverflowed(void) const; + //----------------------------------------------------------------------------- +private: + bool m_bProcessingMessages; + bool m_bShouldDelete; + bool m_bStopProcessing; + bool shutting_down; + int m_nOutSequenceNr; + int m_nInSequenceNr; + int m_nOutSequenceNrAck; + int m_nChokedPackets; + int unknown_challenge_var; + int m_nLastRecvFlags; + RTL_SRWLOCK LOCK; + bf_write m_StreamReliable; + CUtlMemory m_ReliableDataBuffer; + bf_write m_StreamUnreliable; + CUtlMemory m_UnreliableDataBuffer; + bf_write m_StreamVoice; + CUtlMemory m_VoiceDataBuffer; + int m_Socket; + int m_MaxReliablePayloadSize; + double last_received; + double connect_time; + uint32_t m_Rate; + int padding_maybe; + double m_fClearTime; + VecNetDataFragments m_WaitingList; + dataFragments_t m_ReceiveList; + int m_nSubOutFragmentsAck; + int m_nSubInFragments; + int m_nNonceHost; + uint32_t m_nNonceRemote; + bool m_bReceivedRemoteNonce; + bool m_bInReliableState; + bool m_bPendingRemoteNonceAck; + uint32_t m_nSubOutSequenceNr; + int m_nLastRecvNonce; + bool m_bUseCompression; + uint32_t dword168; + float m_Timeout; + INetChannelHandler* m_MessageHandler; + VecNetMessages m_NetMessages; + uint64_t qword198; + int m_nQueuedPackets; + float m_flRemoteFrameTime; + float m_flRemoteFrameTimeStdDeviation; + uint8_t m_bUnkTickBool; + int m_nMaxRoutablePayloadSize; + int m_nSplitPacketSequence; + int64_t m_StreamSendBuffer; + bf_write m_StreamSend; + uint8_t m_bInMatch_maybe; + netflow_t m_DataFlow[2]; + int m_nLifetimePacketsDropped; + int m_nSessionPacketsDropped; + int m_nSequencesSkipped_MAYBE; + int m_nSessionRecvs; + uint32_t m_nLiftimeRecvs; + char m_Name[NET_LEN_CHANNELNAME]; + uint8_t m_bRetrySendLong; + v_netadr_t remote_address; +}; + +static_assert(sizeof(CNetChan) == 0x1AC8); + +#endif // NET_CHAN_H diff --git a/r5dev/gameui/IBrowser.cpp b/r5dev/gameui/IBrowser.cpp index a171ec13..f2caf4cc 100644 --- a/r5dev/gameui/IBrowser.cpp +++ b/r5dev/gameui/IBrowser.cpp @@ -20,7 +20,7 @@ History: #include "tier0/completion.h" #include "windows/id3dx.h" #include "windows/console.h" -#include "engine/net_chan.h" +#include "engine/net.h" #include "engine/sys_utils.h" #include "engine/host_state.h" #include "networksystem/serverlisting.h" @@ -718,7 +718,7 @@ void IBrowser::SettingsSection(void) //----------------------------------------------------------------------------- void IBrowser::RegenerateEncryptionKey(void) const { - HNET_GenerateKey(); + NET_GenerateKey(); } //----------------------------------------------------------------------------- @@ -726,7 +726,7 @@ void IBrowser::RegenerateEncryptionKey(void) const //----------------------------------------------------------------------------- void IBrowser::ChangeEncryptionKeyTo(const std::string& svNetKey) const { - HNET_SetKey(svNetKey); + NET_SetKey(svNetKey); } //----------------------------------------------------------------------------- diff --git a/r5dev/networksystem/pylon.cpp b/r5dev/networksystem/pylon.cpp index 00163850..9676d0dd 100644 --- a/r5dev/networksystem/pylon.cpp +++ b/r5dev/networksystem/pylon.cpp @@ -7,9 +7,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/r5dev/public/bansystem.cpp b/r5dev/public/bansystem.cpp index 971d1b76..222f7bf0 100644 --- a/r5dev/public/bansystem.cpp +++ b/r5dev/public/bansystem.cpp @@ -6,7 +6,7 @@ //=====================================================================================// #include "core/stdafx.h" -#include "engine/net_chan.h" +#include "engine/net.h" #include "engine/sys_utils.h" #include "engine/baseclient.h" #include "public/include/bansystem.h" @@ -32,27 +32,27 @@ void CBanSystem::operator[](std::pair pair) //----------------------------------------------------------------------------- void CBanSystem::Load(void) { - std::filesystem::path path = std::filesystem::current_path() /= "banlist.config"; // Get current path + banlist.config + std::filesystem::path path = std::filesystem::current_path() /= "platform\\banlist.json"; nlohmann::json jsIn; - std::ifstream banFile(path, std::ios::in); // Parse ban list. + std::ifstream banFile(path, std::ios::in); int nTotalBans = 0; if (banFile.good() && banFile) // Check if it parsed. { banFile >> jsIn; // Into json. - banFile.close(); // Close file. + banFile.close(); if (!jsIn.is_null()) // Check if json is valid { - if (!jsIn["totalBans"].is_null()) // Is the totalBans field populated? + if (!jsIn["totalBans"].is_null()) { - nTotalBans = jsIn["totalBans"].get(); // Get the totalBans field. + nTotalBans = jsIn["totalBans"].get(); } } - for (int i = 0; i < nTotalBans; i++) // Loop through total bans. + for (int i = 0; i < nTotalBans; i++) { nlohmann::json jsEntry = jsIn[std::to_string(i).c_str()]; // Get Entry for current ban. if (jsEntry.is_null()) // Check if entry is valid. @@ -63,7 +63,7 @@ void CBanSystem::Load(void) std::int64_t nOriginID = jsEntry["originID"].get(); // Get originID field from entry. std::string svIpAddress = jsEntry["ipAddress"].get(); // Get ipAddress field from entry. - vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID)); // Push back into vector. + vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID)); } } } @@ -82,7 +82,7 @@ void CBanSystem::Save(void) const jsOut[std::to_string(i).c_str()]["originID"] = vsvBanList[i].second; // Populate originID field for this entry. } - std::filesystem::path path = std::filesystem::current_path() /= "banlist.config"; // Get current path + banlist.config + std::filesystem::path path = std::filesystem::current_path() /= "platform\\banlist.json"; std::ofstream outFile(path, std::ios::out | std::ios::trunc); // Write config file.. outFile << jsOut.dump(4); // Dump it into config file.. @@ -197,53 +197,29 @@ void CBanSystem::BanListCheck(void) { if (IsRefuseListValid()) { - for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector. + for (int i = 0; i < vsvrefuseList.size(); i++) { for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances. { - CBaseClient* client = g_pClient->GetClient(c); // Get client instance. - if (!client) + CBaseClient* pClient = g_pClient->GetClient(c); + CNetChan* pNetChan = pClient->GetNetChan(); + + if (!pClient || !pNetChan) { continue; } - if (!client->GetNetChan()) // Netchan valid? + if (pClient->GetOriginID() != vsvrefuseList[i].second) // See if NucleusID matches entry. { continue; } - if (g_pClient->GetOriginID() != vsvrefuseList[i].second) // See if nucleus id matches entry. - { - continue; - } + std::string svIpAddress = pNetChan->GetAddress(); - std::string finalIpAddress = std::string(); - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField && ipAddressField.GetValue() != 0x0) - { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); - - finalIpAddress = ss.str(); - } - - DevMsg(eDLL_T::SERVER, "\n"); - DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); - DevMsg(eDLL_T::SERVER, "] PYLON_NOTICE -----------------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS GETTING DISCONNECTED.\n", g_pClient->GetOriginID()); - if (finalIpAddress.empty()) - DevMsg(eDLL_T::SERVER, "] IP-ADDR : | CLIENT MODIFIED PACKET.\n"); - else - DevMsg(eDLL_T::SERVER, "] IP-ADDR : | '%s'\n", finalIpAddress.c_str()); - DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "\n"); - - AddEntry(finalIpAddress, g_pClient->GetOriginID()); // Add local entry to reserve a non needed request. - Save(); // Save list. - NET_DisconnectClient(g_pClient, c, vsvrefuseList[i].first.c_str(), 0, 1); // Disconnect client. + Warning(eDLL_T::SERVER, "Connection rejected for '%s' ('%lld' is banned from this Server!)\n", svIpAddress.c_str(), pClient->GetOriginID()); + AddEntry(svIpAddress, pClient->GetOriginID()); // Add local entry to reserve a non needed request. + Save(); // Save banlist to file. + NET_DisconnectClient(pClient, c, vsvrefuseList[i].first.c_str(), 0, 1); } } } diff --git a/r5dev/public/include/inetchannel.h b/r5dev/public/include/inetchannel.h new file mode 100644 index 00000000..e4fef886 --- /dev/null +++ b/r5dev/public/include/inetchannel.h @@ -0,0 +1,13 @@ +#ifndef INETCHANNEL_H +#define INETCHANNEL_H + +#define NET_FRAMES_BACKUP 128 +#define FLOW_OUTGOING 0 +#define FLOW_INCOMING 1 +#define MAX_FLOWS 2 // in & out + +struct INetChannelHandler +{ + void* iNetMessageHandlerVTable /*VFT*/; +}; +#endif // !INETCHANNEL_H diff --git a/r5dev/public/utility.cpp b/r5dev/public/utility.cpp index 1dfc4255..acc3f549 100644 --- a/r5dev/public/utility.cpp +++ b/r5dev/public/utility.cpp @@ -77,11 +77,11 @@ DWORD64 FindPatternSIMD(const char* szModule, const unsigned char* szPattern, co const unsigned char* end = pData + length - strlen(szMask); int num_masks = (int)ceil((float)strlen(szMask) / (float)16); - int masks[32]; // 32*16 = enough masks for 512 bytes. + int masks[64]; // 64*16 = enough masks for 1024 bytes. memset(masks, 0, num_masks * sizeof(int)); - for (int64_t i = 0; i < num_masks; ++i) + for (int i = 0; i < num_masks; ++i) { - for (int64_t j = strnlen(szMask + i * 16, 16) - 1; j >= 0; --j) + for (int j = strnlen(szMask + i * 16, 16) - 1; j >= 0; --j) { if (szMask[i * 16 + j] == 'x') { diff --git a/r5dev/server/IVEngineServer.cpp b/r5dev/server/IVEngineServer.cpp index 6a1ed691..aad24d49 100644 --- a/r5dev/server/IVEngineServer.cpp +++ b/r5dev/server/IVEngineServer.cpp @@ -21,34 +21,19 @@ bool HIVEngineServer__PersistenceAvailable(void* entidx, int clientidx) if (!g_bIsPersistenceVarSet[clientidx] && sv_showconnecting->GetBool()) { - void* clientNamePtr = (void**)(((std::uintptr_t)pClient->GetNetChan()) + 0x1A8D); // Get client name from netchan. - std::string clientName((char*)clientNamePtr, 32); // Get full name. - std::int64_t originID = pClient->GetOriginID(); - std::int64_t clientID = static_cast(pClient->GetUserID() + 1); + CNetChan* pNetChan = pClient->GetNetChan(); - std::string ipAddress = "null"; // If this stays null they modified the packet somehow. - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)pClient->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField) - { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); + string svClientName(pNetChan->GetName(), NET_LEN_CHANNELNAME); + string svIpAddress = pNetChan->GetAddress(); + int64_t nOriginID = pClient->GetOriginID(); - ipAddress = ss.str(); - } - - DevMsg(eDLL_T::SERVER, "\n"); DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); - DevMsg(eDLL_T::SERVER, "] CLIENT_INSTANCE_DETAILS ------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "] INDEX: | '#%d'\n", clientidx); - DevMsg(eDLL_T::SERVER, "] NAME : | '%s'\n", clientName.c_str()); - DevMsg(eDLL_T::SERVER, "] OID : | '%lld'\n", originID); - DevMsg(eDLL_T::SERVER, "] UID : | '%lld'\n", clientID); - DevMsg(eDLL_T::SERVER, "] IPADR: | '%s'\n", ipAddress.c_str()); - DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "\n"); + DevMsg(eDLL_T::SERVER, "+- NetChannel details\n"); + DevMsg(eDLL_T::SERVER, " |- IDX : | '#%d'\n", clientidx); + DevMsg(eDLL_T::SERVER, " |- UID : | '%s'\n", svClientName.c_str()); + DevMsg(eDLL_T::SERVER, " |- OID : | '%lld'\n", nOriginID); + DevMsg(eDLL_T::SERVER, " |- ADR : | '%s'\n", svIpAddress.c_str()); + DevMsg(eDLL_T::SERVER, " -------------------------------------------------------------\n"); g_bIsPersistenceVarSet[clientidx] = true; } diff --git a/r5dev/server/server.cpp b/r5dev/server/server.cpp index ac27b1d1..71c51ccf 100644 --- a/r5dev/server/server.cpp +++ b/r5dev/server/server.cpp @@ -17,7 +17,7 @@ void IsClientBanned(R5Net::Client* pR5net, const std::string svIPAddr, std::int6 { DevMsg(eDLL_T::SERVER, "\n"); DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); - DevMsg(eDLL_T::SERVER, "] PYLON NOTICE -----------------------------------------------\n"); + DevMsg(eDLL_T::SERVER, "] PYLON_NOTICE -----------------------------------------------\n"); DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS PYLON BANNED.\n", nNucleusID); DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); DevMsg(eDLL_T::SERVER, "\n"); @@ -30,28 +30,15 @@ void IsClientBanned(R5Net::Client* pR5net, const std::string svIPAddr, std::int6 //----------------------------------------------------------------------------- void* HCServer_Authenticate(void* pServer, user_creds* pInpacket) { - std::string svIpAddress = "null"; - ADDRESS ipAddressField = ADDRESS(&pInpacket->m_nIpAddr); - - if (ipAddressField && ipAddressField.GetValue() != 0x0) - { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); - - svIpAddress = ss.str(); - } - + std::string svIpAddress = pInpacket->m_nAddr.GetAddress(); if (sv_showconnecting->GetBool()) { DevMsg(eDLL_T::SERVER, "\n"); DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); - DevMsg(eDLL_T::SERVER, "] AUTHENTICATION_DETAILS -------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "] UserID : | '%s'\n", pInpacket->m_nUserID); - DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld'\n", pInpacket->m_nNucleusID); - DevMsg(eDLL_T::SERVER, "] IP-ADDR : | '%s'\n", svIpAddress.c_str()); + DevMsg(eDLL_T::SERVER, "] AUTHENTICATION ---------------------------------------------\n"); + DevMsg(eDLL_T::SERVER, "] UID : | '%s'\n", pInpacket->m_nUserID); + DevMsg(eDLL_T::SERVER, "] OID : | '%lld'\n", pInpacket->m_nNucleusID); + DevMsg(eDLL_T::SERVER, "] ADR : | '%s'\n", svIpAddress.c_str()); DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); } @@ -63,8 +50,7 @@ void* HCServer_Authenticate(void* pServer, user_creds* pInpacket) if (sv_showconnecting->GetBool()) { - DevMsg(eDLL_T::SERVER, "] NOTICE : | THIS CLIENT IS BANNED!\n"); - DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n\n"); + Warning(eDLL_T::SERVER, "Connection rejected for '%s' ('%lld' is banned from this Server!)\n", svIpAddress.c_str(), pInpacket->m_nNucleusID); } return nullptr; } diff --git a/r5dev/server/server.h b/r5dev/server/server.h index aaf0846e..90747100 100644 --- a/r5dev/server/server.h +++ b/r5dev/server/server.h @@ -1,15 +1,15 @@ #pragma once +#include "tier1/NetAdr2.h" #include "networksystem/r5net.h" struct user_creds { - std::uint8_t gap0[16]; - std::uint32_t m_nIpAddr; - std::uint8_t gap1[4]; - std::int32_t m_nProtocolVer; - std::uint8_t gap2[12]; - std::int64_t m_nNucleusID; - std::int64_t m_nUserID; + v_netadr_t m_nAddr; + int32_t m_nProtocolVer; + int32_t m_nchallenge; + uint8_t gap2[8]; + int64_t m_nNucleusID; + int64_t m_nUserID; }; namespace diff --git a/r5dev/tier0/completion.cpp b/r5dev/tier0/completion.cpp index a2e0baf5..47d0d931 100644 --- a/r5dev/tier0/completion.cpp +++ b/r5dev/tier0/completion.cpp @@ -12,7 +12,7 @@ #ifndef DEDICATED #include "engine/cl_rcon.h" #endif // !DEDICATED -#include "engine/net_chan.h" +#include "engine/net.h" #include "engine/sys_utils.h" #include "engine/baseclient.h" #include "rtech/rtech_game.h" @@ -108,63 +108,49 @@ void _KickID_f_CompletionFunc(const CCommand& args) try { - bool onlyDigits = args.HasOnlyDigits(1); + bool bOnlyDigits = args.HasOnlyDigits(1); for (int i = 0; i < MAX_PLAYERS; i++) { - CBaseClient* client = g_pClient->GetClient(i); - if (!client) + CBaseClient* pClient = g_pClient->GetClient(i); + CNetChan* pNetChan = pClient->GetNetChan(); + + if (!pClient || !pNetChan) { continue; } - if (!client->GetNetChan()) - { - continue; - } + std::string svIpAddress = pNetChan->GetAddress(); // If this stays null they modified the packet somehow. - std::string finalIpAddress = "null"; // If this stays null they modified the packet somehow. - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField) + if (bOnlyDigits) { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); - - finalIpAddress = ss.str(); - } - - if (onlyDigits) - { - std::int64_t ID = static_cast(std::stoll(args.Arg(1))); - if (ID > MAX_PLAYERS) // Is it a possible originID? + std::int64_t nTargetID = static_cast(std::stoll(args.Arg(1))); + if (nTargetID > MAX_PLAYERS) // Is it a possible originID? { - std::int64_t originID = client->GetOriginID(); - if (originID != ID) + std::int64_t nOriginID = pClient->GetOriginID(); + if (nOriginID != nTargetID) { continue; } } else // If its not try by userID. { - std::int64_t clientID = static_cast(client->GetUserID() + 1); // Get UserID + 1. - if (clientID != ID) + std::int64_t nClientID = static_cast(pClient->GetUserID() + 1); // Get userID + 1. + if (nClientID != nTargetID) { continue; } } - NET_DisconnectClient(client, i, "Kicked from Server", 0, 1); + NET_DisconnectClient(pClient, i, "Kicked from Server", 0, 1); } else { - if (std::string(args.Arg(1)).compare(finalIpAddress) != NULL) + if (std::string(args.Arg(1)).compare(svIpAddress) != NULL) { continue; } - NET_DisconnectClient(client, i, "Kicked from Server", 0, 1); + NET_DisconnectClient(pClient, i, "Kicked from Server", 0, 1); } } } @@ -189,19 +175,15 @@ void _Ban_f_CompletionFunc(const CCommand& args) for (int i = 0; i < MAX_PLAYERS; i++) { - CBaseClient* client = g_pClient->GetClient(i); - if (!client) + CBaseClient* pClient = g_pClient->GetClient(i); + CNetChan* pNetChan = pClient->GetNetChan(); + + if (!pClient || !pNetChan) { continue; } - if (!client->GetNetChan()) - { - continue; - } - - void* pClientName = (void**)(((std::uintptr_t)client->GetNetChan()) + 0x1A8D); // Get client name from netchan. - std::string svClientName((char*)pClientName, 32); // Get full name. + std::string svClientName(pNetChan->GetName(), NET_LEN_CHANNELNAME); // Get full name. if (svClientName.empty()) { @@ -213,22 +195,11 @@ void _Ban_f_CompletionFunc(const CCommand& args) continue; } - std::string finalIpAddress = "null"; // If this stays null they modified the packet somehow. - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField && ipAddressField.GetValue() != 0x0) - { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); + std::string svIpAddress = pNetChan->GetAddress(); // If this stays empty they modified the packet somehow. - finalIpAddress = ss.str(); - } - - g_pBanSystem->AddEntry(finalIpAddress, client->GetOriginID()); + g_pBanSystem->AddEntry(svIpAddress, pClient->GetOriginID()); g_pBanSystem->Save(); - NET_DisconnectClient(client, i, "Banned from Server", 0, 1); + NET_DisconnectClient(pClient, i, "Banned from Server", 0, 1); } } @@ -246,67 +217,53 @@ void _BanID_f_CompletionFunc(const CCommand& args) try { - bool onlyDigits = args.HasOnlyDigits(1); + bool bOnlyDigits = args.HasOnlyDigits(1); for (int i = 0; i < MAX_PLAYERS; i++) { - CBaseClient* client = g_pClient->GetClient(i); - if (!client) + CBaseClient* pClient = g_pClient->GetClient(i); + CNetChan* pNetChan = pClient->GetNetChan(); + + if (!pClient || !pNetChan) { continue; } - if (!client->GetNetChan()) - { - continue; - } + std::string svIpAddress = pNetChan->GetAddress(); // If this stays empty they modified the packet somehow. - std::string finalIpAddress = "null"; // If this stays null they modified the packet somehow. - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField) + if (bOnlyDigits) { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); - - finalIpAddress = ss.str(); - } - - if (onlyDigits) - { - std::int64_t ID = static_cast(std::stoll(args.Arg(1))); - if (ID > MAX_PLAYERS) // Is it a possible originID? + std::int64_t nTargetID = static_cast(std::stoll(args.Arg(1))); + if (nTargetID > MAX_PLAYERS) // Is it a possible originID? { - std::int64_t originID = client->GetOriginID(); - if (originID != ID) + std::int64_t nOriginID = pClient->GetOriginID(); + if (nOriginID != nTargetID) { continue; } } else // If its not try by userID. { - std::int64_t clientID = static_cast(client->GetUserID() + 1); // Get UserID + 1. - if (clientID != ID) + std::int64_t nClientID = static_cast(pClient->GetUserID() + 1); // Get UserID + 1. + if (nClientID != nTargetID) { continue; } } - g_pBanSystem->AddEntry(finalIpAddress, client->GetOriginID()); + g_pBanSystem->AddEntry(svIpAddress, pClient->GetOriginID()); g_pBanSystem->Save(); - NET_DisconnectClient(client, i, "Banned from Server", 0, 1); + NET_DisconnectClient(pClient, i, "Banned from Server", 0, 1); } else { - if (std::string(args.Arg(1)).compare(finalIpAddress) != NULL) + if (std::string(args.Arg(1)).compare(svIpAddress) != NULL) { continue; } - g_pBanSystem->AddEntry(finalIpAddress, client->GetOriginID()); + g_pBanSystem->AddEntry(svIpAddress, pClient->GetOriginID()); g_pBanSystem->Save(); - NET_DisconnectClient(client, i, "Banned from Server", 0, 1); + NET_DisconnectClient(pClient, i, "Banned from Server", 0, 1); } } } @@ -610,7 +567,7 @@ void _NET_TraceNetChan_f_CompletionFunc(const CCommand& args) DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - CNetChan_Trace_Attach(); + NET_Trace_Attach(); // Commit the transaction. if (DetourTransactionCommit() != NO_ERROR) { @@ -630,7 +587,7 @@ void _NET_TraceNetChan_f_CompletionFunc(const CCommand& args) DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - CNetChan_Trace_Detach(); + NET_Trace_Detach(); // Commit the transaction. DetourTransactionCommit(); @@ -689,7 +646,7 @@ void _NET_SetKey_f_CompletionFunc(const CCommand& args) return; } - HNET_SetKey(args.Arg(1)); + NET_SetKey(args.Arg(1)); } /* @@ -701,7 +658,7 @@ _NET_GenerateKey_f_CompletionFunc */ void _NET_GenerateKey_f_CompletionFunc(const CCommand& args) { - HNET_GenerateKey(); + NET_GenerateKey(); } #ifndef DEDICATED /* diff --git a/r5dev/tier1/NetAdr2.h b/r5dev/tier1/NetAdr2.h index 4e9c3c16..2521b953 100644 --- a/r5dev/tier1/NetAdr2.h +++ b/r5dev/tier1/NetAdr2.h @@ -43,35 +43,35 @@ class CNetAdr2 { public: CNetAdr2(void) {}; - CNetAdr2(std::string svInAdr); - CNetAdr2(std::string svInAdr, std::string svInPort); + CNetAdr2(string svInAdr); + CNetAdr2(string svInAdr, string svInPort); ~CNetAdr2(void); - void SetIP(const std::string& svInAdr); - void SetPort(const std::string& svInPort); - void SetIPAndPort(std::string svInAdr); - void SetIPAndPort(std::string svInAdr, std::string svInPort); + void SetIP(const string& svInAdr); + void SetPort(const string& svInPort); + void SetIPAndPort(string svInAdr); + void SetIPAndPort(string svInAdr, string svInPort); void SetType(const netadrtype_t& type); void SetVersion(void); void SetFromSocket(const int& hSocket); bool SetFromSockadr(sockaddr_storage* s); - std::string GetIP(bool bBaseOnly) const; - std::string GetPort(void) const; - std::string GetPort(std::string svInPort) const; - std::string GetIPAndPort(void) const; + string GetIP(bool bBaseOnly) const; + string GetPort(void) const; + string GetPort(string svInPort) const; + string GetIPAndPort(void) const; netadrtype_t GetType(void) const; netadrversion_t GetVersion(void) const; - std::string GetBase(void) const; - std::string GetBase(std::string svInAdr) const; - std::vector GetParts(void) const; + string GetBase(void) const; + string GetBase(string svInAdr) const; + vector GetParts(void) const; int GetSize(void) const; int GetFamily(void) const; void ToSockadr(sockaddr_storage* pSadr) const; void ToAdrinfo(addrinfo* pHint) const; - bool IsValidPort(const std::string& svInPort) const; + bool IsValidPort(const string& svInPort) const; bool IsLocalhost(void) const; bool IsLoopback(void) const; bool IsReservedAdr(void) const; @@ -83,8 +83,36 @@ public: void Clear(void); private: - std::string m_svip; + string m_svip; netadrtype_t m_type{}; netadrversion_t m_version{}; sockaddr_storage* m_sadr{}; }; + +class v_netadr_t // !TODO: Move this to 'NetAdr.h' instead and adjust existing class to new system. +{ +public: + inline netadrtype_t GetType(void) const + { + return this->type; + } + inline const char* GetAddress(void) const + { + char szAdr[INET6_ADDRSTRLEN]{}; + inet_ntop(AF_INET6, &this->adr, szAdr, INET6_ADDRSTRLEN); + return szAdr; + } + inline uint16_t GetPort(void) const + { + return this->port; + } + inline bool IsReliable(void) const + { + return this->reliable; + } + netadrtype_t type{}; + IN6_ADDR adr{}; + uint16_t port{}; + bool field_16{}; + bool reliable{}; +}; diff --git a/r5dev/tier1/bitbuf.cpp b/r5dev/tier1/bitbuf.cpp new file mode 100644 index 00000000..491b2071 --- /dev/null +++ b/r5dev/tier1/bitbuf.cpp @@ -0,0 +1,75 @@ +//===========================================================================// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "core/stdafx.h" +#include "tier1/bitbuf.h" + +inline int BitByte(int bits) +{ + // return PAD_NUMBER( bits, 8 ) >> 3; + return (bits + 7) >> 3; +} + +bool bf_write::IsOverflowed() const +{ + return this->m_bOverflow; +} + +int bf_write::GetNumBytesWritten() const +{ + return BitByte(this->m_iCurBit); +} + +int bf_write::GetNumBitsWritten() const +{ + return this->m_iCurBit; +} + +int bf_write::GetMaxNumBits() const +{ + return this->m_nDataBits; +} + +int bf_write::GetNumBitsLeft() const +{ + return this->m_nDataBits - m_iCurBit; +} + +int bf_write::GetNumBytesLeft() const +{ + return this->GetNumBitsLeft() >> 3; +} + +unsigned char* bf_write::GetData() +{ + return this->m_pData; +} + +const unsigned char* bf_write::GetData() const +{ + return this->m_pData; +} + +bool bf_write::CheckForOverflow(int nBits) +{ + if (this->m_iCurBit + nBits > this->m_nDataBits) + { + this->SetOverflowFlag(); + } + + return this->m_bOverflow; +} + +void bf_write::SetOverflowFlag() +{ + if (this->m_bAssertOnOverflow) + { + Assert(false); + } + + this->m_bOverflow = true; +} \ No newline at end of file diff --git a/r5dev/tier1/bitbuf.h b/r5dev/tier1/bitbuf.h new file mode 100644 index 00000000..b69d70b5 --- /dev/null +++ b/r5dev/tier1/bitbuf.h @@ -0,0 +1,40 @@ +#ifndef BITBUF_H +#define BITBUF_H + +typedef enum +{ + BITBUFERROR_VALUE_OUT_OF_RANGE = 0, // Tried to write a value with too few bits. + BITBUFERROR_BUFFER_OVERRUN, // Was about to overrun a buffer. + + BITBUFERROR_NUM_ERRORS +} BitBufErrorType; + +//----------------------------------------------------------------------------- +// Used for serialization +//----------------------------------------------------------------------------- +struct bf_write +{ +public: + // How many bytes are filled in? + int GetNumBytesWritten() const; + int GetNumBitsWritten() const; + int GetMaxNumBits() const; + int GetNumBitsLeft() const; + int GetNumBytesLeft() const; + unsigned char* GetData(); + const unsigned char* GetData() const; + + // Has the buffer overflowed? + bool CheckForOverflow(int nBits); + bool IsOverflowed() const; + void SetOverflowFlag(); +private: + unsigned __int8* m_pData; + int m_nDataBytes; + int m_nDataBits; + int m_iCurBit; + bool m_bOverflow; + bool m_bAssertOnOverflow; + const char* m_pDebugName; +}; +#endif // BITBUF_H diff --git a/r5dev/tier1/utlmemory.h b/r5dev/tier1/utlmemory.h new file mode 100644 index 00000000..5e85c01c --- /dev/null +++ b/r5dev/tier1/utlmemory.h @@ -0,0 +1,20 @@ +//============ Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// A growable memory class. +//===========================================================================// + +#ifndef UTLMEMORY_H +#define UTLMEMORY_H + +struct __declspec(align(8)) CUtlMemory +{ + void* m_pMemory; + int64_t m_nAllocationCount; + int64_t m_nGrowSize; +}; + +#endif // UTLMEMORY_H diff --git a/r5dev/tier1/utlvector.h b/r5dev/tier1/utlvector.h new file mode 100644 index 00000000..649e0f05 --- /dev/null +++ b/r5dev/tier1/utlvector.h @@ -0,0 +1,23 @@ +//============ Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// A growable array class that maintains a free list and keeps elements +// in the same location +//===========================================================================// + +#ifndef UTLVECTOR_H +#define UTLVECTOR_H + +#include "tier1/utlmemory.h" + +struct __declspec(align(4)) CUtlVector +{ + void* vtable; + CUtlMemory m_Memory; + int m_Size; +}; + +#endif // CCVECTOR_H diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj index f8a42e00..5876f7a1 100644 --- a/r5dev/vproj/clientsdk.vcxproj +++ b/r5dev/vproj/clientsdk.vcxproj @@ -81,6 +81,7 @@ + @@ -161,6 +162,7 @@ + @@ -326,7 +328,10 @@ + + + diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters index c1c697e7..fd3951c7 100644 --- a/r5dev/vproj/clientsdk.vcxproj.filters +++ b/r5dev/vproj/clientsdk.vcxproj.filters @@ -390,6 +390,9 @@ sdk\rtech\rui + + sdk\tier1 + @@ -1124,6 +1127,18 @@ sdk\squirrel + + sdk\public\include + + + sdk\tier1 + + + sdk\tier1 + + + sdk\tier1 + diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj index dc3caa5c..97e5b16a 100644 --- a/r5dev/vproj/dedicated.vcxproj +++ b/r5dev/vproj/dedicated.vcxproj @@ -182,6 +182,7 @@ + @@ -336,7 +337,10 @@ + + + @@ -414,6 +418,7 @@ + diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters index 137e992f..a41ecfa1 100644 --- a/r5dev/vproj/dedicated.vcxproj.filters +++ b/r5dev/vproj/dedicated.vcxproj.filters @@ -816,6 +816,18 @@ sdk\squirrel + + sdk\public\include + + + sdk\tier1 + + + sdk\tier1 + + + sdk\tier1 + @@ -1019,6 +1031,9 @@ sdk\engine + + sdk\tier1 + diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index e132fcfb..ea8ab65a 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -68,6 +68,7 @@ + @@ -87,6 +88,7 @@ + @@ -175,6 +177,7 @@ + @@ -342,7 +345,10 @@ + + + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index 81f79662..fbdece2e 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -417,6 +417,12 @@ sdk\engine + + sdk\public + + + sdk\tier1 + @@ -1181,6 +1187,18 @@ sdk\squirrel + + sdk\public\include + + + sdk\tier1 + + + sdk\tier1 + + + sdk\tier1 +