diff --git a/r5dev/common/netmessages.h b/r5dev/common/netmessages.h index d8ef82a1..9d30c4d3 100644 --- a/r5dev/common/netmessages.h +++ b/r5dev/common/netmessages.h @@ -87,6 +87,13 @@ public: bf_write m_DataOut; }; +struct NET_StringCmd : CNetMessage, INetMessageHandler +{ + const char* cmd; + char buffer[1024]; +}; + + //------------------------------------------------------------------------- // MM_HEARTBEAT //------------------------------------------------------------------------- diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 6bbc3f50..c4e2ac07 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -63,6 +63,9 @@ #include "rtech/rtech_utils.h" #include "rtech/stryder/stryder.h" #include "rtech/rui/rui.h" +#ifndef DEDICATED +#include "engine/client/cl_ents_parse.h" +#endif // !DEDICATED #include "engine/client/cl_main.h" #include "engine/client/client.h" #include "engine/client/clientstate.h" @@ -149,6 +152,9 @@ void Systems_Init() #ifdef DEDICATED //PRX_Attach(); #endif // DEDICATED +#ifndef DEDICATED + CL_Ents_Parse_Attach(); +#endif // !DEDICATED CBaseClient_Attach(); CBaseFileSystem_Attach(); @@ -182,7 +188,7 @@ void Systems_Init() #endif // !DEDICATED && GAMEDLL_S3 NET_Attach(); - //NetChan_Attach(); + NetChan_Attach(); ConCommand_Attach(); IConVar_Attach(); @@ -191,6 +197,7 @@ void Systems_Init() #ifndef CLIENT_DLL Persistence_Attach(); IVEngineServer_Attach(); + CServerGameDLL_Attach(); #endif // !CLIENT_DLL SQAPI_Attach(); @@ -275,6 +282,9 @@ void Systems_Shutdown() #ifdef DEDICATED //PRX_Detach(); #endif // DEDICATED +#ifndef DEDICATED + CL_Ents_Parse_Detach(); +#endif // !DEDICATED CBaseClient_Detach(); CBaseFileSystem_Detach(); @@ -308,7 +318,7 @@ void Systems_Shutdown() #endif // !DEDICATED && GAMEDLL_S3 NET_Detach(); - //NetChan_Detach(); + NetChan_Detach(); ConCommand_Detach(); IConVar_Detach(); @@ -317,6 +327,7 @@ void Systems_Shutdown() #ifndef CLIENT_DLL Persistence_Detach(); IVEngineServer_Detach(); + CServerGameDLL_Detach(); #endif // !CLIENT_DLL SQAPI_Detach(); SQVM_Detach(); diff --git a/r5dev/engine/client/cl_ents_parse.cpp b/r5dev/engine/client/cl_ents_parse.cpp new file mode 100644 index 00000000..090249cf --- /dev/null +++ b/r5dev/engine/client/cl_ents_parse.cpp @@ -0,0 +1,35 @@ +//====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======// +// +// Purpose: Parsing of entity network packets. +// +// $NoKeywords: $ +//=============================================================================// +#include "core/stdafx.h" +#include "public/const.h" +#include "engine/client/cl_ents_parse.h" + +bool CL_CopyExistingEntity(__int64 a1, unsigned int* a2, char* a3) +{ + int nNewEntity = *reinterpret_cast(a1 + 40); + if (nNewEntity >= MAX_EDICTS || nNewEntity < NULL) + { + // Value isn't sanitized in release builds for + // every game powered by the Source Engine 1 + // causing read/write outside of array bounds. + // This defect has let to the achievement of a + // full-chain RCE exploit. We hook and perform + // sanity checks for the value of m_nNewEntity + // here to prevent this behavior from happening. + return false; + } + return v_CL_CopyExistingEntity(a1, a2, a3); +} + +void CL_Ents_Parse_Attach() +{ + DetourAttach((LPVOID*)&v_CL_CopyExistingEntity, &CL_CopyExistingEntity); +} +void CL_Ents_Parse_Detach() +{ + DetourDetach((LPVOID*)&v_CL_CopyExistingEntity, &CL_CopyExistingEntity); +} \ No newline at end of file diff --git a/r5dev/engine/client/cl_ents_parse.h b/r5dev/engine/client/cl_ents_parse.h new file mode 100644 index 00000000..cba4ba0b --- /dev/null +++ b/r5dev/engine/client/cl_ents_parse.h @@ -0,0 +1,32 @@ +#ifndef CL_ENTS_PARSE_H +#define CL_ENTS_PARSE_H + +inline CMemory p_CL_CopyExistingEntity; +inline auto v_CL_CopyExistingEntity = p_CL_CopyExistingEntity.RCast(); + + +/////////////////////////////////////////////////////////////////////////////// +class V_CL_Ents_Parse : public IDetour +{ + virtual void GetAdr(void) const + { + spdlog::debug("| FUN: CL_CopyExistingEntity : {:#18x} |\n", p_CL_CopyExistingEntity.GetPtr()); + spdlog::debug("+----------------------------------------------------------------+\n"); + } + virtual void GetFun(void) const + { + p_CL_CopyExistingEntity = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x70\x4C\x63\x51\x28"), "xxxxxxxxxx"); + v_CL_CopyExistingEntity = p_CL_CopyExistingEntity.RCast(); /*40 53 48 83 EC 70 4C 63 51 28*/ + } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Attach(void) const { } + virtual void Detach(void) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + +void CL_Ents_Parse_Attach(); +void CL_Ents_Parse_Detach(); + +REGISTER(V_CL_Ents_Parse); +#endif // !CL_ENTS_PARSE_H diff --git a/r5dev/engine/client/client.cpp b/r5dev/engine/client/client.cpp index 1a6c7cb8..a24c7192 100644 --- a/r5dev/engine/client/client.cpp +++ b/r5dev/engine/client/client.cpp @@ -9,6 +9,8 @@ // /////////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" +#include "tier1/cvar.h" +#include "engine/server/server.h" #include "engine/client/client.h" //--------------------------------------------------------------------------------- @@ -207,16 +209,22 @@ bool CClient::IsHumanPlayer(void) const //--------------------------------------------------------------------------------- void CClient::Clear(void) { +#ifndef CLIENT_DLL + g_ServerPlayer[GetUserID()].Reset(); // Reset ServerPlayer slot. +#endif // !CLIENT_DLL v_CClient_Clear(this); } //--------------------------------------------------------------------------------- // Purpose: throw away any residual garbage in the channel -// Input : *pBaseClient - +// Input : *pClient - //--------------------------------------------------------------------------------- -void CClient::VClear(CClient* pBaseClient) +void CClient::VClear(CClient* pClient) { - v_CClient_Clear(pBaseClient); +#ifndef CLIENT_DLL + g_ServerPlayer[pClient->GetUserID()].Reset(); // Reset ServerPlayer slot. +#endif // !CLIENT_DLL + v_CClient_Clear(pClient); } //--------------------------------------------------------------------------------- @@ -247,7 +255,81 @@ bool CClient::Connect(const char* szName, void* pNetChannel, bool bFakePlayer, v //--------------------------------------------------------------------------------- bool CClient::VConnect(CClient* pClient, const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize) { - return v_CClient_Connect(pClient, szName, pNetChannel, bFakePlayer, a5, szMessage, nMessageSize); + bool bResult = v_CClient_Connect(pClient, szName, pNetChannel, bFakePlayer, a5, szMessage, nMessageSize); +#ifndef CLIENT_DLL + g_ServerPlayer[pClient->GetUserID()].Reset(); // Reset ServerPlayer slot. +#endif // !CLIENT_DLL + return bResult; +} + +//--------------------------------------------------------------------------------- +// Purpose: disconnect client +// Input : nRepLvl - +// *szReason - +// ... - +//--------------------------------------------------------------------------------- +void CClient::Disconnect(const Reputation_t nRepLvl, const char* szReason, ...) +{ + if (m_nSignonState != SIGNONSTATE::SIGNONSTATE_NONE) + { + char szBuf[1024]; + {///////////////////////////// + va_list vArgs{}; + va_start(vArgs, szReason); + + vsnprintf(szBuf, sizeof(szBuf), szReason, vArgs); + + szBuf[sizeof(szBuf) - 1] = '\0'; + va_end(vArgs); + }///////////////////////////// + v_CClient_Disconnect(this, nRepLvl, szBuf); + } +} + +//--------------------------------------------------------------------------------- +// Purpose: process string commands (kicking anyone attempting to DOS) +// Input : *pClient - (ADJ) +// *pMsg - +// Output : false if cmd should be passed to CServerGameClients +//--------------------------------------------------------------------------------- +bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg) +{ +#ifndef CLIENT_DLL +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + CClient* pClient_Adj = pClient; +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + /* Original function called method "CClient::ExecuteStringCommand" with an optimization + * that shifted the 'this' pointer with 8 bytes. + * Since this has been inlined with "CClient::ProcessStringCmd" as of S2, the shifting + * happens directly to anything calling this function. */ + char* pShifted = reinterpret_cast(pClient) - 8; + CClient* pClient_Adj = reinterpret_cast(pShifted); +#endif // !GAMEDLL_S0 || !GAMEDLL_S1 + ServerPlayer_t* pSlot = &g_ServerPlayer[pClient_Adj->GetUserID()]; + double flStartTime = Plat_FloatTime(); + int nCmdQuotaLimit = sv_quota_stringCmdsPerSecond->GetInt(); + + if (!nCmdQuotaLimit) + return true; + + if (flStartTime - pSlot->m_flStringCommandQuotaTimeStart >= 1.0) + { + pSlot->m_flStringCommandQuotaTimeStart = flStartTime; + pSlot->m_nStringCommandQuotaCount = 0; + } + ++pSlot->m_nStringCommandQuotaCount; + + if (pSlot->m_nStringCommandQuotaCount > nCmdQuotaLimit) + { + Warning(eDLL_T::SERVER, "Removing client '%s' from slot '%i' ('%llu' exceeded string command quota!)\n", + pClient_Adj->GetNetChan()->GetAddress(), pClient_Adj->GetUserID(), pClient_Adj->GetNucleusID()); + + pClient_Adj->Disconnect(Reputation_t::REP_MARK_BAD, "#DISCONNECT_STRINGCMD_OVERFLOW"); + return true; + } +#endif // !CLIENT_DLL + + return v_CClient_ProcessStringCmd(pClient, pMsg); } /////////////////////////////////////////////////////////////////////////////////// @@ -255,11 +337,13 @@ void CBaseClient_Attach() { DetourAttach((LPVOID*)&v_CClient_Clear, &CClient::VClear); DetourAttach((LPVOID*)&v_CClient_Connect, &CClient::VConnect); + DetourAttach((LPVOID*)&v_CClient_ProcessStringCmd, &CClient::VProcessStringCmd); } void CBaseClient_Detach() { DetourDetach((LPVOID*)&v_CClient_Clear, &CClient::VClear); DetourDetach((LPVOID*)&v_CClient_Connect, &CClient::VConnect); + DetourDetach((LPVOID*)&v_CClient_ProcessStringCmd, &CClient::VProcessStringCmd); } /////////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/engine/client/client.h b/r5dev/engine/client/client.h index 8e6cacc2..775a91da 100644 --- a/r5dev/engine/client/client.h +++ b/r5dev/engine/client/client.h @@ -3,6 +3,16 @@ #include "common/protocol.h" #include "engine/net_chan.h" +//----------------------------------------------------------------------------- +// Enumerations +//----------------------------------------------------------------------------- +enum Reputation_t +{ + REP_NONE = 0, + REP_REMOVE_ONLY, + REP_MARK_BAD +}; + //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- @@ -12,7 +22,7 @@ class CClient; /////////////////////////////////////////////////////////////////////////////// extern CClient* g_pClient; -class CClient : INetChannelHandler, IClientMessageHandler +class CClient : IClientMessageHandler, INetChannelHandler { public: CClient* GetClient(int nIndex) const; @@ -38,9 +48,11 @@ public: bool IsFakeClient(void) const; bool IsHumanPlayer(void) const; bool Connect(const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize); + void Disconnect(const Reputation_t nRepLvl, const char* szReason, ...); static bool VConnect(CClient* pClient, const char* szName, void* pNetChannel, bool bFakePlayer, void* a5, char* szMessage, int nMessageSize); void Clear(void); - static void VClear(CClient* pBaseClient); + static void VClear(CClient* pClient); + static bool VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg); private: uint32_t m_nUserID; //0x0010 @@ -87,10 +99,16 @@ static_assert(sizeof(CClient) == 0x4A4C0); /* ==== CBASECLIENT ===================================================================================================================================================== */ inline CMemory p_CClient_Connect; -inline auto v_CClient_Connect = p_CClient_Connect.RCast(); +inline auto v_CClient_Connect = p_CClient_Connect.RCast(); + +inline CMemory p_CClient_Disconnect; +inline auto v_CClient_Disconnect = p_CClient_Disconnect.RCast(); inline CMemory p_CClient_Clear; -inline auto v_CClient_Clear = p_CClient_Clear.RCast(); +inline auto v_CClient_Clear = p_CClient_Clear.RCast(); + +inline CMemory p_CClient_ProcessStringCmd; +inline auto v_CClient_ProcessStringCmd = p_CClient_ProcessStringCmd.RCast(); /////////////////////////////////////////////////////////////////////////////// void CBaseClient_Attach(); @@ -102,17 +120,31 @@ class VClient : public IDetour virtual void GetAdr(void) const { spdlog::debug("| FUN: CClient::Connect : {:#18x} |\n", p_CClient_Connect.GetPtr()); + spdlog::debug("| FUN: CClient::Disconnect : {:#18x} |\n", p_CClient_Disconnect.GetPtr()); spdlog::debug("| FUN: CClient::Clear : {:#18x} |\n", p_CClient_Clear.GetPtr()); + spdlog::debug("| FUN: CClient::ProcessStringCmd : {:#18x} |\n", p_CClient_ProcessStringCmd.GetPtr()); spdlog::debug("| VAR: g_pClient[128] : {:#18x} |\n", reinterpret_cast(g_pClient)); spdlog::debug("+----------------------------------------------------------------+\n"); } virtual void GetFun(void) const { - p_CClient_Connect = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x56\x57\x41\x56\x48\x83\xEC\x20\x41\x0F\xB6\xE9"), "xxxx?xxxx?xxxxxxxxxxxx"); - p_CClient_Clear = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x41\x56\x41\x57\x48\x83\xEC\x20\x48\x8B\xD9\x48\x89\x74"), "xxxxxxxxxxxxxxxx"); + p_CClient_Connect = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x56\x57\x41\x56\x48\x83\xEC\x20\x41\x0F\xB6\xE9"), "xxxx?xxxx?xxxxxxxxxxxx"); +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2) + p_CClient_Disconnect = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x00\x00\x00\x00\x83\xB9\x00\x00\x00\x00\x00\x49\x8B\xF8\x0F\xB6\xF2"), "xxxxxxxxxxxxxxxxx????xx?????xxxxxx"); +#else // !GAMEDLL_S0 || !GAMEDLL_S1 || !GAMEDLL_S2 + p_CClient_Disconnect = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x00\x00\x00\x00\x83\xB9\x00\x00\x00\x00\x00\x49\x8B\xF8\x8B\xF2"), "xxxxxxxxxxxxxxxxx????xx?????xxxxx"); +#endif + p_CClient_Clear = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x41\x56\x41\x57\x48\x83\xEC\x20\x48\x8B\xD9\x48\x89\x74"), "xxxxxxxxxxxxxxxx"); +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + p_CClient_ProcessStringCmd = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\x4C\x8B\x42\x20"), "xxxxxxxx"); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + p_CClient_ProcessStringCmd = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x6C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x7A\x20"), "xxxx?xxxx????xxxx"); +#endif // !GAMEDLL_S0 || !GAMEDLL_S1 - v_CClient_Connect = p_CClient_Connect.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 20 41 0F B6 E9*/ - v_CClient_Clear = p_CClient_Clear.RCast(); /*40 53 41 56 41 57 48 83 EC 20 48 8B D9 48 89 74*/ + v_CClient_Connect = p_CClient_Connect.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 20 41 0F B6 E9*/ + v_CClient_Disconnect = p_CClient_Disconnect.RCast(); /*48 8B C4 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 49 8B F8 8B F2*/ + v_CClient_Clear = p_CClient_Clear.RCast(); /*40 53 41 56 41 57 48 83 EC 20 48 8B D9 48 89 74*/ + v_CClient_ProcessStringCmd = p_CClient_ProcessStringCmd.RCast(); /*48 89 6C 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B 7A 20*/ } virtual void GetVar(void) const { diff --git a/r5dev/engine/host.h b/r5dev/engine/host.h index ecf24131..6b8fc228 100644 --- a/r5dev/engine/host.h +++ b/r5dev/engine/host.h @@ -7,7 +7,7 @@ inline CMemory p_Host_RunFrame_Render; inline auto v_Host_RunFrame_Render = p_Host_RunFrame_Render.RCast(); inline CMemory p_Host_Error; -inline auto v_Host_Error = p_Host_Error.RCast(); +inline auto v_Host_Error = p_Host_Error.RCast(); inline CMemory p_VCR_EnterPausedState; inline auto v_VCR_EnterPausedState = p_VCR_EnterPausedState.RCast(); @@ -47,7 +47,7 @@ class VHost : public IDetour v_Host_RunFrame = p_Host_RunFrame.RCast(); v_Host_RunFrame_Render = p_Host_Error.RCast(); - v_Host_Error = p_Host_Error.RCast(); + v_Host_Error = p_Host_Error.RCast(); v_VCR_EnterPausedState = p_VCR_EnterPausedState.RCast(); } virtual void GetVar(void) const diff --git a/r5dev/engine/host_state.cpp b/r5dev/engine/host_state.cpp index 44a0dc11..4b90e17e 100644 --- a/r5dev/engine/host_state.cpp +++ b/r5dev/engine/host_state.cpp @@ -232,14 +232,14 @@ FORCEINLINE void CHostState::Think(void) const bInitialized = true; } #ifndef CLIENT_DLL - if (banListTimer.GetDurationInProgress().GetSeconds() > sv_banlistRefreshInterval->GetDouble()) + if (banListTimer.GetDurationInProgress().GetSeconds() > sv_banlistRefreshRate->GetDouble()) { g_pBanSystem->BanListCheck(); banListTimer.Start(); } #endif // !CLIENT_DLL #ifdef DEDICATED - if (pylonTimer.GetDurationInProgress().GetSeconds() > sv_pylonRefreshInterval->GetDouble()) + if (pylonTimer.GetDurationInProgress().GetSeconds() > sv_pylonRefreshRate->GetDouble()) { const NetGameServer_t netGameServer { @@ -273,7 +273,7 @@ FORCEINLINE void CHostState::Think(void) const reloadTimer.Start(); } } - if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshInterval->GetDouble()) + if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate->GetDouble()) { string svCurrentPlaylist = KeyValues_GetCurrentPlaylist(); int32_t nPlayerCount = g_pServer->GetNumHumanPlayers(); @@ -330,7 +330,7 @@ FORCEINLINE void CHostState::GameShutDown(void) #ifndef CLIENT_DLL g_pServerGameDLL->GameShutdown(); #endif // !CLIENT_DLL - m_bActiveGame = 0; + m_bActiveGame = false; ResetLevelName(); } } diff --git a/r5dev/engine/net.cpp b/r5dev/engine/net.cpp index 2504e1a6..d7d29dea 100644 --- a/r5dev/engine/net.cpp +++ b/r5dev/engine/net.cpp @@ -162,7 +162,7 @@ void NET_Shutdown(void* thisptr, const char* szReason, uint8_t bBadRep, bool bRe // bBadRep - // bRemoveNow - //----------------------------------------------------------------------------- -void NET_DisconnectClient(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow) +void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow) { #ifndef CLIENT_DLL if (!pClient || std::strlen(szReason) == NULL || !pClient->GetNetChan()) @@ -170,9 +170,9 @@ void NET_DisconnectClient(CClient* pClient, int nIndex, const char* szReason, ui return; } - v_NET_Shutdown(pClient->GetNetChan(), szReason, bBadRep, bRemoveNow); // Shutdown netchan. + v_NET_Shutdown(pClient->GetNetChan(), szReason, bBadRep, bRemoveNow); // Shutdown NetChannel. pClient->Clear(); // Reset CClient instance for client. - g_bIsPersistenceVarSet[nIndex] = false; // Reset Persistence var. + g_ServerPlayer[nIndex].Reset(); // Reset ServerPlayer slot. #endif // !CLIENT_DLL } #endif // !NETCONSOLE diff --git a/r5dev/engine/net.h b/r5dev/engine/net.h index 02fc0129..ce6d1c40 100644 --- a/r5dev/engine/net.h +++ b/r5dev/engine/net.h @@ -43,7 +43,7 @@ void NET_SetKey(string svNetKey); void NET_GenerateKey(); void NET_PrintFunc(const char* fmt, ...); void NET_Shutdown(void* thisptr, const char* szReason, uint8_t bBadRep, bool bRemoveNow); -void NET_DisconnectClient(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow); +void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8_t bBadRep, bool bRemoveNow); void NET_Attach(); void NET_Detach(); diff --git a/r5dev/engine/net_chan.cpp b/r5dev/engine/net_chan.cpp index d95fd30b..5d284ca7 100644 --- a/r5dev/engine/net_chan.cpp +++ b/r5dev/engine/net_chan.cpp @@ -8,6 +8,12 @@ #include "tier1/cvar.h" #include "engine/net.h" #include "engine/net_chan.h" +#ifndef CLIENT_DLL +#include "engine/server/server.h" +#include "engine/client/client.h" +#include "server/vengineserver_impl.h" +#endif // !CLIENT_DLL + //----------------------------------------------------------------------------- // Purpose: gets the netchannel name @@ -201,9 +207,50 @@ void CNetChan::Clear(bool bStopProcessing) v_NetChan_Clear(this, bStopProcessing); } +//----------------------------------------------------------------------------- +// Purpose: process message +// Input : *pChan - +// *pMsg - +// Output : true on success, false on failure +//----------------------------------------------------------------------------- bool CNetChan::ProcessMessages(CNetChan* pChan, bf_read* pMsg) { +#ifndef CLIENT_DLL + if (!ThreadInServerFrameThread() || !net_processTimeBudget->GetInt()) + return v_NetChan_ProcessMessages(pChan, pMsg); + + const double flStartTime = Plat_FloatTime(); + const bool bResult = v_NetChan_ProcessMessages(pChan, pMsg); + + if (!pChan->m_MessageHandler) // NetChannel removed? + return bResult; + + CClient* pClient = reinterpret_cast(pChan->m_MessageHandler); + ServerPlayer_t* pSlot = &g_ServerPlayer[pClient->GetUserID()]; + + if (flStartTime - pSlot->m_flLastNetProcessTime >= 1.0 || + pSlot->m_flLastNetProcessTime == -1.0) + { + pSlot->m_flLastNetProcessTime = flStartTime; + pSlot->m_flCurrentNetProcessTime = 0.0; + } + pSlot->m_flCurrentNetProcessTime += + (Plat_FloatTime() * 1000) - (flStartTime * 1000); + + if (pSlot->m_flCurrentNetProcessTime > + net_processTimeBudget->GetDouble()) + { + Warning(eDLL_T::ENGINE, "Removing netchannel '%s' ('%s' exceeded frame budget by '%3.1f'ms!)\n", + pChan->GetName(), pChan->GetAddress(), (pSlot->m_flCurrentNetProcessTime - net_processTimeBudget->GetDouble())); + pClient->Disconnect(Reputation_t::REP_MARK_BAD, "#DISCONNECT_NETCHAN_OVERFLOW"); + + return false; + } + + return bResult; +#else // !CLIENT_DLL return v_NetChan_ProcessMessages(pChan, pMsg); +#endif } /////////////////////////////////////////////////////////////////////////////// @@ -214,4 +261,4 @@ void NetChan_Attach() void NetChan_Detach() { DetourDetach((LPVOID*)&v_NetChan_ProcessMessages, &CNetChan::ProcessMessages); -} \ No newline at end of file +} diff --git a/r5dev/engine/server/server.h b/r5dev/engine/server/server.h index a02c98bd..ae12f961 100644 --- a/r5dev/engine/server/server.h +++ b/r5dev/engine/server/server.h @@ -103,14 +103,17 @@ class VServer : public IDetour { virtual void GetAdr(void) const { +#ifndef CLIENT_DLL spdlog::debug("| FUN: CServer::Think : {:#18x} |\n", p_CServer_Think.GetPtr()); spdlog::debug("| FUN: CServer::ConnectClient : {:#18x} |\n", p_CServer_Authenticate.GetPtr()); spdlog::debug("| FUN: CServer::RejectConnection : {:#18x} |\n", p_CServer_RejectConnection.GetPtr()); spdlog::debug("| VAR: g_pServer[128] : {:#18x} |\n", reinterpret_cast(g_pServer)); spdlog::debug("+----------------------------------------------------------------+\n"); +#endif // !CLIENT_DLL } virtual void GetFun(void) const { +#ifndef CLIENT_DLL p_CServer_Think = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00"), "xxxx?xxxx?xxxx????xx?????"); #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) p_CServer_Authenticate = g_GameDll.FindPatternSIMD(reinterpret_cast("\x44\x89\x44\x24\x00\x55\x56\x57\x48\x8D\xAC\x24\x00\x00\x00\x00"), "xxxx?xxxxxxx????"); @@ -122,13 +125,16 @@ class VServer : public IDetour p_CServer_RejectConnection = g_GameDll.FindPatternSIMD(reinterpret_cast("\x4C\x89\x4C\x24\x00\x53\x55\x56\x57\x48\x81\xEC\x00\x00\x00\x00\x49\x8B\xD9"), "xxxx?xxxxxxx????xxx"); v_CServer_Think = p_CServer_Think.RCast(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??*/ - v_CServer_ConnectClient = p_CServer_Authenticate.RCast(); /*40 55 57 41 55 41 57 48 8D AC 24 ?? ?? ?? ??*/ + v_CServer_ConnectClient = p_CServer_Authenticate.RCast(); /*40 55 57 41 55 41 57 48 8D AC 24 ?? ?? ?? ??*/ v_CServer_RejectConnection = p_CServer_RejectConnection.RCast(); /*4C 89 4C 24 ?? 53 55 56 57 48 81 EC ?? ?? ?? ?? 49 8B D9*/ +#endif // !CLIENT_DLL } virtual void GetVar(void) const { +#ifndef CLIENT_DLL g_pServer = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x48\x0F\xBF\xD1"), "xxxx?xxxxxxxxx") .FindPatternSelf("48 8D 3D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#endif // !CLIENT_DLL } virtual void GetCon(void) const { } virtual void Attach(void) const { } diff --git a/r5dev/game/server/gameinterface.cpp b/r5dev/game/server/gameinterface.cpp index 16842435..24bad774 100644 --- a/r5dev/game/server/gameinterface.cpp +++ b/r5dev/game/server/gameinterface.cpp @@ -56,6 +56,29 @@ float CServerGameDLL::GetTickInterval(void) return CallVFunc(index, this); } +void __fastcall CServerGameDLL::OnReceivedSayTextMessage(void* thisptr, int senderId, const char* text, bool isTeamChat) +{ +#if defined(GAMEDLL_S3) + // set isTeamChat to false so that we can let the convar sv_forceChatToTeamOnly decide whether team chat should be enforced + // this isn't a great way of doing it but it works so meh + CServerGameDLL__OnReceivedSayTextMessage(thisptr, senderId, text, false); +#endif +} + +void CServerGameDLL_Attach() +{ +#if defined(GAMEDLL_S3) + DetourAttach((LPVOID*)&CServerGameDLL__OnReceivedSayTextMessage, &CServerGameDLL::OnReceivedSayTextMessage); +#endif +} + +void CServerGameDLL_Detach() +{ +#if defined(GAMEDLL_S3) + DetourDetach((LPVOID*)&CServerGameDLL__OnReceivedSayTextMessage, &CServerGameDLL::OnReceivedSayTextMessage); +#endif +} + // Pointer to CServerGameDLL virtual function table. CServerGameDLL* g_pServerGameDLL = nullptr; CServerGameClients* g_pServerGameClients = nullptr; diff --git a/r5dev/game/server/gameinterface.h b/r5dev/game/server/gameinterface.h index 513a7d9f..8dc11315 100644 --- a/r5dev/game/server/gameinterface.h +++ b/r5dev/game/server/gameinterface.h @@ -13,24 +13,40 @@ public: void LevelShutdown(void); void GameShutdown(void); float GetTickInterval(void); + + static void __fastcall OnReceivedSayTextMessage(void* thisptr, int senderId, const char* text, bool isTeamChat); }; class CServerGameClients { }; +inline CMemory p_CServerGameDLL__OnReceivedSayTextMessage; +inline auto CServerGameDLL__OnReceivedSayTextMessage = p_CServerGameDLL__OnReceivedSayTextMessage.RCast(); + extern CServerGameDLL* g_pServerGameDLL; extern CServerGameClients* g_pServerGameClients; +void CServerGameDLL_Attach(); +void CServerGameDLL_Detach(); + /////////////////////////////////////////////////////////////////////////////// class VServerGameDLL : public IDetour { virtual void GetAdr(void) const { + spdlog::debug("| FUN: OnReceivedSayTextMessage : {:#18x} |\n", p_CServerGameDLL__OnReceivedSayTextMessage.GetPtr()); spdlog::debug("| VAR: g_pServerGameDLL : {:#18x} |\n", reinterpret_cast(g_pServerGameDLL)); spdlog::debug("| VAR: g_pServerGameClients : {:#18x} |\n", reinterpret_cast(g_pServerGameClients)); spdlog::debug("+----------------------------------------------------------------+\n"); } - virtual void GetFun(void) const { } + virtual void GetFun(void) const + { +#if defined(GAMEDLL_S3) + p_CServerGameDLL__OnReceivedSayTextMessage = g_GameDll.FindPatternSIMD(reinterpret_cast("\x85\xD2\x0F\x8E\x00\x00\x00\x00\x4C\x8B\xDC"), "xxxx????xxx"); + + CServerGameDLL__OnReceivedSayTextMessage = p_CServerGameDLL__OnReceivedSayTextMessage.RCast(); +#endif + } virtual void GetVar(void) const { g_pServerGameDLL = p_SV_CreateBaseline.Offset(0x0).FindPatternSelf("48 8B", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).Deref().RCast(); diff --git a/r5dev/networksystem/bansystem.cpp b/r5dev/networksystem/bansystem.cpp index 53f7b656..794f75f8 100644 --- a/r5dev/networksystem/bansystem.cpp +++ b/r5dev/networksystem/bansystem.cpp @@ -223,11 +223,11 @@ void CBanSystem::BanListCheck(void) string svIpAddress = pNetChan->GetAddress(); - Warning(eDLL_T::SERVER, "Removing client '%s' from slot '%hu' ('%llu' is banned from this server!)\n", svIpAddress.c_str(), pClient->GetHandle(), pClient->GetNucleusID()); + Warning(eDLL_T::SERVER, "Removing client '%s' from slot '%i' ('%llu' is banned from this server!)\n", svIpAddress.c_str(), c, pClient->GetNucleusID()); if (AddEntry(svIpAddress, pClient->GetNucleusID()) && !bSave) bSave = true; - NET_DisconnectClient(pClient, c, m_vRefuseList[i].first.c_str(), 0, true); + pClient->Disconnect(Reputation_t::REP_MARK_BAD, m_vRefuseList[i].first.c_str()); } } @@ -299,7 +299,7 @@ void CBanSystem::KickPlayerByName(const string& svPlayerName) if (strlen(pNetChan->GetName()) > 0) { if (svPlayerName.compare(pNetChan->GetName()) == NULL) // Our wanted name? - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Kicked from server"); } } } @@ -344,14 +344,14 @@ void CBanSystem::KickPlayerById(const string& svHandle) continue; } - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Kicked from server"); } else { if (svHandle.compare(pNetChan->GetAddress()) != NULL) continue; - NET_DisconnectClient(pClient, i, "Kicked from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Kicked from server"); } } } @@ -386,7 +386,7 @@ void CBanSystem::BanPlayerByName(const string& svPlayerName) if (AddEntry(pNetChan->GetAddress(), pClient->GetNucleusID()) && !bSave) bSave = true; - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Banned from server"); } } } @@ -441,7 +441,7 @@ void CBanSystem::BanPlayerById(const string& svHandle) bSave = true; Save(); - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Banned from server"); } else { @@ -452,7 +452,7 @@ void CBanSystem::BanPlayerById(const string& svHandle) bSave = true; Save(); - NET_DisconnectClient(pClient, i, "Banned from server", 0, true); + pClient->Disconnect(REP_MARK_BAD, "Banned from server"); } } diff --git a/r5dev/public/const.h b/r5dev/public/const.h index 806799a3..b797e11a 100644 --- a/r5dev/public/const.h +++ b/r5dev/public/const.h @@ -8,6 +8,11 @@ #ifndef CONST_H #define CONST_H +// How many bits to use to encode an edict. +#define MAX_EDICT_BITS 14 // # of bits needed to represent max edicts +// Max # of edicts in a level +#define MAX_EDICTS (1< StringSplit(string svInput, char cDelim, size_t nMax) diff --git a/r5dev/public/utility/utility.h b/r5dev/public/utility/utility.h index d6595544..24edebcd 100644 --- a/r5dev/public/utility/utility.h +++ b/r5dev/public/utility/utility.h @@ -48,6 +48,7 @@ bool StringReplace(string& svInput, const string& svFrom, const string& svTo); string StringReplaceC(const string& svInput, const string& svFrom, const string& svTo); string StringEscape(const string& svInput); string StringUnescape(const string& svInput); +size_t StringCount(const string& svInput, char cDelim); vector StringSplit(string svInput, char cDelim, size_t nMax = SIZE_MAX); ///////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/resource/cfg/autoexec.cfg b/r5dev/resource/cfg/autoexec.cfg index f99c5a08..22a8f194 100644 --- a/r5dev/resource/cfg/autoexec.cfg +++ b/r5dev/resource/cfg/autoexec.cfg @@ -2,7 +2,6 @@ //// REPLICATED //// ////////////////////////// mp_allowed "1" // Whether multiplayer is allowed or not. -developer "1" // Required for certain script functionality. ////////////////////////// //// SQUIRREL //// diff --git a/r5dev/resource/cfg/autoexec_client_dev.cfg b/r5dev/resource/cfg/autoexec_client_dev.cfg index 0e3ed573..be9fa874 100644 --- a/r5dev/resource/cfg/autoexec_client_dev.cfg +++ b/r5dev/resource/cfg/autoexec_client_dev.cfg @@ -6,6 +6,7 @@ ////////////////////////// cl_noTimeoutLocalHost "1" // Do not time-out on local connections. cl_threaded_bone_setup "0" // Has to be disabled on the client to prevent deadlock. +cl_quota_stringCmdsPerSecond "256" // Max string commands submissions on the client. ////////////////////////// //// SIMULATION //// !!WARNING!!: CHANGING THESE CAN CAUSE SIMULATION ISSUES. DO NOT CHANGE FOR NON-DEBUG ACTIVITY! @@ -73,5 +74,5 @@ cl_ent_absbox "1" // Display entity abs bo ////////////////////////// mat_showdxoutput "1" // Shows debug information from the DirectX hook system. gl_clear_color_buffer "1" // Enable or disable the clearing of the main color buffer. -//mat_sync_rt "1" // Enable to debug render threads more easily (!slower!). -//mat_sync_rt_flushes_gpu "1" // Enable to debug render threads more easily (!slower!). +//mat_sync_rt "1" // Enable to debug render threads more easily ( !slower! ). +//mat_sync_rt_flushes_gpu "1" // Enable to debug render threads more easily ( !slower! ). diff --git a/r5dev/resource/cfg/autoexec_dev.cfg b/r5dev/resource/cfg/autoexec_dev.cfg index 54853d22..4e2e1d83 100644 --- a/r5dev/resource/cfg/autoexec_dev.cfg +++ b/r5dev/resource/cfg/autoexec_dev.cfg @@ -3,12 +3,14 @@ ////////////////////////// sv_cheats "1" // Allow cheats on the server. mp_allowed "1" // Whether multiplayer is allowed or not. -developer "1" // Required for certain script functionality. +bhit_enable "1" // Bullet trajectory debug. +developer "1" // Required for DEVELOPER script. ////////////////////////// //// NETCHAN //// ////////////////////////// -net_userandomkey "0" // Whether to use the default netkey or a randomized key on launch. +net_useRandomKey "0" // Use a randomized netkey on launch. +net_processTimeBudget "0" // Net message process budget in milliseconds (removing netchannel if exceeded). net_usesocketsforloopback "1" // Whether to use network sockets layer for packets. ////////////////////////// diff --git a/r5dev/resource/cfg/autoexec_server_dev.cfg b/r5dev/resource/cfg/autoexec_server_dev.cfg index b76da7b7..41bd23a0 100644 --- a/r5dev/resource/cfg/autoexec_server_dev.cfg +++ b/r5dev/resource/cfg/autoexec_server_dev.cfg @@ -6,6 +6,7 @@ ////////////////////////// //hostname "R5" // Determines the name of the server displayed in the server browser. sv_requireOriginToken "0" // Enables origin token verification on the server +sv_quota_stringCmdsPerSecond "256" // Max string commands per second from a specific client. ////////////////////////// //// SIMULATION //// !!WARNING!!: CHANGING THESE CAN CAUSE SIMULATION ISSUES. DO NOT CHANGE FOR NON-DEBUG ACTIVITY! @@ -25,4 +26,4 @@ sv_visualizetraces "1" // Show native and script related debug tr ////////////////////////// ai_ainRebuildOnMapStart "0" // Whether to rebuild the AI Network graph on level load. ai_ainDumpOnLoad "0" // Whether to dump the parsed AI Network graph file loaded from disk. -ai_ainDebugConnect "1" // Show AI Network graph connection debug. \ No newline at end of file +ai_ainDebugConnect "1" // Show AI Network graph connection debug. diff --git a/r5dev/resource/cfg/startup_dedi_default.cfg b/r5dev/resource/cfg/startup_dedi_default.cfg index 14137936..fe921edb 100644 --- a/r5dev/resource/cfg/startup_dedi_default.cfg +++ b/r5dev/resource/cfg/startup_dedi_default.cfg @@ -1,3 +1,2 @@ -ansiclr --dev -playlistfile "playlists_r5_patch.txt" diff --git a/r5dev/resource/cfg/startup_dedi_debug.cfg b/r5dev/resource/cfg/startup_dedi_dev.cfg similarity index 100% rename from r5dev/resource/cfg/startup_dedi_debug.cfg rename to r5dev/resource/cfg/startup_dedi_dev.cfg index b9bd9826..6a3279ff 100644 --- a/r5dev/resource/cfg/startup_dedi_debug.cfg +++ b/r5dev/resource/cfg/startup_dedi_dev.cfg @@ -1,6 +1,6 @@ -ansiclr --notimeout -dev -devsdk +-notimeout -tools -playlistfile "playlists_r5_patch.txt" diff --git a/r5dev/resource/cfg/startup_dedi_retail.cfg b/r5dev/resource/cfg/startup_dedi_retail.cfg index 14137936..fe921edb 100644 --- a/r5dev/resource/cfg/startup_dedi_retail.cfg +++ b/r5dev/resource/cfg/startup_dedi_retail.cfg @@ -1,3 +1,2 @@ -ansiclr --dev -playlistfile "playlists_r5_patch.txt" diff --git a/r5dev/resource/cfg/startup_default.cfg b/r5dev/resource/cfg/startup_default.cfg index 17c52d3f..c38360ab 100644 --- a/r5dev/resource/cfg/startup_default.cfg +++ b/r5dev/resource/cfg/startup_default.cfg @@ -1,4 +1,3 @@ --dev -fnf -multiple -novid diff --git a/r5dev/resource/cfg/startup_debug.cfg b/r5dev/resource/cfg/startup_dev.cfg similarity index 100% rename from r5dev/resource/cfg/startup_debug.cfg rename to r5dev/resource/cfg/startup_dev.cfg diff --git a/r5dev/resource/cfg/startup_launcher.cfg b/r5dev/resource/cfg/startup_launcher.cfg index 5ce162c4..49fd3d39 100644 --- a/r5dev/resource/cfg/startup_launcher.cfg +++ b/r5dev/resource/cfg/startup_launcher.cfg @@ -1,4 +1,3 @@ --dev -fnf -multiple -showdevmenu diff --git a/r5dev/resource/cfg/startup_retail.cfg b/r5dev/resource/cfg/startup_retail.cfg index f405522e..bcc89c5e 100644 --- a/r5dev/resource/cfg/startup_retail.cfg +++ b/r5dev/resource/cfg/startup_retail.cfg @@ -1,5 +1,4 @@ -ansiclr --dev -fnf -multiple -novid diff --git a/r5dev/resource/playlist/playlists_r5_patch.txt b/r5dev/resource/playlist/playlists_r5_patch.txt index 88635589..66d81be3 100644 --- a/r5dev/resource/playlist/playlists_r5_patch.txt +++ b/r5dev/resource/playlist/playlists_r5_patch.txt @@ -1,7 +1,7 @@ playlists { version stable - versionNum 224 + versionNum 225 Gamemodes { defaults @@ -965,7 +965,7 @@ playlists character_select_time_min 4.0 survival_enable_gladiator_intros 1 match_ending_enabled 0 - player_revive_enabled 0 + player_revive_enabled 0 max_teams 2 max_players 2 min_players 1 @@ -1073,8 +1073,13 @@ playlists "PLAYER_ENDED_KILLSTREAK" "`1%s1`0 ended `1%s2`0's killstreak" "PLAYER_ENDED_OWN_KILLSTREAK" "`1%s1`0 ended their own killstreak" - "DISCONNECT_BANNED" "The client's game account has been banned: Banned" "VALVE_REJECT_BANNED" "You have been banned from this server." + "DISCONNECT_BANNED" "The client's game account has been banned." + + "DISCONNECT_SEND_RELIABLEOVERFLOW" "Connection to server overflowed (code:river)." + "DISCONNECT_SEND_OVERFLOW" "Connection to server overflowed (code:dam)." + "DISCONNECT_NETCHAN_OVERFLOW" "Connection to server overflowed (code:vulkan)." + "DISCONNECT_STRINGCMD_OVERFLOW" "Connection to server overflowed (code:mountain)." } } } diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h index 78742b0f..95b8e580 100644 --- a/r5dev/rtech/rtech_utils.h +++ b/r5dev/rtech/rtech_utils.h @@ -114,31 +114,33 @@ struct RPakUnknownStruct_t struct RPakHeader_t { - uint32_t m_nMagic; // 'RPak' - uint16_t m_nVersion; // R2 = '7' R5 = '8' - uint8_t m_nFlags[0x2]; // - uint8_t m_nHash0[0x8]; // - uint8_t m_nHash1[0x8]; // - uint64_t m_nSizeDisk; // Compressed size - uint64_t m_nEmbeddedStarpakOffset; // - uint8_t unk0[0x8]; // - uint64_t m_nSizeMemory; // Decompressed size - uint64_t m_nEmbeddedStarpakSize; // - uint8_t unk1[0x8]; // + uint32_t m_nMagic; // 'RPak' + uint16_t m_nVersion; // R2 = '7' R5 = '8' + uint8_t m_nFlags[0x2]; // + uint8_t m_nHash0[0x8]; // + uint8_t m_nHash1[0x8]; // + uint64_t m_nSizeDisk; // Compressed size + uint64_t m_nEmbeddedStarpakOffset; // + uint8_t unk0[0x8]; // + uint64_t m_nSizeMemory; // Decompressed size + uint64_t m_nEmbeddedStarpakSize; // + uint8_t unk1[0x8]; // - uint16_t m_nStarpakReferenceSize; // - uint16_t m_nStarpakOptReferenceSize; // - uint16_t m_nVirtualSegmentCount; // * 0x10 - uint16_t m_nVirtualSegmentBlockCount; // * 0xC + uint16_t m_nStarpakReferenceSize; // + uint16_t m_nStarpakOptReferenceSize; // + uint16_t m_nVirtualSegmentCount; // * 0x10 + uint16_t m_nMemPageCount; // * 0xC - uint32_t m_nPatchIndex; // + uint32_t m_nPatchIndex; // - uint32_t m_nDescriptorCount; // - uint32_t m_nAssetEntryCount; // File entry count - uint32_t m_nGuidDescriptorCount; // - uint32_t m_nRelationsCounts; // + uint32_t m_nDescriptorCount; // + uint32_t m_nAssetEntryCount; // File entry count + uint32_t m_nGuidDescriptorCount; // + uint32_t m_nRelationsCounts; // - uint8_t unk2[0x1C]; // + uint8_t unk2[0x10]; // + uint32_t m_nMemPageOffset; // Size not verified. Offsets every page by x amount, if not 0 start of first page has data corresponding for 'patching some page' + uint8_t unk3[0x8]; // }; struct __declspec(align(8)) RPakPatchCompressedHeader_t @@ -424,11 +426,22 @@ public: char* m_pszFileName; //0x0018 void* m_pMalloc; //0x0020 uint64_t* m_pAssetGuids; //0x0028 size of the array is m_nAssetCount - char pad_0030[128]; //0x0030 +#if defined GAMEDLL_S3 + void* m_pVSegBuffers[4]; //0x0030 + char pad_0050[16]; //0x0050 + void* m_pPakInfo; //0x0060 + RPakLoadedInfo_t* m_pUnknownLoadedPakInfo; //0x0068 + char pad_0070[4]; //0x0070 + int8_t m_nUnk3; //0x0074 + char pad_0075[51]; //0x0075 + uint32_t m_nUnk4; //0x00A8 + uint8_t m_nUnk5; //0x00AC +#endif #if not defined GAMEDLL_S3 - char pad_00B0[48]; + char pad_0030[128]; //0x0030 + char pad_00B0[48]; //0x00B0 #endif // !GAMEDLL_S3 - uint64_t m_nUnkEnd; //0x00B0 + uint64_t m_nUnkEnd; //0x00B0/0x00E8 }; //Size: 0x00B8/0x00E8 /* ==== RTECH =========================================================================================================================================================== */ diff --git a/r5dev/sdklauncher/basepanel.cpp b/r5dev/sdklauncher/basepanel.cpp index 2d3173f4..22abf92a 100644 --- a/r5dev/sdklauncher/basepanel.cpp +++ b/r5dev/sdklauncher/basepanel.cpp @@ -739,8 +739,9 @@ eLaunchMode CUIBaseSurface::BuildParameter(string& svParameters) } if (this->m_DevelopmentToggle->Checked()) { + svParameters.append("-dev\n"); svParameters.append("-devsdk\n"); - results = eLaunchMode::LM_HOST_DEBUG; + results = eLaunchMode::LM_HOST_DEV; } else results = eLaunchMode::LM_HOST; @@ -864,8 +865,9 @@ eLaunchMode CUIBaseSurface::BuildParameter(string& svParameters) } if (this->m_DevelopmentToggle->Checked()) { + svParameters.append("-dev\n"); svParameters.append("-devsdk\n"); - results = eLaunchMode::LM_SERVER_DEBUG; + results = eLaunchMode::LM_SERVER_DEV; } else results = eLaunchMode::LM_SERVER; @@ -950,8 +952,9 @@ eLaunchMode CUIBaseSurface::BuildParameter(string& svParameters) // GAME ############################################################### if (this->m_DevelopmentToggle->Checked()) { + svParameters.append("-dev\n"); svParameters.append("-devsdk\n"); - results = eLaunchMode::LM_CLIENT_DEBUG; + results = eLaunchMode::LM_CLIENT_DEV; } else results = eLaunchMode::LM_CLIENT; diff --git a/r5dev/sdklauncher/sdklauncher.cpp b/r5dev/sdklauncher/sdklauncher.cpp index a7c156a0..17368387 100644 --- a/r5dev/sdklauncher/sdklauncher.cpp +++ b/r5dev/sdklauncher/sdklauncher.cpp @@ -17,7 +17,7 @@ void CLauncher::InitSurface() } /////////////////////////////////////////////////////////////////////////////// -// Purpose: initializes the console (release builds only) +// Purpose: initializes the console (development only) /////////////////////////////////////////////////////////////////////////////// void CLauncher::InitConsole() { @@ -41,16 +41,16 @@ void CLauncher::InitLogger() // Purpose: handles user input pre-init // Input : argc - // *argv - -// Output : exit_code (-1 if EP should continue to HandleInput) +// Output : exit_code (-1 if EntryPoint should continue to HandleInput) /////////////////////////////////////////////////////////////////////////////// int CLauncher::HandleCmdLine(int argc, char* argv[]) { for (int i = 1; i < __argc; ++i) { std::string arg = __argv[i]; - if ((arg == "-debug") || (arg == "-dbg")) + if ((arg == "-developer") || (arg == "-dev")) { - if (g_pLauncher->Setup(eLaunchMode::LM_HOST_DEBUG, eLaunchState::LS_CHEATS)) + if (g_pLauncher->Setup(eLaunchMode::LM_HOST_DEV, eLaunchState::LS_CHEATS)) { if (g_pLauncher->Launch()) { @@ -62,7 +62,7 @@ int CLauncher::HandleCmdLine(int argc, char* argv[]) Sleep(2000); return EXIT_FAILURE; } - if ((arg == "-release") || (arg == "-rel")) + if ((arg == "-retail") || (arg == "-prod")) { if (g_pLauncher->Setup(eLaunchMode::LM_HOST, eLaunchState::LS_CHEATS)) { @@ -78,7 +78,7 @@ int CLauncher::HandleCmdLine(int argc, char* argv[]) } if ((arg == "-dedicated_dev") || (arg == "-dedid")) { - if (g_pLauncher->Setup(eLaunchMode::LM_SERVER_DEBUG, eLaunchState::LS_CHEATS)) + if (g_pLauncher->Setup(eLaunchMode::LM_SERVER_DEV, eLaunchState::LS_CHEATS)) { if (g_pLauncher->Launch()) { @@ -106,7 +106,7 @@ int CLauncher::HandleCmdLine(int argc, char* argv[]) } if ((arg == "-client_dev") || (arg == "-cld")) { - if (g_pLauncher->Setup(eLaunchMode::LM_CLIENT_DEBUG, eLaunchState::LS_CHEATS)) + if (g_pLauncher->Setup(eLaunchMode::LM_CLIENT_DEV, eLaunchState::LS_CHEATS)) { if (g_pLauncher->Launch()) { @@ -143,23 +143,23 @@ int CLauncher::HandleCmdLine(int argc, char* argv[]) int CLauncher::HandleInput() { std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "If a DEBUG option has been chosen as launch parameter, do not broadcast servers to the Server Browser!\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "If a DEV option has been chosen as launch parameter, do not broadcast servers to the Server Browser!\n"); g_pLauncher->AddLog(spdlog::level::level_enum::warn, "All FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ConVar's/ConCommand's will be enabled.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Connected clients will be able to set and execute anything flagged FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Connected clients will be able to set and execute anything marked FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY.\n"); std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG HOST [0] for research and development purposes.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE HOST [1] for playing the game and creating servers.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG SERVER [2] for research and development purposes.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE SERVER [3] for running and hosting dedicated servers.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEBUG CLIENT [4] for research and development purposes.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RELEASE CLIENT [5] for running client only builds against remote servers.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEV HOST [0] for research and development purposes.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RETAIL HOST [1] for playing the game and creating servers.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEV SERVER [2] for research and development purposes.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RETAIL SERVER [3] for running and hosting dedicated servers.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use DEV CLIENT [4] for research and development purposes.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::warn, "Use RETAIL CLIENT [5] for running client only builds against remote servers.\n"); std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '0' for 'DEBUG HOST'.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '1' for 'RELEASE HOST'.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '2' for 'DEBUG SERVER'.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '3' for 'RELEASE SERVER'.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '4' for 'DEBUG CLIENT'.\n"); - g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '5' for 'RELEASE CLIENT'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '0' for 'DEV HOST'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '1' for 'RETAIL HOST'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '2' for 'DEV SERVER'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '3' for 'RETAIL SERVER'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '4' for 'DEV CLIENT'.\n"); + g_pLauncher->AddLog(spdlog::level::level_enum::info, "Enter '5' for 'RETAIL CLIENT'.\n"); std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; std::cout << "User input: "; @@ -171,7 +171,7 @@ int CLauncher::HandleInput() eLaunchMode mode = static_cast(std::stoi(input)); switch (mode) { - case eLaunchMode::LM_HOST_DEBUG: + case eLaunchMode::LM_HOST_DEV: { if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS)) { @@ -199,7 +199,7 @@ int CLauncher::HandleInput() Sleep(2000); return EXIT_FAILURE; } - case eLaunchMode::LM_SERVER_DEBUG: + case eLaunchMode::LM_SERVER_DEV: { if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS)) { @@ -227,7 +227,7 @@ int CLauncher::HandleInput() Sleep(2000); return EXIT_FAILURE; } - case eLaunchMode::LM_CLIENT_DEBUG: + case eLaunchMode::LM_CLIENT_DEV: { if (g_pLauncher->Setup(mode, eLaunchState::LS_CHEATS)) { @@ -290,9 +290,9 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) /////////////////////////////////////////////////////////////////////////// switch (lMode) { - case eLaunchMode::LM_HOST_DEBUG: + case eLaunchMode::LM_HOST_DEV: { - fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_debug.cfg"; + fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dev.cfg"; std::ifstream cfgFile(cfgPath); if (cfgFile.good() && cfgFile) { @@ -302,7 +302,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) } else { - AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_debug.cfg' does not exist!\n"); + AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_dev.cfg' does not exist!\n"); return false; } @@ -310,7 +310,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [DEV] ***\n"); break; } case eLaunchMode::LM_HOST: @@ -333,12 +333,12 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [RETAIL] ***\n"); break; } - case eLaunchMode::LM_SERVER_DEBUG: + case eLaunchMode::LM_SERVER_DEV: { - fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_debug.cfg"; + fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_dedi_dev.cfg"; std::ifstream cfgFile(cfgPath); if (cfgFile.good() && cfgFile) { @@ -348,7 +348,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) } else { - AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_dedi_debug.cfg' does not exist!\n"); + AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_dedi_dev.cfg' does not exist!\n"); return false; } @@ -356,7 +356,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [DEV] ***\n"); break; } case eLaunchMode::LM_SERVER: @@ -379,12 +379,12 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [RETAIL] ***\n"); break; } - case eLaunchMode::LM_CLIENT_DEBUG: + case eLaunchMode::LM_CLIENT_DEV: { - fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_client_debug.cfg"; + fs::path cfgPath = fs::current_path() /= "platform\\cfg\\startup_client_dev.cfg"; std::ifstream cfgFile(cfgPath); if (cfgFile.good() && cfgFile) { @@ -394,7 +394,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) } else { - AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_client_debug.cfg' does not exist!\n"); + AddLog(spdlog::level::level_enum::err, "File 'platform\\cfg\\startup_client_dev.cfg' does not exist!\n"); return false; } @@ -402,7 +402,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [DEV] ***\n"); break; } case eLaunchMode::LM_CLIENT: @@ -425,7 +425,7 @@ bool CLauncher::Setup(eLaunchMode lMode, eLaunchState lState) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCmdLineArgs; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [RETAIL] ***\n"); break; } default: @@ -460,13 +460,13 @@ bool CLauncher::Setup(eLaunchMode lMode, const string& svCommandLine) /////////////////////////////////////////////////////////////////////////// switch (lMode) { - case eLaunchMode::LM_HOST_DEBUG: + case eLaunchMode::LM_HOST_DEV: { m_svWorkerDll = m_svCurrentDir + "\\gamesdk.dll"; m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [DEV] ***\n"); break; } case eLaunchMode::LM_HOST: @@ -475,16 +475,16 @@ bool CLauncher::Setup(eLaunchMode lMode, const string& svCommandLine) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR HOST [RETAIL] ***\n"); break; } - case eLaunchMode::LM_SERVER_DEBUG: + case eLaunchMode::LM_SERVER_DEV: { m_svWorkerDll = m_svCurrentDir + "\\dedicated.dll"; m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [DEV] ***\n"); break; } case eLaunchMode::LM_SERVER: @@ -493,16 +493,16 @@ bool CLauncher::Setup(eLaunchMode lMode, const string& svCommandLine) m_svGameExe = m_svCurrentDir + "\\r5apex_ds.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex_ds.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR DEDICATED [RETAIL] ***\n"); break; } - case eLaunchMode::LM_CLIENT_DEBUG: + case eLaunchMode::LM_CLIENT_DEV: { m_svWorkerDll = m_svCurrentDir + "\\bin\\x64_retail\\client.dll"; m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [DEBUG] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [DEV] ***\n"); break; } case eLaunchMode::LM_CLIENT: @@ -511,7 +511,7 @@ bool CLauncher::Setup(eLaunchMode lMode, const string& svCommandLine) m_svGameExe = m_svCurrentDir + "\\r5apex.exe"; m_svCmdLine = m_svCurrentDir + "\\r5apex.exe " + svCommandLine; - AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [RELEASE] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHER SETUP FOR CLIENT [RETAIL] ***\n"); break; } default: @@ -592,7 +592,7 @@ bool CLauncher::Launch() const } /////////////////////////////////////////////////////////////////////////////// -// Entrypoint. +// EntryPoint. /////////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[], char* envp[]) { diff --git a/r5dev/sdklauncher/sdklauncher_const.h b/r5dev/sdklauncher/sdklauncher_const.h index cdd2206e..ad87bf6a 100644 --- a/r5dev/sdklauncher/sdklauncher_const.h +++ b/r5dev/sdklauncher/sdklauncher_const.h @@ -1,26 +1,16 @@ #pragma once //----------------------------------------------------------------------------- -// Launch and inject specified dll based on launchmode +// Launch and inject specified dll based on launch mode //----------------------------------------------------------------------------- -//enum class eLaunchMode : int -//{ -// LM_NULL, -// LM_DEBUG_GAME, // Debug worker DLL. -// LM_RELEASE_GAME, // Release worker DLL. -// LM_DEBUG_DEDI, // Debug dedicated DLL. -// LM_RELEASE_DEDI // Release dedicated DLL. -//}; - - enum class eLaunchMode : int { LM_NONE = -1, - LM_HOST_DEBUG, + LM_HOST_DEV, LM_HOST, - LM_SERVER_DEBUG, + LM_SERVER_DEV, LM_SERVER, - LM_CLIENT_DEBUG, + LM_CLIENT_DEV, LM_CLIENT, }; @@ -32,5 +22,5 @@ enum class eLaunchState : int LS_NULL, LS_NOCHEATS, // Disabled cheats LS_CHEATS, // Enable cheats - LS_DEBUG // Enable debug + LS_DEV // Enable devonly }; \ No newline at end of file diff --git a/r5dev/server/vengineserver_impl.cpp b/r5dev/server/vengineserver_impl.cpp index 26e62f39..dc64b5e3 100644 --- a/r5dev/server/vengineserver_impl.cpp +++ b/r5dev/server/vengineserver_impl.cpp @@ -18,7 +18,7 @@ bool HIVEngineServer__PersistenceAvailable(void* entidx, int clienthandle) CClient* pClient = g_pClient->GetClient(clienthandle); // Get client instance. pClient->SetPersistenceState(PERSISTENCE::PERSISTENCE_READY); // Set the client instance to 'ready'. - if (!g_bIsPersistenceVarSet[clienthandle] && sv_showconnecting->GetBool()) + if (!g_ServerPlayer[clienthandle].m_bPersistenceEnabled && sv_showconnecting->GetBool()) { CNetChan* pNetChan = pClient->GetNetChan(); @@ -34,7 +34,7 @@ bool HIVEngineServer__PersistenceAvailable(void* entidx, int clienthandle) DevMsg(eDLL_T::SERVER, " |- ADR : | '%s'\n", svIpAddress.c_str()); DevMsg(eDLL_T::SERVER, " -------------------------------------------------------------\n"); - g_bIsPersistenceVarSet[clienthandle] = true; + g_ServerPlayer[clienthandle].m_bPersistenceEnabled = true; } /////////////////////////////////////////////////////////////////////////// return IVEngineServer__PersistenceAvailable(entidx, clienthandle); @@ -51,4 +51,4 @@ void IVEngineServer_Detach() } /////////////////////////////////////////////////////////////////////////////// -bool g_bIsPersistenceVarSet[MAX_PLAYERS]; +ServerPlayer_t g_ServerPlayer[MAX_PLAYERS]; diff --git a/r5dev/server/vengineserver_impl.h b/r5dev/server/vengineserver_impl.h index e11fe8c0..afc744cc 100644 --- a/r5dev/server/vengineserver_impl.h +++ b/r5dev/server/vengineserver_impl.h @@ -13,6 +13,9 @@ inline auto IVEngineServer__GetNumHumanPlayers = p_IVEngineServer__GetNumHumanPl inline CMemory p_IVEngineServer__GetNumFakeClients; inline auto IVEngineServer__GetNumFakeClients = p_IVEngineServer__GetNumFakeClients.RCast(); +//inline CMemory p_RunFrameServer; +//inline auto v_RunFrameServer = p_RunFrameServer.RCast(); + inline bool* g_bDedicated = nullptr; /////////////////////////////////////////////////////////////////////////////// @@ -22,7 +25,33 @@ void IVEngineServer_Attach(); void IVEngineServer_Detach(); /////////////////////////////////////////////////////////////////////////////// -extern bool g_bIsPersistenceVarSet[MAX_PLAYERS]; + +struct ServerPlayer_t +{ + ServerPlayer_t(void) + : m_flCurrentNetProcessTime(0.0) + , m_flLastNetProcessTime(0.0) + , m_flStringCommandQuotaTimeStart(0.0) + , m_nStringCommandQuotaCount(0) + , m_bPersistenceEnabled(false) + {} + inline void Reset(void) + { + m_flCurrentNetProcessTime = 0.0; + m_flLastNetProcessTime = 0.0; + m_flStringCommandQuotaTimeStart = 0.0; + m_nStringCommandQuotaCount = 0; + m_bPersistenceEnabled = false; + } + + double m_flCurrentNetProcessTime; + double m_flLastNetProcessTime; + double m_flStringCommandQuotaTimeStart; + int m_nStringCommandQuotaCount; + bool m_bPersistenceEnabled; +}; + +extern ServerPlayer_t g_ServerPlayer[MAX_PLAYERS]; /////////////////////////////////////////////////////////////////////////////// class HVEngineServer : public IDetour @@ -33,6 +62,7 @@ class HVEngineServer : public IDetour spdlog::debug("| FUN: IVEngineServer::IsDedicatedServer : {:#18x} |\n", p_IVEngineServer__IsDedicatedServer.GetPtr()); spdlog::debug("| FUN: IVEngineServer::GetNumHumanPlayers : {:#18x} |\n", p_IVEngineServer__GetNumHumanPlayers.GetPtr()); spdlog::debug("| FUN: IVEngineServer::GetNumFakeClients : {:#18x} |\n", p_IVEngineServer__GetNumFakeClients.GetPtr()); + //spdlog::debug("| FUN: RunFrameServer : {:#18x} |\n", p_RunFrameServer.GetPtr()); spdlog::debug("| VAR: g_bDedicated : {:#18x} |\n", reinterpret_cast(g_bDedicated)); spdlog::debug("+----------------------------------------------------------------+\n"); } @@ -42,11 +72,13 @@ class HVEngineServer : public IDetour p_IVEngineServer__IsDedicatedServer = g_GameDll.FindPatternSIMD(reinterpret_cast("\x0F\xB6\x05\x00\x00\x00\x00\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x48\x8B\x05\x00\x00\x00\x00\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x40\x53"), "xxx????xxxxxxxxxxxx????xxxxxxxxxxx"); p_IVEngineServer__GetNumHumanPlayers = g_GameDll.FindPatternSIMD(reinterpret_cast("\x8B\x15\x00\x00\x00\x00\x33\xC0\x85\xD2\x7E\x24"), "xx????xxxxxx"); p_IVEngineServer__GetNumFakeClients = g_GameDll.FindPatternSIMD(reinterpret_cast("\x8B\x05\x00\x00\x00\x00\x33\xC9\x85\xC0\x7E\x2D"), "xx????xxxxxx"); +// p_RunFrameServer = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x00\x48\x8D\x0D\x00\x00\x00\x00"), "xxxx?xxxxxxxxx?xxx????"); - IVEngineServer__PersistenceAvailable = p_IVEngineServer__PersistenceAvailable.RCast(); /*3B 15 ?? ?? ?? ?? 7D 33*/ - IVEngineServer__IsDedicatedServer = p_IVEngineServer__IsDedicatedServer.RCast(); /*0F B6 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 8B 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 40 53*/ - IVEngineServer__GetNumHumanPlayers = p_IVEngineServer__GetNumHumanPlayers.RCast(); /*8B 15 ?? ?? ?? ?? 33 C0 85 D2 7E 24*/ - IVEngineServer__GetNumFakeClients = p_IVEngineServer__GetNumFakeClients.RCast(); /*8B 05 ?? ?? ?? ?? 33 C9 85 C0 7E 2D*/ + IVEngineServer__PersistenceAvailable = p_IVEngineServer__PersistenceAvailable.RCast(); /*3B 15 ?? ?? ?? ?? 7D 33*/ + IVEngineServer__IsDedicatedServer = p_IVEngineServer__IsDedicatedServer.RCast(); /*0F B6 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 8B 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 40 53*/ + IVEngineServer__GetNumHumanPlayers = p_IVEngineServer__GetNumHumanPlayers.RCast(); /*8B 15 ?? ?? ?? ?? 33 C0 85 D2 7E 24*/ + IVEngineServer__GetNumFakeClients = p_IVEngineServer__GetNumFakeClients.RCast(); /*8B 05 ?? ?? ?? ?? 33 C9 85 C0 7E 2D*/ +// v_RunFrameServer = p_RunFrameServer.RCast(); /*48 89 5C 24 ?? 57 48 83 EC 30 0F 29 74 24 ?? 48 8D 0D ?? ?? ?? ??*/ } virtual void GetVar(void) const { diff --git a/r5dev/squirrel/sqapi.cpp b/r5dev/squirrel/sqapi.cpp index 3b19ab71..d46ffddd 100644 --- a/r5dev/squirrel/sqapi.cpp +++ b/r5dev/squirrel/sqapi.cpp @@ -44,12 +44,6 @@ void sq_pushinteger(HSQUIRRELVM v, SQInteger val) v_sq_pushinteger(v, val); } -//--------------------------------------------------------------------------------- -void sq_pushconstant(HSQUIRRELVM v, const SQChar* name, SQInteger val) -{ - v_sq_pushconstant(v, name, val); -} - //--------------------------------------------------------------------------------- void sq_newarray(HSQUIRRELVM v, SQInteger size) { @@ -98,7 +92,6 @@ void SQAPI_Attach() DetourAttach((LPVOID*)&v_sq_pushbool, &sq_pushbool); DetourAttach((LPVOID*)&v_sq_pushstring, &sq_pushstring); DetourAttach((LPVOID*)&v_sq_pushinteger, &sq_pushinteger); - DetourAttach((LPVOID*)&v_sq_pushconstant, &sq_pushconstant); DetourAttach((LPVOID*)&v_sq_newarray, &sq_newarray); DetourAttach((LPVOID*)&v_sq_newtable, &sq_newtable); DetourAttach((LPVOID*)&v_sq_newslot, &sq_newslot); @@ -114,7 +107,6 @@ void SQAPI_Detach() DetourDetach((LPVOID*)&v_sq_pushbool, &sq_pushbool); DetourDetach((LPVOID*)&v_sq_pushstring, &sq_pushstring); DetourDetach((LPVOID*)&v_sq_pushinteger, &sq_pushinteger); - DetourDetach((LPVOID*)&v_sq_pushconstant, &sq_pushconstant); DetourDetach((LPVOID*)&v_sq_newarray, &sq_newarray); DetourDetach((LPVOID*)&v_sq_newtable, &sq_newtable); DetourDetach((LPVOID*)&v_sq_newslot, &sq_newslot); diff --git a/r5dev/squirrel/sqapi.h b/r5dev/squirrel/sqapi.h index 490be28f..8d2eba1c 100644 --- a/r5dev/squirrel/sqapi.h +++ b/r5dev/squirrel/sqapi.h @@ -10,7 +10,6 @@ SQRESULT sq_pushroottable(HSQUIRRELVM v); void sq_pushbool(HSQUIRRELVM v, SQBool b); void sq_pushstring(HSQUIRRELVM v, const SQChar* string, SQInteger len); void sq_pushinteger(HSQUIRRELVM v, SQInteger val); -void sq_pushconstant(HSQUIRRELVM v, const SQChar* name, SQInteger val); void sq_newarray(HSQUIRRELVM v, SQInteger size); void sq_newtable(HSQUIRRELVM v); SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx); @@ -35,9 +34,6 @@ inline auto v_sq_pushstring = p_sq_pushstring.RCast(); -inline CMemory p_sq_pushconstant; -inline auto v_sq_pushconstant = p_sq_pushconstant.RCast(); - inline CMemory p_sq_newarray; inline auto v_sq_newarray = p_sq_newarray.RCast(); @@ -68,7 +64,6 @@ class VSqapi : public IDetour spdlog::debug("| FUN: sq_pushbool : {:#18x} |\n", p_sq_pushbool.GetPtr()); spdlog::debug("| FUN: sq_pushstring : {:#18x} |\n", p_sq_pushstring.GetPtr()); spdlog::debug("| FUN: sq_pushinteger : {:#18x} |\n", p_sq_pushinteger.GetPtr()); - spdlog::debug("| FUN: sq_pushconstant : {:#18x} |\n", p_sq_pushconstant.GetPtr()); spdlog::debug("| FUN: sq_newarray : {:#18x} |\n", p_sq_newarray.GetPtr()); spdlog::debug("| FUN: sq_arrayappend : {:#18x} |\n", p_sq_arrayappend.GetPtr()); spdlog::debug("| FUN: sq_newtable : {:#18x} |\n", p_sq_newtable.GetPtr()); @@ -88,7 +83,6 @@ class VSqapi : public IDetour p_sq_pushstring = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x56\x48\x83\xEC\x30\x48\x8B\xF1\x48\x85\xD2\x0F\x84\x8F\x00"), "xxxxxxxxxxxxxxxx"); #endif p_sq_pushinteger = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x38\x33\xC0\x48\xC7\x44\x24\x20\x02\x00\x00\x05\x48"), "xxxxxxxxxxxxxxxx"); - p_sq_pushconstant = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x4C\x8B"), "xxxx?xxxx?xxxx?xxxxxxx"); p_sq_newarray = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x30\x48\x8B\xD9\x48\xC7\x44\x24\x20\x40"), "xxxxxxxxxxxxxxxxxxx"); p_sq_newtable = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x30\x48\x8B\xD9\x48\xC7\x44\x24\x20\x20"), "xxxxxxxxxxxxxxxxxxx"); p_sq_newslot = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x30\x44\x8B\x49\x00\x48\x8B\xD9\x41\x8B\xC1"), "xxxxxxxxx?xxxxxx"); @@ -105,7 +99,6 @@ class VSqapi : public IDetour v_sq_pushbool = p_sq_pushbool.RCast(); /*48 83 EC 38 33 C0 48 C7 44 24 20 08 00 00 01 48*/ v_sq_pushstring = p_sq_pushstring.RCast(); /*40 56 48 83 EC 30 48 8B F1 48 85 D2 0F 84 8F 00*/ v_sq_pushinteger = p_sq_pushinteger.RCast(); /*48 83 EC 38 33 C0 48 C7 44 24 20 02 00 00 05 48*/ - v_sq_pushconstant = p_sq_pushconstant.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 4C 8B*/ v_sq_newarray = p_sq_newarray.RCast(); /*48 89 5C 24 08 57 48 83 EC 30 48 8B D9 48 C7 44 24 20 40*/ v_sq_newtable = p_sq_newtable.RCast(); /*48 89 5C 24 08 57 48 83 EC 30 48 8B D9 48 C7 44 24 20 20*/ v_sq_newslot = p_sq_newslot.RCast(); /*40 53 48 83 EC 20 8B 41 ?? 48 8B D9 2B 41 ?? 83 F8 02 7D*/ diff --git a/r5dev/squirrel/sqscript.cpp b/r5dev/squirrel/sqscript.cpp index 5a306853..5def95a8 100644 --- a/r5dev/squirrel/sqscript.cpp +++ b/r5dev/squirrel/sqscript.cpp @@ -11,28 +11,42 @@ #include "squirrel/sqscript.h" //--------------------------------------------------------------------------------- -// Purpose: registers and exposes code functions to target context -// Input : *pSquirrelVM - -// *szName - -// *szHelpString - -// *szRetValType - -// *szArgTypes - -// *pFunction - +// Purpose: registers global constant for target context +// Input : *v - +// *name - +// value - //--------------------------------------------------------------------------------- -SQRESULT Script_RegisterFunction(CSquirrelVM* pSquirrelVM, const SQChar* szScriptName,const SQChar* szNativeName, - const SQChar* szHelpString, const SQChar* szRetValType, const SQChar* szArgTypes, void* pFunction) +SQRESULT Script_RegisterConstant(CSquirrelVM* s, const SQChar* name, SQInteger value) { - ScriptFunctionBinding_t* sqFunc = new ScriptFunctionBinding_t(); + return v_Script_RegisterConstant(s, name, value); +} - sqFunc->m_szScriptName = szScriptName; - sqFunc->m_szNativeName = szNativeName; - sqFunc->m_szHelpString = szHelpString; - sqFunc->m_szRetValType = szRetValType; - sqFunc->m_szArgTypes = szArgTypes; - sqFunc->m_pFunction = pFunction; +//--------------------------------------------------------------------------------- +// Purpose: registers and exposes code functions to target context +// Input : *s - +// *scriptname - +// *nativename - +// *helpstring - +// *returntype - +// *arguments - +// *functor - +//--------------------------------------------------------------------------------- +SQRESULT Script_RegisterFunction(CSquirrelVM* s, const SQChar* scriptname, const SQChar* nativename, + const SQChar* helpstring, const SQChar* returntype, const SQChar* parameters, void* functor) +{ + ScriptFunctionBinding_t* binding = MemAllocSingleton()->Alloc(sizeof(ScriptFunctionBinding_t)); + memset(binding, '\0', sizeof(ScriptFunctionBinding_t)); - SQRESULT results = v_Script_RegisterFunction(pSquirrelVM, sqFunc, 1); - delete sqFunc; + binding->_scriptname = scriptname; + binding->_nativename = nativename; + binding->_helpstring = helpstring; + binding->_returntype = returntype; + binding->_parameters = parameters; + binding->_functor = functor; + binding->_nparamscheck = 5; + + SQRESULT results = v_Script_RegisterFunction(s, binding, 1); + MemAllocSingleton()->Free(binding); return results; } @@ -40,99 +54,100 @@ SQRESULT Script_RegisterFunction(CSquirrelVM* pSquirrelVM, const SQChar* szScrip #ifndef CLIENT_DLL //--------------------------------------------------------------------------------- // Purpose: registers script functions in SERVER context -// Input : *pSquirrelVM - +// Input : *s - //--------------------------------------------------------------------------------- -void Script_RegisterServerFunctions(CSquirrelVM* pSquirrelVM) +void Script_RegisterServerFunctions(CSquirrelVM* s) { - Script_RegisterFunction(pSquirrelVM, "SDKNativeTest", "Script_SDKNativeTest", "Native SERVER test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); - Script_RegisterFunction(pSquirrelVM, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); + Script_RegisterFunction(s, "SDKNativeTest", "Script_SDKNativeTest", "Native SERVER test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); + Script_RegisterFunction(s, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); - Script_RegisterFunction(pSquirrelVM, "GetNumHumanPlayers", "Script_GetNumHumanPlayers", "Gets the number of human players on the server", "int", "", &VSquirrel::SERVER::GetNumHumanPlayers); - Script_RegisterFunction(pSquirrelVM, "GetNumFakeClients", "Script_GetNumFakeClients", "Gets the number of bot players on the server", "int", "", &VSquirrel::SERVER::GetNumFakeClients); + Script_RegisterFunction(s, "GetNumHumanPlayers", "Script_GetNumHumanPlayers", "Gets the number of human players on the server", "int", "", &VSquirrel::SERVER::GetNumHumanPlayers); + Script_RegisterFunction(s, "GetNumFakeClients", "Script_GetNumFakeClients", "Gets the number of bot players on the server", "int", "", &VSquirrel::SERVER::GetNumFakeClients); - Script_RegisterFunction(pSquirrelVM, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); - Script_RegisterFunction(pSquirrelVM, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); + Script_RegisterFunction(s, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); + Script_RegisterFunction(s, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); - Script_RegisterFunction(pSquirrelVM, "KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VSquirrel::SHARED::KickPlayerByName); - Script_RegisterFunction(pSquirrelVM, "KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::KickPlayerById); + Script_RegisterFunction(s, "KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VSquirrel::SHARED::KickPlayerByName); + Script_RegisterFunction(s, "KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::KickPlayerById); - Script_RegisterFunction(pSquirrelVM, "BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VSquirrel::SHARED::BanPlayerByName); - Script_RegisterFunction(pSquirrelVM, "BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::BanPlayerById); + Script_RegisterFunction(s, "BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VSquirrel::SHARED::BanPlayerByName); + Script_RegisterFunction(s, "BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::BanPlayerById); - Script_RegisterFunction(pSquirrelVM, "UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VSquirrel::SHARED::UnbanPlayer); + Script_RegisterFunction(s, "UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VSquirrel::SHARED::UnbanPlayer); - Script_RegisterFunction(pSquirrelVM, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); + Script_RegisterFunction(s, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); } #endif // !CLIENT_DLL #ifndef DEDICATED //--------------------------------------------------------------------------------- // Purpose: registers script functions in CLIENT context -// Input : *pSquirrelVM - +// Input : *s - //--------------------------------------------------------------------------------- -void Script_RegisterClientFunctions(CSquirrelVM* pSquirrelVM) +void Script_RegisterClientFunctions(CSquirrelVM* s) { - Script_RegisterFunction(pSquirrelVM, "SDKNativeTest", "Script_SDKNativeTest", "Native CLIENT test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); - Script_RegisterFunction(pSquirrelVM, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); + Script_RegisterFunction(s, "SDKNativeTest", "Script_SDKNativeTest", "Native CLIENT test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); + Script_RegisterFunction(s, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); - Script_RegisterFunction(pSquirrelVM, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); - Script_RegisterFunction(pSquirrelVM, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); + Script_RegisterFunction(s, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); + Script_RegisterFunction(s, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); - Script_RegisterFunction(pSquirrelVM, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); + Script_RegisterFunction(s, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); } //--------------------------------------------------------------------------------- // Purpose: registers script functions in UI context -// Input : *pSquirrelVM - +// Input : *s - //--------------------------------------------------------------------------------- -void Script_RegisterUIFunctions(CSquirrelVM* pSquirrelVM) +void Script_RegisterUIFunctions(CSquirrelVM* s) { - Script_RegisterFunction(pSquirrelVM, "SDKNativeTest", "Script_SDKNativeTest", "Native UI test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); + Script_RegisterFunction(s, "SDKNativeTest", "Script_SDKNativeTest", "Native UI test function", "void", "", &VSquirrel::SHARED::SDKNativeTest); - Script_RegisterFunction(pSquirrelVM, "RefreshServerList", "Script_RefreshServerList", "Refreshes the public server list and returns the count", "int", "", &VSquirrel::UI::RefreshServerCount); + Script_RegisterFunction(s, "RefreshServerList", "Script_RefreshServerList", "Refreshes the public server list and returns the count", "int", "", &VSquirrel::UI::RefreshServerCount); // Functions for retrieving server browser data - Script_RegisterFunction(pSquirrelVM, "GetServerName", "Script_GetServerName", "Gets the name of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerName); - Script_RegisterFunction(pSquirrelVM, "GetServerDescription", "Script_GetServerDescription", "Gets the description of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerDescription); - Script_RegisterFunction(pSquirrelVM, "GetServerMap", "Script_GetServerMap", "Gets the map of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerMap); - Script_RegisterFunction(pSquirrelVM, "GetServerPlaylist", "Script_GetServerPlaylist", "Gets the playlist of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerPlaylist); - Script_RegisterFunction(pSquirrelVM, "GetServerCurrentPlayers", "Script_GetServerCurrentPlayers", "Gets the current player count of the server at the specified index of the server list", "int", "int", &VSquirrel::UI::GetServerCurrentPlayers); - Script_RegisterFunction(pSquirrelVM, "GetServerMaxPlayers", "Script_GetServerMaxPlayers", "Gets the max player count of the server at the specified index of the server list", "int", "int", &VSquirrel::UI::GetServerMaxPlayers); - Script_RegisterFunction(pSquirrelVM, "GetServerCount", "Script_GetServerCount", "Gets the number of public servers", "int", "", &VSquirrel::UI::GetServerCount); + Script_RegisterFunction(s, "GetServerName", "Script_GetServerName", "Gets the name of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerName); + Script_RegisterFunction(s, "GetServerDescription", "Script_GetServerDescription", "Gets the description of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerDescription); + Script_RegisterFunction(s, "GetServerMap", "Script_GetServerMap", "Gets the map of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerMap); + Script_RegisterFunction(s, "GetServerPlaylist", "Script_GetServerPlaylist", "Gets the playlist of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerPlaylist); + Script_RegisterFunction(s, "GetServerCurrentPlayers", "Script_GetServerCurrentPlayers", "Gets the current player count of the server at the specified index of the server list", "int", "int", &VSquirrel::UI::GetServerCurrentPlayers); + Script_RegisterFunction(s, "GetServerMaxPlayers", "Script_GetServerMaxPlayers", "Gets the max player count of the server at the specified index of the server list", "int", "int", &VSquirrel::UI::GetServerMaxPlayers); + Script_RegisterFunction(s, "GetServerCount", "Script_GetServerCount", "Gets the number of public servers", "int", "", &VSquirrel::UI::GetServerCount); // Misc main menu functions - Script_RegisterFunction(pSquirrelVM, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); - Script_RegisterFunction(pSquirrelVM, "GetPromoData", "Script_GetPromoData", "Gets promo data for specified slot type", "string", "int", &VSquirrel::UI::GetPromoData); + Script_RegisterFunction(s, "GetSDKVersion", "Script_GetSDKVersion", "Gets the SDK version as a string", "string", "", &VSquirrel::SHARED::GetSDKVersion); + Script_RegisterFunction(s, "GetPromoData", "Script_GetPromoData", "Gets promo data for specified slot type", "string", "int", &VSquirrel::UI::GetPromoData); // Functions for connecting to servers - Script_RegisterFunction(pSquirrelVM, "CreateServer", "Script_CreateServer", "Start server with the specified settings", "void", "string, string, string, string, int", &VSquirrel::UI::CreateServerFromMenu); - Script_RegisterFunction(pSquirrelVM, "SetEncKeyAndConnect", "Script_SetEncKeyAndConnect", "Set the encryption key to that of the specified server and connects to it", "void", "int", &VSquirrel::UI::SetEncKeyAndConnect); - Script_RegisterFunction(pSquirrelVM, "JoinPrivateServerFromMenu", "Script_JoinPrivateServerFromMenu", "Joins private server by token", "void", "string", &VSquirrel::UI::JoinPrivateServerFromMenu); - Script_RegisterFunction(pSquirrelVM, "GetPrivateServerMessage", "Script_GetPrivateServerMessage", "Gets private server join status message", "string", "string", &VSquirrel::UI::GetPrivateServerMessage); - Script_RegisterFunction(pSquirrelVM, "ConnectToIPFromMenu", "Script_ConnectToIPFromMenu", "Joins server by ip address and encryption key", "void", "string, string", &VSquirrel::UI::ConnectToIPFromMenu); + Script_RegisterFunction(s, "CreateServer", "Script_CreateServer", "Start server with the specified settings", "void", "string, string, string, string, int", &VSquirrel::UI::CreateServerFromMenu); + Script_RegisterFunction(s, "SetEncKeyAndConnect", "Script_SetEncKeyAndConnect", "Set the encryption key to that of the specified server and connects to it", "void", "int", &VSquirrel::UI::SetEncKeyAndConnect); + Script_RegisterFunction(s, "JoinPrivateServerFromMenu", "Script_JoinPrivateServerFromMenu", "Joins private server by token", "void", "string", &VSquirrel::UI::JoinPrivateServerFromMenu); + Script_RegisterFunction(s, "GetPrivateServerMessage", "Script_GetPrivateServerMessage", "Gets private server join status message", "string", "string", &VSquirrel::UI::GetPrivateServerMessage); + Script_RegisterFunction(s, "ConnectToIPFromMenu", "Script_ConnectToIPFromMenu", "Joins server by ip address and encryption key", "void", "string, string", &VSquirrel::UI::ConnectToIPFromMenu); - Script_RegisterFunction(pSquirrelVM, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); - Script_RegisterFunction(pSquirrelVM, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); + Script_RegisterFunction(s, "GetAvailableMaps", "Script_GetAvailableMaps", "Gets an array of all available maps", "array< string >", "", &VSquirrel::SHARED::GetAvailableMaps); + Script_RegisterFunction(s, "GetAvailablePlaylists", "Script_GetAvailablePlaylists", "Gets an array of all available playlists", "array< string >", "", &VSquirrel::SHARED::GetAvailablePlaylists); #ifndef CLIENT_DLL - Script_RegisterFunction(pSquirrelVM, "KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VSquirrel::SHARED::KickPlayerByName); - Script_RegisterFunction(pSquirrelVM, "KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::KickPlayerById); + Script_RegisterFunction(s, "KickPlayerByName", "Script_KickPlayerByName", "Kicks a player from the server by name", "void", "string", &VSquirrel::SHARED::KickPlayerByName); + Script_RegisterFunction(s, "KickPlayerById", "Script_KickPlayerById", "Kicks a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::KickPlayerById); - Script_RegisterFunction(pSquirrelVM, "BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VSquirrel::SHARED::BanPlayerByName); - Script_RegisterFunction(pSquirrelVM, "BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::BanPlayerById); + Script_RegisterFunction(s, "BanPlayerByName", "Script_BanPlayerByName", "Bans a player from the server by name", "void", "string", &VSquirrel::SHARED::BanPlayerByName); + Script_RegisterFunction(s, "BanPlayerById", "Script_BanPlayerById", "Bans a player from the server by handle or nucleus id", "void", "string", &VSquirrel::SHARED::BanPlayerById); - Script_RegisterFunction(pSquirrelVM, "UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VSquirrel::SHARED::UnbanPlayer); + Script_RegisterFunction(s, "UnbanPlayer", "Script_UnbanPlayer", "Unbans a player from the server by nucleus id or ip address", "void", "string", &VSquirrel::SHARED::UnbanPlayer); #endif // !CLIENT_DLL - Script_RegisterFunction(pSquirrelVM, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); + Script_RegisterFunction(s, "ShutdownHostGame", "Script_ShutdownHostGame", "Shuts the local host game down", "void", "", &VSquirrel::SHARED::ShutdownHostGame); } //--------------------------------------------------------------------------------- // Purpose: Initialize all CLIENT/UI global structs and register SDK (CLIENT/UI) script functions -// Input : *pSquirrelVM - +// Input : *v - // context - (1 = CLIENT 2 = UI) //--------------------------------------------------------------------------------- -SQRESULT Script_InitializeCLGlobalStructs(CSquirrelVM* pSquirrelVM, SQCONTEXT context) +SQRESULT Script_InitializeCLGlobalStructs(HSQUIRRELVM v, SQCONTEXT context) { - SQRESULT results = v_Script_InitializeCLGlobalStructs(pSquirrelVM, context); + SQRESULT results = v_Script_InitializeCLGlobalStructs(v, context); + if (context == SQCONTEXT::CLIENT) Script_RegisterClientFunctions(g_pClientScript.GetValue()); if (context == SQCONTEXT::UI) @@ -144,12 +159,12 @@ SQRESULT Script_InitializeCLGlobalStructs(CSquirrelVM* pSquirrelVM, SQCONTEXT co #ifndef CLIENT_DLL //--------------------------------------------------------------------------------- // Purpose: Initialize all SERVER global structs and register SDK (SERVER) script functions -// Input : *pSquirrelVM - +// Input : *v - //--------------------------------------------------------------------------------- -void Script_InitializeSVGlobalStructs(CSquirrelVM* pSquirrelVM) +void Script_InitializeSVGlobalStructs(HSQUIRRELVM v) { - v_Script_InitializeSVGlobalStructs(pSquirrelVM); - Script_RegisterServerFunctions(g_pServerScript.GetValue()); + v_Script_InitializeSVGlobalStructs(v); + Script_RegisterServerFunctions(Script_GetContextObject(SQCONTEXT::SERVER)); } //--------------------------------------------------------------------------------- @@ -160,7 +175,7 @@ SQBool Script_CreateServerVM() { SQBool results = v_Script_CreateServerVM(); if (results) - DevMsg(eDLL_T::SERVER, "Created SERVER VM: '%p'\n", g_pServerScript.GetValue()); + DevMsg(eDLL_T::SERVER, "Created SERVER VM: '%p'\n", Script_GetContextObject(SQCONTEXT::SERVER)); else Error(eDLL_T::SERVER, EXIT_FAILURE, "Failed to create SERVER VM\n"); return results; @@ -170,14 +185,14 @@ SQBool Script_CreateServerVM() #ifndef DEDICATED //--------------------------------------------------------------------------------- // Purpose: Creates the CLIENT Squirrel VM -// Input : *pHlClient - +// Input : *hlClient - // Output : True on success, false on failure //--------------------------------------------------------------------------------- -SQBool Script_CreateClientVM(CHLClient* pHlClient) +SQBool Script_CreateClientVM(CHLClient* hlclient) { - SQBool results = v_Script_CreateClientVM(pHlClient); + SQBool results = v_Script_CreateClientVM(hlclient); if (results) - DevMsg(eDLL_T::CLIENT, "Created CLIENT VM: '%p'\n", g_pClientScript.GetValue()); + DevMsg(eDLL_T::CLIENT, "Created CLIENT VM: '%p'\n", Script_GetContextObject(SQCONTEXT::CLIENT)); else Error(eDLL_T::CLIENT, EXIT_FAILURE, "Failed to create CLIENT VM\n"); return results; @@ -191,7 +206,7 @@ SQBool Script_CreateUIVM() { SQBool results = v_Script_CreateUIVM(); if (results) - DevMsg(eDLL_T::UI, "Created UI VM: '%p'\n", g_pUIScript.GetValue()); + DevMsg(eDLL_T::UI, "Created UI VM: '%p'\n", Script_GetContextObject(SQCONTEXT::UI)); else Error(eDLL_T::UI, EXIT_FAILURE, "Failed to create UI VM\n"); return results; @@ -203,7 +218,7 @@ SQBool Script_CreateUIVM() // Input : context - // Output : SQVM* //--------------------------------------------------------------------------------- -CSquirrelVM* Script_GetContextObject(SQCONTEXT context) +CSquirrelVM* Script_GetContextObject(const SQCONTEXT context) { switch (context) { @@ -222,35 +237,49 @@ CSquirrelVM* Script_GetContextObject(SQCONTEXT context) } } +//--------------------------------------------------------------------------------- +// Purpose: destroys the signal entry list head +// Input : *s - +// v - +// f - +// Output : true on success, false otherwise +//--------------------------------------------------------------------------------- +SQBool Script_DestroySignalEntryListHead(CSquirrelVM* s, HSQUIRRELVM v, SQFloat f) +{ + SQBool result = v_Script_DestroySignalEntryListHead(s, v, f); + Script_RegisterConstant(s, "DEVELOPER", developer->GetInt()); + return result; +} + //--------------------------------------------------------------------------------- // Purpose: prints the global include file the compiler loads for loading scripts // Input : *szRsonName - //--------------------------------------------------------------------------------- -SQInteger Script_LoadRson(const SQChar* szRsonName) +SQInteger Script_LoadRson(const SQChar* rsonfile) { if (sq_showrsonloading->GetBool()) { - DevMsg(eDLL_T::ENGINE, "Loading RSON: '%s'\n", szRsonName); + DevMsg(eDLL_T::ENGINE, "Loading RSON: '%s'\n", rsonfile); } - return v_Script_LoadRson(szRsonName); + return v_Script_LoadRson(rsonfile); } //--------------------------------------------------------------------------------- // Purpose: prints the scripts the compiler loads from global include to be compiled // Input : *v - -// *szScriptPath - -// *szScriptName - -// nFlag - +// *path - +// *name - +// flags - //--------------------------------------------------------------------------------- -SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* szScriptPath, const SQChar* szScriptName, SQInteger nFlag) +SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* path, const SQChar* name, SQInteger flags) { if (sq_showscriptloading->GetBool()) { - DevMsg(eDLL_T::ENGINE, "Loading script: '%s'\n", szScriptName); + DevMsg(eDLL_T::ENGINE, "Loading script: '%s'\n", name); } /////////////////////////////////////////////////////////////////////////////// - return v_Script_LoadScript(v, szScriptPath, szScriptName, nFlag); + return v_Script_LoadScript(v, path, name, flags); } //--------------------------------------------------------------------------------- @@ -258,7 +287,7 @@ SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* szScriptPath, const SQChar // Input : *code - // context - //--------------------------------------------------------------------------------- -void Script_Execute(const SQChar* code, SQCONTEXT context) +void Script_Execute(const SQChar* code, const SQCONTEXT context) { if (!ThreadInMainThread()) { @@ -271,25 +300,24 @@ void Script_Execute(const SQChar* code, SQCONTEXT context) return; // Only run in main thread. } - CSquirrelVM* script = Script_GetContextObject(context); - if (!script) + CSquirrelVM* s = Script_GetContextObject(context); + if (!s) { - Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to run %s script with no handle to script context\n", SQVM_GetContextName(context)); + Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to run %s script with no handle to VM\n", SQVM_GetContextName(context)); return; } - HSQUIRRELVM v = script->GetVM(); + HSQUIRRELVM v = s->GetVM(); if (!v) { Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to run %s script while VM isn't initialized\n", SQVM_GetContextName(context)); return; } - SQRESULT compileResult{}; SQBufState bufState = SQBufState(code); + SQRESULT compileResult = sq_compilebuffer(v, &bufState, "console", -1); - compileResult = sq_compilebuffer(v, &bufState, "console", -1); - if (compileResult >= 0) + if (compileResult >= NULL) { sq_pushroottable(v); SQRESULT callResult = sq_call(v, 1, false, false); @@ -299,6 +327,7 @@ void Script_Execute(const SQChar* code, SQCONTEXT context) //--------------------------------------------------------------------------------- void SQScript_Attach() { + DetourAttach((LPVOID*)&v_Script_RegisterConstant, &Script_RegisterConstant); #ifndef DEDICATED DetourAttach((LPVOID*)&v_Script_InitializeCLGlobalStructs, &Script_InitializeCLGlobalStructs); #endif // !DEDICATED @@ -310,12 +339,14 @@ void SQScript_Attach() DetourAttach((LPVOID*)&v_Script_CreateClientVM, &Script_CreateClientVM); DetourAttach((LPVOID*)&v_Script_CreateUIVM, &Script_CreateUIVM); #endif // !DEDICATED + DetourAttach((LPVOID*)&v_Script_DestroySignalEntryListHead, &Script_DestroySignalEntryListHead); DetourAttach((LPVOID*)&v_Script_LoadRson, &Script_LoadRson); DetourAttach((LPVOID*)&v_Script_LoadScript, &Script_LoadScript); } //--------------------------------------------------------------------------------- void SQScript_Detach() { + DetourDetach((LPVOID*)&v_Script_RegisterConstant, &Script_RegisterConstant); #ifndef DEDICATED DetourDetach((LPVOID*)&v_Script_InitializeCLGlobalStructs, &Script_InitializeCLGlobalStructs); #endif // !DEDICATED @@ -327,6 +358,7 @@ void SQScript_Detach() DetourDetach((LPVOID*)&v_Script_CreateClientVM, &Script_CreateClientVM); DetourDetach((LPVOID*)&v_Script_CreateUIVM, &Script_CreateUIVM); #endif // !DEDICATED + DetourDetach((LPVOID*)&v_Script_DestroySignalEntryListHead, &Script_DestroySignalEntryListHead); DetourDetach((LPVOID*)&v_Script_LoadRson, &Script_LoadRson); DetourDetach((LPVOID*)&v_Script_LoadScript, &Script_LoadScript); } diff --git a/r5dev/squirrel/sqscript.h b/r5dev/squirrel/sqscript.h index 03a65e78..773d0637 100644 --- a/r5dev/squirrel/sqscript.h +++ b/r5dev/squirrel/sqscript.h @@ -4,28 +4,43 @@ struct ScriptFunctionBinding_t { - const SQChar* m_szScriptName; // 00 - const SQChar* m_szNativeName; // 08 - const SQChar* m_szHelpString; // 10 - const SQChar* m_szRetValType; // 18 - const SQChar* m_szArgTypes; // 20 - std::int16_t unk28; // 28 - std::int16_t padding1; // 2A - std::int32_t unk2c; // 2C - std::int64_t unk30; // 30 - std::int32_t unk38; // 38 - std::int32_t padding2; // 3C - std::int64_t unk40; // 40 - std::int64_t unk48; // 48 - std::int64_t unk50; // 50 - std::int32_t unk58; // 58 - std::int32_t padding3; // 5C - void* m_pFunction; // 60 + const SQChar* _scriptname; // 00 + const SQChar* _nativename; // 08 + const SQChar* _helpstring; // 10 + const SQChar* _returntype; // 18 + const SQChar* _parameters; // 20 + std::int16_t unk28; // 28 + std::int16_t padding1; // 2A + std::int32_t unk2c; // 2C + const SQChar* _codehook; // 30 + std::int32_t unk38; // 38 + SQInteger _nparamscheck; // 3C + std::int64_t unk40; // 40 + std::int64_t unk48; // 48 + std::int64_t unk50; // 50 + std::int32_t unk58; // 58 + std::int32_t padding3; // 5C + void* _functor; // 60 ScriptFunctionBinding_t() { - memset(this, '\0', sizeof(ScriptFunctionBinding_t)); - this->padding2 = 6; + _scriptname = nullptr; + _nativename = nullptr; + _helpstring = nullptr; + _returntype = nullptr; + _parameters = nullptr; + unk28 = 0; + padding1 = 0; + unk2c = 0; + _codehook = nullptr; + unk38 = 0; + _nparamscheck = 6; + unk40 = 0; + unk48 = 0; + unk50 = 0; + unk58 = 0; + padding3 = 0; + _functor = nullptr; } }; @@ -59,14 +74,17 @@ private: #pragma pack(pop) inline CMemory p_Script_RegisterFunction; -inline auto v_Script_RegisterFunction = p_Script_RegisterFunction.RCast(); +inline auto v_Script_RegisterFunction = p_Script_RegisterFunction.RCast(); + +inline CMemory p_Script_RegisterConstant; +inline auto v_Script_RegisterConstant = p_Script_RegisterConstant.RCast(); #if !defined (CLIENT_DLL) inline CMemory p_Script_InitializeSVGlobalStructs; -inline auto v_Script_InitializeSVGlobalStructs = p_Script_InitializeSVGlobalStructs.RCast(); +inline auto v_Script_InitializeSVGlobalStructs = p_Script_InitializeSVGlobalStructs.RCast(); #endif // !CLIENT_DLL #if !defined (DEDICATED) inline CMemory p_Script_InitializeCLGlobalStructs; -inline auto v_Script_InitializeCLGlobalStructs = p_Script_InitializeCLGlobalStructs.RCast(); +inline auto v_Script_InitializeCLGlobalStructs = p_Script_InitializeCLGlobalStructs.RCast(); #endif // !DEDICATED #if !defined (CLIENT_DLL) && defined (GAMEDLL_S0) || defined (GAMEDLL_S1) inline CMemory p_Script_CreateServerVM; @@ -77,20 +95,23 @@ inline auto v_Script_CreateServerVM = p_Script_CreateServerVM.RCast(); +inline auto v_Script_CreateClientVM = p_Script_CreateClientVM.RCast(); #elif !defined (DEDICATED) && defined (GAMEDLL_S3) inline CMemory p_Script_CreateClientVM; -inline auto v_Script_CreateClientVM = p_Script_CreateClientVM.RCast(); +inline auto v_Script_CreateClientVM = p_Script_CreateClientVM.RCast(); #endif #if !defined (DEDICATED) inline CMemory p_Script_CreateUIVM; inline auto v_Script_CreateUIVM = p_Script_CreateUIVM.RCast(); #endif // !DEDICATED +inline CMemory p_Script_DestroySignalEntryListHead; +inline auto v_Script_DestroySignalEntryListHead = p_Script_DestroySignalEntryListHead.RCast(); + inline CMemory p_Script_LoadRson; -inline auto v_Script_LoadRson = p_Script_LoadRson.RCast(); +inline auto v_Script_LoadRson = p_Script_LoadRson.RCast(); inline CMemory p_Script_LoadScript; -inline auto v_Script_LoadScript = p_Script_LoadScript.RCast(); +inline auto v_Script_LoadScript = p_Script_LoadScript.RCast(); #if !defined (CLIENT_DLL) inline CMemory g_pServerScript; @@ -100,26 +121,27 @@ inline CMemory g_pClientScript; inline CMemory g_pUIScript; #endif // !DEDICATED -SQRESULT Script_RegisterFunction(CSquirrelVM* pSquirrelVM, const SQChar* szScriptName, const SQChar* szNativeName, - const SQChar* szHelpString, const SQChar* szRetValType, const SQChar* szArgTypes, void* pFunction); -void Script_RegisterServerFunctions(CSquirrelVM* pSquirrelVM); -void Script_RegisterClientFunctions(CSquirrelVM* pSquirrelVM); -void Script_RegisterUIFunctions(CSquirrelVM* pSquirrelVM); +SQRESULT Script_RegisterConstant(CSquirrelVM* s, const SQChar* name, SQInteger value); +SQRESULT Script_RegisterFunction(CSquirrelVM* s, const SQChar* scriptname, const SQChar* nativename, + const SQChar* helpstring, const SQChar* returntype, const SQChar* arguments, void* functor); +void Script_RegisterServerFunctions(CSquirrelVM* s); +void Script_RegisterClientFunctions(CSquirrelVM* s); +void Script_RegisterUIFunctions(CSquirrelVM* s); -SQRESULT Script_InitializeCLGlobalStructs(CSquirrelVM*, SQCONTEXT context); -void Script_InitializeSVGlobalStructs(CSquirrelVM* pSquirrelVM); +SQRESULT Script_InitializeCLGlobalStructs(HSQUIRRELVM v, SQCONTEXT context); +void Script_InitializeSVGlobalStructs(HSQUIRRELVM v); SQBool Script_CreateServerVM(); #ifndef DEDICATED SQBool Script_CreateClientVM(CHLClient* hlclient); #endif // !DEDICATED SQBool Script_CreateUIVM(); -CSquirrelVM* Script_GetContextObject(SQCONTEXT context); +CSquirrelVM* Script_GetContextObject(const SQCONTEXT context); -SQInteger Script_LoadRson(const SQChar* szRsonName); -SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* szScriptPath, const SQChar* szScriptName, SQInteger nFlag); +SQInteger Script_LoadRson(const SQChar* rsonfile); +SQBool Script_LoadScript(HSQUIRRELVM v, const SQChar* path, const SQChar* name, SQInteger flags); -void Script_Execute(const SQChar* code, SQCONTEXT context); +void Script_Execute(const SQChar* code, const SQCONTEXT context); void SQScript_Attach(); void SQScript_Detach(); @@ -128,7 +150,8 @@ class VSquirrelVM : public IDetour { virtual void GetAdr(void) const { - spdlog::debug("| FUN: Script_RegisterFunc : {:#18x} |\n", p_Script_RegisterFunction.GetPtr()); + spdlog::debug("| FUN: Script_RegisterConstant : {:#18x} |\n", p_Script_RegisterConstant.GetPtr()); + spdlog::debug("| FUN: Script_RegisterFunction : {:#18x} |\n", p_Script_RegisterFunction.GetPtr()); #ifndef CLIENT_DLL spdlog::debug("| FUN: Script_InitializeSVGlobalStructs : {:#18x} |\n", p_Script_InitializeSVGlobalStructs.GetPtr()); #endif // !CLIENT_DLL @@ -142,6 +165,7 @@ class VSquirrelVM : public IDetour spdlog::debug("| FUN: Script_CreateClientVM : {:#18x} |\n", p_Script_CreateClientVM.GetPtr()); spdlog::debug("| FUN: Script_CreateUIVM : {:#18x} |\n", p_Script_CreateUIVM.GetPtr()); #endif // !DEDICATED + spdlog::debug("| FUN: Script_DestroySignalEntryListHead : {:#18x} |\n", p_Script_DestroySignalEntryListHead.GetPtr()); spdlog::debug("| FUN: Script_LoadRson : {:#18x} |\n", p_Script_LoadRson.GetPtr()); spdlog::debug("| FUN: Script_LoadScript : {:#18x} |\n", p_Script_LoadScript.GetPtr()); #ifndef CLIENT_DLL @@ -155,6 +179,7 @@ class VSquirrelVM : public IDetour } virtual void GetFun(void) const { + p_Script_RegisterConstant = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x4C\x8B"), "xxxx?xxxx?xxxx?xxxxxxx"); p_Script_RegisterFunction = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x38\x45\x0F\xB6\xC8"), "xxxxxxxx"); #if !defined (CLIENT_DLL) p_Script_InitializeSVGlobalStructs = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x48\x8B\x3D\x00\x00\x00\x00\x48\x8B\xF1"), "xxxx?xxxxxxxx????xxx"); @@ -175,28 +200,31 @@ class VSquirrelVM : public IDetour #if !defined (DEDICATED) p_Script_CreateUIVM = g_GameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x48\x8B\x1D\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x00"), "xxxxxxxxx????xx?????"); #endif // !DEDICATED + p_Script_DestroySignalEntryListHead = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x56\x57\x41\x56\x48\x83\xEC\x50\x44\x8B\x42\x78"), "xxxx?xxxx?xxxxxxxxxxxx"); p_Script_LoadRson = g_GameDll.FindPatternSIMD(reinterpret_cast("\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xA0\x00\x00\x00\x33"), "xxxxxxxxxxxxxxxx"); #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) p_Script_LoadScript = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C"), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) p_Script_LoadScript = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x48\x89\x48\x08\x55\x41\x56\x48\x8D\x68"), "xxxxxxxxxxxxx"); #endif - v_Script_RegisterFunction = p_Script_RegisterFunction.RCast(); /*48 83 EC 38 45 0F B6 C8*/ + v_Script_RegisterConstant = p_Script_RegisterConstant.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 4C 8B*/ + v_Script_RegisterFunction = p_Script_RegisterFunction.RCast(); /*48 83 EC 38 45 0F B6 C8*/ #if !defined (CLIENT_DLL) - v_Script_InitializeSVGlobalStructs = p_Script_InitializeSVGlobalStructs.RCast(); /*48 89 74 24 ?? 57 48 83 EC 30 48 8B 3D ?? ?? ?? ?? 48 8B F1*/ + v_Script_InitializeSVGlobalStructs = p_Script_InitializeSVGlobalStructs.RCast(); /*48 89 74 24 ?? 57 48 83 EC 30 48 8B 3D ?? ?? ?? ?? 48 8B F1*/ #endif // !CLIENT_DLL #if !defined (DEDICATED) - v_Script_InitializeCLGlobalStructs = p_Script_InitializeCLGlobalStructs.RCast(); /*48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 63 C2 48 8D 3D ?? ?? ?? ??*/ + v_Script_InitializeCLGlobalStructs = p_Script_InitializeCLGlobalStructs.RCast(); /*48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 30 48 63 C2 48 8D 3D ?? ?? ?? ??*/ #endif // !DEDICATED #if !defined (CLIENT_DLL) - v_Script_CreateServerVM = p_Script_CreateServerVM.RCast(); /*40 53 56 48 83 EC 48 48 8D 0D ?? ?? ?? ??*/ + v_Script_CreateServerVM = p_Script_CreateServerVM.RCast(); /*40 53 56 48 83 EC 48 48 8D 0D ?? ?? ?? ??*/ #endif // !CLIENT_DLL #if !defined (DEDICATED) - v_Script_CreateClientVM = p_Script_CreateClientVM.RCast(); /*40 53 41 57 48 83 EC 68 48 83 3D ?? ?? ?? ?? ??*/ - v_Script_CreateUIVM = p_Script_CreateUIVM.RCast(); /*40 53 48 83 EC 20 48 8B 1D ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??*/ + v_Script_CreateClientVM = p_Script_CreateClientVM.RCast(); /*40 53 41 57 48 83 EC 68 48 83 3D ?? ?? ?? ?? ??*/ + v_Script_CreateUIVM = p_Script_CreateUIVM.RCast(); /*40 53 48 83 EC 20 48 8B 1D ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??*/ #endif // !DEDICATED - v_Script_LoadRson = p_Script_LoadRson.RCast(); /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/ - v_Script_LoadScript = p_Script_LoadScript.RCast(); /*48 8B C4 48 89 48 08 55 41 56 48 8D 68*/ + v_Script_DestroySignalEntryListHead = p_Script_DestroySignalEntryListHead.RCast();/*48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 50 44 8B 42*/ + v_Script_LoadRson = p_Script_LoadRson.RCast(); /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/ + v_Script_LoadScript = p_Script_LoadScript.RCast(); /*48 8B C4 48 89 48 08 55 41 56 48 8D 68*/ } virtual void GetVar(void) const { diff --git a/r5dev/squirrel/sqtype.h b/r5dev/squirrel/sqtype.h index dc580145..6a3f6291 100644 --- a/r5dev/squirrel/sqtype.h +++ b/r5dev/squirrel/sqtype.h @@ -18,6 +18,7 @@ typedef char SQChar; typedef float SQFloat; typedef long SQInteger; typedef unsigned long SQUnsignedInteger; +typedef void* SQFunctor; typedef SQUnsignedInteger SQBool; typedef SQInteger SQRESULT; diff --git a/r5dev/squirrel/sqvm.cpp b/r5dev/squirrel/sqvm.cpp index 740db93d..8ff6fc08 100644 --- a/r5dev/squirrel/sqvm.cpp +++ b/r5dev/squirrel/sqvm.cpp @@ -319,7 +319,7 @@ void SQVM_CompileError(HSQUIRRELVM v, const SQChar* pszError, const SQChar* pszF context = SQVM_GetContextIndex(v); #endif - v_SQVM_GetErrorLine(pszFile, nLine, szContextBuf, sizeof(szContextBuf)); + v_SQVM_GetErrorLine(pszFile, nLine, szContextBuf, sizeof(szContextBuf) - 1); Error(static_cast(context), NO_ERROR, "%s SCRIPT COMPILE ERROR: %s\n", SQVM_GetContextName(context), pszError); Error(static_cast(context), NO_ERROR, " -> %s\n\n", szContextBuf); diff --git a/r5dev/thirdparty/imgui/include/imgui_logger.h b/r5dev/thirdparty/imgui/include/imgui_logger.h index 824b7f83..7b6bfea5 100644 --- a/r5dev/thirdparty/imgui/include/imgui_logger.h +++ b/r5dev/thirdparty/imgui/include/imgui_logger.h @@ -185,7 +185,8 @@ private: Coordinates SanitizeCoordinates(const Coordinates& aValue) const; void Advance(Coordinates& aCoordinates) const; void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd); - int InsertTextAt(Coordinates& aWhere, const char* aValue, ImVec4 aColor); + int InsertTextAt(Coordinates& aWhere, const char* aValue, const ImVec4& aColor); + void MarkNewline(Coordinates& aWhere, const ImVec4& aColor, int aIndex); Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const; Coordinates FindWordStart(const Coordinates& aFrom) const; Coordinates FindWordEnd(const Coordinates& aFrom) const; diff --git a/r5dev/thirdparty/imgui/src/imgui_logger.cpp b/r5dev/thirdparty/imgui/src/imgui_logger.cpp index 4265db97..87ea7102 100644 --- a/r5dev/thirdparty/imgui/src/imgui_logger.cpp +++ b/r5dev/thirdparty/imgui/src/imgui_logger.cpp @@ -196,7 +196,24 @@ void CTextLogger::DeleteRange(const Coordinates & aStart, const Coordinates & aE } } -int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aValue, ImVec4 aColor) +void CTextLogger::MarkNewline(Coordinates& /* inout */ aWhere, const ImVec4& aColor, int aIndex) +{ + if (aIndex < static_cast(m_Lines[aWhere.m_nLine].size())) + { + Line& newLine = InsertLine(aWhere.m_nLine + 1); + Line& line = m_Lines[aWhere.m_nLine]; + newLine.insert(newLine.begin(), line.begin() + aIndex, line.end()); + line.erase(line.begin() + aIndex, line.end()); + } + else + { + Line& newLine = InsertLine(aWhere.m_nLine + 1); + Line& line = m_Lines[aWhere.m_nLine]; + line.insert(line.begin() + aIndex, Glyph('\n', aColor)); + } +} + +int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aValue, const ImVec4& aColor) { int cindex = GetCharacterIndex(aWhere); int totalLines = 0; @@ -212,19 +229,7 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aVal } else if (*aValue == '\n') { - if (cindex < static_cast(m_Lines[aWhere.m_nLine].size())) - { - Line& newLine = InsertLine(aWhere.m_nLine + 1); - Line& line = m_Lines[aWhere.m_nLine]; - newLine.insert(newLine.begin(), line.begin() + cindex, line.end()); - line.erase(line.begin() + cindex, line.end()); - } - else - { - Line& newLine = InsertLine(aWhere.m_nLine + 1); - Line& line = m_Lines[aWhere.m_nLine]; - line.insert(line.begin() + cindex, Glyph(*aValue, aColor)); - } + MarkNewline(aWhere, aColor, cindex); ++aWhere.m_nLine; aWhere.m_nColumn = 0; cindex = 0; @@ -234,12 +239,28 @@ int CTextLogger::InsertTextAt(Coordinates& /* inout */ aWhere, const char * aVal else { Line& line = m_Lines[aWhere.m_nLine]; + if (!line.empty() && ImGui::ColorConvertFloat4ToU32(aColor) != ImGui::ColorConvertFloat4ToU32(line[0].m_Color)) + { + MarkNewline(aWhere, line[0].m_Color, cindex); + ++aWhere.m_nLine; + aWhere.m_nColumn = 0; + cindex = 0; + ++totalLines; + continue; + } + int d = UTF8CharLength(*aValue); while (d-- > 0 && *aValue != '\0') line.insert(line.begin() + cindex++, Glyph(*aValue++, aColor)); ++aWhere.m_nColumn; } } + if (!*aValue) + { + Line& line = m_Lines[aWhere.m_nLine]; + if (!line.empty()) + line.insert(line.begin() + cindex, Glyph(' ', aColor)); + } return totalLines; } diff --git a/r5dev/tier0/basetypes.h b/r5dev/tier0/basetypes.h index 783cb840..baed3f8b 100644 --- a/r5dev/tier0/basetypes.h +++ b/r5dev/tier0/basetypes.h @@ -134,7 +134,7 @@ #endif // Max BSP file name len. #define MAX_MAP_NAME 64 -#define SDK_VERSION "VGameSDK003" // Increment this with every /breaking/ SDK change (i.e. security/backend changes breaking compatibility). +#define SDK_VERSION "VGameSDK005" // Increment this with every /breaking/ SDK change (i.e. security/backend changes breaking compatibility). #define SDK_ARRAYSIZE(arr) ((sizeof(arr) / sizeof(*arr))) // Name due to IMGUI implementation and NT implementation that we shouldn't share across everywhere. #ifndef DEDICATED diff --git a/r5dev/tier0/threadtools.cpp b/r5dev/tier0/threadtools.cpp index e3e86baa..ff03656e 100644 --- a/r5dev/tier0/threadtools.cpp +++ b/r5dev/tier0/threadtools.cpp @@ -40,6 +40,11 @@ bool ThreadInRenderThread() return (ThreadGetCurrentId() == g_ThreadRenderThreadID); } +bool ThreadInServerFrameThread() +{ + return (ThreadGetCurrentId() == (*g_ThreadServerFrameThreadID)); +} + ThreadId_t ThreadGetCurrentId() { #ifdef _WIN32 diff --git a/r5dev/tier0/threadtools.h b/r5dev/tier0/threadtools.h index 468e9559..28ba2594 100644 --- a/r5dev/tier0/threadtools.h +++ b/r5dev/tier0/threadtools.h @@ -55,6 +55,7 @@ inline void ThreadPause() bool ThreadInMainThread(); bool ThreadInRenderThread(); +bool ThreadInServerFrameThread(); ThreadId_t ThreadGetCurrentId(); //----------------------------------------------------------------------------- @@ -215,6 +216,7 @@ inline auto v_DeclareCurrentThreadIsMainThread = p_DeclareCurrentThreadIsMainThr inline ThreadId_t* g_ThreadMainThreadID = nullptr; inline ThreadId_t g_ThreadRenderThreadID = NULL; +inline ThreadId_t* g_ThreadServerFrameThreadID = nullptr; /////////////////////////////////////////////////////////////////////////////// class CThreadFastMutex @@ -248,6 +250,7 @@ class VThreadTools : public IDetour spdlog::debug("| FUN: CThreadFastMutex::ReleaseWaiter : {:#18x} |\n", p_MutexInternal_ReleaseWaiter.GetPtr()); spdlog::debug("| FUN: DeclareCurrentThreadIsMainThread : {:#18x} |\n", p_DeclareCurrentThreadIsMainThread.GetPtr()); spdlog::debug("| VAR: g_ThreadMainThreadID : {:#18x} |\n", reinterpret_cast(g_ThreadMainThreadID)); + spdlog::debug("| VAR: g_ThreadServerFrameThreadID : {:#18x} |\n", reinterpret_cast(g_ThreadServerFrameThreadID)); spdlog::debug("+----------------------------------------------------------------+\n"); } virtual void GetFun(void) const @@ -262,7 +265,9 @@ class VThreadTools : public IDetour } virtual void GetVar(void) const { - g_ThreadMainThreadID = p_DeclareCurrentThreadIsMainThread.FindPattern("89 05").ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + g_ThreadMainThreadID = p_DeclareCurrentThreadIsMainThread.FindPattern("89 05").ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + g_ThreadServerFrameThreadID = g_GameDll.FindPatternSIMD(reinterpret_cast("\x83\x79\x00\x00\x75\x28\x8B"), "xx?xxxx") + .FindPatternSelf("8B 05").ResolveRelativeAddressSelf(0x2, 0x6).RCast(); } virtual void GetCon(void) const { } virtual void Attach(void) const { } diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index d5db9bc2..2d3c6093 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -101,11 +101,11 @@ void ConVar::Init(void) const #endif // !DEDICATED sv_showconnecting = ConVar::Create("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr); sv_pylonVisibility = ConVar::Create("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", false, 0.f, false, 0.f, nullptr, "0 = Offline, 1 = Hidden, 2 = Public."); - sv_pylonRefreshInterval = ConVar::Create("sv_pylonRefreshInterval" , "5.0", FCVAR_RELEASE, "Pylon server host request post update interval (seconds).", true, 2.f, true, 8.f, nullptr, nullptr); - sv_banlistRefreshInterval = ConVar::Create("sv_banlistRefreshInterval", "1.0", FCVAR_RELEASE, "Banlist refresh interval (seconds).", true, 1.f, false, 0.f, nullptr, nullptr); - sv_statusRefreshInterval = ConVar::Create("sv_statusRefreshInterval" , "0.5", FCVAR_RELEASE, "Server status bar update interval (seconds).", false, 0.f, false, 0.f, nullptr, nullptr); - - sv_autoReloadRate = ConVar::Create("sv_autoReloadRate" , "0", FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null). ", true, 0.f, false, 0.f, nullptr, nullptr); + sv_pylonRefreshRate = ConVar::Create("sv_pylonRefreshRate" , "5.0", FCVAR_RELEASE, "Pylon host refresh rate (seconds).", true, 2.f, true, 8.f, nullptr, nullptr); + sv_banlistRefreshRate = ConVar::Create("sv_banlistRefreshRate", "1.0", FCVAR_RELEASE, "Banned list refresh rate (seconds).", true, 1.f, false, 0.f, nullptr, nullptr); + sv_statusRefreshRate = ConVar::Create("sv_statusRefreshRate" , "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", false, 0.f, false, 0.f, nullptr, nullptr); + sv_autoReloadRate = ConVar::Create("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null). ", true, 0.f, false, 0.f, nullptr, nullptr); + sv_quota_stringCmdsPerSecond = ConVar::Create("sv_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands.", true, 0.f, false, 0.f, nullptr, nullptr); #ifdef DEDICATED sv_rcon_debug = ConVar::Create("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); sv_rcon_sendlogs = ConVar::Create("sv_rcon_sendlogs" , "0" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr); @@ -123,6 +123,7 @@ void ConVar::Init(void) const // CLIENT | #ifndef DEDICATED cl_rcon_request_sendlogs = ConVar::Create("cl_rcon_request_sendlogs", "1" , FCVAR_RELEASE, "Request the rcon server to send console logs on connect.", false, 0.f, false, 0.f, nullptr, nullptr); + cl_quota_stringCmdsPerSecond = ConVar::Create("cl_quota_stringCmdsPerSecond", "16" , FCVAR_RELEASE, "How many string commands per second user is allowed to submit, 0 to allow all submissions.", true, 0.f, false, 0.f, nullptr, nullptr); cl_showhoststats = ConVar::Create("cl_showhoststats" , "0", FCVAR_DEVELOPMENTONLY, "Host speeds debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr); cl_hoststats_invert_x = ConVar::Create("cl_hoststats_invert_x", "0", FCVAR_DEVELOPMENTONLY, "Inverts the X offset for host speeds debug overlay.", false, 0.f, false, 0.f, nullptr, nullptr); @@ -203,6 +204,7 @@ void ConVar::Init(void) const net_tracePayload = ConVar::Create("net_tracePayload" , "0", FCVAR_DEVELOPMENTONLY , "Log the payload of the send/recv datagram to a file on the disk.", false, 0.f, false, 0.f, nullptr, nullptr); net_encryptionEnable = ConVar::Create("net_encryptionEnable" , "1", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED , "Use AES encryption on game packets.", false, 0.f, false, 0.f, nullptr, nullptr); net_useRandomKey = ConVar::Create("net_useRandomKey" , "1" , FCVAR_RELEASE , "Use random AES encryption key for game packets.", false, 0.f, false, 0.f, &NET_UseRandomKeyChanged_f, nullptr); + net_processTimeBudget = ConVar::Create("net_processTimeBudget" ,"150" , FCVAR_RELEASE , "Net message process budget in milliseconds (removing netchannel if exceeded).", true, 0.f, false, 0.f, nullptr, "0 = disabled."); //------------------------------------------------------------------------- // NETWORKSYSTEM | pylon_matchmaking_hostname = ConVar::Create("pylon_matchmaking_hostname", "ms.r5reloaded.com", FCVAR_RELEASE , "Holds the pylon matchmaking hostname.", false, 0.f, false, 0.f, &MP_HostName_Changed_f, nullptr); @@ -229,6 +231,7 @@ void ConVar::InitShipped(void) const #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) bhit_enable = g_pCVar->FindVar("bhit_enable"); #endif // !GAMEDLL_S0 && !GAMEDLL_S1 + developer = g_pCVar->FindVar("developer"); #endif // !CLIENT_DLL #ifndef DEDICATED cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup"); @@ -255,9 +258,14 @@ void ConVar::InitShipped(void) const hostport = g_pCVar->FindVar("hostport"); host_hasIrreversibleShutdown = g_pCVar->FindVar("host_hasIrreversibleShutdown"); net_usesocketsforloopback = g_pCVar->FindVar("net_usesocketsforloopback"); - #ifndef CLIENT_DLL + sv_forceChatToTeamOnly = g_pCVar->FindVar("sv_forceChatToTeamOnly"); + + sv_forceChatToTeamOnly->RemoveFlags(FCVAR_DEVELOPMENTONLY); + sv_forceChatToTeamOnly->AddFlags(FCVAR_REPLICATED); + ai_script_nodes_draw->SetValue(-1); + bhit_enable->SetValue(0); #endif // !CLIENT_DLL #ifndef DEDICATED cl_threaded_bone_setup->RemoveFlags(FCVAR_DEVELOPMENTONLY); diff --git a/r5dev/tier1/cmd.cpp b/r5dev/tier1/cmd.cpp index 2b4d9c8a..6b6eb4f5 100644 --- a/r5dev/tier1/cmd.cpp +++ b/r5dev/tier1/cmd.cpp @@ -660,13 +660,65 @@ ECommandTarget_t Cbuf_GetCurrentPlayer(void) return ECommandTarget_t::CBUF_FIRST_PLAYER; } +//----------------------------------------------------------------------------- +// Purpose: Sends the entire command line over to the server +// Input : *args - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool Cmd_ForwardToServer(const CCommand* args) +{ +#ifndef DEDICATED + // Client -> Server command throttling. + static double flForwardedCommandQuotaStartTime = -1; + static int nForwardedCommandQuotaCount = 0; + + // No command to forward. + if (args->ArgC() == 0) + return false; + + double flStartTime = Plat_FloatTime(); + int nCmdQuotaLimit = cl_quota_stringCmdsPerSecond->GetInt(); + const char* pszCmdString = nullptr; + + // Special case: "cmd whatever args..." is forwarded as "whatever args..."; + // in this case we strip "cmd" from the input. + if (Q_strcasecmp(args->Arg(0), "cmd") == 0) + pszCmdString = args->ArgS(); + else + pszCmdString = args->GetCommandString(); + + if (nCmdQuotaLimit) + { + if (flStartTime - flForwardedCommandQuotaStartTime >= 1.0) + { + flForwardedCommandQuotaStartTime = flStartTime; + nForwardedCommandQuotaCount = 0; + } + ++nForwardedCommandQuotaCount; + + if (nForwardedCommandQuotaCount > nCmdQuotaLimit) + { + // If we are over quota commands per second, dump this on the floor. + // If we spam the server with too many commands, it will kick us. + Warning(eDLL_T::CLIENT, "Command '%s' ignored (submission quota of '%d' per second exceeded!)\n", args->ArgS(), nCmdQuotaLimit); + return false; + } + } + return v_Cmd_ForwardToServer(args); +#else // !DEDICATED + return false; // Client only. +#endif // DEDICATED +} + /////////////////////////////////////////////////////////////////////////////// void ConCommand_Attach() { DetourAttach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal); + DetourAttach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer); } void ConCommand_Detach() { DetourDetach((LPVOID*)&ConCommandBase_IsFlagSet, &ConCommandBase::IsFlagSetInternal); + DetourDetach((LPVOID*)&v_Cmd_ForwardToServer, &Cmd_ForwardToServer); } ConCommand* g_pConCommand = new ConCommand(); diff --git a/r5dev/tier1/cmd.h b/r5dev/tier1/cmd.h index dde9e316..c0041ae8 100644 --- a/r5dev/tier1/cmd.h +++ b/r5dev/tier1/cmd.h @@ -164,6 +164,9 @@ inline auto Cbuf_AddText = p_Cbuf_AddText.RCast(); +inline CMemory p_Cmd_ForwardToServer; +inline auto v_Cmd_ForwardToServer = p_Cmd_ForwardToServer.RCast(); + /* ==== CONCOMMAND ====================================================================================================================================================== */ inline CMemory p_ConCommandBase_IsFlagSet; inline auto ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet.RCast(); @@ -191,6 +194,7 @@ class VConCommand : public IDetour { spdlog::debug("| FUN: Cbuf_AddText : {:#18x} |\n", p_Cbuf_AddText.GetPtr()); spdlog::debug("| FUN: Cbuf_Execute : {:#18x} |\n", p_Cbuf_Execute.GetPtr()); + spdlog::debug("| FUN: Cmd_ForwardToServer : {:#18x} |\n", p_Cmd_ForwardToServer.GetPtr()); spdlog::debug("+----------------------------------------------------------------+\n"); spdlog::debug("| FUN: ConCommandBase::IsFlagSet : {:#18x} |\n", p_ConCommandBase_IsFlagSet.GetPtr()); spdlog::debug("+----------------------------------------------------------------+\n"); @@ -204,12 +208,14 @@ class VConCommand : public IDetour { p_Cbuf_AddText = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x63\xD9\x41\x8B\xF8\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\xF2\xFF\x15\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\x41\xB9\x00\x00\x00\x00"), "xxxx?xxxx?xxxxxxxxxxxxxx????xxxxx????xxx????xx????"); p_Cbuf_Execute = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\xFF\x15\x00\x00\x00\x00"), "xxxx?xxxx?xxxx?xxxxxxx????"); + p_Cmd_ForwardToServer = g_GameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x44\x8B\x59\x04"), "xxxx?xxxx?xxxx?xxxx????xxxx"); p_ConCommandBase_IsFlagSet = g_GameDll.FindPatternSIMD(reinterpret_cast("\x85\x51\x38\x0F\x95\xC0\xC3"), "xxxxxxx"); p_NullSub = g_GameDll.FindPatternSIMD(reinterpret_cast("\xC2\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00"), "xxxxxxxxxxxxxxxxxxxxxxxxx????"); p_CallbackStub = g_GameDll.FindPatternSIMD(reinterpret_cast("\x33\xC0\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x80\x49\x68\x08"), "xxxxxxxxxxxxxxxxxxxx"); Cbuf_AddText = p_Cbuf_AddText.RCast(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??*/ Cbuf_Execute = p_Cbuf_Execute.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??*/ + v_Cmd_ForwardToServer = p_Cmd_ForwardToServer.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04*/ ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet.RCast(); /*85 51 38 0F 95 C0 C3*/ NullSub = p_NullSub.RCast(); /*C2 00 00 CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/ CallbackStub = p_CallbackStub.RCast(); /*33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08*/ /*UserMathErrorFunction*/ diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index 9a0a19f2..9c69c43a 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -14,6 +14,8 @@ ConVar* old_gather_props = nullptr; ConVar* enable_debug_overlays = nullptr; ConVar* cm_unset_all_cmdquery = nullptr; +ConVar* developer = nullptr; + ConVar* staticProp_defaultBuildFrustum = nullptr; ConVar* staticProp_no_fade_scalar = nullptr; ConVar* staticProp_gather_size_weight = nullptr; @@ -63,11 +65,13 @@ ConVar* navmesh_draw_poly_bounds_inner = nullptr; ConVar* sv_showconnecting = nullptr; ConVar* sv_pylonVisibility = nullptr; -ConVar* sv_pylonRefreshInterval = nullptr; -ConVar* sv_banlistRefreshInterval = nullptr; -ConVar* sv_statusRefreshInterval = nullptr; +ConVar* sv_pylonRefreshRate = nullptr; +ConVar* sv_banlistRefreshRate = nullptr; +ConVar* sv_statusRefreshRate = nullptr; +ConVar* sv_forceChatToTeamOnly = nullptr; ConVar* sv_autoReloadRate = nullptr; +ConVar* sv_quota_stringCmdsPerSecond = nullptr; #ifdef DEDICATED ConVar* sv_rcon_debug = nullptr; @@ -89,6 +93,7 @@ ConVar* bhit_abs_origin = nullptr; // CLIENT | #ifndef DEDICATED ConVar* cl_rcon_request_sendlogs = nullptr; +ConVar* cl_quota_stringCmdsPerSecond = nullptr; ConVar* cl_showhoststats = nullptr; ConVar* cl_hoststats_invert_x = nullptr; @@ -171,6 +176,8 @@ ConVar* net_tracePayload = nullptr; ConVar* net_encryptionEnable = nullptr; ConVar* net_useRandomKey = nullptr; ConVar* net_usesocketsforloopback = nullptr; +ConVar* net_processTimeBudget = nullptr; + ConVar* pylon_matchmaking_hostname = nullptr; ConVar* pylon_host_update_interval = nullptr; ConVar* pylon_showdebuginfo = nullptr; diff --git a/r5dev/tier1/cvar.h b/r5dev/tier1/cvar.h index f585a45f..83a34c31 100644 --- a/r5dev/tier1/cvar.h +++ b/r5dev/tier1/cvar.h @@ -10,6 +10,8 @@ extern ConVar* old_gather_props; extern ConVar* enable_debug_overlays; extern ConVar* cm_unset_all_cmdquery; +extern ConVar* developer; + extern ConVar* staticProp_defaultBuildFrustum; extern ConVar* staticProp_no_fade_scalar; extern ConVar* staticProp_gather_size_weight; @@ -59,11 +61,13 @@ extern ConVar* navmesh_draw_poly_bounds_inner; #endif // DEDICATED extern ConVar* sv_showconnecting; extern ConVar* sv_pylonVisibility; -extern ConVar* sv_pylonRefreshInterval; -extern ConVar* sv_banlistRefreshInterval; -extern ConVar* sv_statusRefreshInterval; +extern ConVar* sv_pylonRefreshRate; +extern ConVar* sv_banlistRefreshRate; +extern ConVar* sv_statusRefreshRate; +extern ConVar* sv_forceChatToTeamOnly; extern ConVar* sv_autoReloadRate; +extern ConVar* sv_quota_stringCmdsPerSecond; #ifdef DEDICATED extern ConVar* sv_rcon_debug; @@ -84,6 +88,7 @@ extern ConVar* bhit_abs_origin; // CLIENT | #ifndef DEDICATED extern ConVar* cl_rcon_request_sendlogs; +extern ConVar* cl_quota_stringCmdsPerSecond; extern ConVar* cl_showhoststats; extern ConVar* cl_hoststats_invert_x; @@ -166,6 +171,8 @@ extern ConVar* net_tracePayload; extern ConVar* net_encryptionEnable; extern ConVar* net_useRandomKey; extern ConVar* net_usesocketsforloopback; +extern ConVar* net_processTimeBudget; + extern ConVar* pylon_matchmaking_hostname; extern ConVar* pylon_host_update_interval; extern ConVar* pylon_showdebuginfo; diff --git a/r5dev/vgui/vgui_debugpanel.cpp b/r5dev/vgui/vgui_debugpanel.cpp index a36bfb0c..12604ffa 100644 --- a/r5dev/vgui/vgui_debugpanel.cpp +++ b/r5dev/vgui/vgui_debugpanel.cpp @@ -112,9 +112,9 @@ void CLogSystem::DrawNotify(void) float flTimeleft = pNotify->m_flLifeRemaining; - if (flTimeleft < .5f) + if (flTimeleft < 1.0f) { - float f = clamp(flTimeleft, 0.0f, .5f) / .5f; + float f = clamp(flTimeleft, 0.0f, 1.0f) / 1.0f; c[3] = (int)(f * 255.0f); if (i == 0 && f < 0.2f) diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj index f12fd9e6..4d3d1c2d 100644 --- a/r5dev/vproj/clientsdk.vcxproj +++ b/r5dev/vproj/clientsdk.vcxproj @@ -29,6 +29,7 @@ + @@ -170,6 +171,7 @@ + diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters index 77a060f1..607c2890 100644 --- a/r5dev/vproj/clientsdk.vcxproj.filters +++ b/r5dev/vproj/clientsdk.vcxproj.filters @@ -594,6 +594,9 @@ sdk\engine + + sdk\engine\client + @@ -1754,6 +1757,9 @@ sdk\engine + + sdk\engine\client + diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index 21a1ee84..d77e2633 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -29,6 +29,7 @@ + @@ -180,6 +181,7 @@ + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index 2bc16ec9..b678ae2c 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -633,6 +633,9 @@ sdk\engine + + sdk\engine\client + @@ -1841,6 +1844,9 @@ sdk\engine + + sdk\engine\client + diff --git a/r5dev/vstdlib/callback.cpp b/r5dev/vstdlib/callback.cpp index 3464aee1..2515ca7e 100644 --- a/r5dev/vstdlib/callback.cpp +++ b/r5dev/vstdlib/callback.cpp @@ -649,7 +649,7 @@ void RCON_CmdQuery_f(const CCommand& args) { if (!RCONClient()->IsInitialized()) { - Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: uninitialized\n"); + Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "uninitialized"); return; } else if (RCONClient()->IsConnected()) @@ -680,7 +680,7 @@ void RCON_CmdQuery_f(const CCommand& args) } else { - Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: unconnected\n"); + Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "unconnected"); return; } }