diff --git a/license/thirdpartylegalnotices.txt b/license/thirdpartylegalnotices.txt index 3f00d2c7..f4cd422e 100644 --- a/license/thirdpartylegalnotices.txt +++ b/license/thirdpartylegalnotices.txt @@ -70,29 +70,6 @@ NVIDIA NvAPI // the above Disclaimer (as applicable) and U.S. Government End Users Notice. //////////////////////////////////////////////////////////////////////////// -************************************************************************************ -Recast & Detour -************************************************************************************ - - // Copyright (c) 2009 Mikko Mononen memon@inside.org - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - //////////////////////////////////////////////////////////////////////////// - ************************************************************************************ Google protocol buffers ************************************************************************************ @@ -131,6 +108,29 @@ Google protocol buffers // support library is itself covered by the above license. //////////////////////////////////////////////////////////////////////////// +************************************************************************************ +Recast & Detour +************************************************************************************ + + // Copyright (c) 2009 Mikko Mononen memon@inside.org + // + // This software is provided 'as-is', without any express or implied + // warranty. In no event will the authors be held liable for any damages + // arising from the use of this software. + // + // Permission is granted to anyone to use this software for any purpose, + // including commercial applications, and to alter it and redistribute it + // freely, subject to the following restrictions: + // + // 1. The origin of this software must not be misrepresented; you must not + // claim that you wrote the original software. If you use this software + // in a product, an acknowledgment in the product documentation would be + // appreciated but is not required. + // 2. Altered source versions must be plainly marked as such, and must not be + // misrepresented as being the original software. + // 3. This notice may not be removed or altered from any source distribution. + //////////////////////////////////////////////////////////////////////////// + ************************************************************************************ Dear ImGui ************************************************************************************ @@ -299,33 +299,6 @@ Format {fmt} // without including the above copyright and permission notices. //////////////////////////////////////////////////////////////////////////// -************************************************************************************ -VDF Parser -************************************************************************************ - - // The MIT License (MIT) - // - // Copyright (c) Matthias Moeller 2016 m_moeller@live.de - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in all - // copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - // SOFTWARE. - //////////////////////////////////////////////////////////////////////////// - ************************************************************************************ RapidJSON ************************************************************************************ @@ -642,7 +615,7 @@ EAThread (EA WebKit) // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //-------------------------------------------------------------------------- - // + // // Additional licenses also apply to this software package as detailed below. // //-------------------------------------------------------------------------- @@ -788,6 +761,7 @@ LZHAM // THE SOFTWARE. //////////////////////////////////////////////////////////////////////////// + ************************************************************************************ CRC32 ************************************************************************************ diff --git a/r5dev/codecs/CMakeLists.txt b/r5dev/codecs/CMakeLists.txt index 6cbfc8ca..11824776 100644 --- a/r5dev/codecs/CMakeLists.txt +++ b/r5dev/codecs/CMakeLists.txt @@ -11,6 +11,8 @@ add_sources( SOURCE_GROUP "Bink" add_sources( SOURCE_GROUP "Miles" "miles/miles_impl.cpp" "miles/miles_impl.h" + "miles/miles_shim.cpp" + "miles/miles_shim.h" "miles/miles_types.h" # TODO[ AMOS ]: move to public! "miles/radshal_wasapi.h" ) diff --git a/r5dev/codecs/Miles/miles_impl.cpp b/r5dev/codecs/Miles/miles_impl.cpp index 9de48fa9..01d90704 100644 --- a/r5dev/codecs/Miles/miles_impl.cpp +++ b/r5dev/codecs/Miles/miles_impl.cpp @@ -1,11 +1,13 @@ #include "core/stdafx.h" -#include "miles_impl.h" #include "tier0/fasttimer.h" #include "tier0/commandline.h" #include "tier1/cvar.h" #include "filesystem/filesystem.h" +#include "ebisusdk/EbisuSDK.h" +#include "miles_impl.h" -static ConVar miles_debug("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System", "1 = print; 0 (zero) = no print"); +static ConVar miles_debug("miles_debug", "0", FCVAR_DEVELOPMENTONLY, "Enables debug prints for the Miles Sound System", "1 = print; 0 (zero) = no print"); +static ConVar miles_warnings("miles_warnings", "0", FCVAR_RELEASE, "Enables warning prints for the Miles Sound System", "1 = print; 0 (zero) = no print"); //----------------------------------------------------------------------------- // Purpose: logs debug output emitted from the Miles Sound System @@ -24,23 +26,21 @@ void AIL_LogFunc(int64_t nLogLevel, const char* pszMessage) //----------------------------------------------------------------------------- bool Miles_Initialize() { - const char* pszLanguage = miles_language->GetString(); - if (!pszLanguage[0]) - pszLanguage = MILES_DEFAULT_LANGUAGE; + const char* pszLanguage = HEbisuSDK_GetLanguage(); + const bool isDefaultLanguage = _stricmp(pszLanguage, MILES_DEFAULT_LANGUAGE) == 0; - const bool isEnglishLanguage = _stricmp(pszLanguage, "english") == 0; - - if (!isEnglishLanguage) + if (!isDefaultLanguage) { const bool useShipSound = !CommandLine()->FindParm("-devsound") || CommandLine()->FindParm("-shipsound"); const std::string baseStreamFilePath = Format("%s/general_%s.mstr", useShipSound ? "audio/ship" : "audio/dev", pszLanguage); - // if the requested language for miles does not have a MSTR file present, throw a non-fatal error and force english as a fallback - // if we are loading english and the file is still not found, we can let it hit the regular engine error, since that is not recoverable + // if the requested language for miles does not have a MSTR file present, throw a non-fatal error and force MILES_DEFAULT_LANGUAGE as a fallback + // if we are loading MILES_DEFAULT_LANGUAGE and the file is still not found, we can let it hit the regular engine error, since that is not recoverable if (!FileSystem()->FileExists(baseStreamFilePath.c_str())) { - Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required streaming source file (%s) was not found. falling back to english...\n", __FUNCTION__, pszLanguage, baseStreamFilePath.c_str()); + Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required streaming source file (%s) was not found. falling back to '%s'...\n", + __FUNCTION__, pszLanguage, baseStreamFilePath.c_str(), MILES_DEFAULT_LANGUAGE); pszLanguage = MILES_DEFAULT_LANGUAGE; miles_language->SetValue(pszLanguage); @@ -82,7 +82,7 @@ void MilesBankPatch(Miles::Bank* bank, char* streamPatch, char* localizedStreamP if (header->bankIndex >= header->project->bankCount) Error(eDLL_T::AUDIO, EXIT_FAILURE, - "%s: Attempted to patch bank '%s' that identified itself as bank idx %i.\nProject expects a highest index of %i\n", + "%s: attempted to patch bank \"%s\" that identified itself as bank #%i, project expects a highest index of #%i\n", __FUNCTION__, bank->GetBankName(), header->bankIndex, @@ -99,11 +99,14 @@ void CSOM_AddEventToQueue(const char* eventName) v_CSOM_AddEventToQueue(eventName); - if (g_milesGlobals->queuedEventHash == 1) - Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName); + if (miles_warnings.GetBool()) + { + if (g_milesGlobals->queuedEventHash == 1) + Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName); - if (g_milesGlobals->queuedEventHash == 2) - Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName); + if (g_milesGlobals->queuedEventHash == 2) + Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName); + } }; diff --git a/r5dev/codecs/Miles/miles_impl.h b/r5dev/codecs/Miles/miles_impl.h index 74c4483c..e3ff048b 100644 --- a/r5dev/codecs/Miles/miles_impl.h +++ b/r5dev/codecs/Miles/miles_impl.h @@ -6,6 +6,7 @@ inline void(*v_AIL_LogFunc)(int64_t nLogLevel, const char* pszMessage); inline bool(*v_Miles_Initialize)(); inline void(*v_MilesQueueEventRun)(Miles::Queue*, const char*); inline void(*v_MilesBankPatch)(Miles::Bank*, char*, char*); +inline unsigned int (*v_MilesSampleSetSourceRaw)(__int64 a1, __int64 a2, unsigned int a3, int a4, unsigned __int16 a5, bool a6); inline void(*v_CSOM_AddEventToQueue)(const char* eventName); struct MilesBankList_t @@ -54,6 +55,7 @@ class MilesCore : public IDetour LogFunAdr("Miles_Initialize", v_Miles_Initialize); LogFunAdr("MilesQueueEventRun", v_MilesQueueEventRun); LogFunAdr("MilesBankPatch", v_MilesBankPatch); + LogFunAdr("MilesSampleSetSourceRaw", v_MilesSampleSetSourceRaw); LogFunAdr("CSOM_AddEventToQueue", v_CSOM_AddEventToQueue); LogVarAdr("g_milesGlobals", g_milesGlobals); } @@ -69,6 +71,7 @@ class MilesCore : public IDetour g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun").GetPtr(v_MilesQueueEventRun); g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch").GetPtr(v_MilesBankPatch); + g_RadAudioSystemDll.GetExportedSymbol("MilesSampleSetSourceRaw").GetPtr(v_MilesSampleSetSourceRaw); } virtual void GetVar(void) const { } virtual void GetCon(void) const { } diff --git a/r5dev/codecs/Miles/miles_types.h b/r5dev/codecs/Miles/miles_types.h index 3ac735e1..ade5ee64 100644 --- a/r5dev/codecs/Miles/miles_types.h +++ b/r5dev/codecs/Miles/miles_types.h @@ -31,7 +31,7 @@ namespace Miles // internal project data structure struct IntProjectData_t { - char gap0[0xCF0]; + char gap0[0xE28]; int bankCount; BankHeader_t** loadedBanks; }; diff --git a/r5dev/codecs/miles/miles_shim.cpp b/r5dev/codecs/miles/miles_shim.cpp new file mode 100644 index 00000000..8f794f77 --- /dev/null +++ b/r5dev/codecs/miles/miles_shim.cpp @@ -0,0 +1,27 @@ +//=============================================================================// +// +// Purpose: Miles Sound System interface shim +// +//----------------------------------------------------------------------------- +// The engine is compiled with version 10.0.42, this shim layer fixes any +// incompatibilities between upgrades. On more recent versions of the Miles +// Sound System, some exports have been renamed and/or thoroughly changed. +// If we upgrade to these versions, we need to convert this into an actual +// DLL shim layer instead of linking it statically with the SDK module. +//=============================================================================// +#include "miles_impl.h" +#include "miles_shim.h" + +unsigned int MilesSampleSetSourceRaw(__int64 a1, __int64 a2, unsigned int a3, int a4, unsigned __int16 a5, bool a6) +{ + // interface fix from 10.0.42 --> 10.0.47. As of version (10.0.43 ?) the + // export 'MilesSampleSetSourceRaw' has a newly added bool parameter. The + // purpose of this is unknown, but we need to set it to false as they + // otherwise would distort the voice comm bus. + return v_MilesSampleSetSourceRaw(a1, a2, a3, a4, a5, false); +} + +void MilesShim::Detour(const bool bAttach) const +{ + DetourSetup(&v_MilesSampleSetSourceRaw, &MilesSampleSetSourceRaw, bAttach); +} diff --git a/r5dev/codecs/miles/miles_shim.h b/r5dev/codecs/miles/miles_shim.h new file mode 100644 index 00000000..1e475895 --- /dev/null +++ b/r5dev/codecs/miles/miles_shim.h @@ -0,0 +1,13 @@ +#ifndef MILES_SHIM_H +#define MILES_SHIM_H + +class MilesShim : public IDetour +{ + virtual void GetAdr(void) const { } + virtual void GetFun(void) const { } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Detour(const bool bAttach) const; +}; + +#endif // MILES_SHIM_H diff --git a/r5dev/common/callback.cpp b/r5dev/common/callback.cpp index 8ea1e366..f98f42ed 100644 --- a/r5dev/common/callback.cpp +++ b/r5dev/common/callback.cpp @@ -10,6 +10,7 @@ #include "tier0/fasttimer.h" #include "tier1/cvar.h" #include "tier1/fmtstr.h" +#include "engine/shared/shared_rcon.h" #ifndef CLIENT_DLL #include "engine/server/sv_rcon.h" #endif // !CLIENT_DLL @@ -227,33 +228,6 @@ void VPK_Unmount_f(const CCommand& args) FileSystem()->UnmountVPKFile(args.Arg(1)); } -/* -===================== -NET_UseSocketsForLoopbackChanged_f - - Use random AES encryption - key for game packets -===================== -*/ -void NET_UseSocketsForLoopbackChanged_f(IConVar* pConVar, const char* pOldString) -{ - if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) - { - if (strcmp(pOldString, pConVarRef->GetString()) == NULL) - return; // Same value. - -#ifndef CLIENT_DLL - // Reboot the RCON server to switch address type. - if (RCONServer()->IsInitialized()) - { - Msg(eDLL_T::SERVER, "Rebooting RCON server...\n"); - RCONServer()->Shutdown(); - RCONServer()->Init(); - } -#endif // !CLIENT_DLL - } -} - void LanguageChanged_f(IConVar* pConVar, const char* pOldString) { if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) diff --git a/r5dev/common/callback.h b/r5dev/common/callback.h index 07426375..47a48858 100644 --- a/r5dev/common/callback.h +++ b/r5dev/common/callback.h @@ -14,7 +14,6 @@ void VPK_Pack_f(const CCommand& args); void VPK_Unpack_f(const CCommand& args); void VPK_Mount_f(const CCommand& args); void VPK_Unmount_f(const CCommand& args); -void NET_UseSocketsForLoopbackChanged_f(IConVar* pConVar, const char* pOldString); #ifndef DEDICATED void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString); diff --git a/r5dev/common/global.cpp b/r5dev/common/global.cpp index d18725d6..0323a17d 100644 --- a/r5dev/common/global.cpp +++ b/r5dev/common/global.cpp @@ -63,6 +63,14 @@ ConVar* eula_version_accepted = nullptr; ConVar* language_cvar = nullptr; +ConVar* voice_noxplat = nullptr; + +ConVar* platform_user_id = nullptr; + +#ifndef DEDICATED +ConVar* name_cvar = nullptr; +#endif // !DEDICATED + //----------------------------------------------------------------------------- // SERVER | #ifndef CLIENT_DLL @@ -72,8 +80,9 @@ ConVar* sv_forceChatToTeamOnly = nullptr; ConVar* sv_single_core_dedi = nullptr; -ConVar* sv_maxunlag = nullptr; -ConVar* sv_clockcorrection_msecs = nullptr; +ConVar* sv_maxunlag = nullptr; +ConVar* sv_lagpushticks = nullptr; +ConVar* sv_clockcorrection_msecs = nullptr; ConVar* sv_updaterate_sp = nullptr; ConVar* sv_updaterate_mp = nullptr; @@ -85,7 +94,13 @@ ConVar* sv_voiceEcho = nullptr; ConVar* sv_voiceenable = nullptr; ConVar* sv_alltalk = nullptr; +ConVar* sv_clampPlayerFrameTime = nullptr; + +ConVar* playerframetimekick_margin = nullptr; +ConVar* playerframetimekick_decayrate = nullptr; + ConVar* player_userCmdsQueueWarning = nullptr; +ConVar* player_disallow_negative_frametime = nullptr; #endif // !CLIENT_DLL ConVar* sv_cheats = nullptr; @@ -145,8 +160,11 @@ void ConVar_InitShipped(void) eula_version = g_pCVar->FindVar("eula_version"); eula_version_accepted = g_pCVar->FindVar("eula_version_accepted"); - language_cvar = g_pCVar->FindVar("language"); + language_cvar = g_pCVar->FindVar("language"); + voice_noxplat = g_pCVar->FindVar("voice_noxplat"); + platform_user_id = g_pCVar->FindVar("platform_user_id"); #ifndef DEDICATED + name_cvar = g_pCVar->FindVar("name"); cl_updaterate_mp = g_pCVar->FindVar("cl_updaterate_mp"); cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup"); #endif // !DEDICATED @@ -195,6 +213,7 @@ void ConVar_InitShipped(void) sv_stats = g_pCVar->FindVar("sv_stats"); sv_maxunlag = g_pCVar->FindVar("sv_maxunlag"); + sv_lagpushticks = g_pCVar->FindVar("sv_lagpushticks"); sv_clockcorrection_msecs = g_pCVar->FindVar("sv_clockcorrection_msecs"); sv_updaterate_sp = g_pCVar->FindVar("sv_updaterate_sp"); @@ -208,7 +227,14 @@ void ConVar_InitShipped(void) sv_voiceenable = g_pCVar->FindVar("sv_voiceenable"); sv_voiceEcho = g_pCVar->FindVar("sv_voiceEcho"); sv_alltalk = g_pCVar->FindVar("sv_alltalk"); + + sv_clampPlayerFrameTime = g_pCVar->FindVar("sv_clampPlayerFrameTime"); + + playerframetimekick_margin = g_pCVar->FindVar("playerframetimekick_margin"); + playerframetimekick_decayrate = g_pCVar->FindVar("playerframetimekick_decayrate"); + player_userCmdsQueueWarning = g_pCVar->FindVar("player_userCmdsQueueWarning"); + player_disallow_negative_frametime = g_pCVar->FindVar("player_disallow_negative_frametime"); sv_updaterate_sp->RemoveFlags(FCVAR_DEVELOPMENTONLY); sv_updaterate_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY); @@ -232,6 +258,7 @@ void ConVar_InitShipped(void) origin_disconnectWhenOffline->RemoveFlags(FCVAR_DEVELOPMENTONLY); discord_updatePresence->RemoveFlags(FCVAR_DEVELOPMENTONLY); #endif // !DEDICATED + fps_max->AddFlags(FCVAR_ARCHIVE); fps_max_vsync->RemoveFlags(FCVAR_DEVELOPMENTONLY); base_tickinterval_sp->RemoveFlags(FCVAR_DEVELOPMENTONLY); @@ -241,7 +268,6 @@ void ConVar_InitShipped(void) mp_gamemode->RemoveChangeCallback(mp_gamemode->m_fnChangeCallbacks[0]); mp_gamemode->InstallChangeCallback(MP_GameMode_Changed_f, false); net_usesocketsforloopback->RemoveFlags(FCVAR_DEVELOPMENTONLY); - net_usesocketsforloopback->InstallChangeCallback(NET_UseSocketsForLoopbackChanged_f, false); #ifndef DEDICATED language_cvar->InstallChangeCallback(LanguageChanged_f, false); #endif // !DEDICATED @@ -377,7 +403,6 @@ void ConCommand_InitShipped(void) "connectAsSpectator", "connectWithKey", "silentconnect", - "set", "ping", #endif // !DEDICATED "launchplaylist", @@ -385,6 +410,7 @@ void ConCommand_InitShipped(void) "exit", "reload", "restart", + "set", "status", "version", }; diff --git a/r5dev/common/global.h b/r5dev/common/global.h index e958199b..5df2c062 100644 --- a/r5dev/common/global.h +++ b/r5dev/common/global.h @@ -50,6 +50,14 @@ extern ConVar* eula_version_accepted; extern ConVar* language_cvar; +extern ConVar* voice_noxplat; + +extern ConVar* platform_user_id; + +#ifndef DEDICATED +extern ConVar* name_cvar; +#endif // !DEDICATED + //------------------------------------------------------------------------- // SERVER | #ifndef CLIENT_DLL @@ -60,6 +68,7 @@ extern ConVar* sv_forceChatToTeamOnly; extern ConVar* sv_single_core_dedi; extern ConVar* sv_maxunlag; +extern ConVar* sv_lagpushticks; extern ConVar* sv_clockcorrection_msecs; extern ConVar* sv_updaterate_sp; @@ -72,7 +81,13 @@ extern ConVar* sv_voiceEcho; extern ConVar* sv_voiceenable; extern ConVar* sv_alltalk; +extern ConVar* sv_clampPlayerFrameTime; + +extern ConVar* playerframetimekick_margin; +extern ConVar* playerframetimekick_decayrate; + extern ConVar* player_userCmdsQueueWarning; +extern ConVar* player_disallow_negative_frametime; #endif // CLIENT_DLL extern ConVar* sv_cheats; diff --git a/r5dev/common/netmessages.h b/r5dev/common/netmessages.h index e94ed440..9bfa31d0 100644 --- a/r5dev/common/netmessages.h +++ b/r5dev/common/netmessages.h @@ -372,6 +372,70 @@ public: void* m_DataOut; }; +struct SVC_DurangoVoiceData : public CNetMessage +{ +public: + SVC_DurangoVoiceData() = default; + SVC_DurangoVoiceData(int senderClient, int nBytes, char* data, int unknown, bool useUnreliableStream) + { + void** pVFTable = reinterpret_cast(this); + *pVFTable = g_pSVC_VoiceData_VFTable; + + m_bReliable = false; + m_NetChannel = nullptr; + + m_nFromClient = senderClient; + m_nLength = nBytes; // length in bits + + m_unknown = unknown; + m_useVoiceStream = useUnreliableStream; + + m_DataOut = data; + + m_nGroup = 2; // must be set to 2 to avoid being copied into replay buffer + }; + + virtual ~SVC_DurangoVoiceData() {}; + + virtual void SetNetChannel(CNetChan* netchan) { m_NetChannel = netchan; } + virtual void SetReliable(bool state) { m_bReliable = state; }; + + virtual bool Process(void) + { + return CallVFunc(NetMessageVtbl::Process, this); + }; + virtual bool ReadFromBuffer(bf_read* buffer) + { + return CallVFunc(NetMessageVtbl::ReadFromBuffer, this, buffer); + } + virtual bool WriteToBuffer(bf_write* buffer) + { + return CallVFunc(NetMessageVtbl::WriteToBuffer, this, buffer); + } + + virtual bool IsReliable(void) const { return m_bReliable; }; + + virtual int GetGroup(void) const { return m_nGroup; }; + virtual int GetType(void) const { return NetMessageType::svc_DurangoVoiceData; }; + virtual const char* GetName(void) const { return "svc_DurangoVoiceData"; }; + virtual CNetChan* GetNetChannel(void) const { return m_NetChannel; }; + virtual const char* ToString(void) const + { + static char szBuf[4096]; + V_snprintf(szBuf, sizeof(szBuf), "%s: client %i, bytes %i", this->GetName(), m_nFromClient, ((m_nLength + 7) >> 3)); + + return szBuf; + }; + virtual size_t GetSize(void) const { return sizeof(SVC_DurangoVoiceData); }; + + int m_nFromClient; + int m_nLength; + int m_unknown; + bool m_useVoiceStream; + bf_read m_DataIn; + void* m_DataOut; +}; + class SVC_PlaylistOverrides : public CNetMessage { private: @@ -385,6 +449,29 @@ private: // Client messages: /////////////////////////////////////////////////////////////////////////////////////// +class CLC_VoiceData : public CNetMessage +{ +public: + int m_nLength; + bf_read m_DataIn; + bf_write m_DataOut; + int unk1; + int unk2; +}; + +class CLC_DurangoVoiceData : public CNetMessage +{ +public: + int m_nLength; + bf_read m_DataIn; + bf_write m_DataOut; + bool m_skipXidCheck; + bool m_useVoiceStream; + int m_xid; + int m_unknown; +}; + + class CLC_ClientTick : public CNetMessage { public: diff --git a/r5dev/core/CMakeLists.txt b/r5dev/core/CMakeLists.txt index d8f575bf..088125d1 100644 --- a/r5dev/core/CMakeLists.txt +++ b/r5dev/core/CMakeLists.txt @@ -59,8 +59,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE "SigCache_Pb" "LiveAPI_Pb" - "SV_RCon_Pb" - "CL_RCon_Pb" + "NetCon_Pb" "rson" "rtech_game" @@ -81,6 +80,10 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE "EAThread" "DirtySDK" + "libmbedcrypto" + "libmbedtls" + "libmbedx509" + "networksystem" "pluginsystem" "filesystem" @@ -115,9 +118,6 @@ endif() if( NOT ${PROJECT_NAME} STREQUAL "client" ) target_link_libraries( ${PROJECT_NAME} PRIVATE - "libmbedcrypto" - "libmbedtls" - "libmbedx509" "libjwt" ) endif() diff --git a/r5dev/core/dllmain.cpp b/r5dev/core/dllmain.cpp index 5415390a..819030ac 100644 --- a/r5dev/core/dllmain.cpp +++ b/r5dev/core/dllmain.cpp @@ -30,7 +30,9 @@ bool g_bSdkInitCallInitiated = false; bool g_bSdkShutdownCallInitiated = false; bool g_bSdkShutdownInitiatedFromConsoleHandler = false; -HMODULE s_hModuleHandle = NULL; + +static bool s_bConsoleInitialized = false; +static HMODULE s_hModuleHandle = NULL; //############################################################################# // UTILITY @@ -116,9 +118,11 @@ void SDK_Init() #ifndef DEDICATED if (CommandLine()->CheckParm("-wconsole")) -#endif // !DEDICATED +#else + if (!CommandLine()->CheckParm("-noconsole")) +#endif // !DEDICATED { - Console_Init(bAnsiColor); + s_bConsoleInitialized = Console_Init(bAnsiColor); } SpdLog_Init(bAnsiColor); @@ -186,7 +190,7 @@ void SDK_Shutdown() // If the shutdown was initiated from the console window itself, don't // shutdown the console as it would otherwise deadlock in FreeConsole! - if (!g_bSdkShutdownInitiatedFromConsoleHandler) + if (s_bConsoleInitialized && !g_bSdkShutdownInitiatedFromConsoleHandler) Console_Shutdown(); g_bSdkInitialized = false; diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 3677676d..1c7fbb50 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -35,6 +35,7 @@ #ifndef DEDICATED #include "codecs/bink/bink_impl.h" #include "codecs/miles/miles_impl.h" +#include "codecs/miles/miles_shim.h" #include "codecs/miles/radshal_wasapi.h" #endif // !DEDICATED #include "vphysics/physics_collide.h" @@ -135,6 +136,8 @@ #include "game/server/detour_impl.h" #include "game/server/gameinterface.h" #include "game/server/movehelper_server.h" +#include "game/server/player.h" +#include "game/server/player_command.h" #include "game/server/physics_main.h" #include "game/server/vscript_server.h" #endif // !CLIENT_DLL @@ -523,6 +526,7 @@ void DetourRegister() // Register detour classes to be searched and hooked. // Codecs REGISTER(BinkCore); // REGISTER CLIENT ONLY! REGISTER(MilesCore); // REGISTER CLIENT ONLY! + REGISTER(MilesShim); REGISTER(VRadShal); #endif // !DEDICATED @@ -663,6 +667,7 @@ void DetourRegister() // Register detour classes to be searched and hooked. REGISTER(VBaseEntity); REGISTER(VBaseAnimating); REGISTER(VPlayer); + REGISTER(VPlayerMove); #endif // !CLIENT_DLL diff --git a/r5dev/core/logger.cpp b/r5dev/core/logger.cpp index ebc1ba08..867f774b 100644 --- a/r5dev/core/logger.cpp +++ b/r5dev/core/logger.cpp @@ -284,9 +284,9 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context, if (bToConsole) { #ifndef CLIENT_DLL - if (!LoggedFromClient(context) && RCONServer()->ShouldSend(sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG)) + if (!LoggedFromClient(context) && RCONServer()->ShouldSend(netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG)) { - RCONServer()->SendEncode(formatted.c_str(), pszUpTime, sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, + RCONServer()->SendEncoded(formatted.c_str(), pszUpTime, netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG, int(context), int(logType)); } #endif // !CLIENT_DLL diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index 407fa68a..b1b45b2a 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -176,7 +176,7 @@ struct studioanimcache_t const char* rigName; int unk0; int numSequences; - PakPage_t sequences; + PakPage_u sequences; int unk1; int unk2; }; diff --git a/r5dev/ebisusdk/EbisuSDK.cpp b/r5dev/ebisusdk/EbisuSDK.cpp index a87115a5..1487a250 100644 --- a/r5dev/ebisusdk/EbisuSDK.cpp +++ b/r5dev/ebisusdk/EbisuSDK.cpp @@ -1,20 +1,96 @@ #include "core/stdafx.h" +#include "tier0/commandline.h" #include "ebisusdk/EbisuSDK.h" #include "engine/server/sv_main.h" //----------------------------------------------------------------------------- -// Purpose: sets the EbisuSDK globals for dedicated to satisfy command callbacks +// Purpose: initialize the EbisuSDK //----------------------------------------------------------------------------- void HEbisuSDK_Init() { - if (IsDedicated()) + const bool isDedicated = IsDedicated(); + const bool noOrigin = IsOriginDisabled(); + + // Fill with default data if this is a dedicated server, or if the game was + // launched with the platform system disabled. Engine code requires these + // to be set for the game to function, else stuff like the "map" command + // won't run as 'IsOriginInitialized()' returns false (which got inlined in + // every place this was called in the game's executable). + if (isDedicated || noOrigin) { - *g_EbisuSDKInit = true; // <- 1st EbisuSDK - *g_EbisuProfileInit = true; // <- 2nd EbisuSDK - *g_NucleusID = 9990000; // <- 3rd EbisuSDK + *g_EbisuSDKInit = true; + *g_EbisuProfileInit = true; + *g_NucleusID = FAKE_BASE_NUCLEUD_ID; + + Q_snprintf(g_OriginAuthCode, 256, "%s", "INVALID_OAUTH_CODE"); + Q_snprintf(g_NucleusToken, 1024, "%s", "INVALID_NUCLEUS_TOKEN"); + + if (!isDedicated) + { + platform_user_id->SetValue(FAKE_BASE_NUCLEUD_ID); + } } } +//----------------------------------------------------------------------------- +// Purpose: runs the EbisuSDK state machine +//----------------------------------------------------------------------------- +void HEbisuSDK_RunFrame() +{ + if (IsOriginDisabled()) + { + return; + } + + EbisuSDK_RunFrame(); +} + +//----------------------------------------------------------------------------- +// Purpose: returns the currently set language +//----------------------------------------------------------------------------- +const char* HEbisuSDK_GetLanguage() +{ + static bool initialized = false; + static char languageName[32]; + + if (initialized) + { + return languageName; + } + + const char* value = nullptr; + bool useDefault = true; + + if (CommandLine()->CheckParm("-language", &value)) + { + if (V_LocaleNameExists(value)) + { + strncpy(languageName, value, sizeof(languageName)); + useDefault = false; + } + } + + if (useDefault) + { + strncpy(languageName, g_LanguageNames[0], sizeof(languageName)); + } + + languageName[sizeof(languageName) - 1] = '\0'; + initialized = true; + + return languageName; +} + +//----------------------------------------------------------------------------- +// Purpose: checks if the EbisuSDK is disabled +// Output : true on success, false on failure +//----------------------------------------------------------------------------- +bool IsOriginDisabled() +{ + const static bool isDisabled = CommandLine()->CheckParm("-noorigin"); + return isDisabled; +} + //----------------------------------------------------------------------------- // Purpose: checks if the EbisuSDK is initialized // Output : true on success, false on failure @@ -57,3 +133,9 @@ bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen) size_t pos = strspn(pszName, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"); return pszName[pos] == '\0'; } + +void VEbisuSDK::Detour(const bool bAttach) const +{ + DetourSetup(&EbisuSDK_RunFrame, &HEbisuSDK_RunFrame, bAttach); + DetourSetup(&EbisuSDK_GetLanguage, &HEbisuSDK_GetLanguage, bAttach); +} diff --git a/r5dev/ebisusdk/EbisuSDK.h b/r5dev/ebisusdk/EbisuSDK.h index 894f8bac..79dbaaa7 100644 --- a/r5dev/ebisusdk/EbisuSDK.h +++ b/r5dev/ebisusdk/EbisuSDK.h @@ -1,19 +1,28 @@ #pragma once +#define MAX_PERSONA_NAME_LEN 64 // sizeof( g_PersonaName ) +#define FAKE_BASE_NUCLEUD_ID 9990000 + inline void(*EbisuSDK_Tier0_Init)(void); inline void(*EbisuSDK_CVar_Init)(void); -inline void(*EbisuSDK_SetState)(void); +inline void(*EbisuSDK_RunFrame)(void); +inline const char*(*EbisuSDK_GetLanguage)(void); inline uint64_t* g_NucleusID = nullptr; inline char* g_NucleusToken = nullptr; /*SIZE = 1024*/ inline char* g_OriginAuthCode = nullptr; /*SIZE = 256*/ +inline char* g_PersonaName = nullptr; /*SIZE = 64*/ inline int* g_OriginErrorLevel = nullptr; inline bool* g_EbisuSDKInit = nullptr; inline bool* g_EbisuProfileInit = nullptr; /////////////////////////////////////////////////////////////////////////////// void HEbisuSDK_Init(); +const char* HEbisuSDK_GetLanguage(); + +bool IsOriginDisabled(); bool IsOriginInitialized(); + bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen); /////////////////////////////////////////////////////////////////////////////// @@ -23,10 +32,12 @@ class VEbisuSDK : public IDetour { LogFunAdr("EbisuSDK_Tier0_Init", EbisuSDK_Tier0_Init); LogFunAdr("EbisuSDK_CVar_Init", EbisuSDK_CVar_Init); - LogFunAdr("EbisuSDK_SetState", EbisuSDK_SetState); + LogFunAdr("EbisuSDK_RunFrame", EbisuSDK_RunFrame); + LogFunAdr("EbisuSDK_GetLanguage", EbisuSDK_GetLanguage); LogVarAdr("g_NucleusID", g_NucleusID); LogVarAdr("g_NucleusToken", g_NucleusToken); LogVarAdr("g_OriginAuthCode", g_OriginAuthCode); + LogVarAdr("g_PersonaName", g_PersonaName); LogVarAdr("g_OriginErrorLevel", g_OriginErrorLevel); LogVarAdr("g_EbisuProfileInit", g_EbisuProfileInit); LogVarAdr("g_EbisuSDKInit", g_EbisuSDKInit); @@ -35,18 +46,20 @@ class VEbisuSDK : public IDetour { g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 0F 85 ?? 02 ?? ?? 48 89 5C 24 20").GetPtr(EbisuSDK_Tier0_Init); g_GameDll.FindPatternSIMD("40 57 48 83 EC 40 83 3D").GetPtr(EbisuSDK_CVar_Init); - g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B").GetPtr(EbisuSDK_SetState); + g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 5B").GetPtr(EbisuSDK_RunFrame); + g_GameDll.FindPatternSIMD("48 8B C4 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ??").GetPtr(EbisuSDK_GetLanguage); } virtual void GetVar(void) const { g_NucleusID = CMemory(EbisuSDK_CVar_Init).Offset(0x20).FindPatternSelf("4C 89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - g_NucleusToken = CMemory(EbisuSDK_SetState).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); - g_OriginAuthCode = CMemory(EbisuSDK_SetState).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - g_OriginErrorLevel = CMemory(EbisuSDK_SetState).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast(); + g_NucleusToken = CMemory(EbisuSDK_RunFrame).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); + g_OriginAuthCode = CMemory(EbisuSDK_RunFrame).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_PersonaName = CMemory(EbisuSDK_CVar_Init).Offset(0x120).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_OriginErrorLevel = CMemory(EbisuSDK_RunFrame).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast(); g_EbisuProfileInit = CMemory(EbisuSDK_CVar_Init).Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); g_EbisuSDKInit = CMemory(EbisuSDK_Tier0_Init).Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); } virtual void GetCon(void) const { } - virtual void Detour(const bool bAttach) const { } + virtual void Detour(const bool bAttach) const; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/engine/client/cdll_engine_int.h b/r5dev/engine/client/cdll_engine_int.h index 7952fb9c..ce2972e0 100644 --- a/r5dev/engine/client/cdll_engine_int.h +++ b/r5dev/engine/client/cdll_engine_int.h @@ -47,6 +47,12 @@ public: const static int index = 28; return CallVFunc(index, this, sequenceNumber); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 44 8B C2*/ } + + bool DispatchUserMessage(int msgType, bf_read* msgData) + { + const static int index = 59; + return CallVFunc(index, this, msgType, msgData); + } }; /* ==== CHLCLIENT ======================================================================================================================================================= */ diff --git a/r5dev/engine/client/cl_main.cpp b/r5dev/engine/client/cl_main.cpp index 49e013a6..d3424289 100644 --- a/r5dev/engine/client/cl_main.cpp +++ b/r5dev/engine/client/cl_main.cpp @@ -29,13 +29,12 @@ void CL_MoveEx() if (!v_Host_ShouldRun()) return; - int commandTick = -1; - - if (cl->m_CurrFrameSnapshot) - commandTick = cl->m_CurrFrameSnapshot->m_TickUpdate.m_nCommandTick; + const int commandTick = cl->m_CurrFrameSnapshot + ? cl->m_CurrFrameSnapshot->m_TickUpdate.m_nCommandTick + : -1; bool sendPacket = true; - CNetChan* chan = cl->m_NetChannel; + CNetChan* const chan = cl->m_NetChannel; // Only perform clamping and packeting if the timescale value is default, // else the timescale change won't be handled in the player's movement. diff --git a/r5dev/engine/client/cl_rcon.cpp b/r5dev/engine/client/cl_rcon.cpp index 5ff53e41..ce56c027 100644 --- a/r5dev/engine/client/cl_rcon.cpp +++ b/r5dev/engine/client/cl_rcon.cpp @@ -7,8 +7,7 @@ #include "core/stdafx.h" #include "tier1/cmd.h" #include "tier1/cvar.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "engine/client/cl_rcon.h" #include "engine/shared/shared_rcon.h" #include "engine/net.h" @@ -19,16 +18,18 @@ //----------------------------------------------------------------------------- // Purpose: console variables //----------------------------------------------------------------------------- -static ConVar rcon_address("rcon_address", "[loopback]:37015", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access address"); +static void RCON_AddressChanged_f(IConVar* pConVar, const char* pOldString); +static void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString); + +static ConVar cl_rcon_address("cl_rcon_address", "", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access address (rcon client is disabled if empty)", &RCON_AddressChanged_f); +static ConVar cl_rcon_inputonly("cl_rcon_inputonly", "0", FCVAR_RELEASE, "Tells the rcon server whether or not we are input only.", RCON_InputOnlyChanged_f); //----------------------------------------------------------------------------- // Purpose: console commands //----------------------------------------------------------------------------- -static void RCON_Disconnect_f(); static void RCON_CmdQuery_f(const CCommand& args); -static ConCommand rcon("rcon", RCON_CmdQuery_f, "Forward RCON query to remote server", FCVAR_CLIENTDLL | FCVAR_RELEASE, nullptr, "rcon \"\""); -static ConCommand rcon_disconnect("rcon_disconnect", RCON_Disconnect_f, "Disconnect from RCON server", FCVAR_CLIENTDLL | FCVAR_RELEASE); +static ConCommand rcon("rcon", RCON_CmdQuery_f, "Forward RCON message to remote server", FCVAR_CLIENTDLL | FCVAR_RELEASE, nullptr, "rcon \"\""); //----------------------------------------------------------------------------- // Purpose: @@ -51,8 +52,9 @@ CRConClient::~CRConClient(void) //----------------------------------------------------------------------------- // Purpose: NETCON systems init //----------------------------------------------------------------------------- -void CRConClient::Init(void) +void CRConClient::Init(const char* pNetKey) { + SetKey(pNetKey); m_bInitialized = true; } @@ -105,18 +107,17 @@ void CRConClient::Disconnect(const char* szReason) //----------------------------------------------------------------------------- bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen) { - sv_rcon::response response; - bool bSuccess = Decode(&response, pMsgBuf, nMsgLen); + netcon::response response; - if (!bSuccess) + if (!SH_NetConUnpackEnvelope(this, pMsgBuf, nMsgLen, &response, rcon_debug.GetBool())) { - Error(eDLL_T::CLIENT, NO_ERROR, "Failed to decode RCON buffer\n"); + Disconnect("received invalid message"); return false; } switch (response.responsetype()) { - case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: + case netcon::response_e::SERVERDATA_RESPONSE_AUTH: { if (!response.responseval().empty()) { @@ -132,7 +133,7 @@ bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen) Msg(eDLL_T::NETCON, "%s", response.responsemsg().c_str()); break; } - case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG: + case netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG: { NetMsg(static_cast(response.messagetype()), static_cast(response.messageid()), @@ -165,7 +166,7 @@ void CRConClient::RequestConsoleLog(const bool bWantLog) const SocketHandle_t hSocket = GetSocket(); vector vecMsg; - bool ret = Serialize(vecMsg, "", szEnable, cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); + bool ret = Serialize(vecMsg, "", szEnable, netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size()))) { @@ -181,9 +182,10 @@ void CRConClient::RequestConsoleLog(const bool bWantLog) // Output : serialized results as string //----------------------------------------------------------------------------- bool CRConClient::Serialize(vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType) const + const char* szReqVal, const netcon::request_e requestType) const { - return CL_NetConSerialize(this, vecBuf, szReqBuf, szReqVal, requestType); + return CL_NetConSerialize(this, vecBuf, szReqBuf, szReqVal, requestType, + rcon_encryptframes.GetBool(), rcon_debug.GetBool()); } //----------------------------------------------------------------------------- @@ -204,17 +206,6 @@ SocketHandle_t CRConClient::GetSocket(void) return SH_GetNetConSocketHandle(this, 0); } -//----------------------------------------------------------------------------- -// Purpose: request whether to recv logs from RCON server when cvar changes -//----------------------------------------------------------------------------- -static void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString) -{ - RCONClient()->RequestConsoleLog(RCONClient()->ShouldReceive()); -} - -static ConVar cl_rcon_inputonly("cl_rcon_inputonly", "0", FCVAR_RELEASE, "Tells the rcon server whether or not we are input only.", - false, 0.f, false, 0.f, RCON_InputOnlyChanged_f); - //----------------------------------------------------------------------------- // Purpose: returns whether or not we should receive logs from the server //----------------------------------------------------------------------------- @@ -254,6 +245,56 @@ CRConClient* RCONClient() // Singleton RCON Client. return &s_RCONClient; } +/* +===================== +RCON_AddressChanged_f + + changes the address of the rcon + server and attempts to connect + to it +===================== +*/ +static void RCON_AddressChanged_f(IConVar* pConVar, const char* pOldString) +{ + if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) + { + const char* pNewString = pConVarRef->GetString(); + + if (!*pNewString) // Empty address means nothing to network to; shutdown client... + { + RCONClient()->Shutdown(); + } + else + { + RCON_InitClientAndTrySyncKeys(); + + if (RCONClient()->IsInitialized() && !RCONClient()->IsConnected()) + { + if (RCONClient()->IsConnected()) + { + RCONClient()->Disconnect("address change requested"); + } + + RCONClient()->Connect(pNewString); + } + } + } +} + +/* +===================== +RCON_InputOnlyChanged_f + + request whether to recv logs + from RCON server when cvar + changes +===================== +*/ +static void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString) +{ + RCONClient()->RequestConsoleLog(RCONClient()->ShouldReceive()); +} + /* ===================== RCON_CmdQuery_f @@ -268,14 +309,8 @@ static void RCON_CmdQuery_f(const CCommand& args) if (argCount < 2) { - const char* pszAddress = rcon_address.GetString(); - - if (RCONClient()->IsInitialized() - && !RCONClient()->IsConnected() - && pszAddress[0]) - { - RCONClient()->Connect(pszAddress); - } + Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "no command provided"); + return; } else { @@ -290,15 +325,15 @@ static void RCON_CmdQuery_f(const CCommand& args) bool bSuccess = false; const SocketHandle_t hSocket = RCONClient()->GetSocket(); - if (strcmp(args.Arg(1), "PASS") == 0) // Auth with RCON server using rcon_password ConVar value. + if (strcmp(args.Arg(1), "PASS") == 0) { if (argCount > 2) { - bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", cl_rcon::request_t::SERVERDATA_REQUEST_AUTH); + bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", netcon::request_e::SERVERDATA_REQUEST_AUTH); } - else + else // Need at least 3 arguments for a password in PASS command (rcon PASS ) { - Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "no password given"); + Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "no password provided"); return; } @@ -311,11 +346,11 @@ static void RCON_CmdQuery_f(const CCommand& args) } else if (strcmp(args.Arg(1), "disconnect") == 0) // Disconnect from RCON server. { - RCONClient()->Disconnect("issued by user"); + RCONClient()->Disconnect("ordered by user"); return; } - bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND); + bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND); if (bSuccess) { RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size())); @@ -329,21 +364,3 @@ static void RCON_CmdQuery_f(const CCommand& args) } } } - -/* -===================== -RCON_Disconnect_f - - Disconnect from RCON server -===================== -*/ -static void RCON_Disconnect_f() -{ - const bool bIsConnected = RCONClient()->IsConnected(); - RCONClient()->Disconnect("issued by user"); - - if (bIsConnected) // Log if client was indeed connected. - { - Msg(eDLL_T::CLIENT, "User closed RCON connection\n"); - } -} diff --git a/r5dev/engine/client/cl_rcon.h b/r5dev/engine/client/cl_rcon.h index 72f8a769..0dd4ed4a 100644 --- a/r5dev/engine/client/cl_rcon.h +++ b/r5dev/engine/client/cl_rcon.h @@ -1,8 +1,7 @@ #pragma once #include "tier1/NetAdr.h" #include "tier2/socketcreator.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "engine/shared/base_rcon.h" class CRConClient : public CNetConBase @@ -11,7 +10,7 @@ public: CRConClient(void); ~CRConClient(void); - void Init(void); + void Init(const char* pNetKey = nullptr); void Shutdown(void); void RunFrame(void); @@ -19,7 +18,7 @@ public: virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override; bool Serialize(vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType) const; + const char* szReqVal, const netcon::request_e requestType) const; void RequestConsoleLog(const bool bWantLog); bool ShouldReceive(void); diff --git a/r5dev/engine/client/cl_splitscreen.h b/r5dev/engine/client/cl_splitscreen.h index eb3e8d02..9ad5f89d 100644 --- a/r5dev/engine/client/cl_splitscreen.h +++ b/r5dev/engine/client/cl_splitscreen.h @@ -133,7 +133,7 @@ class VSplitScreen : public IDetour virtual void GetFun(void) const { } virtual void GetVar(void) const { - const char* const pszPattern = "40 53 48 83 EC 20 48 8D 1D ?? ?? ?? ?? 83 FA FF 75 12 48 8B 05 ?? ?? ?? ?? 48 8B CB FF 50 28 48 63 C8 EB 03 48 63 CA 48 69 C1 ?? ?? ?? ?? 66 C7 84 18 ?? ?? ?? ?? ?? ??";; + const char* const pszPattern = "40 53 48 83 EC 20 48 8D 1D ?? ?? ?? ?? 83 FA FF 75 12 48 8B 05 ?? ?? ?? ?? 48 8B CB FF 50 28 48 63 C8 EB 03 48 63 CA 48 69 C1 ?? ?? ?? ?? 66 C7 84 18 ?? ?? ?? ?? ?? ??"; const char* const pszInstruction = "48 8D"; g_pSplitScreenMgr = g_GameDll.FindPatternSIMD(pszPattern).FindPatternSelf(pszInstruction).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); diff --git a/r5dev/engine/client/client.cpp b/r5dev/engine/client/client.cpp index 496e7afe..4c380ce6 100644 --- a/r5dev/engine/client/client.cpp +++ b/r5dev/engine/client/client.cpp @@ -9,6 +9,7 @@ // /////////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" +#include "mathlib/bitvec.h" #include "tier1/cvar.h" #include "tier1/strtools.h" #include "engine/server/server.h" @@ -259,7 +260,7 @@ bool CClient::Connect(const char* szName, CNetChan* pNetChan, bool bFakePlayer, bool CClient::VConnect(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer, CUtlVector* conVars, char* szMessage, int nMessageSize) { - return pClient->Connect(szName, pNetChan, bFakePlayer, conVars, szMessage, nMessageSize);; + return pClient->Connect(szName, pNetChan, bFakePlayer, conVars, szMessage, nMessageSize); } //--------------------------------------------------------------------------------- @@ -524,6 +525,93 @@ bool CClient::VProcessSetConVar(CClient* pClient, NET_SetConVar* pMsg) return true; } +//--------------------------------------------------------------------------------- +// Purpose: process voice data +// Input : *pClient - (ADJ) +// *pMsg - +// Output : +//--------------------------------------------------------------------------------- +bool CClient::VProcessVoiceData(CClient* pClient, CLC_VoiceData* pMsg) +{ +#ifndef CLIENT_DLL + char voiceDataBuffer[4096]; + const int bitsRead = pMsg->m_DataIn.ReadBitsClamped(voiceDataBuffer, pMsg->m_nLength); + + if (pMsg->m_DataIn.IsOverflowed()) + return false; + + CClient* const pAdj = AdjustShiftedThisPointer(pClient); + SV_BroadcastVoiceData(pAdj, Bits2Bytes(bitsRead), voiceDataBuffer); +#endif // !CLIENT_DLL + + return true; +} + +//--------------------------------------------------------------------------------- +// Purpose: process durango voice data +// Input : *pClient - (ADJ) +// *pMsg - +// Output : +//--------------------------------------------------------------------------------- +bool CClient::VProcessDurangoVoiceData(CClient* pClient, CLC_DurangoVoiceData* pMsg) +{ +#ifndef CLIENT_DLL + char voiceDataBuffer[4096]; + const int bitsRead = pMsg->m_DataIn.ReadBitsClamped(voiceDataBuffer, pMsg->m_nLength); + + if (pMsg->m_DataIn.IsOverflowed()) + return false; + + CClient* const pAdj = AdjustShiftedThisPointer(pClient); + SV_BroadcastDurangoVoiceData(pAdj, Bits2Bytes(bitsRead), voiceDataBuffer, + pMsg->m_xid, pMsg->m_unknown, pMsg->m_useVoiceStream, pMsg->m_skipXidCheck); +#endif // !CLIENT_DLL + + return true; +} + +//--------------------------------------------------------------------------------- +// Purpose: set UserCmd time buffer +// Input : numUserCmdProcessTicksMax - +// tickInterval - +//--------------------------------------------------------------------------------- +void CClientExtended::InitializeMovementTimeForUserCmdProcessing(const int numUserCmdProcessTicksMax, const float tickInterval) +{ + // Grant the client some time buffer to execute user commands + m_flMovementTimeForUserCmdProcessingRemaining += tickInterval; + + // but never accumulate more than N ticks + if (m_flMovementTimeForUserCmdProcessingRemaining > numUserCmdProcessTicksMax * tickInterval) + m_flMovementTimeForUserCmdProcessingRemaining = numUserCmdProcessTicksMax * tickInterval; +} + +//--------------------------------------------------------------------------------- +// Purpose: consume UserCmd time buffer +// Input : flTimeNeeded - +// Output : max time allowed for processing +//--------------------------------------------------------------------------------- +float CClientExtended::ConsumeMovementTimeForUserCmdProcessing(const float flTimeNeeded) +{ + if (m_flMovementTimeForUserCmdProcessingRemaining <= 0.0f) + return 0.0f; + else if (flTimeNeeded > m_flMovementTimeForUserCmdProcessingRemaining + FLT_EPSILON) + { + const float flResult = m_flMovementTimeForUserCmdProcessingRemaining; + m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; + + return flResult; + } + else + { + m_flMovementTimeForUserCmdProcessingRemaining -= flTimeNeeded; + + if (m_flMovementTimeForUserCmdProcessingRemaining < 0.0f) + m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; + + return flTimeNeeded; + } +} + void VClient::Detour(const bool bAttach) const { #ifndef CLIENT_DLL @@ -536,5 +624,7 @@ void VClient::Detour(const bool bAttach) const DetourSetup(&CClient__ProcessStringCmd, &CClient::VProcessStringCmd, bAttach); DetourSetup(&CClient__ProcessSetConVar, &CClient::VProcessSetConVar, bAttach); + DetourSetup(&CClient__ProcessVoiceData, &CClient::VProcessVoiceData, bAttach); + DetourSetup(&CClient__ProcessDurangoVoiceData, &CClient::VProcessDurangoVoiceData, bAttach); #endif // !CLIENT_DLL } diff --git a/r5dev/engine/client/client.h b/r5dev/engine/client/client.h index a40456af..9a273b36 100644 --- a/r5dev/engine/client/client.h +++ b/r5dev/engine/client/client.h @@ -69,6 +69,7 @@ public: inline edict_t GetHandle(void) const { return m_nHandle; } inline int GetUserID(void) const { return m_nUserID; } inline NucleusID_t GetNucleusID(void) const { return m_nNucleusID; } + inline int GetXPlatID(void) const { return m_XPlatID; } inline SIGNONSTATE GetSignonState(void) const { return m_nSignonState; } inline PERSISTENCE GetPersistenceState(void) const { return m_nPersistenceState; } @@ -79,7 +80,11 @@ public: CClientExtended* GetClientExtended(void) const; #endif // !CLIENT_DLL + inline int GetDeltaTick(void) const { return m_nDeltaTick; } inline int GetCommandTick(void) const { return m_nCommandTick; } + inline int GetLastMovementTick() const { return m_LastMovementTick; } + inline int GetSnapshotTick() const { return m_nSnapshotTick; } + inline const char* GetServerName(void) const { return m_szServerName; } inline const char* GetClientName(void) const { return m_szClientName; } @@ -120,6 +125,8 @@ public: // Hook statics: static bool VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg); static bool VProcessSetConVar(CClient* pClient, NET_SetConVar* pMsg); + static bool VProcessVoiceData(CClient* pClient, CLC_VoiceData* pMsg); + static bool VProcessDurangoVoiceData(CClient* pClient, CLC_DurangoVoiceData* pMsg); private: // Stub reimplementation to avoid the 'no overrider' compiler errors in the @@ -197,14 +204,26 @@ private: bool m_bReceivedPacket; bool m_bLowViolence; bool m_bFullyAuthenticated; - char pad_05A4[24]; + int unk_5A4; + int unknownTick; + float m_fNextMessageTime; + int unk_5B0; + char pad_5B8[8]; PERSISTENCE m_nPersistenceState; char pad_05C0[48]; + char SnapshotBuffer_AndSomeUnknowns[98344]; // TODO: needs to be reversed further. + int m_XPlatID; + char pad_30758[196964]; ServerDataBlock m_DataBlock; char pad_4A3D8[60]; int m_LastMovementTick; char pad_4A418[86]; - char pad_4A46E[80]; + char pad_4A46E[58]; + int unkInt_4A4A8; + int m_nSnapshotTick; + int unkTick_4A4B0; + int unkTick_4A4B4; + int unkInt_4A4B8; }; static_assert(sizeof(CClient) == 0x4A4C0); @@ -230,6 +249,7 @@ public: m_flNetProcessTimeBase = 0.0; m_flStringCommandQuotaTimeStart = 0.0; m_nStringCommandQuotaCount = NULL; + m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; m_bInitialConVarsSet = false; } @@ -247,6 +267,12 @@ public: // Inlines: inline void SetStringCommandQuotaCount(const int iCount) { m_nStringCommandQuotaCount = iCount; } inline int GetStringCommandQuotaCount(void) const { return m_nStringCommandQuotaCount; } + inline void SetRemainingMovementTimeForUserCmdProcessing(const float flValue) { m_flMovementTimeForUserCmdProcessingRemaining = flValue; } + inline float GetRemainingMovementTimeForUserCmdProcessing() const { return m_flMovementTimeForUserCmdProcessingRemaining; } + + void InitializeMovementTimeForUserCmdProcessing(const int numUserCmdProcessTicksMax, const float tickInterval); + float ConsumeMovementTimeForUserCmdProcessing(const float flTimeNeeded); + private: // Measure how long this client's packets took to process. double m_flNetProcessingTimeMsecs; @@ -256,6 +282,9 @@ private: double m_flStringCommandQuotaTimeStart; int m_nStringCommandQuotaCount; + // How much of a movement time buffer can we process from this user? + float m_flMovementTimeForUserCmdProcessingRemaining; + bool m_bInitialConVarsSet; // Whether or not the initial ConVar KV's are set }; @@ -270,6 +299,8 @@ inline void*(*CClient__SendSnapshot)(CClient* pClient, CClientFrame* pFrame, int inline void(*CClient__WriteDataBlock)(CClient* pClient, bf_write& buf); inline bool(*CClient__ProcessStringCmd)(CClient* pClient, NET_StringCmd* pMsg); inline bool(*CClient__ProcessSetConVar)(CClient* pClient, NET_SetConVar* pMsg); +inline bool(*CClient__ProcessVoiceData)(CClient* pClient, CLC_VoiceData* pMsg); +inline bool(*CClient__ProcessDurangoVoiceData)(CClient* pClient, CLC_DurangoVoiceData* pMsg); /////////////////////////////////////////////////////////////////////////////// class VClient : public IDetour @@ -286,6 +317,8 @@ class VClient : public IDetour LogFunAdr("CClient::WriteDataBlock", CClient__WriteDataBlock); LogFunAdr("CClient::ProcessStringCmd", CClient__ProcessStringCmd); LogFunAdr("CClient::ProcessSetConVar", CClient__ProcessSetConVar); + LogFunAdr("CClient::ProcessVoiceData", CClient__ProcessVoiceData); + LogFunAdr("CClient::ProcessDurangoVoiceData", CClient__ProcessDurangoVoiceData); } virtual void GetFun(void) const { @@ -300,6 +333,8 @@ class VClient : public IDetour g_GameDll.FindPatternSIMD("48 83 EC 28 48 83 C2 20").GetPtr(CClient__ProcessSetConVar); g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 10 48 89 70 18 57 48 81 EC ?? ?? ?? ?? 0F 29 70 E8 8B F2").GetPtr(CClient__SetSignonState); + g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 44 8B 42 20").GetPtr(CClient__ProcessVoiceData); + g_GameDll.FindPatternSIMD("40 53 57 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 44 8B 42 20").GetPtr(CClient__ProcessDurangoVoiceData); } virtual void GetVar(void) const { } virtual void GetCon(void) const { } diff --git a/r5dev/engine/client/clientstate.cpp b/r5dev/engine/client/clientstate.cpp index f7c42b5a..f8064e02 100644 --- a/r5dev/engine/client/clientstate.cpp +++ b/r5dev/engine/client/clientstate.cpp @@ -9,6 +9,7 @@ // ///////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" +#include "mathlib/bitvec.h" #include "tier0/frametask.h" #include "engine/common.h" #include "engine/host.h" @@ -24,6 +25,36 @@ #include #include +//------------------------------------------------------------------------------ +// Purpose: console command callbacks +//------------------------------------------------------------------------------ +static void SetName_f(const CCommand& args) +{ + if (args.ArgC() < 2) + return; + + if (!IsOriginDisabled()) + return; + + const char* pszName = args.Arg(1); + + if (!pszName[0]) + pszName = "unnamed"; + + const size_t nLen = strlen(pszName); + + if (nLen > MAX_PERSONA_NAME_LEN) + return; + + // Update nucleus name. + memset(g_PersonaName, '\0', MAX_PERSONA_NAME_LEN); + strncpy(g_PersonaName, pszName, nLen); +} + +//------------------------------------------------------------------------------ +// Purpose: console commands +//------------------------------------------------------------------------------ +static ConCommand cl_setname("cl_setname", SetName_f, "Sets the client's persona name", FCVAR_RELEASE); //------------------------------------------------------------------------------ // Purpose: returns true if client simulation is paused @@ -307,6 +338,36 @@ bool CClientState::_ProcessCreateStringTable(CClientState* thisptr, SVC_CreateSt return (endbit - startbit) == msg->m_nLength; } +//------------------------------------------------------------------------------ +// Purpose: processes user message data +// Input : *thisptr - +// *msg - +// Output : true on success, false otherwise +//------------------------------------------------------------------------------ +bool CClientState::_ProcessUserMessage(CClientState* thisptr, SVC_UserMessage* msg) +{ + CClientState* const cl = thisptr->GetShiftedBasePointer(); + + if (!cl->IsConnected()) + return false; + + // buffer for incoming user message + ALIGN4 byte userdata[MAX_USER_MSG_DATA] ALIGN4_POST = { 0 }; + bf_read userMsg("UserMessage(read)", userdata, sizeof(userdata)); + + int bitsRead = msg->m_DataIn.ReadBitsClamped(userdata, msg->m_nLength); + userMsg.StartReading(userdata, Bits2Bytes(bitsRead)); + + // dispatch message to client.dll + if (!g_pHLClient->DispatchUserMessage(msg->m_nMsgType, &userMsg)) + { + Warning(eDLL_T::CLIENT, "Couldn't dispatch user message (%i)\n", msg->m_nMsgType); + return false; + } + + return true; +} + static ConVar cl_onlineAuthEnable("cl_onlineAuthEnable", "1", FCVAR_RELEASE, "Enables the client-side online authentication system"); static ConVar cl_onlineAuthToken("cl_onlineAuthToken", "", FCVAR_HIDDEN | FCVAR_USERINFO | FCVAR_DONTRECORD | FCVAR_SERVER_CANNOT_QUERY | FCVAR_PLATFORM_SYSTEM, "The client's online authentication token"); @@ -402,6 +463,7 @@ void VClientState::Detour(const bool bAttach) const DetourSetup(&CClientState__ProcessStringCmd, &CClientState::_ProcessStringCmd, bAttach); DetourSetup(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick, bAttach); DetourSetup(&CClientState__ProcessCreateStringTable, &CClientState::_ProcessCreateStringTable, bAttach); + DetourSetup(&CClientState__ProcessUserMessage, &CClientState::_ProcessUserMessage, bAttach); DetourSetup(&CClientState__Connect, &CClientState::VConnect, bAttach); } diff --git a/r5dev/engine/client/clientstate.h b/r5dev/engine/client/clientstate.h index 106272ac..8c663507 100644 --- a/r5dev/engine/client/clientstate.h +++ b/r5dev/engine/client/clientstate.h @@ -40,6 +40,7 @@ public: // Hook statics. static bool _ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg); static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg); static bool _ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* msg); + static bool _ProcessUserMessage(CClientState* thisptr, SVC_UserMessage* msg); static void VConnect(CClientState* thisptr, connectparams_t* connectParams); @@ -100,7 +101,7 @@ public: _BYTE field_149; int m_nDeltaTick; int m_nStringTableAckTick; - int m_nProcesseedDeltaTick; + int m_nProcessedDeltaTick; int m_nProcessedStringTableAckTick; bool m_bPendingTicksAvailable; _BYTE field_15D; @@ -228,6 +229,7 @@ inline bool(*CClientState__HookClientStringTable)(CClientState* thisptr, const c inline bool(*CClientState__ProcessStringCmd)(CClientState* thisptr, NET_StringCmd* msg); inline bool(*CClientState__ProcessServerTick)(CClientState* thisptr, SVC_ServerTick* msg); inline bool(*CClientState__ProcessCreateStringTable)(CClientState* thisptr, SVC_CreateStringTable* msg); +inline bool(*CClientState__ProcessUserMessage)(CClientState* thisptr, SVC_UserMessage* msg); /////////////////////////////////////////////////////////////////////////////// class VClientState : public IDetour @@ -242,6 +244,7 @@ class VClientState : public IDetour LogFunAdr("CClientState::ProcessStringCmd", CClientState__ProcessStringCmd); LogFunAdr("CClientState::ProcessServerTick", CClientState__ProcessServerTick); LogFunAdr("CClientState::ProcessCreateStringTable", CClientState__ProcessCreateStringTable); + LogFunAdr("CClientState::ProcessUserMessage", CClientState__ProcessUserMessage); LogVarAdr("g_ClientState", g_pClientState); LogVarAdr("g_ClientState_Shifted", g_pClientState_Shifted); } @@ -255,6 +258,7 @@ class VClientState : public IDetour g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 80 B9 ?? ?? ?? ?? ?? 48 8B DA").GetPtr(CClientState__ProcessStringCmd); g_GameDll.FindPatternSIMD("40 57 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B F9 7C 66").GetPtr(CClientState__ProcessServerTick); g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 53 56 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??").GetPtr(CClientState__ProcessCreateStringTable); + g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??").GetPtr(CClientState__ProcessUserMessage); } virtual void GetVar(void) const { diff --git a/r5dev/engine/cmd.cpp b/r5dev/engine/cmd.cpp index 6b78bc74..fb52a7f8 100644 --- a/r5dev/engine/cmd.cpp +++ b/r5dev/engine/cmd.cpp @@ -110,6 +110,79 @@ bool Cmd_ForwardToServer(const CCommand* args) #endif // DEDICATED } +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// Purpose: execute commands directly (ignores all protection flags) +// Input : *pCommandString - +// *pValueString - +// Output : true on success, false otherwise +// +// NOTE : this function is dangerous, as it allows execution of any command +// without restrictions. Currently, this is only enabled on the +// dedicated server for the local console input and RCON, as they both +// are considered secure (local console needs physical access to the +// terminal application, RCON requires authentication and its protocol +// is secure. Do not use this anywhere else without a valid reason !!! +// +// NOTE : if client support is ever considered (unlikely), then the convar +// flag 'FCVAR_MATERIAL_THREAD_MASK' probably needs to be taken into +// account as well, also, change the DLL context of the warning to +// ENGINE if the client ever utilizes this. +//----------------------------------------------------------------------------- +bool Cmd_ExecuteUnrestricted(const char* const pCommandString, const char* const pValueString) +{ + ConCommandBase* const pCommandBase = g_pCVar->FindCommandBase(pCommandString); + + if (!pCommandBase) + { + // Found nothing. + Warning(eDLL_T::SERVER, "Command '%s' doesn't exist; request '%s' ignored\n", pCommandString, pValueString); + return false; + } + + if (pCommandBase->IsFlagSet(FCVAR_SERVER_FRAME_THREAD)) + ThreadJoinServerJob(); + + if (!pCommandBase->IsCommand()) + { + // Here we want to skip over the command string in the value buffer. + // So if we got 'sv_cheats 1' in our value buffer, we want to skip + // over 'sv_cheats ', so that we are pointing directly to the value. + const char* pFound = V_strstr(pValueString, pCommandString); + const char* pValue = nullptr; + + if (pFound) + { + pValue = pFound + V_strlen(pCommandString); + + // Skip any leading space characters. + while (*pValue == ' ') + { + ++pValue; + } + } + + ConVar* const pConVar = reinterpret_cast(pCommandBase); + pConVar->SetValue(pValue ? pValue : pValueString); + } + else // Invoke command callback directly. + { + CCommand cmd; + + // Only tokenize if we actually have strings in the value buffer, some + // commands (like 'status') don't need any additional parameters. + if (VALID_CHARSTAR(pValueString)) + { + cmd.Tokenize(pValueString, cmd_source_t::kCommandSrcCode); + } + + v_Cmd_Dispatch(ECommandTarget_t::CBUF_SERVER, pCommandBase, &cmd, false); + } + + return true; +} +#endif // !CLIENT_DLL + /////////////////////////////////////////////////////////////////////////////// void VCmd::Detour(const bool bAttach) const { diff --git a/r5dev/engine/cmd.h b/r5dev/engine/cmd.h index da1caa37..915d218e 100644 --- a/r5dev/engine/cmd.h +++ b/r5dev/engine/cmd.h @@ -26,6 +26,10 @@ FORCEINLINE ECommandTarget_t Cbuf_GetCurrentPlayer(void) extern bool Cbuf_HasRoomForExecutionMarkers(const int cExecutionMarkers); extern bool Cbuf_AddTextWithMarkers(const char* text, const ECmdExecutionMarker markerLeft, const ECmdExecutionMarker markerRight); +#ifndef CLIENT_DLL +extern bool Cmd_ExecuteUnrestricted(const char* const pCommandString, const char* const pValueString); +#endif // CLIENT_DLL + /* ==== COMMAND_BUFFER ================================================================================================================================================== */ inline void(*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_source_t cmdSource); inline void(*Cbuf_AddExecutionMarker)(ECommandTarget_t target, ECmdExecutionMarker marker); diff --git a/r5dev/engine/cmodel_bsp.cpp b/r5dev/engine/cmodel_bsp.cpp index 07033291..7daa8cf5 100644 --- a/r5dev/engine/cmodel_bsp.cpp +++ b/r5dev/engine/cmodel_bsp.cpp @@ -9,6 +9,7 @@ #include "tier0/memstd.h" #include "tier0/jobthread.h" #include "tier1/fmtstr.h" +#include "tier1/keyvalues.h" #include "tier2/fileutils.h" #include "engine/sys_dll2.h" #include "engine/host_cmd.h" @@ -19,7 +20,7 @@ #include "rtech/pak/paktools.h" #include "rtech/pak/pakstream.h" -#include "tier1/keyvalues.h" +#include "vpklib/packedstore.h" #include "datacache/mdlcache.h" #include "filesystem/filesystem.h" #ifndef DEDICATED @@ -29,8 +30,6 @@ CUtlVector g_InstalledMaps; CFmtStrN s_CurrentLevelName; -static std::regex s_ArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" }; - static CustomPakData_t s_customPakData; static KeyValues* s_pLevelSetKV = nullptr; @@ -42,13 +41,13 @@ PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile) if (numHandles >= MAX_CUSTOM_PAKS) { Error(eDLL_T::ENGINE, NO_ERROR, "Tried to load pak '%s', but already reached the SDK's limit of %d!\n", pakFile, MAX_CUSTOM_PAKS); - return INVALID_PAK_HANDLE; + return PAK_INVALID_HANDLE; } const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0); // failure, don't add and return the invalid handle. - if (pakId == INVALID_PAK_HANDLE) + if (pakId == PAK_INVALID_HANDLE) return pakId; handles[numHandles++] = pakId; @@ -64,14 +63,14 @@ void CustomPakData_t::UnloadAndRemoveAll() { const PakHandle_t pakId = handles[numHandles-1]; - if (pakId == INVALID_PAK_HANDLE) + if (pakId == PAK_INVALID_HANDLE) { assert(0); // invalid handles should not be inserted return; } g_pakLoadApi->UnloadAsync(pakId); - handles[numHandles-1] = INVALID_PAK_HANDLE; + handles[numHandles-1] = PAK_INVALID_HANDLE; } } @@ -83,7 +82,7 @@ PakHandle_t CustomPakData_t::LoadBasePak(const char* const pakFile, const EPakTy const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0); // the file is most likely missing - assert(pakId != INVALID_PAK_HANDLE); + assert(pakId != PAK_INVALID_HANDLE); handles[type] = pakId; return pakId; @@ -97,10 +96,10 @@ void CustomPakData_t::UnloadBasePak(const EPakType type) const PakHandle_t pakId = handles[type]; // only unload if it was actually successfully loaded - if (pakId != INVALID_PAK_HANDLE) + if (pakId != PAK_INVALID_HANDLE) { g_pakLoadApi->UnloadAsync(pakId); - handles[type] = INVALID_PAK_HANDLE; + handles[type] = PAK_INVALID_HANDLE; } } @@ -136,11 +135,11 @@ void Mod_GetAllInstalledMaps() // slash, as the files are loaded from 'vpk/'. Assert(pFileName); - std::regex_search(pFileName, regexMatches, s_ArchiveRegex); + std::regex_search(pFileName, regexMatches, g_VpkDirFileRegex); if (!regexMatches.empty()) { - const std::sub_match& match = regexMatches[1]; + const std::sub_match& match = regexMatches[2]; if (match.compare("frontend") == 0) continue; // Frontend contains no BSP's. @@ -155,6 +154,7 @@ void Mod_GetAllInstalledMaps() else { const string mapName = match.str(); + if (!g_InstalledMaps.HasElement(mapName.c_str())) g_InstalledMaps.AddToTail(mapName.c_str()); } @@ -236,8 +236,8 @@ void Mod_QueuedPakCacheFrame() { if (*data->pakName) { - PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(data->pakId); - EPakStatus status; + PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(data->pakId); + PakStatus_e status; // TODO: revisit this, this appears incorrect but also the way // respawn does this. it this always supposed to be true on @@ -313,7 +313,7 @@ void Mod_QueuedPakCacheFrame() data->keepLoaded = false; data->pakName[0] = '\0'; - data->pakId = INVALID_PAK_HANDLE; + data->pakId = PAK_INVALID_HANDLE; } --numLeftToProcess; --data; @@ -352,7 +352,7 @@ void Mod_QueuedPakCacheFrame() if (*commonData->pakName) break; - commonData->pakId = INVALID_PAK_HANDLE; + commonData->pakId = PAK_INVALID_HANDLE; LOOP_AGAIN_OR_FINISH: ++it; @@ -421,9 +421,9 @@ void Mod_QueuedPakCacheFrame() CHECK_FOR_FAILURE: - if (commonData->pakId != INVALID_PAK_HANDLE) + if (commonData->pakId != PAK_INVALID_HANDLE) { - const PakLoadedInfo_t* const pli = Pak_GetPakInfo(commonData->pakId); + const PakLoadedInfo_s* const pli = Pak_GetPakInfo(commonData->pakId); if (pli->handle != commonData->pakId || ((pli->status - 9) & 0xFFFFFFFB) != 0) { @@ -502,7 +502,7 @@ void Mod_PreloadLevelPaks(const char* const pszLevelName) snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName()); const PakHandle_t nPakId = s_customPakData.LoadAndAddPak(szPathBuffer); - if (nPakId == INVALID_PAK_HANDLE) + if (nPakId == PAK_INVALID_HANDLE) Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId); } } diff --git a/r5dev/engine/cmodel_bsp.h b/r5dev/engine/cmodel_bsp.h index da8eaec5..019134df 100644 --- a/r5dev/engine/cmodel_bsp.h +++ b/r5dev/engine/cmodel_bsp.h @@ -39,7 +39,7 @@ struct CommonPakData_t void Reset() { - pakId = INVALID_PAK_HANDLE; + pakId = PAK_INVALID_HANDLE; keepLoaded = false; basePakName = nullptr; @@ -83,14 +83,14 @@ struct CustomPakData_t // the absolute max number of custom paks, note that the engine's limit // could still be reached before this number as game scripts and other // code still loads paks such as gladiator cards or load screens - MAX_CUSTOM_PAKS = (PAK_MAX_HANDLES - CommonPakData_t::PAK_TYPE_COUNT) + MAX_CUSTOM_PAKS = (PAK_MAX_LOADED_PAKS - CommonPakData_t::PAK_TYPE_COUNT) }; CustomPakData_t() { for (size_t i = 0; i < V_ARRAYSIZE(handles); i++) { - handles[i] = INVALID_PAK_HANDLE; + handles[i] = PAK_INVALID_HANDLE; } // the first # handles are reserved for base SDK paks diff --git a/r5dev/engine/host_state.cpp b/r5dev/engine/host_state.cpp index 09213da5..9871e075 100644 --- a/r5dev/engine/host_state.cpp +++ b/r5dev/engine/host_state.cpp @@ -57,10 +57,10 @@ #include "game/shared/vscript_shared.h" #ifndef CLIENT_DLL -static ConVar sv_pylonVisibility("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", "0 = Offline, 1 = Hidden, 2 = Public."); -static ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds)."); +static ConVar host_statusRefreshRate("host_statusRefreshRate", "0.5", FCVAR_RELEASE, "Host status refresh rate (seconds).", true, 0.f, false, 0.f); -static ConVar sv_autoReloadRate("sv_autoReloadRate", "0", FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null)."); +static ConVar host_autoReloadRate("host_autoReloadRate", "0", FCVAR_RELEASE, "Time in seconds between each auto-reload (disabled if null)."); +static ConVar host_autoReloadRespectGameState("host_autoReloadRespectGameState", "0", FCVAR_RELEASE, "Check the game state before proceeding to auto-reload (don't reload in the middle of a match)."); #endif // !CLIENT_DLL #ifdef DEDICATED @@ -136,6 +136,24 @@ static void HostState_KeepAlive() } #endif // DEDICATED +#ifndef CLIENT_DLL +void HostState_HandleAutoReload() +{ + if (host_autoReloadRate.GetBool()) + { + if (g_ServerGlobalVariables->m_flCurTime > host_autoReloadRate.GetFloat()) + { + // We should respect the game state, and the game isn't finished yet so + // don't reload the server now. + if (host_autoReloadRespectGameState.GetBool() && !g_hostReloadState) + return; + + Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode); + } + } +} +#endif // !CLIENT_DLL + //----------------------------------------------------------------------------- // Purpose: state machine's main processing loop //----------------------------------------------------------------------------- @@ -299,13 +317,6 @@ void CHostState::Setup(void) #endif // !CLIENT_DLL ConVar_PurgeHostNames(); -#ifndef CLIENT_DLL - RCONServer()->Init(); -#endif // !CLIENT_DLL -#ifndef DEDICATED - RCONClient()->Init(); -#endif // !DEDICATED - #ifndef CLIENT_DLL LiveAPISystem()->Init(); #endif // !CLIENT_DLL @@ -350,14 +361,10 @@ void CHostState::Think(void) const #endif // DEDICATED bInitialized = true; } - if (sv_autoReloadRate.GetBool()) - { - if (g_ServerGlobalVariables->m_flCurTime > sv_autoReloadRate.GetFloat()) - { - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode); - } - } - if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate.GetFloat()) + + HostState_HandleAutoReload(); + + if (statsTimer.GetDurationInProgress().GetSeconds() > host_statusRefreshRate.GetFloat()) { SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d)", hostname->GetString(), g_pServer->GetNumClients(), @@ -414,6 +421,9 @@ void CHostState::LoadConfig(void) const Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec tools/rcon_client_dev.cfg\n", cmd_source_t::kCommandSrcCode); #endif // !DEDICATED } +#ifndef CLIENT_DLL + Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec liveapi.cfg\n", cmd_source_t::kCommandSrcCode); +#endif //!CLIENT_DLL #ifndef DEDICATED Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec bind.cfg\n", cmd_source_t::kCommandSrcCode); #endif // !DEDICATED @@ -551,3 +561,7 @@ void VHostState::Detour(const bool bAttach) const /////////////////////////////////////////////////////////////////////////////// CHostState* g_pHostState = nullptr; + +#ifndef CLIENT_DLL +bool g_hostReloadState = false; +#endif // !CLIENT_DLL diff --git a/r5dev/engine/host_state.h b/r5dev/engine/host_state.h index be1dbc0f..77ced4c7 100644 --- a/r5dev/engine/host_state.h +++ b/r5dev/engine/host_state.h @@ -58,6 +58,9 @@ inline void(*v_HostState_ChangeLevelMP)(char const* pNewLevel, char const* pLand /////////////////////////////////////////////////////////////////////////////// extern CHostState* g_pHostState; +#ifndef CLIENT_DLL +extern bool g_hostReloadState; +#endif // !CLIENT_DLL /////////////////////////////////////////////////////////////////////////////// class VHostState : public IDetour diff --git a/r5dev/engine/net.cpp b/r5dev/engine/net.cpp index 0734c769..dff24f62 100644 --- a/r5dev/engine/net.cpp +++ b/r5dev/engine/net.cpp @@ -8,6 +8,7 @@ #include "engine/net.h" #ifndef _TOOLS #include "tier1/cvar.h" +#include "tier2/cryptutils.h" #include "mathlib/color.h" #include "net.h" #include "net_chan.h" @@ -202,21 +203,16 @@ void NET_GenerateKey() return; // Change callback will handle this. } - BCRYPT_ALG_HANDLE hAlgorithm; - if (BCryptOpenAlgorithmProvider(&hAlgorithm, L"RNG", 0, 0) < 0) + uint8_t keyBuf[AES_128_KEY_SIZE]; + const char* errorMsg = nullptr; + + if (!Plat_GenerateRandom(keyBuf, sizeof(keyBuf), errorMsg)) { - Error(eDLL_T::ENGINE, NO_ERROR, "Failed to open rng algorithm\n"); + Error(eDLL_T::ENGINE, NO_ERROR, "%s\n", errorMsg); return; } - uint8_t pBuffer[AES_128_KEY_SIZE]; - if (BCryptGenRandom(hAlgorithm, pBuffer, AES_128_KEY_SIZE, 0) < 0) - { - Error(eDLL_T::ENGINE, NO_ERROR, "Failed to generate random data\n"); - return; - } - - NET_SetKey(Base64Encode(string(reinterpret_cast(&pBuffer), AES_128_KEY_SIZE))); + NET_SetKey(Base64Encode(string(reinterpret_cast(&keyBuf), AES_128_KEY_SIZE))); } //----------------------------------------------------------------------------- diff --git a/r5dev/engine/net.h b/r5dev/engine/net.h index 70e60aab..55eec1b9 100644 --- a/r5dev/engine/net.h +++ b/r5dev/engine/net.h @@ -1,5 +1,9 @@ #pragma once +constexpr unsigned int AES_128_KEY_SIZE = 16; +constexpr unsigned int AES_128_B64_ENCODED_SIZE = 24; +constexpr const char* DEFAULT_NET_ENCRYPTION_KEY = "WDNWLmJYQ2ZlM0VoTid3Yg=="; + #ifndef _TOOLS #include "engine/net_chan.h" #include "tier1/lzss.h" @@ -14,10 +18,6 @@ #define NETMSG_LENGTH_BITS 12 // 512 bytes (11 in Valve Source, 256 bytes). #define NET_MIN_MESSAGE 5 // Even connectionless packets require int32 value (-1) + 1 byte content -constexpr unsigned int AES_128_KEY_SIZE = 16; -constexpr unsigned int AES_128_B64_ENCODED_SIZE = 24; -constexpr const char* DEFAULT_NET_ENCRYPTION_KEY = "WDNWLmJYQ2ZlM0VoTid3Yg=="; - /* ==== CNETCHAN ======================================================================================================================================================== */ inline void*(*v_NET_Init)(bool bDeveloper); inline void(*v_NET_SetKey)(netkey_t* pKey, const char* szHash); diff --git a/r5dev/engine/net_chan.h b/r5dev/engine/net_chan.h index 1a032bbe..88414cd0 100644 --- a/r5dev/engine/net_chan.h +++ b/r5dev/engine/net_chan.h @@ -124,10 +124,12 @@ public: int GetSequenceNr(int flow) const; double GetTimeConnected(void) const; - inline float GetTimeoutSeconds(void) const { return m_Timeout; } - inline int GetSocket(void) const { return m_Socket; } - inline const bf_write& GetStreamVoice(void) const { return m_StreamVoice; } - inline const netadr_t& GetRemoteAddress(void) const { return remote_address; } + inline float GetTimeoutSeconds(void) const { return m_Timeout; } + inline int GetSocket(void) const { return m_Socket; } + inline const bf_write& GetStreamVoice(void) const { return m_StreamVoice; } + inline const bf_write& GetStreamReliable(void) const { return m_StreamReliable; } + inline const bf_write& GetStreamUnreliable(void) const { return m_StreamUnreliable; } + inline const netadr_t& GetRemoteAddress(void) const { return remote_address; } int GetNumBitsWritten(const bool bReliable); int GetNumBitsLeft(const bool bReliable); diff --git a/r5dev/engine/server/datablock_sender.h b/r5dev/engine/server/datablock_sender.h index 29f505a9..3f48995e 100644 --- a/r5dev/engine/server/datablock_sender.h +++ b/r5dev/engine/server/datablock_sender.h @@ -23,7 +23,6 @@ public: struct ServerDataBlock { - char blockBuffer[295312]; // this might be wrong !!! void* userData; char gapC0008[56]; ServerDataBlockSender sender; diff --git a/r5dev/engine/server/server.cpp b/r5dev/engine/server/server.cpp index b5efc531..8e5676ab 100644 --- a/r5dev/engine/server/server.cpp +++ b/r5dev/engine/server/server.cpp @@ -10,6 +10,7 @@ ///////////////////////////////////////////////////////////////////////////////// #include "core/stdafx.h" #include "common/protocol.h" +#include "tier0/frametask.h" #include "tier1/cvar.h" #include "tier1/strtools.h" #include "engine/server/sv_main.h" @@ -25,10 +26,12 @@ // Console variables //--------------------------------------------------------------------------------- ConVar sv_showconnecting("sv_showconnecting", "1", FCVAR_RELEASE, "Logs information about the connecting client to the console"); -ConVar sv_globalBanlist("sv_globalBanlist", "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, "0 = Disable, 1 = Enable."); +ConVar sv_pylonVisibility("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", "0 = Offline, 1 = Hidden, 2 = Public."); +ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds)."); + +ConVar sv_globalBanlist("sv_globalBanlist", "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, "0 = Disable, 1 = Enable."); ConVar sv_banlistRefreshRate("sv_banlistRefreshRate", "30.0", FCVAR_DEVELOPMENTONLY, "Banned list refresh rate (seconds).", true, 1.f, false, 0.f); -ConVar sv_statusRefreshRate("sv_statusRefreshRate", "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", true, 0.f, false, 0.f); static ConVar sv_validatePersonaName("sv_validatePersonaName", "1", FCVAR_RELEASE, "Validate the client's textual persona name on connect."); static ConVar sv_minPersonaNameLength("sv_minPersonaNameLength", "4", FCVAR_RELEASE, "The minimum length of the client's textual persona name.", true, 0.f, false, 0.f); @@ -174,7 +177,7 @@ CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge) for (auto& callback : !g_PluginSystem.GetConnectClientCallbacks()) { - if (!callback(pServer, pClient, pChallenge)) + if (!callback.Function()(pServer, pClient, pChallenge)) { pClient->Disconnect(REP_MARK_BAD, "#Valve_Reject_Banned"); return nullptr; diff --git a/r5dev/engine/server/server.h b/r5dev/engine/server/server.h index cc05ac46..ffbb1fac 100644 --- a/r5dev/engine/server/server.h +++ b/r5dev/engine/server/server.h @@ -1,4 +1,5 @@ #pragma once +#include "tier0/frametask.h" #include "tier1/NetAdr.h" #include "networksystem/pylon.h" #include "engine/client/client.h" @@ -111,19 +112,21 @@ static_assert(sizeof(CServer) == 0x25264C0); extern CServer* g_pServer; +extern ConVar sv_showconnecting; + +extern ConVar sv_pylonVisibility; +extern ConVar sv_pylonRefreshRate; + extern ConVar sv_globalBanlist; extern ConVar sv_banlistRefreshRate; -extern ConVar sv_statusRefreshRate; - -extern ConVar sv_showconnecting; - /* ==== CSERVER ========================================================================================================================================================= */ inline void(*CServer__FrameJob)(double flFrameTime, bool bRunOverlays, bool bUpdateFrame); inline void(*CServer__RunFrame)(CServer* pServer); inline CClient*(*CServer__ConnectClient)(CServer* pServer, user_creds_s* pCreds); inline void*(*CServer__RejectConnection)(CServer* pServer, int iSocket, netadr_t* pNetAdr, const char* szMessage); inline void (*CServer__BroadcastMessage)(CServer* pServer, CNetMessage* const msg, const bool onlyActive, const bool reliable); +inline bool(*CServer__SpawnServer)(CServer* pServer, const char* pszMapName, const char* pszMapGroupName); /////////////////////////////////////////////////////////////////////////////// class VServer : public IDetour @@ -136,6 +139,7 @@ class VServer : public IDetour LogFunAdr("CServer::ConnectClient", CServer__ConnectClient); LogFunAdr("CServer::RejectConnection", CServer__RejectConnection); LogFunAdr("CServer::BroadcastMessage", CServer__BroadcastMessage); + LogFunAdr("CServer::SpawnServer", CServer__SpawnServer); LogVarAdr("g_Server", g_pServer); #endif // !CLIENT_DLL } @@ -148,6 +152,7 @@ class VServer : public IDetour g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 88 05 ?? ?? ?? ??").FollowNearCallSelf().GetPtr(CServer__RunFrame); g_GameDll.FindPatternSIMD("4C 89 4C 24 ?? 53 55 56 57 48 81 EC ?? ?? ?? ?? 49 8B D9").GetPtr(CServer__RejectConnection); g_GameDll.FindPatternSIMD("4C 8B DC 45 88 43 18 56").GetPtr(CServer__BroadcastMessage); + g_GameDll.FindPatternSIMD("48 8B C4 53 55 56 57 41 54 41 55 41 57").GetPtr(CServer__SpawnServer); #endif // !CLIENT_DLL } virtual void GetVar(void) const diff --git a/r5dev/engine/server/sv_main.cpp b/r5dev/engine/server/sv_main.cpp index 9ad96112..144448a9 100644 --- a/r5dev/engine/server/sv_main.cpp +++ b/r5dev/engine/server/sv_main.cpp @@ -162,19 +162,39 @@ bool SV_ActivateServer() return v_SV_ActivateServer(); } -void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data) +//----------------------------------------------------------------------------- +// Purpose: returns whether voice data can be broadcasted from the server +//----------------------------------------------------------------------------- +bool SV_CanBroadcastVoice() { + if (IsPartyDedi()) + return false; + + if (IsTrainingDedi()) + return false; + if (!sv_voiceenable->GetBool()) - return; + return false; if (g_ServerGlobalVariables->m_nMaxClients <= 0) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: relays voice data to other clients +//----------------------------------------------------------------------------- +void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data) +{ + if (!SV_CanBroadcastVoice()) return; SVC_VoiceData voiceData(cl->GetUserID(), nBytes, data); for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++) { - CClient* pClient = g_pServer->GetClient(i); + CClient* const pClient = g_pServer->GetClient(i); if (!pClient) continue; @@ -191,10 +211,13 @@ void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data if (pClient->GetTeamNum() != cl->GetTeamNum() && !sv_alltalk->GetBool()) continue; - // there's also supposed to be some xplat checks here - // but since r5r is only on PC, there's no point in implementing them here + //if (voice_noxplat->GetBool() && cl->GetXPlatID() != pClient->GetXPlatID()) + //{ + // if ((cl->GetXPlatID() -1) > 1 || (pClient->GetXPlatID() -1) > 1) + // continue; + //} - CNetChan* pNetChan = pClient->GetNetChan(); + CNetChan* const pNetChan = pClient->GetNetChan(); if (!pNetChan) continue; @@ -204,3 +227,69 @@ void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data pClient->SendNetMsgEx(&voiceData, false, false, true); } } + +//----------------------------------------------------------------------------- +// Purpose: relays durango voice data to other clients +//----------------------------------------------------------------------------- +void SV_BroadcastDurangoVoiceData(CClient* const cl, const int nBytes, char* const data, + const int nXid, const int unknown, const bool useVoiceStream, const bool skipXidCheck) +{ + if (!SV_CanBroadcastVoice()) + return; + + SVC_DurangoVoiceData voiceData(cl->GetUserID(), nBytes, data, unknown, useVoiceStream); + + for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++) + { + CClient* const pClient = g_pServer->GetClient(i); + + if (!pClient) + continue; + + // is this client fully connected + if (pClient->GetSignonState() != SIGNONSTATE::SIGNONSTATE_FULL) + continue; + + // is this client the sender + if (pClient == cl && !sv_voiceEcho->GetBool()) + continue; + + if (!skipXidCheck && i != nXid) + continue; + + // is this client on the sender's team + if (pClient->GetTeamNum() != cl->GetTeamNum() && !sv_alltalk->GetBool()) + { + // NOTE: on Durango packets, the game appears to bypass the team + // check if 'useVoiceStream' is false, thus forcing the usage + // of the reliable stream. Omitted the check as it appears that + // could be exploited to transmit voice to other teams while cvar + // 'sv_alltalk' is unset. + continue; + } + + // NOTE: xplat code checks disabled; CClient::GetXPlatID() seems to be + // an enumeration of platforms, but the enum hasn't been reversed yet. + //if (voice_noxplat->GetBool() && cl->GetXPlatID() != pClient->GetXPlatID()) + //{ + // if ((cl->GetXPlatID() - 1) > 1 || (pClient->GetXPlatID() - 1) > 1) + // continue; + //} + + CNetChan* const pNetChan = pClient->GetNetChan(); + + if (!pNetChan) + continue; + + // NOTE: the game appears to have the ability to use the unreliable + // stream as well, but the condition to hit that code path can never + // evaluate to true - appears to be a compile time option that hasn't + // been fully optimized away? For now only switch between voice and + // reliable streams as that is what the original code does. + const bf_write& stream = useVoiceStream ? pNetChan->GetStreamVoice() : pNetChan->GetStreamReliable(); + + // if stream has enough space for new data + if (stream.GetNumBitsLeft() >= 8 * nBytes + 34) + pClient->SendNetMsgEx(&voiceData, false, !useVoiceStream, useVoiceStream); + } +} diff --git a/r5dev/engine/server/sv_main.h b/r5dev/engine/server/sv_main.h index 1c2e75d2..8f861709 100644 --- a/r5dev/engine/server/sv_main.h +++ b/r5dev/engine/server/sv_main.h @@ -8,7 +8,6 @@ class CClient; class CClient; /* ==== SV_MAIN ======================================================================================================================================================= */ -inline bool(*CGameServer__SpawnServer)(void* thisptr, const char* pszMapName, const char* pszMapGroupName); inline void(*v_SV_InitGameDLL)(void); inline void(*v_SV_ShutdownGameDLL)(void); inline bool(*v_SV_ActivateServer)(void); @@ -17,18 +16,57 @@ inline void(*v_SV_BroadcastVoiceData)(CClient* cl, int nBytes, char* data); inline bool* s_bIsDedicated = nullptr; +inline bool* s_bPartyDediOnly = nullptr; +inline bool* s_bTrainingDedi = nullptr; +inline bool* s_bStagingDedi = nullptr; +inline bool* s_bFiringRangeDedi = nullptr; + // Returns true if this is a dedicated server. inline bool IsDedicated() { return *s_bIsDedicated; } +// If this is true, a maximum of 2 teams will be enforced. No voice data will +// be processed or broad casted to clients. +// This is set with command line option '-partyDediOnly'. +inline bool IsPartyDedi() +{ + return *s_bPartyDediOnly; +} + +// If this is true, no playlist matching checks will be performed. No voice +// data will be processed or broad casted to clients. +// This is set with command line option '-trainingDedi'. +inline bool IsTrainingDedi() +{ + return *s_bTrainingDedi; +} + +// If this is true, no playlist matching checks will be performed. +// This is set with command line option '-stagingDedi'. +inline bool IsStagingDedi() +{ + return *s_bStagingDedi; +} + +// If this is true, no playlist matching checks will be performed. +// The system expects a 'max_team_size' key in the playlists file +// that will be used to enforce the max team size, which defaults +// to '3' if key is absent. +// This is set with command line option '-firingRangeDedi'. +inline bool IsFiringRangeDedi() +{ + return *s_bFiringRangeDedi; +} + /////////////////////////////////////////////////////////////////////////////// void SV_InitGameDLL(); void SV_ShutdownGameDLL(); bool SV_ActivateServer(); void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data); +void SV_BroadcastDurangoVoiceData(CClient* const cl, const int nBytes, char* const data, const int nXid, const int unknown, const bool useVoiceStream, const bool skipXidCheck); void SV_CheckForBanAndDisconnect(CClient* const pClient, const string& svIPAddr, const NucleusID_t nNucleusID, const string& svPersonaName, const int nPort); void SV_CheckClientsForBan(const CBanSystem::BannedList_t* const pBannedVec = nullptr); /////////////////////////////////////////////////////////////////////////////// @@ -38,17 +76,16 @@ class HSV_Main : public IDetour { virtual void GetAdr(void) const { - LogFunAdr("CGameServer::SpawnServer", CGameServer__SpawnServer); LogFunAdr("SV_InitGameDLL", v_SV_InitGameDLL); LogFunAdr("SV_ShutdownGameDLL", v_SV_ShutdownGameDLL); LogFunAdr("SV_ActivateServer", v_SV_ActivateServer); LogFunAdr("SV_CreateBaseline", v_SV_CreateBaseline); LogFunAdr("SV_BroadcastVoiceData", v_SV_BroadcastVoiceData); + LogVarAdr("s_bIsDedicated", s_bIsDedicated); } virtual void GetFun(void) const { - g_GameDll.FindPatternSIMD("48 8B C4 53 55 56 57 41 54 41 55 41 57").GetPtr(CGameServer__SpawnServer); g_GameDll.FindPatternSIMD("48 81 EC ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ??").GetPtr(v_SV_InitGameDLL); g_GameDll.FindPatternSIMD("48 83 EC 28 80 3D ?? ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48").GetPtr(v_SV_ShutdownGameDLL); g_GameDll.FindPatternSIMD("48 8B C4 56 48 81 EC ?? ?? ?? ?? 48 89 ?? ?? 48 8D").GetPtr(v_SV_ActivateServer); @@ -59,6 +96,14 @@ class HSV_Main : public IDetour { s_bIsDedicated = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 57 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9 48 8D BC 24 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 89 7C 24 ?? 48 8D 54 24 ?? 33 FF") .FindPatternSelf("40 38 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + + CMemory baseAdr = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 83 3D ?? ?? ?? ?? ?? 75 2A").OffsetSelf(0x100); + + // Grab the 4 globals in a row (FindPatternSelf moves the base address to found address). + baseAdr.FindPatternSelf("0F 95 05").ResolveRelativeAddress(3, 7).GetPtr(s_bPartyDediOnly); + baseAdr.FindPatternSelf("0F 95 05").ResolveRelativeAddress(3, 7).GetPtr(s_bTrainingDedi); + baseAdr.FindPatternSelf("0F 95 05").ResolveRelativeAddress(3, 7).GetPtr(s_bStagingDedi); + baseAdr.FindPatternSelf("0F 95 05").ResolveRelativeAddress(3, 7).GetPtr(s_bFiringRangeDedi); } virtual void GetCon(void) const { } /////////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/engine/server/sv_rcon.cpp b/r5dev/engine/server/sv_rcon.cpp index b1acbf3d..a283f83a 100644 --- a/r5dev/engine/server/sv_rcon.cpp +++ b/r5dev/engine/server/sv_rcon.cpp @@ -10,11 +10,13 @@ #include "tier2/socketcreator.h" #include "engine/cmd.h" #include "engine/net.h" +#include "engine/shared/shared_rcon.h" #include "engine/server/sv_rcon.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "common/igameserverdata.h" #include "mbedtls/include/mbedtls/sha512.h" +#include "mbedtls/aes.h" +#include "mbedtls/ctr_drbg.h" //----------------------------------------------------------------------------- // Purpose: constants @@ -27,15 +29,13 @@ static const char s_BannedMessage[] = "Go away.\n"; //----------------------------------------------------------------------------- // Purpose: console variables //----------------------------------------------------------------------------- +static void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString); static void RCON_WhiteListAddresChanged_f(IConVar* pConVar, const char* pOldString); static void RCON_ConnectionCountChanged_f(IConVar* pConVar, const char* pOldString); -static void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString); +static void RCON_UseLoopbackSocketChanged_f(IConVar* pConVar, const char* pOldString); -static ConVar rcon_password("rcon_password", "", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access password (rcon is disabled if empty)", false, 0.f, false, 0.f, &RCON_PasswordChanged_f); - -static ConVar sv_rcon_debug("sv_rcon_debug", "0", FCVAR_RELEASE, "Show rcon debug information ( !slower! )"); +static ConVar sv_rcon_password("sv_rcon_password", "", FCVAR_RELEASE, "Remote server access password (rcon server is disabled if empty)", &RCON_PasswordChanged_f); static ConVar sv_rcon_sendlogs("sv_rcon_sendlogs", "0", FCVAR_RELEASE, "Network console logs to connected and authenticated sockets"); - //static ConVar sv_rcon_banpenalty("sv_rcon_banpenalty" , "10", FCVAR_RELEASE, "Number of minutes to ban users who fail rcon authentication"); static ConVar sv_rcon_maxfailures("sv_rcon_maxfailures", "10", FCVAR_RELEASE, "Max number of times an user can fail rcon authentication before being banned", true, 1.f, false, 0.f); @@ -43,8 +43,10 @@ static ConVar sv_rcon_maxignores("sv_rcon_maxignores", "15", FCVAR_RELEASE, "Max static ConVar sv_rcon_maxsockets("sv_rcon_maxsockets", "32", FCVAR_RELEASE, "Max number of accepted sockets before the server starts closing redundant sockets", true, 1.f, true, MAX_PLAYERS); static ConVar sv_rcon_maxconnections("sv_rcon_maxconnections", "1", FCVAR_RELEASE, "Max number of authenticated connections before the server closes the listen socket", true, 1.f, true, MAX_PLAYERS, &RCON_ConnectionCountChanged_f); -static ConVar sv_rcon_maxpacketsize("sv_rcon_maxpacketsize", "1024", FCVAR_RELEASE, "Max number of bytes allowed in a command packet from a non-authenticated netconsole", true, 0.f, false, 0.f); -static ConVar sv_rcon_whitelist_address("sv_rcon_whitelist_address", "", FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts", &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'"); +static ConVar sv_rcon_maxframesize("sv_rcon_maxframesize", "1024", FCVAR_RELEASE, "Max number of bytes allowed in a message frame from a non-authenticated netconsole", true, 0.f, false, 0.f); +static ConVar sv_rcon_whitelistaddress("sv_rcon_whitelistaddress", "", FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts", &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'"); + +static ConVar sv_rcon_useloopbacksocket("sv_rcon_useloopbacksocket", "0", FCVAR_RELEASE, "Whether to bind rcon server to the loopback socket", &RCON_UseLoopbackSocketChanged_f); //----------------------------------------------------------------------------- // Purpose: @@ -54,6 +56,7 @@ CRConServer::CRConServer(void) , m_nAuthConnections(0) , m_bInitialized(false) { + memset(m_PasswordHash, 0, sizeof(m_PasswordHash)); } //----------------------------------------------------------------------------- @@ -62,18 +65,20 @@ CRConServer::CRConServer(void) CRConServer::~CRConServer(void) { // NOTE: do not call Shutdown() from the destructor as the OS's socket - // system would be shutdown by now, call Shutdown() in application + // system would be shutdown by then, call Shutdown() in application // shutdown code instead } //----------------------------------------------------------------------------- // Purpose: NETCON systems init //----------------------------------------------------------------------------- -void CRConServer::Init(void) +void CRConServer::Init(const char* pPassword, const char* pNetKey) { if (!m_bInitialized) { - if (!SetPassword(rcon_password.GetString())) + SetKey(pNetKey); + + if (!SetPassword(pPassword)) { return; } @@ -84,12 +89,14 @@ void CRConServer::Init(void) return; } - const char* pszAddress = net_usesocketsforloopback->GetBool() ? NET_IPV6_UNSPEC : NET_IPV6_LOOPBACK; + const char* pszAddress = sv_rcon_useloopbacksocket.GetBool() ? NET_IPV6_LOOPBACK : NET_IPV6_UNSPEC; m_Address.SetFromString(Format("[%s]:%i", pszAddress, hostport->GetInt()).c_str(), true); m_Socket.CreateListenSocket(m_Address); - Msg(eDLL_T::SERVER, "Remote server access initialized ('%s')\n", m_Address.ToString()); + Msg(eDLL_T::SERVER, "Remote server access initialized ('%s') with key %s'%s%s%s'\n", + m_Address.ToString(), g_svReset, g_svGreyB, GetKey(), g_svReset); + m_bInitialized = true; } @@ -120,6 +127,19 @@ void CRConServer::Shutdown(void) Msg(eDLL_T::SERVER, "Remote server access deinitialized ('%i' accepted sockets closed)\n", nConnCount); } +//----------------------------------------------------------------------------- +// Purpose: reboots the RCON server if initialized +//----------------------------------------------------------------------------- +void CRConServer::Reboot(void) +{ + if (RCONServer()->IsInitialized()) + { + Msg(eDLL_T::SERVER, "Rebooting RCON server...\n"); + RCONServer()->Shutdown(); + RCONServer()->Init(sv_rcon_password.GetString(), RCONServer()->GetKey()); + } +} + //----------------------------------------------------------------------------- // Purpose: run tasks for the RCON server //----------------------------------------------------------------------------- @@ -232,14 +252,14 @@ void CRConServer::RunFrame(void) if (CheckForBan(data)) { - SendEncode(data.m_hSocket, s_BannedMessage, "", - sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON)); + SendEncoded(data.m_hSocket, s_BannedMessage, "", + netcon::response_e::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON)); Disconnect("banned"); continue; } - Recv(data, sv_rcon_maxpacketsize.GetInt()); + Recv(data, sv_rcon_maxframesize.GetInt()); } } } @@ -292,8 +312,8 @@ bool CRConServer::SendToAll(const char* pMsgBuf, const int nMsgLen) const // nMessageType - // Output: true on success, false otherwise //----------------------------------------------------------------------------- -bool CRConServer::SendEncode(const char* pResponseMsg, const char* pResponseVal, - const sv_rcon::response_t responseType, const int nMessageId, const int nMessageType) const +bool CRConServer::SendEncoded(const char* pResponseMsg, const char* pResponseVal, + const netcon::response_e responseType, const int nMessageId, const int nMessageType) const { vector vecMsg; if (!Serialize(vecMsg, pResponseMsg, pResponseVal, @@ -320,8 +340,8 @@ bool CRConServer::SendEncode(const char* pResponseMsg, const char* pResponseVal, // nMessageType - // Output: true on success, false otherwise //----------------------------------------------------------------------------- -bool CRConServer::SendEncode(const SocketHandle_t hSocket, const char* pResponseMsg, const char* pResponseVal, - const sv_rcon::response_t responseType, const int nMessageId, const int nMessageType) const +bool CRConServer::SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, const char* pResponseVal, + const netcon::response_e responseType, const int nMessageId, const int nMessageType) const { vector vecMsg; if (!Serialize(vecMsg, pResponseMsg, pResponseVal, @@ -349,26 +369,10 @@ bool CRConServer::SendEncode(const SocketHandle_t hSocket, const char* pResponse // Output : serialized results as string //----------------------------------------------------------------------------- bool CRConServer::Serialize(vector& vecBuf, const char* pResponseMsg, const char* pResponseVal, - const sv_rcon::response_t responseType, const int nMessageId, const int nMessageType) const + const netcon::response_e responseType, const int nMessageId, const int nMessageType) const { - sv_rcon::response response; - - response.set_messageid(nMessageId); - response.set_messagetype(nMessageType); - response.set_responsetype(responseType); - response.set_responsemsg(pResponseMsg); - response.set_responseval(pResponseVal); - - const size_t msgLen = response.ByteSizeLong(); - vecBuf.resize(msgLen); - - if (!Encode(&response, &vecBuf[0], msgLen)) - { - Error(eDLL_T::SERVER, NO_ERROR, "Failed to encode RCON buffer\n"); - return false; - } - - return true; + return SV_NetConSerialize(this, vecBuf, pResponseMsg, pResponseVal, responseType, nMessageId, nMessageType, + rcon_encryptframes.GetBool(), rcon_debug.GetBool()); } //----------------------------------------------------------------------------- @@ -376,7 +380,7 @@ bool CRConServer::Serialize(vector& vecBuf, const char* pResponseMsg, cons // Input : &request - // &data - //----------------------------------------------------------------------------- -void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData& data) +void CRConServer::Authenticate(const netcon::request& request, CConnectedNetConsoleData& data) { if (data.m_bAuthorized) { @@ -395,19 +399,19 @@ void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetCon const char* pSendLogs = (!sv_rcon_sendlogs.GetBool() || data.m_bInputOnly) ? "0" : "1"; - SendEncode(data.m_hSocket, s_AuthMessage, pSendLogs, - sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); + SendEncoded(data.m_hSocket, s_AuthMessage, pSendLogs, + netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); } else // Bad password. { const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex); - if (sv_rcon_debug.GetBool()) + if (rcon_debug.GetBool()) { Msg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString()); } - SendEncode(data.m_hSocket, s_WrongPwMessage, "", - sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); + SendEncoded(data.m_hSocket, s_WrongPwMessage, "", + netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); data.m_bAuthorized = false; data.m_bValidated = false; @@ -442,21 +446,22 @@ bool CRConServer::Comparator(const string& svPassword) const //----------------------------------------------------------------------------- bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen) { - CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); + netcon::request request; - cl_rcon::request request; - if (!Decode(&request, pMsgBuf, nMsgLen)) + if (!SH_NetConUnpackEnvelope(this, pMsgBuf, nMsgLen, &request, rcon_debug.GetBool())) { - Error(eDLL_T::SERVER, NO_ERROR, "Failed to decode RCON buffer\n"); + Disconnect("received invalid message"); return false; } + CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); + if (!data.m_bAuthorized && - request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH) + request.requesttype() != netcon::request_e::SERVERDATA_REQUEST_AUTH) { // Notify netconsole that authentication is required. - SendEncode(data.m_hSocket, s_NoAuthMessage, "", - sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); + SendEncoded(data.m_hSocket, s_NoAuthMessage, "", + netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast(eDLL_T::NETCON)); data.m_bValidated = false; data.m_nIgnoredMessage++; @@ -464,12 +469,12 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen) } switch (request.requesttype()) { - case cl_rcon::request_t::SERVERDATA_REQUEST_AUTH: + case netcon::request_e::SERVERDATA_REQUEST_AUTH: { Authenticate(request, data); break; } - case cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND: + case netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND: { if (data.m_bAuthorized) // Only execute if auth was successful. { @@ -477,7 +482,7 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen) } break; } - case cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG: + case netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG: { if (data.m_bAuthorized) { @@ -507,59 +512,9 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen) // Purpose: execute commands issued from netconsole (ignores all protection flags) // Input : &request - //----------------------------------------------------------------------------- -void CRConServer::Execute(const cl_rcon::request& request) const +void CRConServer::Execute(const netcon::request& request) const { - const string& commandString = request.requestmsg(); - const char* const pCommandString = commandString.c_str(); - - ConCommandBase* pCommandBase = g_pCVar->FindCommandBase(pCommandString); - - if (!pCommandBase) - { - // Found nothing. - return; - } - - const char* const pValueString = request.requestval().c_str(); - - if (pCommandBase->IsFlagSet(FCVAR_SERVER_FRAME_THREAD)) - ThreadJoinServerJob(); - - if (!pCommandBase->IsCommand()) - { - // Here we want to skip over the command string in the value buffer. - // So if we got 'sv_cheats 1' in our value buffer, we want to skip - // over 'sv_cheats ', so that we are pointing directly to the value. - const char* pFound = V_strstr(pValueString, pCommandString); - const char* pValue = nullptr; - - if (pFound) - { - pValue = pFound + commandString.length(); - - // Skip any leading space characters. - while (*pValue == ' ') - { - ++pValue; - } - } - - ConVar* pConVar = reinterpret_cast(pCommandBase); - pConVar->SetValue(pValue ? pValue : pValueString); - } - else // Invoke command callback directly. - { - CCommand cmd; - - // Only tokenize if we actually have strings in the value buffer, some - // commands (like 'status') don't need any additional parameters. - if (VALID_CHARSTAR(pValueString)) - { - cmd.Tokenize(pValueString, cmd_source_t::kCommandSrcCode); - } - - v_Cmd_Dispatch(ECommandTarget_t::CBUF_SERVER, pCommandBase, &cmd, false); - } + Cmd_ExecuteUnrestricted(request.requestmsg().c_str(), request.requestval().c_str()); } //----------------------------------------------------------------------------- @@ -578,10 +533,10 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData& data) if (m_BannedList.size() >= RCON_MAX_BANNEDLIST_SIZE) { - const char* pszWhiteListAddress = sv_rcon_whitelist_address.GetString(); + const char* pszWhiteListAddress = sv_rcon_whitelistaddress.GetString(); if (!pszWhiteListAddress[0]) { - Warning(eDLL_T::SERVER, "Banned list overflowed; please use a whitelist address. RCON shutting down...\n"); + Warning(eDLL_T::SERVER, "Banned list overflowed, please use a whitelist address; remote server access shutting down...\n"); Shutdown(); return true; @@ -590,9 +545,9 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData& data) // Only allow whitelisted at this point. if (!m_WhiteListAddress.CompareAdr(netAdr)) { - if (sv_rcon_debug.GetBool()) + if (rcon_debug.GetBool()) { - Msg(eDLL_T::SERVER, "Banned list is full; dropping '%s'\n", szNetAdr); + Warning(eDLL_T::SERVER, "Banned list is full, dropping '%s'\n", szNetAdr); } return true; @@ -680,7 +635,7 @@ void CRConServer::CloseNonAuthConnection(void) // Input : responseType - // Output : true if it should send, false otherwise //----------------------------------------------------------------------------- -bool CRConServer::ShouldSend(const sv_rcon::response_t responseType) const +bool CRConServer::ShouldSend(const netcon::response_e responseType) const { if (!IsInitialized() || !m_Socket.GetAcceptedSocketCount()) { @@ -688,7 +643,7 @@ bool CRConServer::ShouldSend(const sv_rcon::response_t responseType) const return false; } - if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG) + if (responseType == netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG) { if (!sv_rcon_sendlogs.GetBool() || !m_Socket.GetAuthorizedSocketCount()) { @@ -716,6 +671,29 @@ int CRConServer::GetAuthenticatedCount(void) const return m_nAuthConnections; } +//----------------------------------------------------------------------------- +// Purpose: change RCON password on server and drop all connections +//----------------------------------------------------------------------------- +static void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString) +{ + if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) + { + const char* pNewString = pConVarRef->GetString(); + + if (strcmp(pOldString, pNewString) == NULL) + return; // Same password. + + if (RCONServer()->IsInitialized()) + { + RCONServer()->SetPassword(pNewString); + } + else // Initialize first + { + RCON_InitServerAndTrySyncKeys(pNewString); + } + } +} + //----------------------------------------------------------------------------- // Purpose: change whitelist address on RCON server //----------------------------------------------------------------------------- @@ -773,19 +751,19 @@ static void RCON_ConnectionCountChanged_f(IConVar* pConVar, const char* pOldStri } //----------------------------------------------------------------------------- -// Purpose: change RCON password on server and drop all connections +// Purpose: change whether to bind on loopback socket //----------------------------------------------------------------------------- -void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString) +static void RCON_UseLoopbackSocketChanged_f(IConVar* pConVar, const char* pOldString) { if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) { if (strcmp(pOldString, pConVarRef->GetString()) == NULL) - return; // Same password. + return; // Same value. - if (RCONServer()->IsInitialized()) - RCONServer()->SetPassword(pConVarRef->GetString()); - else - RCONServer()->Init(); // Initialize first. +#ifndef CLIENT_DLL + // Reboot the RCON server to switch address type. + RCONServer()->Reboot(); +#endif // !CLIENT_DLL } } diff --git a/r5dev/engine/server/sv_rcon.h b/r5dev/engine/server/sv_rcon.h index a557181c..821c7589 100644 --- a/r5dev/engine/server/sv_rcon.h +++ b/r5dev/engine/server/sv_rcon.h @@ -1,8 +1,7 @@ #pragma once #include "tier1/NetAdr.h" #include "tier2/socketcreator.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "engine/shared/base_rcon.h" #define RCON_MIN_PASSWORD_LEN 8 @@ -15,45 +14,48 @@ public: CRConServer(void); ~CRConServer(void); - void Init(void); + void Init(const char* pPassword, const char* pNetKey = nullptr); void Shutdown(void); + void Reboot(void); + bool SetPassword(const char* pszPassword); bool SetWhiteListAddress(const char* pszAddress); void Think(void); void RunFrame(void); - bool SendEncode(const char* pResponseMsg, const char* pResponseVal, - const sv_rcon::response_t responseType, + bool SendEncoded(const char* pResponseMsg, const char* pResponseVal, + const netcon::response_e responseType, const int nMessageId = static_cast(eDLL_T::NETCON), const int nMessageType = static_cast(LogType_t::LOG_NET)) const; - bool SendEncode(const SocketHandle_t hSocket, const char* pResponseMsg, - const char* pResponseVal, const sv_rcon::response_t responseType, + bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg, + const char* pResponseVal, const netcon::response_e responseType, const int nMessageId = static_cast(eDLL_T::NETCON), const int nMessageType = static_cast(LogType_t::LOG_NET)) const; bool SendToAll(const char* pMsgBuf, const int nMsgLen) const; - bool Serialize(vector& vecBuf, const char* pResponseMsg, const char* pResponseVal, const sv_rcon::response_t responseType, + bool Serialize(vector& vecBuf, const char* pResponseMsg, const char* pResponseVal, const netcon::response_e responseType, const int nMessageId = static_cast(eDLL_T::NETCON), const int nMessageType = static_cast(LogType_t::LOG_NET)) const; - void Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData& data); + void Authenticate(const netcon::request& request, CConnectedNetConsoleData& data); bool Comparator(const string& svPassword) const; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override; - void Execute(const cl_rcon::request& request) const; + void Execute(const netcon::request& request) const; bool CheckForBan(CConnectedNetConsoleData& data); virtual void Disconnect(const char* szReason = nullptr) override; void Disconnect(const int nIndex, const char* szReason = nullptr); void CloseNonAuthConnection(void); - bool ShouldSend(const sv_rcon::response_t responseType) const; + bool ShouldSend(const netcon::response_e responseType) const; bool IsInitialized(void) const; int GetAuthenticatedCount(void) const; + void CloseAllSockets() { m_Socket.CloseAllAcceptedSockets(); } private: int m_nConnIndex; diff --git a/r5dev/engine/shared/base_rcon.cpp b/r5dev/engine/shared/base_rcon.cpp index f7e2fb21..5008737e 100644 --- a/r5dev/engine/shared/base_rcon.cpp +++ b/r5dev/engine/shared/base_rcon.cpp @@ -4,9 +4,126 @@ // //===========================================================================// #include "core/stdafx.h" +#include "tier2/cryptutils.h" #include "base_rcon.h" #include "engine/net.h" #include "shared_rcon.h" +#include "protoc/netcon.pb.h" +#include "mbedtls/base64.h" + +//----------------------------------------------------------------------------- +// Purpose: sets the encryption key, a key will always be set, either random or +// the default key on failure +// Input : *pBase64NetKey - +// bUseDefaultOnFailure - +//----------------------------------------------------------------------------- +void CNetConBase::SetKey(const char* pBase64NetKey, const bool bUseDefaultOnFailure/* = false*/) +{ + // Drop all connections as they would be unable to decipher the message + // frames once the key has been swapped. + m_Socket.CloseAllAcceptedSockets(); + + bool parseInput = pBase64NetKey && *pBase64NetKey; + bool genRandom = !parseInput; + + bool failure = false; + + if (parseInput) + { + const size_t keyLen = strlen(pBase64NetKey); + string tokenizedKey; + + if (keyLen != AES_128_B64_ENCODED_SIZE || !IsValidBase64(pBase64NetKey, &tokenizedKey)) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: invalid key (%s)\n", pBase64NetKey); + failure = true; + } + else + { + size_t numBytesDecoded = 0; + + const int decodeRet = mbedtls_base64_decode(m_NetKey, sizeof(m_NetKey), &numBytesDecoded, + reinterpret_cast(tokenizedKey.c_str()), tokenizedKey.length()); + + if (decodeRet != 0) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: decode error (%d)\n", decodeRet); + failure = true; + } + else if (numBytesDecoded != sizeof(m_NetKey)) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: read error (%zu != %zu)\n", numBytesDecoded, sizeof(m_NetKey)); + failure = true; + } + else + { + m_Base64NetKey = tokenizedKey.c_str(); + } + } + } + + bool useDefaultKey = false; // Last resort + + if (genRandom || failure) // Generate random key + { + if (failure && bUseDefaultOnFailure) + { + useDefaultKey = true; + } + else + { + const char* errorMsg = nullptr; + + if (!Plat_GenerateRandom(m_NetKey, sizeof(m_NetKey), errorMsg)) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: generate error (%s)\n", errorMsg); + useDefaultKey = true; + } + else // Try to encode it + { + char encodedKey[45]; + memset(encodedKey, 0, sizeof(encodedKey)); + + size_t numBytesEncoded = 0; + + const int encodeRet = mbedtls_base64_encode(reinterpret_cast(&encodedKey), + sizeof(encodedKey), &numBytesEncoded, m_NetKey, sizeof(m_NetKey)); + + if (encodeRet != 0) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: encode error (%d)\n", encodeRet); + useDefaultKey = true; + } + else if (numBytesEncoded != AES_128_B64_ENCODED_SIZE) + { + Error(eDLL_T::ENGINE, NO_ERROR, "RCON Key: write error (%zu != %zu)\n", numBytesEncoded, AES_128_B64_ENCODED_SIZE); + failure = true; + } + else + { + m_Base64NetKey = encodedKey; + } + } + } + } + + if (useDefaultKey) // Use the default key if everything failed (unlikely) + { + size_t numBytesDecoded = 0; + mbedtls_base64_decode(m_NetKey, sizeof(m_NetKey), &numBytesDecoded, + reinterpret_cast(DEFAULT_NET_ENCRYPTION_KEY), AES_128_B64_ENCODED_SIZE); + + m_Base64NetKey = DEFAULT_NET_ENCRYPTION_KEY; + } +} + +//----------------------------------------------------------------------------- +// Purpose: gets the encryption key as a base64 encoded string +//----------------------------------------------------------------------------- +const char* CNetConBase::GetKey(void) const +{ + return m_Base64NetKey.String(); +} //----------------------------------------------------------------------------- // Purpose: connect to remote @@ -56,7 +173,7 @@ bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data, data.m_nPayloadRead = 0; } } - else if (data.m_nPayloadRead+1 <= sizeof(int)) // Read size field. + else if (data.m_nPayloadRead < sizeof(int)) // Read size field. { data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf; @@ -95,6 +212,39 @@ bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data, return bSuccess; } +//----------------------------------------------------------------------------- +// Purpose: encrypt message to buffer +// Input : &ctx - +// *pInBuf - +// *pOutBuf - +// nDataLen - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool CNetConBase::Encrypt(CryptoContext_s& ctx, const char* pInBuf, + char* pOutBuf, const size_t nDataLen) const +{ + if (Crypto_GenerateIV(ctx, reinterpret_cast(pInBuf), nDataLen)) + return Crypto_CTREncrypt(ctx, reinterpret_cast(pInBuf), + reinterpret_cast(pOutBuf), m_NetKey, nDataLen); + + return false; // failure +} + +//----------------------------------------------------------------------------- +// Purpose: decrypt message to buffer +// Input : &ctx - +// *pInBuf - +// *pOutBuf - +// nDataLen - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool CNetConBase::Decrypt(CryptoContext_s& ctx, const char* pInBuf, + char* pOutBuf, const size_t nDataLen) const +{ + return Crypto_CTRDecrypt(ctx, reinterpret_cast(pInBuf), + reinterpret_cast(pOutBuf), m_NetKey, nDataLen); +} + //----------------------------------------------------------------------------- // Purpose: encode message to buffer // Input : *pMsg - diff --git a/r5dev/engine/shared/base_rcon.h b/r5dev/engine/shared/base_rcon.h index 5ce54733..8bbf2ec4 100644 --- a/r5dev/engine/shared/base_rcon.h +++ b/r5dev/engine/shared/base_rcon.h @@ -2,14 +2,23 @@ #define BASE_RCON_H #include "tier1/NetAdr.h" +#include "tier2/cryptutils.h" #include "tier2/socketcreator.h" #include "protobuf/message_lite.h" +// Max size of the payload in the envelope frame +#define RCON_MAX_PAYLOAD_SIZE 1024*1024 + class CNetConBase { public: CNetConBase(void) - {} + { + memset(m_NetKey, 0, sizeof(m_NetKey)); + } + + void SetKey(const char* pBase64NetKey, const bool bUseDefaultOnFailure = false); + const char* GetKey(void) const; virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR); virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); }; @@ -17,6 +26,9 @@ public: virtual bool ProcessBuffer(CConnectedNetConsoleData& data, const char* pRecvBuf, int nRecvLen, const int nMaxLen = SOCKET_ERROR); virtual bool ProcessMessage(const char* /*pMsgBuf*/, int /*nMsgLen*/) { return true; }; + virtual bool Encrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const; + virtual bool Decrypt(CryptoContext_s& ctx, const char* pInBuf, char* pOutBuf, const size_t nDataLen) const; + virtual bool Encode(google::protobuf::MessageLite* pMsg, char* pMsgBuf, const size_t nMsgLen) const; virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const; @@ -29,6 +41,8 @@ public: protected: CSocketCreator m_Socket; netadr_t m_Address; + CryptoKey_t m_NetKey; + CUtlString m_Base64NetKey; }; #endif // BASE_RCON_H diff --git a/r5dev/engine/shared/shared_rcon.cpp b/r5dev/engine/shared/shared_rcon.cpp index 1ead017f..9104d608 100644 --- a/r5dev/engine/shared/shared_rcon.cpp +++ b/r5dev/engine/shared/shared_rcon.cpp @@ -6,6 +6,39 @@ #include "core/stdafx.h" #include "base_rcon.h" #include "shared_rcon.h" +#include "protoc/netcon.pb.h" + +//----------------------------------------------------------------------------- +// Purpose: serialize message to vector +// Input : *pBase - +// &vecBuf - +// *pResponseMsg - +// *pResponseVal - +// responseType - +// nMessageId - +// nMessageType - +// bEncrypt - +// bDebug - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool SV_NetConSerialize(const CNetConBase* pBase, vector& vecBuf, const char* pResponseMsg, const char* pResponseVal, + const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug) +{ + netcon::response response; + + response.set_messageid(nMessageId); + response.set_messagetype(nMessageType); + response.set_responsetype(responseType); + response.set_responsemsg(pResponseMsg); + response.set_responseval(pResponseVal); + + if (!SH_NetConPackEnvelope(pBase, vecBuf, response.ByteSizeLong(), &response, bEncrypt, bDebug)) + { + return false; + } + + return true; +} //----------------------------------------------------------------------------- // Purpose: serialize message to vector @@ -14,24 +47,22 @@ // *szReqBuf - // *szReqVal - // *requestType - +// bEncrypt - +// bDebug - // Output : true on success, false otherwise //----------------------------------------------------------------------------- bool CL_NetConSerialize(const CNetConBase* pBase, vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType) + const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug) { - cl_rcon::request request; + netcon::request request; request.set_messageid(-1); request.set_requesttype(requestType); request.set_requestmsg(szReqBuf); request.set_requestval(szReqVal); - const size_t msgLen = request.ByteSizeLong(); - vecBuf.resize(msgLen); - - if (!pBase->Encode(&request, &vecBuf[0], msgLen)) + if (!SH_NetConPackEnvelope(pBase, vecBuf, request.ByteSizeLong(), &request, bEncrypt, bDebug)) { - Error(eDLL_T::CLIENT, NO_ERROR, "Failed to encode RCON buffer\n"); return false; } @@ -50,7 +81,7 @@ bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostP string svLocalHost; const bool bValidSocket = nHostPort != SOCKET_ERROR; - if (bValidSocket && strcmp(pHostAdr, "localhost") == 0) + if (bValidSocket && (strcmp(pHostAdr, "localhost") == 0)) { char szHostName[512]; if (!gethostname(szHostName, sizeof(szHostName))) @@ -83,6 +114,165 @@ bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostP return true; } +//----------------------------------------------------------------------------- +// Purpose: packs a message envelope +// Input : *pBase - +// &outMsgBuf - +// nMsgLen - +// *inMsg - +// bEncrypt - +// bDebug - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool SH_NetConPackEnvelope(const CNetConBase* pBase, vector& outMsgBuf, const size_t nMsgLen, + google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug) +{ + char* encodeBuf = new char[nMsgLen]; + std::unique_ptr encodedContainer(encodeBuf); + + if (!pBase->Encode(inMsg, encodeBuf, nMsgLen)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to encode RCON message data\n"); + } + + return false; + } + + netcon::envelope envelope; + envelope.set_encrypted(bEncrypt); + + const char* dataBuf = encodeBuf; + std::unique_ptr container; + + if (bEncrypt) + { + char* encryptBuf = new char[nMsgLen]; + container.reset(encryptBuf); + + CryptoContext_s ctx; + if (!pBase->Encrypt(ctx, encodeBuf, encryptBuf, nMsgLen)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to encrypt RCON message data\n"); + } + + return false; + } + + envelope.set_nonce(ctx.ivData, sizeof(ctx.ivData)); + dataBuf = encryptBuf; + } + + envelope.set_data(dataBuf, nMsgLen); + const size_t envelopeSize = envelope.ByteSizeLong(); + + outMsgBuf.resize(envelopeSize); + + if (!pBase->Encode(&envelope, &outMsgBuf[0], envelopeSize)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to encode RCON message envelope\n"); + } + + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: unpacks a message envelope +// Input : *pBase - +// *pMsgBuf - +// nMsgLen - +// *outMsg - +// bEncrypt - +// bDebug - +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool SH_NetConUnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen, + google::protobuf::MessageLite* outMsg, const bool bDebug) +{ + netcon::envelope envelope; + + if (!pBase->Decode(&envelope, pMsgBuf, nMsgLen)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to decode RCON message envelope\n"); + } + + return false; + } + + const size_t msgLen = envelope.data().size(); + + if (msgLen > RCON_MAX_PAYLOAD_SIZE) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Data in RCON message envelope is too large (%zu > %zu)\n", + msgLen, RCON_MAX_PAYLOAD_SIZE); + + return false; + } + + const char* netMsg = envelope.data().c_str(); + const char* dataBuf = netMsg; + + std::unique_ptr container; + + if (envelope.encrypted()) + { + char* decryptBuf = new char[msgLen]; + container.reset(decryptBuf); + + const size_t ivLen = envelope.nonce().size(); + + if (ivLen != sizeof(CryptoIV_t)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Nonce in RCON message envelope is invalid (%zu != %zu)\n", + ivLen, sizeof(CryptoIV_t)); + } + + return false; + } + + CryptoContext_s ctx; + memcpy(ctx.ivData, envelope.nonce().data(), ivLen); + + if (!pBase->Decrypt(ctx, netMsg, decryptBuf, msgLen)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to decrypt RCON message data\n"); + } + + return false; + } + + dataBuf = decryptBuf; + } + + Assert(dataBuf); + + if (!pBase->Decode(outMsg, dataBuf, msgLen)) + { + if (bDebug) + { + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to decode RCON message data\n"); + } + + return false; + } + + return true; +} + //----------------------------------------------------------------------------- // Purpose: gets the netconsole data // Input : *pBase - @@ -119,3 +309,92 @@ SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, const int iSocket) return pData->m_hSocket; } + +#ifndef _TOOLS + +#ifndef CLIENT_DLL +#include "engine/server/sv_rcon.h" +#endif // !CLIENT_DLL +#ifndef DEDICATED +#include "engine/client/cl_rcon.h" +#endif // !DEDICATED + +void RCON_KeyChanged_f(IConVar* pConVar, const char* pOldString); +void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString); + +ConVar rcon_debug("rcon_debug", "0", FCVAR_RELEASE, "Show rcon debug information ( !slower! )"); +ConVar rcon_encryptframes("rcon_encryptframes", "1", FCVAR_RELEASE, "Whether to encrypt RCON messages"); +ConVar rcon_key("rcon_key", "", FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Base64 remote server access encryption key (random if empty or invalid)", &RCON_KeyChanged_f); + +//----------------------------------------------------------------------------- +// Purpose: change RCON key on server and client +//----------------------------------------------------------------------------- +void RCON_KeyChanged_f(IConVar* pConVar, const char* pOldString) +{ + if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) + { + const char* pNewString = pConVarRef->GetString(); + + if (strcmp(pOldString, pNewString) == NULL) + return; // Same key. + + +#if !defined(DEDICATED) && !defined(CLIENT_DLL) + RCONServer()->SetKey(pNewString); + RCONClient()->SetKey(RCONServer()->GetKey()); // Sync server & client keys + + Msg(eDLL_T::ENGINE, "Installed RCON Key: %s'%s%s%s'\n", + g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset); +#else +#ifdef DEDICATED + RCONServer()->SetKey(pNewString); + + Msg(eDLL_T::SERVER, "Installed RCON Key: %s'%s%s%s'\n", + g_svReset, g_svGreyB, RCONServer()->GetKey(), g_svReset); +#endif // DEDICATED +#ifdef CLIENT_DLL + RCONClient()->SetKey(pNewString); + + Msg(eDLL_T::CLIENT, "Installed RCON Key: %s'%s%s%s'\n", + g_svReset, g_svGreyB, RCONClient()->GetKey(), g_svReset); +#endif // CLIENT_DLL + +#endif // !DEDICATED && !CLIENT_DLL + } +} + +#ifndef CLIENT_DLL +void RCON_InitServerAndTrySyncKeys(const char* pPassword) +{ +#ifndef DEDICATED + RCONServer()->Init(pPassword, rcon_key.GetString()); + + if (RCONServer()->IsInitialized()) + { + // Sync server & client keys + RCONClient()->SetKey(RCONServer()->GetKey()); + } +#else + RCONServer()->Init(pPassword, rcon_key.GetString()); +#endif // !DEDICATED +} +#endif // !CLIENT_DLL + +#ifndef DEDICATED +void RCON_InitClientAndTrySyncKeys() +{ +#ifndef CLIENT_DLL + if (RCONServer()->IsInitialized()) + { + // Sync server & client keys + RCONClient()->Init(RCONServer()->GetKey()); + } + else +#endif // !CLIENT_DLL + { + RCONClient()->Init(rcon_key.GetString()); + } +} +#endif // !DEDICATED + +#endif // !_TOOLS diff --git a/r5dev/engine/shared/shared_rcon.h b/r5dev/engine/shared/shared_rcon.h index 394a8f9d..b2ed8fcc 100644 --- a/r5dev/engine/shared/shared_rcon.h +++ b/r5dev/engine/shared/shared_rcon.h @@ -1,13 +1,31 @@ #ifndef SHARED_RCON_H #define SHARED_RCON_H #include "base_rcon.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" + +#ifndef _TOOLS +extern ConVar rcon_debug; +extern ConVar rcon_encryptframes; +extern ConVar rcon_key; + +#ifndef CLIENT_DLL +extern void RCON_InitServerAndTrySyncKeys(const char* pPassword); +#endif // !CLIENT_DLL +#ifndef DEDICATED +extern void RCON_InitClientAndTrySyncKeys(); +#endif // !DEDICATED +#endif // _TOOLS + +bool SV_NetConSerialize(const CNetConBase* pBase, vector& vecBuf, const char* pResponseMsg, const char* pResponseVal, + const netcon::response_e responseType, const int nMessageId, const int nMessageType, const bool bEncrypt, const bool bDebug); bool CL_NetConSerialize(const CNetConBase* pBase, vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType); + const char* szReqVal, const netcon::request_e requestType, const bool bEncrypt, const bool bDebug); bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort); +bool SH_NetConPackEnvelope(const CNetConBase* pBase, vector& outMsgBuf, const size_t nMsgLen, google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug); +bool SH_NetConUnpackEnvelope(const CNetConBase* pBase, const char* pMsgBuf, const size_t nMsgLen, google::protobuf::MessageLite* outMsg, const bool bDebug); + CConnectedNetConsoleData* SH_GetNetConData(CNetConBase* pBase, const int iSocket); SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, const int iSocket); diff --git a/r5dev/engine/sys_dll.cpp b/r5dev/engine/sys_dll.cpp index 5a3d21a2..e65fa81d 100644 --- a/r5dev/engine/sys_dll.cpp +++ b/r5dev/engine/sys_dll.cpp @@ -20,6 +20,7 @@ #include "engine/host_cmd.h" #include "engine/enginetrace.h" #ifndef CLIENT_DLL +#include "engine/server/server.h" #include "engine/server/sv_main.h" #include "server/vengineserver_impl.h" #include "game/server/gameinterface.h" diff --git a/r5dev/game/CMakeLists.txt b/r5dev/game/CMakeLists.txt index b24557d3..68105c4f 100644 --- a/r5dev/game/CMakeLists.txt +++ b/r5dev/game/CMakeLists.txt @@ -7,32 +7,56 @@ start_sources() if( ${PROJECT_NAME} STREQUAL "game_shared_static" ) -add_sources( SOURCE_GROUP "Shared" +add_sources( SOURCE_GROUP "AI" "shared/ai_utility_shared.cpp" "shared/ai_utility_shared.h" - "shared/animation.cpp" - "shared/animation.h" - "shared/collisionproperty.cpp" - "shared/collisionproperty.h" +) + +add_sources( SOURCE_GROUP "Entity" "shared/ehandle.h" "shared/entitylist_base.cpp" "shared/entitylist_base.h" - "shared/imovehelper.h" - "shared/playernet_vars.h" +) + +add_sources( SOURCE_GROUP "Prediction" "shared/predictioncopy.h" - "shared/shared_classnames.h" - "shared/shareddefs.h" - "shared/takedamageinfo.h" +) + +add_sources( SOURCE_GROUP "Animation" + "shared/animation.cpp" + "shared/animation.h" +) + +add_sources( SOURCE_GROUP "Collision" + "shared/collisionproperty.cpp" + "shared/collisionproperty.h" +) + +add_sources( SOURCE_GROUP "Network" + "shared/playernet_vars.h" "shared/usercmd.cpp" "shared/usercmd.h" "shared/usermessages.h" +) + +add_sources( SOURCE_GROUP "Utility" + "shared/imovehelper.h" "shared/util_shared.cpp" "shared/util_shared.h" +) + +add_sources( SOURCE_GROUP "Shared" + "shared/shared_classnames.h" + "shared/shareddefs.h" + "shared/takedamageinfo.h" +) + +add_sources( SOURCE_GROUP "Script" "shared/vscript_shared.cpp" "shared/vscript_shared.h" ) -add_sources( SOURCE_GROUP "Shared/Weapon" +add_sources( SOURCE_GROUP "Weapon" "shared/r1/weapon_bolt.cpp" "shared/r1/weapon_bolt.h" ) @@ -73,6 +97,8 @@ add_sources( SOURCE_GROUP "Network" add_sources( SOURCE_GROUP "Player" "server/player.cpp" "server/player.h" + "server/player_command.cpp" + "server/player_command.h" "server/playerlocaldata.h" ) @@ -114,22 +140,37 @@ endif() if( ${PROJECT_NAME} STREQUAL "client_static" ) -add_sources( SOURCE_GROUP "Client" +add_sources( SOURCE_GROUP "Entity" "client/c_baseentity.cpp" "client/c_baseentity.h" - "client/c_baseplayer.h" "client/cliententitylist.h" - "client/enginesprite.h" - "client/hud.h" +) + +add_sources( SOURCE_GROUP "Player" + "client/c_baseplayer.h" +) + +add_sources( SOURCE_GROUP "Input" "client/input.cpp" "client/input.h" - "client/movehelper_client.cpp" - "client/movehelper_client.h" +) + +add_sources( SOURCE_GROUP "Rendering" + "client/enginesprite.h" + "client/hud.h" "client/spritemodel.cpp" - "client/util_client.cpp" - "client/util_client.h" "client/viewrender.cpp" "client/viewrender.h" +) + +add_sources( SOURCE_GROUP "Utility" + "client/movehelper_client.cpp" + "client/movehelper_client.h" + "client/util_client.cpp" + "client/util_client.h" +) + +add_sources( SOURCE_GROUP "Script" "client/vscript_client.cpp" "client/vscript_client.h" ) diff --git a/r5dev/game/server/ai_network.cpp b/r5dev/game/server/ai_network.cpp index 3604cbd5..2e5591b5 100644 --- a/r5dev/game/server/ai_network.cpp +++ b/r5dev/game/server/ai_network.cpp @@ -63,11 +63,13 @@ int CAI_Network::NumLinks(void) const //----------------------------------------------------------------------------- // Purpose: gets the number of zones +// input : idx - // Output : int //----------------------------------------------------------------------------- -int CAI_Network::NumZones(void) const +int CAI_Network::NumZones(const int idx) const { - return m_iNumZones; + Assert(idx >= 0 && idx < sizeof(m_iNumZones)); + return m_iNumZones[idx]; } //----------------------------------------------------------------------------- diff --git a/r5dev/game/server/ai_network.h b/r5dev/game/server/ai_network.h index ee71feb4..0d81cbfb 100644 --- a/r5dev/game/server/ai_network.h +++ b/r5dev/game/server/ai_network.h @@ -12,7 +12,7 @@ public: static void DebugConnectMsg(int node1, int node2, const char* pszFormat, ...); void* GetVTable(void) const; int NumLinks(void) const; - int NumZones(void) const; + int NumZones(const int idx) const; int NumHints(void) const; int NumScriptNodes(void) const; int NumPathNodes(void) const; @@ -32,12 +32,7 @@ public: int m_nUnk0; CAI_HullData m_HullData[MAX_HULLS]; - - int m_iNumZones; // +0x0088 - int m_iUnkCount0; - int m_iUnkCount1; - int m_iUnkCount2; - int m_iUnkCount4; + int m_iNumZones[MAX_HULLS]; // +0x0088 // unk8 on disk int unk5; // +0x009C diff --git a/r5dev/game/server/ai_networkmanager.cpp b/r5dev/game/server/ai_networkmanager.cpp index 4b8f6abc..f8d8c015 100644 --- a/r5dev/game/server/ai_networkmanager.cpp +++ b/r5dev/game/server/ai_networkmanager.cpp @@ -225,19 +225,18 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) // Dump the hull data blocks // ------------------------------- - // Pointer to numZones counter, incremented up and until - // the last counter field for the hull data block. - int* countPtr = &pNetwork->m_iNumZones; - - for (int i = 0; i < MAX_HULLS; i++, countPtr++) + for (int i = 0; i < MAX_HULLS; i++) { const CAI_HullData& hullData = pNetwork->m_HullData[i]; - const int bufferSize = sizeof(int) * hullData.unk1; + const int numHullZones = pNetwork->m_iNumZones[i]; - buf.PutInt(*countPtr); - buf.PutShort(hullData.m_Count); - buf.PutShort(hullData.unk1); - buf.Put(hullData.pBuffer, bufferSize); + const unsigned short numHullBits = (unsigned short)hullData.m_bitVec.GetNumBits(); + const unsigned short numHullInts = (unsigned short)hullData.m_bitVec.GetNumDWords(); + + buf.PutInt(numHullZones); + buf.PutUnsignedShort(numHullBits); + buf.PutUnsignedShort(numHullInts); + buf.Put(hullData.m_bitVec.Base(), numHullInts * sizeof(int)); } timer.End(); diff --git a/r5dev/game/server/ai_node.h b/r5dev/game/server/ai_node.h index 96a455ea..a315375d 100644 --- a/r5dev/game/server/ai_node.h +++ b/r5dev/game/server/ai_node.h @@ -5,6 +5,7 @@ //=============================================================================// #pragma once #include "mathlib/vector.h" +#include "mathlib/bitvec.h" constexpr int MAX_HULLS = 5; constexpr int NOT_CACHED = -2; // Returned if data not in cache @@ -153,13 +154,15 @@ struct CAI_ScriptNode }; //============================================================================= -// >> CAI_ScriptNode +// >> CAI_HullData //============================================================================= struct CAI_HullData { - short m_Count; // Multiplied by 4; probably total buffer size. - short unk1; - int unk2; - void* pBuffer; // Hull data buffer. + CVarBitVec m_bitVec; + + // Unknown, possible part of CVarBitVec ??? see [r5apex_ds + 1A52B0] if, + // this is part of CVarBitVec, it seems to be unused in any of the + // compiled CVarBitVec and CLargeVarBitVec methods so i think it should be + // just part of this struct. char unk3[8]; }; diff --git a/r5dev/game/server/basecombatcharacter.h b/r5dev/game/server/basecombatcharacter.h index ef93c12a..c92d72da 100644 --- a/r5dev/game/server/basecombatcharacter.h +++ b/r5dev/game/server/basecombatcharacter.h @@ -44,6 +44,10 @@ struct CTether //----------------------------------------------------------------------------- class CBaseCombatCharacter : public CBaseAnimatingOverlay { +public: + inline const char* GetNetName() const { return m_szNetname; }; + +private: bool m_bPreventWeaponPickup; char gap_15b1[3]; float m_phaseShiftTimeStart; @@ -146,5 +150,4 @@ class CBaseCombatCharacter : public CBaseAnimatingOverlay int m_headAttachment; int m_chestAttachment; }; - #endif // BASECOMBATCHARACTER_H diff --git a/r5dev/game/server/baseentity.h b/r5dev/game/server/baseentity.h index 88cd720e..950e8748 100644 --- a/r5dev/game/server/baseentity.h +++ b/r5dev/game/server/baseentity.h @@ -56,6 +56,8 @@ public: inline edict_t GetEdict(void) { return NetworkProp()->GetEdict(); } inline string_t GetEntityName(void) const { return m_iName; } + inline int GetFlags(void) const { return m_fFlags; } + protected: CBaseHandle m_RefEHandle; char gap_c[4]; diff --git a/r5dev/game/server/gameinterface.cpp b/r5dev/game/server/gameinterface.cpp index 8b16f760..7905e32a 100644 --- a/r5dev/game/server/gameinterface.cpp +++ b/r5dev/game/server/gameinterface.cpp @@ -18,14 +18,15 @@ #include "engine/server/server.h" #include "game/shared/usercmd.h" #include "game/server/util_server.h" +#include "pluginsystem/pluginsystem.h" //----------------------------------------------------------------------------- // This is called when a new game is started. (restart, map) //----------------------------------------------------------------------------- -void CServerGameDLL::GameInit(void) +bool CServerGameDLL::GameInit(void) { const static int index = 1; - CallVFunc(index, this); + return CallVFunc(index, this); } //----------------------------------------------------------------------------- @@ -77,8 +78,39 @@ ServerClass* CServerGameDLL::GetAllServerClasses(void) return CallVFunc(index, this); } +static ConVar chat_debug("chat_debug", "0", FCVAR_RELEASE, "Enables chat-related debug printing."); + void __fastcall CServerGameDLL::OnReceivedSayTextMessage(void* thisptr, int senderId, const char* text, bool isTeamChat) { + const CGlobalVars* globals = *g_pGlobals; + if (senderId > 0) + { + if (senderId <= globals->m_nMaxPlayers && senderId != 0xFFFF) + { + CPlayer* player = reinterpret_cast(globals->m_pEdicts[senderId + 30728]); + + if (player && player->IsConnected()) + { + for (auto& cb : !g_PluginSystem.GetChatMessageCallbacks()) + { + if (!cb.Function()(player, text, sv_forceChatToTeamOnly->GetBool())) + { + if (chat_debug.GetBool()) + { + char moduleName[MAX_PATH] = {}; + + V_UnicodeToUTF8(V_UnqualifiedFileName(cb.ModuleName()), moduleName, MAX_PATH); + + Msg(eDLL_T::SERVER, "[%s] Plugin blocked chat message from '%s' (%llu): \"%s\"\n", moduleName, player->GetNetName(), player->GetPlatformUserId(), text); + } + + return; + } + } + } + } + } + // 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); diff --git a/r5dev/game/server/gameinterface.h b/r5dev/game/server/gameinterface.h index 8b92c280..e89084bd 100644 --- a/r5dev/game/server/gameinterface.h +++ b/r5dev/game/server/gameinterface.h @@ -19,7 +19,7 @@ class ServerClass; class CServerGameDLL { public: - void GameInit(void); + bool GameInit(void); void PrecompileScriptsJob(void); void LevelShutdown(void); void GameShutdown(void); @@ -48,11 +48,15 @@ class CServerGameEnts : public IServerGameEnts }; inline void(*CServerGameDLL__OnReceivedSayTextMessage)(void* thisptr, int senderId, const char* text, bool isTeamChat); +inline bool(*CServerGameDLL__GameInit)(void); + inline void(*CServerGameClients__ProcessUserCmds)(CServerGameClients* thisp, edict_t edict, bf_read* buf, int numCmds, int totalCmds, int droppedPackets, bool ignore, bool paused); inline void(*v_RunFrameServer)(double flFrameTime, bool bRunOverlays, bool bUniformUpdate); +inline float* g_pflServerFrameTimeBase = nullptr; + extern CServerGameDLL* g_pServerGameDLL; extern CServerGameClients* g_pServerGameClients; extern CServerGameEnts* g_pServerGameEntities; @@ -65,8 +69,10 @@ class VServerGameDLL : public IDetour virtual void GetAdr(void) const { LogFunAdr("CServerGameDLL::OnReceivedSayTextMessage", CServerGameDLL__OnReceivedSayTextMessage); + LogFunAdr("CServerGameDLL::GameInit", CServerGameDLL__GameInit); LogFunAdr("CServerGameClients::ProcessUserCmds", CServerGameClients__ProcessUserCmds); LogFunAdr("RunFrameServer", v_RunFrameServer); + LogVarAdr("g_flServerFrameTimeBase", g_pflServerFrameTimeBase); LogVarAdr("g_pServerGameDLL", g_pServerGameDLL); LogVarAdr("g_pServerGameClients", g_pServerGameClients); LogVarAdr("g_pServerGameEntities", g_pServerGameEntities); @@ -75,12 +81,14 @@ class VServerGameDLL : public IDetour virtual void GetFun(void) const { g_GameDll.FindPatternSIMD("85 D2 0F 8E ?? ?? ?? ?? 4C 8B DC").GetPtr(CServerGameDLL__OnReceivedSayTextMessage); + g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01").GetPtr(CServerGameDLL__GameInit); g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 55 41 57").GetPtr(CServerGameClients__ProcessUserCmds); g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 30 0F 29 74 24 ?? 48 8D 0D ?? ?? ?? ??").GetPtr(v_RunFrameServer); } virtual void GetVar(void) const { g_pGlobals = g_GameDll.FindPatternSIMD("4C 8B 0D ?? ?? ?? ?? 48 8B D1").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_pflServerFrameTimeBase = CMemory(CServerGameDLL__GameInit).FindPatternSelf("F3 0F 11 0D").ResolveRelativeAddressSelf(0x4, 0x8).RCast(); } virtual void GetCon(void) const { } virtual void Detour(const bool bAttach) const; diff --git a/r5dev/game/server/player.cpp b/r5dev/game/server/player.cpp index 8bb00679..6ebf10f6 100644 --- a/r5dev/game/server/player.cpp +++ b/r5dev/game/server/player.cpp @@ -13,6 +13,9 @@ #include "engine/server/server.h" +// NOTE[ AMOS ]: default tick interval (0.05) * default cvar value (10) = total time buffer of 0.5, which is the default of cvar 'sv_maxunlag'. +static ConVar sv_maxUserCmdProcessTicks("sv_maxUserCmdProcessTicks", "10", FCVAR_NONE, "Maximum number of client-issued UserCmd ticks that can be replayed in packet loss conditions, 0 to allow no restrictions."); + //------------------------------------------------------------------------------ // Purpose: executes a null command for this player //------------------------------------------------------------------------------ @@ -57,37 +60,29 @@ QAngle* CPlayer::EyeAngles(QAngle* pAngles) //------------------------------------------------------------------------------ inline void CPlayer::SetTimeBase(float flTimeBase) { - float flTime = float(TIME_TO_TICKS(flTimeBase)); + const int nRemainderTime = Max(TIME_TO_TICKS(flTimeBase), 0); + SetLastUCmdSimulationRemainderTime(nRemainderTime); - if (flTime < 0.0f) - flTime = 0.0f; - - SetLastUCmdSimulationRemainderTime(flTime); - - float flSimulationTime = flTimeBase - m_lastUCmdSimulationRemainderTime * (*g_pGlobals)->m_flTickInterval; - if (flSimulationTime >= 0.0f) - { - flTime = flSimulationTime; - } - - SetTotalExtraClientCmdTimeAttempted(flTime); + const float flAttemptedTime = Max(flTimeBase - (m_lastUCmdSimulationRemainderTime * TICK_INTERVAL), 0.0f); + SetTotalExtraClientCmdTimeAttempted(flAttemptedTime); } //------------------------------------------------------------------------------ // Purpose: sets the last user cmd simulation remainder time -// Input : flRemainderTime - +// Input : nRemainderTime - //------------------------------------------------------------------------------ -void CPlayer::SetLastUCmdSimulationRemainderTime(float flRemainderTime) +void CPlayer::SetLastUCmdSimulationRemainderTime(int nRemainderTime) { - if (m_lastUCmdSimulationRemainderTime != flRemainderTime) + if (m_lastUCmdSimulationRemainderTime != nRemainderTime) { - edict_t nEdict = NetworkProp()->GetEdict(); + const edict_t nEdict = NetworkProp()->GetEdict(); + if (nEdict != FL_EDICT_INVALID) { _InterlockedOr16((SHORT*)(*g_pGlobals)->m_pEdicts + nEdict + 32, 0x200u); } - m_lastUCmdSimulationRemainderTime = flRemainderTime; + m_lastUCmdSimulationRemainderTime = nRemainderTime; } } @@ -99,7 +94,8 @@ void CPlayer::SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime) { if (m_totalExtraClientCmdTimeAttempted != flAttemptedTime) { - edict_t nEdict = NetworkProp()->GetEdict(); + const edict_t nEdict = NetworkProp()->GetEdict(); + if (nEdict != FL_EDICT_INVALID) { _InterlockedOr16((SHORT*)(*g_pGlobals)->m_pEdicts + nEdict + 32, 0x200u); @@ -109,65 +105,6 @@ void CPlayer::SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime) } } -//------------------------------------------------------------------------------ -// Purpose: clamps the unlag amount to sv_unlag + clockdrift -// Input : *cmd - -//------------------------------------------------------------------------------ -void CPlayer::ClampUnlag(CUserCmd* cmd) -{ - const CClient* client = g_pServer->GetClient(GetEdict() - 1); - const CNetChan* chan = client->GetNetChan(); - - const float clockDriftMsecs = sv_clockcorrection_msecs->GetFloat() / 1000.0f; - const float maxUnlag = sv_maxunlag->GetFloat(); - const float latencyAmount = Clamp(chan->GetLatency(FLOW_OUTGOING), 0.0f, maxUnlag); - const float serverTime = (*g_pGlobals)->m_flCurTime; - - // Command issue time from client, note that this value can be altered - // from the client, and therefore be used to exploit lag compensation. - const float commandTime = cmd->command_time; - const float lastCommandTime = m_LastCmd.command_time; - const float commandDelta = fabs(commandTime - serverTime); - - bool recomputeUnlag = false; - - // Check delta first, otherwise player could set commandTime to a fixed - // time and circumvent the system, as commandTime < lastCommandTime or - // commandTime > localCurTime will always fail. - if (commandDelta > maxUnlag) - { - // Too much to unlag, clamp to max !!! - recomputeUnlag = true; - DevWarning(eDLL_T::SERVER, "%s: commandDelta( %f ) > maxUnlag( %f ) !!!\n", - __FUNCTION__, commandDelta, maxUnlag); - } - else if (commandTime < (lastCommandTime - clockDriftMsecs)) - { - // Can never be lower than last !!! - recomputeUnlag = true; - DevWarning(eDLL_T::SERVER, "%s: cmd->command_time( %f ) < (m_LastCmd.command_time( %f ) - clockDriftMsecs( %f )) !!!\n", - __FUNCTION__, commandTime, lastCommandTime, clockDriftMsecs); - } - else if (commandTime > (serverTime + clockDriftMsecs)) - { - // Too far in the future, clamp to max !!! - recomputeUnlag = true; - DevWarning(eDLL_T::SERVER, "%s: cmd->command_time( %f ) > (g_pGlobals->m_flCurTime( %f ) + clockDriftMsecs( %f )) !!!\n", - __FUNCTION__, commandTime, serverTime, clockDriftMsecs); - } - - if (recomputeUnlag) - { - // Clamp it to server time minus latency. Note that it could still - // be lower than previous, hence the clamp on the recomputation. - float newCommandTime = Clamp(serverTime - latencyAmount, lastCommandTime, serverTime); - cmd->command_time = newCommandTime; - - DevWarning(eDLL_T::SERVER, "%s: Clamped cmd->command_time( %f ) to %f !!!\n", - __FUNCTION__, commandTime, newCommandTime); - } -} - //------------------------------------------------------------------------------ // Purpose: processes user cmd's for this player // Input : *cmds - @@ -179,7 +116,7 @@ void CPlayer::ClampUnlag(CUserCmd* cmd) // TODO: this code is experimental and has reported problems from players with // high latency, needs to be debugged or a different approach needs to be taken! // Defaulted to OFF for now -static ConVar sv_unlag_clamp("sv_unlag_clamp", "0", FCVAR_RELEASE, "Clamp the difference between the current time and received command time to sv_maxunlag + sv_clockcorrection_msecs."); +static ConVar sv_unlag_clamp("sv_unlag_clamp", "0", FCVAR_RELEASE, "Clamp the difference between the current time and received command time to sv_maxunlag."); void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds, int droppedPackets, bool paused) @@ -189,6 +126,9 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds, CUserCmd* lastCmd = &m_Commands[MAX_QUEUED_COMMANDS_PROCESS]; + const float maxUnlag = sv_maxunlag->GetFloat(); + const float currTime = (*g_pGlobals)->m_flCurTime; + for (int i = totalCmds - 1; i >= 0; i--) { CUserCmd* cmd = &cmds[i]; @@ -203,8 +143,22 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds, if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS) return; + // TODO: why are grenades not clamped to sv_maxunlag ??? + // TODO: the command_time is set from the client itself in CInput::CreateMove + // to gpGlobals->curtime in the ucmd packet, perhaps just calculate it from + // the server based on ucmd ticks ??? + // + // Possible solutions that need to be explored and worked out further: + // + // cmd->command_time = TICKS_TO_TIME(cmd->command_number + cmd->tick_count) // seems to be the closest, but also still manipulatable from the client. + // cmd->command_time = TICKS_TO_TIME(client->GetDeltaTick() + cmd->command_number) // delta tick is not necessarily the same as actual ucmd tick, and will be -1 on baseline request. + // cmd->command_time = TICKS_TO_TIME(m_lastUCmdSimulationRemainderTime) + m_totalExtraClientCmdTimeAttempted; // player timebase; also up to 100ms difference between orig sent value. + // + // ... reverse more ticks and floats in CClient since there seem to be a + // bunch still in the padded bytes, possibly one of them is what we could + // and should actually use to get the remote client time since ucmd was sent. if (sv_unlag_clamp.GetBool()) - ClampUnlag(cmd); + cmd->command_time = Min(Max(cmd->command_time, Max(currTime - maxUnlag, 0.0f)), currTime + maxUnlag); CUserCmd* queuedCmd = &m_Commands[lastCommandNumber]; queuedCmd->Copy(cmd); @@ -241,6 +195,25 @@ void CPlayer::SetLastUserCommand(CUserCmd* pUserCmd) m_LastCmd.Copy(pUserCmd); } +//------------------------------------------------------------------------------ +// Purpose: run physics simulation for player +// Input : *player (this) - +// numPerIteration - +// adjustTimeBase - +//------------------------------------------------------------------------------ +bool Player_PhysicsSimulate(CPlayer* player, int numPerIteration, bool adjustTimeBase) +{ + CClientExtended* const cle = g_pServer->GetClientExtended(player->GetEdict() - 1); + const int numUserCmdProcessTicksMax = sv_maxUserCmdProcessTicks.GetInt(); + + if (numUserCmdProcessTicksMax && (*g_pGlobals)->m_nGameMode != GameMode_t::SP_MODE) // don't apply this filter in SP games + cle->InitializeMovementTimeForUserCmdProcessing(numUserCmdProcessTicksMax, TICK_INTERVAL); + else // Otherwise we don't care to track time + cle->SetRemainingMovementTimeForUserCmdProcessing(FLT_MAX); + + return CPlayer__PhysicsSimulate(player, numPerIteration, adjustTimeBase); +} + /* ===================== CC_CreateFakePlayer_f @@ -286,3 +259,8 @@ static void CC_CreateFakePlayer_f(const CCommand& args) } static ConCommand sv_addbot("sv_addbot", CC_CreateFakePlayer_f, "Creates a bot on the server", FCVAR_RELEASE); + +void VPlayer::Detour(const bool bAttach) const +{ + DetourSetup(&CPlayer__PhysicsSimulate, &Player_PhysicsSimulate, bAttach); +} diff --git a/r5dev/game/server/player.h b/r5dev/game/server/player.h index 1b6d05bf..a71752ea 100644 --- a/r5dev/game/server/player.h +++ b/r5dev/game/server/player.h @@ -241,25 +241,28 @@ struct SpeedChangeHistoryEntry class CPlayer : public CBaseCombatCharacter { + friend class CPlayerMove; public: void RunNullCommand(void); QAngle* EyeAngles(QAngle* pAngles); void SetTimeBase(float flTimeBase); - void SetLastUCmdSimulationRemainderTime(float flRemainderTime); + void SetLastUCmdSimulationRemainderTime(int nRemainderTime); void SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime); void ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds, int droppedPackets, bool paused); - void ClampUnlag(CUserCmd* cmd); - void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover); void SetLastUserCommand(CUserCmd* pUserCmd); inline bool IsConnected() const { return m_iConnected != PlayerDisconnected; } inline bool IsDisconnecting() const { return m_iConnected == PlayerDisconnecting; } + inline bool IsBot() const { return (GetFlags() & FL_FAKECLIENT) != 0; } + + inline NucleusID_t GetPlatformUserId() const { return m_platformUserId; }; + private: int m_StuckLast; char gap_5a8c[4]; @@ -276,7 +279,7 @@ private: char m_hardwareIcon[16]; bool m_happyHourActive; char gap_5ee6[2]; - __int64 m_platformUserId; + NucleusID_t m_platformUserId; char m_hardware; char gap_5ef1[7]; __int64 m_classModsActive; @@ -571,7 +574,7 @@ private: float m_totalFrameTime; float m_joinFrameTime; int m_lastUCmdSimulationTicks; - float m_lastUCmdSimulationRemainderTime; + int m_lastUCmdSimulationRemainderTime; // Originally float??? float m_totalExtraClientCmdTimeAttempted; int m_hPlayerViewEntity; bool m_atLeastOneCommandRunThisServerFrame; @@ -796,6 +799,7 @@ static_assert(sizeof(CPlayer) == 0x7EF0); // !TODO: backwards compatibility. inline QAngle*(*CPlayer__EyeAngles)(CPlayer* pPlayer, QAngle* pAngles); inline void(*CPlayer__PlayerRunCommand)(CPlayer* pPlayer, CUserCmd* pUserCmd, IMoveHelper* pMover); +inline bool(*CPlayer__PhysicsSimulate)(CPlayer* pPlayer, int numPerIteration, bool adjustTimeBase); /////////////////////////////////////////////////////////////////////////////// class VPlayer : public IDetour @@ -804,15 +808,17 @@ class VPlayer : public IDetour { LogFunAdr("CPlayer::EyeAngles", CPlayer__EyeAngles); LogFunAdr("CPlayer::PlayerRunCommand", CPlayer__PlayerRunCommand); + LogFunAdr("CPlayer::PhysicsSimulate", CPlayer__PhysicsSimulate); } virtual void GetFun(void) const { g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 F2 0F 10 05 ?? ?? ?? ??").GetPtr(CPlayer__EyeAngles); g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B 03 49 81 C6 ?? ?? ?? ??").FollowNearCallSelf().GetPtr(CPlayer__PlayerRunCommand); + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 84 C0 74 06").FollowNearCallSelf().GetPtr(CPlayer__PhysicsSimulate); } virtual void GetVar(void) const { } virtual void GetCon(void) const { } - virtual void Detour(const bool bAttach) const { } + virtual void Detour(const bool bAttach) const; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/r5dev/game/server/player_command.cpp b/r5dev/game/server/player_command.cpp new file mode 100644 index 00000000..cf40bc61 --- /dev/null +++ b/r5dev/game/server/player_command.cpp @@ -0,0 +1,58 @@ +//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "engine/server/server.h" +#include "engine/client/client.h" + +#include "player_command.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPlayerMove::CPlayerMove(void) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Runs movement commands for the player +// Input : *player - +// *ucmd - +// *moveHelper - +//----------------------------------------------------------------------------- +void CPlayerMove::StaticRunCommand(CPlayerMove* thisp, CPlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper) +{ + CClientExtended* const cle = g_pServer->GetClientExtended(player->GetEdict() - 1); + float playerFrameTime; + + // Always default to clamped UserCmd frame time if this cvar is set + if (player_disallow_negative_frametime->GetBool()) + playerFrameTime = fmaxf(ucmd->frametime, 0.0f); + else + { + if (player->m_bGamePaused) + playerFrameTime = 0.0f; + else + playerFrameTime = TICK_INTERVAL; + + if (ucmd->frametime) + playerFrameTime = ucmd->frametime; + } + + if (sv_clampPlayerFrameTime->GetBool() && player->m_joinFrameTime > ((*g_pflServerFrameTimeBase) + playerframetimekick_margin->GetFloat())) + playerFrameTime = 0.0f; + + const float timeAllowedForProcessing = cle->ConsumeMovementTimeForUserCmdProcessing(playerFrameTime); + + if (!player->IsBot() && (timeAllowedForProcessing < playerFrameTime)) + return; // Don't process this command + + CPlayerMove__RunCommand(thisp, player, ucmd, moveHelper); +} + +void VPlayerMove::Detour(const bool bAttach) const +{ + DetourSetup(&CPlayerMove__RunCommand, &CPlayerMove::StaticRunCommand, bAttach); +} diff --git a/r5dev/game/server/player_command.h b/r5dev/game/server/player_command.h new file mode 100644 index 00000000..2c397243 --- /dev/null +++ b/r5dev/game/server/player_command.h @@ -0,0 +1,67 @@ +//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef PLAYER_COMMAND_H +#define PLAYER_COMMAND_H + +#include "edict.h" +#include "game/shared/usercmd.h" +#include "game/server/player.h" + +class IMoveHelper; +class CMoveData; +class CBasePlayer; + +//----------------------------------------------------------------------------- +// Purpose: Server side player movement +//----------------------------------------------------------------------------- +class CPlayerMove +{ +public: + //DECLARE_CLASS_NOBASE(CPlayerMove); + + // Construction/destruction + CPlayerMove(void); + virtual ~CPlayerMove(void) {} + + // Hook statics: + static void StaticRunCommand(CPlayerMove* thisp, CPlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper); + + // Public interfaces: + // Run a movement command from the player + virtual void RunCommand(CPlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper) = 0; + +protected: + // Prepare for running movement + virtual void SetupMove(CPlayer* player, CUserCmd* ucmd, CMoveData* move) = 0; + + // Finish movement + virtual void FinishMove(CPlayer* player, CUserCmd* ucmd, CMoveData* move) = 0; + + // Called before and after any movement processing + virtual void StartCommand(CPlayer* player, IMoveHelper* pHelper, CUserCmd* cmd) = 0; +}; + +inline void (*CPlayerMove__RunCommand)(CPlayerMove* thisp, CPlayer* player, CUserCmd* ucmd, IMoveHelper* moveHelper); + +/////////////////////////////////////////////////////////////////////////////// +class VPlayerMove : public IDetour +{ + virtual void GetAdr(void) const + { + LogFunAdr("CPlayerMove::RunCommand", CPlayerMove__RunCommand); + } + virtual void GetFun(void) const + { + g_GameDll.FindPatternSIMD("48 8B C4 55 53 56 57 41 57 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 44 0F 29 50 ??").GetPtr(CPlayerMove__RunCommand); + } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Detour(const bool bAttach) const; +}; +/////////////////////////////////////////////////////////////////////////////// + +#endif // PLAYER_COMMAND_H diff --git a/r5dev/game/server/vscript_server.cpp b/r5dev/game/server/vscript_server.cpp index 2123d4d7..0ca711d9 100644 --- a/r5dev/game/server/vscript_server.cpp +++ b/r5dev/game/server/vscript_server.cpp @@ -83,6 +83,7 @@ namespace VScriptCode SCRIPT_CHECK_AND_RETURN(v, SQ_OK); } + //----------------------------------------------------------------------------- // Purpose: shuts the server down and disconnects all clients //----------------------------------------------------------------------------- @@ -94,6 +95,21 @@ namespace VScriptCode SCRIPT_CHECK_AND_RETURN(v, SQ_OK); } + //----------------------------------------------------------------------------- + // Purpose: sets whether the server could auto reload at this time (e.g. if + // server admin has host_autoReloadRate AND host_autoReloadRespectGameState + // set, and its time to auto reload, but the match hasn't finished yet, wait + // until this is set to proceed the reload of the server + //----------------------------------------------------------------------------- + SQRESULT SetAutoReloadState(HSQUIRRELVM v) + { + SQBool state = false; + sq_getbool(v, 2, &state); + + g_hostReloadState = state; + SCRIPT_CHECK_AND_RETURN(v, SQ_OK); + } + //----------------------------------------------------------------------------- // Purpose: kicks a player by given name //----------------------------------------------------------------------------- @@ -231,6 +247,15 @@ namespace VScriptCode SCRIPT_CHECK_AND_RETURN(v, SQ_OK); } + //----------------------------------------------------------------------------- + // Purpose: gets the current server id + //----------------------------------------------------------------------------- + SQRESULT GetServerID(HSQUIRRELVM v) + { + sq_pushstring(v, g_LogSessionUUID.c_str(), (SQInteger)g_LogSessionUUID.length()); + SCRIPT_CHECK_AND_RETURN(v, SQ_OK); + } + //----------------------------------------------------------------------------- // Purpose: checks whether the server is active //----------------------------------------------------------------------------- @@ -282,6 +307,10 @@ void Script_RegisterCoreServerFunctions(CSquirrelVM* s) DEFINE_SERVER_SCRIPTFUNC_NAMED(s, CreateServer, "Starts server with the specified settings", "void", "string, string, string, string, int"); DEFINE_SERVER_SCRIPTFUNC_NAMED(s, DestroyServer, "Shuts the local server down", "void", ""); + + DEFINE_SERVER_SCRIPTFUNC_NAMED(s, SetAutoReloadState, "Set whether we can auto-reload the server", "void", "bool"); + + DEFINE_SERVER_SCRIPTFUNC_NAMED(s, GetServerID, "Gets the current server ID", "string", ""); } //--------------------------------------------------------------------------------- diff --git a/r5dev/game/server/vscript_server.h b/r5dev/game/server/vscript_server.h index d75cd394..8d811524 100644 --- a/r5dev/game/server/vscript_server.h +++ b/r5dev/game/server/vscript_server.h @@ -9,6 +9,8 @@ namespace VScriptCode SQRESULT CreateServer(HSQUIRRELVM v); SQRESULT DestroyServer(HSQUIRRELVM v); + SQRESULT SetAutoReloadState(HSQUIRRELVM v); + SQRESULT KickPlayerByName(HSQUIRRELVM v); SQRESULT KickPlayerById(HSQUIRRELVM v); SQRESULT BanPlayerByName(HSQUIRRELVM v); @@ -18,6 +20,8 @@ namespace VScriptCode SQRESULT GetNumHumanPlayers(HSQUIRRELVM v); SQRESULT GetNumFakeClients(HSQUIRRELVM v); + SQRESULT GetServerID(HSQUIRRELVM v); + SQRESULT IsServerActive(HSQUIRRELVM v); SQRESULT IsDedicated(HSQUIRRELVM v); } diff --git a/r5dev/game/shared/usercmd.cpp b/r5dev/game/shared/usercmd.cpp index ef1403ea..4d5ee354 100644 --- a/r5dev/game/shared/usercmd.cpp +++ b/r5dev/game/shared/usercmd.cpp @@ -27,8 +27,7 @@ int ReadUserCmd(bf_read* buf, CUserCmd* move, CUserCmd* from) const int seed = v_ReadUserCmd(buf, move, from); // Initialize the camera position as <0,0,0>, this should at least avoid - // crash and meme behaviors. Has not been tested yet unlike all the - // patches performed below. + // crash and meme behaviors. if (!move->camerapos.IsValid()) move->camerapos.Init(); diff --git a/r5dev/game/shared/usercmd.h b/r5dev/game/shared/usercmd.h index ae357700..e964c45b 100644 --- a/r5dev/game/shared/usercmd.h +++ b/r5dev/game/shared/usercmd.h @@ -48,12 +48,15 @@ public: int32_t command_number; int32_t tick_count; float_t command_time; + QAngle viewangles; QAngle pitchangles; // Pitch angles? See [r5apex_ds+705D80]. + float_t forwardmove; float_t sidemove; float_t upmove; int32_t buttons; + byte impulse; byte cycleslot; byte weaponindex; @@ -64,12 +67,18 @@ public: bool controllermode; bool fixangles; bool setlastcycleslot; - char pad_0x0034[157]; - QAngle renderangles; // IDK what this is used for. - QAngle renderangles_copy; // IDK what this is used for. + char pad_0x0034[149]; + + // Zipline vars (see [r5apex_ds+8A6573] for read). + bool placedZiplineStation; + char unk[3]; + int nUnkDC; + Vector3D beginStationOrigin; + Vector3D stationWorldRelative; float fUnkF8; - QAngle another_renderangles_copy; // IDK what this is used for. - QAngle yet_another_renderangles_copy; // IDK what this is used for. + Vector3D endStationOrigin; + QAngle stationWorldAngles; + char pad_0x00114[112]; int32_t randomseed; byte bUnk188; diff --git a/r5dev/gameui/IBrowser.cpp b/r5dev/gameui/IBrowser.cpp index b68b43a3..41223dbc 100644 --- a/r5dev/gameui/IBrowser.cpp +++ b/r5dev/gameui/IBrowser.cpp @@ -52,6 +52,7 @@ CBrowser::CBrowser(void) { m_surfaceLabel = "Server Browser"; + memset(m_serverTokenTextBuf, '\0', sizeof(m_serverTokenTextBuf)); memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf)); memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf)); @@ -71,7 +72,7 @@ CBrowser::~CBrowser(void) //----------------------------------------------------------------------------- bool CBrowser::Init(void) { - SetStyleVar(928.f, 524.f, -500.f, 50.f); + SetStyleVar(927.f, 524.f, -500.f, 50.f); bool ret = LoadTextureBuffer(reinterpret_cast(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize), &m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight); @@ -343,10 +344,10 @@ void CBrowser::DrawBrowserPanel(void) ImGui::PushItemWidth(itemWidth); { - ImGui::InputTextWithHint("##ServerBrowser_ServerCon", "Server address and port", m_serverAddressTextBuf, IM_ARRAYSIZE(m_serverAddressTextBuf)); + ImGui::InputTextWithHint("##ServerBrowser_ServerCon", "Server address and port", m_serverAddressTextBuf, sizeof(m_serverAddressTextBuf)); ImGui::SameLine(); - ImGui::InputTextWithHint("##ServerBrowser_ServerKey", "Encryption key", m_serverNetKeyTextBuf, IM_ARRAYSIZE(m_serverNetKeyTextBuf)); + ImGui::InputTextWithHint("##ServerBrowser_ServerKey", "Encryption key", m_serverNetKeyTextBuf, sizeof(m_serverNetKeyTextBuf)); ImGui::SameLine(); if (ImGui::Button("Connect", ImVec2(itemWidth, ImGui::GetFrameHeight()))) @@ -437,8 +438,8 @@ void CBrowser::HiddenServersModal(void) const ImVec2 contentRegionMax = ImGui::GetContentRegionAvail(); ImGui::PushItemWidth(contentRegionMax.x); // Override item width. - string hiddenServerToken; - ImGui::InputTextWithHint("##HiddenServersConnectModal_TokenInput", "Token (required)", &hiddenServerToken); + const bool hitEnter = ImGui::InputTextWithHint("##HiddenServersConnectModal_TokenInput", "Token (required)", + m_serverTokenTextBuf, sizeof(m_serverTokenTextBuf), ImGuiInputTextFlags_EnterReturnsTrue); ImGui::PopItemWidth(); @@ -453,15 +454,15 @@ void CBrowser::HiddenServersModal(void) ImGui::TextColored(m_hiddenServerMessageColor, "%s", m_hiddenServerRequestMessage.c_str()); ImGui::Separator(); - if (ImGui::Button("Connect", ImVec2(contentRegionMax.x, 24))) + if (ImGui::Button("Connect", ImVec2(contentRegionMax.x, 24)) || hitEnter) { m_hiddenServerRequestMessage.clear(); m_reclaimFocusOnTokenField = true; - if (!hiddenServerToken.empty()) + if (m_serverTokenTextBuf[0]) { NetGameServer_t server; - const bool result = g_MasterServer.GetServerByToken(server, m_hiddenServerRequestMessage, hiddenServerToken); // Send token connect request. + const bool result = g_MasterServer.GetServerByToken(server, m_hiddenServerRequestMessage, m_serverTokenTextBuf); // Send token connect request. if (result && !server.name.empty()) { diff --git a/r5dev/gameui/IBrowser.h b/r5dev/gameui/IBrowser.h index 9591892d..123ba6fe 100644 --- a/r5dev/gameui/IBrowser.h +++ b/r5dev/gameui/IBrowser.h @@ -47,8 +47,9 @@ private: bool m_reclaimFocusOnTokenField; bool m_queryNewListNonRecursive; // When set, refreshes the server list once the next frame. bool m_queryGlobalBanList; + char m_serverTokenTextBuf[128]; char m_serverAddressTextBuf[128]; - char m_serverNetKeyTextBuf[30]; + char m_serverNetKeyTextBuf[45]; ID3D11ShaderResourceView* m_lockedIconShaderResource; MODULERESOURCE m_lockedIconDataResource; diff --git a/r5dev/gameui/IConsole.cpp b/r5dev/gameui/IConsole.cpp index 9bf9fb05..b6c0f27b 100644 --- a/r5dev/gameui/IConsole.cpp +++ b/r5dev/gameui/IConsole.cpp @@ -242,7 +242,7 @@ bool CConsole::DrawSurface(void) // Eliminate padding around logger child. This padding gets added when // ImGuiChildFlags_Border flag gets set. - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 1.f, 1.f }); numLoggerStyleVars++; + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 1.f, 1.f }); numLoggerStyleVars++; // if we use the legacy theme, also account for one extra space as the // legacy theme has an extra separator at the bottom of the logger. @@ -255,6 +255,7 @@ bool CConsole::DrawSurface(void) ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_OverlayHorizontalScrollbar; + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); numLoggerStyleVars++; ImGui::BeginChild(m_loggerLabel, ImVec2(0, -footerHeightReserve), loggerFlags, colorLoggerWindowFlags); // NOTE: scoped so the mutex releases after we have rendered. @@ -767,7 +768,7 @@ void CConsole::DetermineAutoCompleteWindowRect(void) const float maxWindowWidth = con_autocomplete_window_width.GetFloat(); const float flWindowWidth = maxWindowWidth > 0 - ? ImMin(con_autocomplete_window_width.GetFloat(), lastItemRectSize.x) + ? ImMin(maxWindowWidth, lastItemRectSize.x) : lastItemRectSize.x; // NOTE: minimum vertical size of the window, going below this will diff --git a/r5dev/localize/localize.cpp b/r5dev/localize/localize.cpp index cae020eb..eee84ab1 100644 --- a/r5dev/localize/localize.cpp +++ b/r5dev/localize/localize.cpp @@ -32,13 +32,7 @@ bool Localize_LoadLocalizationFileLists(CLocalize* thisptr) bool Localize_IsLanguageSupported(const char* pLocaleName) { - for (int i = 0; i < SDK_ARRAYSIZE(g_LanguageNames); ++i) - { - if (strcmp(pLocaleName, g_LanguageNames[i]) == NULL) - return true; - } - - return false; + return V_LocaleNameExists(pLocaleName); } void VLocalize::Detour(const bool bAttach) const diff --git a/r5dev/naveditor/CMakeLists.txt b/r5dev/naveditor/CMakeLists.txt index 1ca19d37..91d6b638 100644 --- a/r5dev/naveditor/CMakeLists.txt +++ b/r5dev/naveditor/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required( VERSION 3.16 ) -add_module( "exe" "naveditor" "" ${FOLDER_CONTEXT} TRUE TRUE ) +add_module( "exe" "recast" "" ${FOLDER_CONTEXT} TRUE TRUE ) start_sources() diff --git a/r5dev/netconsole/CMakeLists.txt b/r5dev/netconsole/CMakeLists.txt index c18e4c43..e978455b 100644 --- a/r5dev/netconsole/CMakeLists.txt +++ b/r5dev/netconsole/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required( VERSION 3.16 ) -add_module( "exe" "netconsole" "vpc" ${FOLDER_CONTEXT} TRUE TRUE ) +add_module( "exe" "netcon" "vpc" ${FOLDER_CONTEXT} TRUE TRUE ) start_sources() @@ -31,11 +31,8 @@ add_sources( SOURCE_GROUP "Windows" end_sources( "${BUILD_OUTPUT_DIR}/bin/" ) -set_target_properties( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME - "netcon32" -) set_target_properties( ${PROJECT_NAME} PROPERTIES - VS_DEBUGGER_COMMAND "netcon32.exe" + VS_DEBUGGER_COMMAND "${PROJECT_NAME}.exe" VS_DEBUGGER_COMMAND_ARGUMENTS "-ansicolor" VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/bin/" ) @@ -48,8 +45,15 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE "tier2" "libprotobuf" "libspdlog" - "SV_RCon_Pb" - "CL_RCon_Pb" + "libmbedcrypto" + "libmbedtls" + "libmbedx509" + "NetCon_Pb" "Rpcrt4.lib" "ws2_32.lib" + "bcrypt.lib" + "crypt32.lib" +) +target_include_directories( ${PROJECT_NAME} PRIVATE + "${THIRDPARTY_SOURCE_DIR}/mbedtls/include" ) diff --git a/r5dev/netconsole/netconsole.cpp b/r5dev/netconsole/netconsole.cpp index 7620fd28..95d7a943 100644 --- a/r5dev/netconsole/netconsole.cpp +++ b/r5dev/netconsole/netconsole.cpp @@ -12,8 +12,7 @@ #include "tier1/NetAdr.h" #include "tier2/socketcreator.h" #include "windows/console.h" -#include "protoc/sv_rcon.pb.h" -#include "protoc/cl_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "engine/net.h" #include "engine/shared/shared_rcon.h" #include "netconsole/netconsole.h" @@ -25,6 +24,7 @@ CNetCon::CNetCon(void) : m_bInitialized(false) , m_bQuitting(false) , m_bPromptConnect(true) + , m_bEncryptFrames(false) , m_flTickInterval(0.05f) { // Empty character set used for ip addresses if we still need to initiate a @@ -44,13 +44,15 @@ CNetCon::~CNetCon(void) // Purpose: WSA and NETCON systems init // Output : true on success, false otherwise //----------------------------------------------------------------------------- -bool CNetCon::Init(const bool bAnsiColor, const char* pHostName, const int nPort) +bool CNetCon::Init(const bool bAnsiColor, const char* pAdr, const char* pKey) { std::lock_guard l(m_Mutex); g_CoreMsgVCallback = &EngineLoggerSink; TermSetup(bAnsiColor); + Msg(eDLL_T::NONE, "R5 TCP net console [Version %s]\n", NETCON_VERSION); + WSAData wsaData; const int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData); @@ -60,19 +62,26 @@ bool CNetCon::Init(const bool bAnsiColor, const char* pHostName, const int nPort return false; } - // Try to connect from given parameters, these are passed in from the - // command line. If we fail, return out as this allows the user to - // quickly retry again. - if (pHostName && nPort != SOCKET_ERROR) + // Install the encryption key and enable encryption if this has been passed + // in by the user. + if (pKey) { - if (!Connect(pHostName, nPort)) + SetKey(pKey, true); + m_bEncryptFrames = true; + } + + // Try and connect to the giver remote address if this has been passed in + // by the user. If we fail, return out as this allows the user to quickly + // try again. + if (pAdr) + { + if (!Connect(pAdr)) { return false; } } m_bInitialized = true; - Msg(eDLL_T::NONE, "R5 TCP net console [Version %s]\n", NETCON_VERSION); static std::thread frame([this]() { @@ -176,6 +185,24 @@ void CNetCon::TermSetup(const bool bAnsiColor) SpdLog_InstallSupplementalLogger("supplemental_logger_mt", "netconsole.log"); } +//----------------------------------------------------------------------------- +// Purpose: tries to set the passed in netkey, falls back to default on failure +//----------------------------------------------------------------------------- +void CNetCon::TrySetKey(const char* const pKey) +{ + if (!*pKey) + { + Warning(eDLL_T::CLIENT, "No key provided; using default %s'%s%s%s'\n", + g_svReset, g_svGreyB, DEFAULT_NET_ENCRYPTION_KEY, g_svReset); + + SetKey(DEFAULT_NET_ENCRYPTION_KEY, true); + } + else + { + SetKey(pKey, true); + } +} + //----------------------------------------------------------------------------- // Purpose: gets input IP and port for initialization //----------------------------------------------------------------------------- @@ -216,17 +243,17 @@ void CNetCon::RunInput(const string& lineInput) if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server. { bSend = Serialize(vecMsg, cmd.Arg(1), "", - cl_rcon::request_t::SERVERDATA_REQUEST_AUTH); + netcon::request_e::SERVERDATA_REQUEST_AUTH); } else // Execute command query. { bSend = Serialize(vecMsg, cmd.Arg(0), cmd.GetCommandString(), - cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND); + netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND); } } else // Single arg command query. { - bSend = Serialize(vecMsg, lineInput.c_str(), "", cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND); + bSend = Serialize(vecMsg, lineInput.c_str(), "", netcon::request_e::SERVERDATA_REQUEST_EXECCOMMAND); } if (bSend) // Only send if serialization process was successful. @@ -244,25 +271,31 @@ void CNetCon::RunInput(const string& lineInput) if (cmd.ArgC() > 1) { - const char* inAddr = cmd.Arg(0); - const char* inPort = cmd.Arg(1); + const char* inAdr = cmd.Arg(0); + const char* inKey = cmd.Arg(1); - if (!*inAddr || !*inPort) + if (!*inAdr) { - Warning(eDLL_T::CLIENT, "No IP address or port provided\n"); + Warning(eDLL_T::CLIENT, "No address provided\n"); SetPrompting(true); return; } - if (!Connect(inAddr, atoi(inPort))) + TrySetKey(inKey); + m_bEncryptFrames = true; + + if (!Connect(inAdr)) { SetPrompting(true); return; } } - else + else // No encryption { - if (!Connect(cmd.GetCommandString())) + const char* inAdr = cmd.GetCommandString(); + m_bEncryptFrames = false; + + if (!Connect(inAdr)) { SetPrompting(true); return; @@ -287,7 +320,7 @@ bool CNetCon::RunFrame(void) } else if (GetPrompting()) { - Msg(eDLL_T::NONE, "Enter []: or : "); + Msg(eDLL_T::NONE, "Enter [
]: and : "); SetPrompting(false); } } @@ -332,6 +365,28 @@ void CNetCon::SetPrompting(const bool bPrompt) m_bPromptConnect = bPrompt; } +//----------------------------------------------------------------------------- +// Purpose: connect to remote +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool CNetCon::Connect(const char* pHostName, const int nPort) +{ + Assert(nPort == SOCKET_ERROR, "Port should be part of the address on the CNetCon implementation!"); + NOTE_UNUSED(nPort); + + if (m_bEncryptFrames) + { + Msg(eDLL_T::CLIENT, "Attempting connection to '%s' with key %s'%s%s%s'\n", + pHostName, g_svReset, g_svGreyB, GetKey(), g_svReset); + } + else + { + Msg(eDLL_T::CLIENT, "Attempting connection to '%s'\n", pHostName); + } + + return CL_NetConConnect(this, pHostName, SOCKET_ERROR); +} + //----------------------------------------------------------------------------- // Purpose: disconnect from current session // Input : *szReason - @@ -360,18 +415,17 @@ void CNetCon::Disconnect(const char* szReason) //----------------------------------------------------------------------------- bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen) { - sv_rcon::response response; - bool bSuccess = Decode(&response, pMsgBuf, nMsgLen); + netcon::response response; - if (!bSuccess) + if (!SH_NetConUnpackEnvelope(this, pMsgBuf, nMsgLen, &response, true)) { - Error(eDLL_T::CLIENT, NO_ERROR, "Failed to decode RCON buffer\n"); + Disconnect("received invalid message"); return false; } switch (response.responsetype()) { - case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: + case netcon::response_e::SERVERDATA_RESPONSE_AUTH: { if (!response.responseval().empty()) { @@ -379,7 +433,7 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen) if (!i) // Means we are marked 'input only' on the rcon server. { vector vecMsg; - bool ret = Serialize(vecMsg, "", "1", cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); + bool ret = Serialize(vecMsg, "", "1", netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG); if (ret && !Send(GetSocket(), vecMsg.data(), int(vecMsg.size()))) { @@ -391,7 +445,7 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen) Msg(eDLL_T::NETCON, "%s", response.responsemsg().c_str()); break; } - case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG: + case netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG: { NetMsg(static_cast(response.messagetype()), static_cast(response.messageid()), @@ -416,9 +470,9 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen) // Output : true on success, false otherwise //----------------------------------------------------------------------------- bool CNetCon::Serialize(vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType) const + const char* szReqVal, const netcon::request_e requestType) const { - return CL_NetConSerialize(this, vecBuf, szReqBuf, szReqVal, requestType); + return CL_NetConSerialize(this, vecBuf, szReqBuf, szReqVal, requestType, m_bEncryptFrames, true); } //----------------------------------------------------------------------------- @@ -453,7 +507,7 @@ bool CNetCon::IsConnected(void) //----------------------------------------------------------------------------- int main(int argc, char* argv[]) { - CheckCPUforSSE2(); + CheckSystemCPUForSSE2(); bool bEnableColor = false; @@ -466,16 +520,21 @@ int main(int argc, char* argv[]) } } - const char* pHostName = nullptr; - int nPort = SOCKET_ERROR; + // The address and key from command line if passed in. + const char* pAdr = nullptr; + const char* pKey = nullptr; - if (argc >= 3) // Get IP and Port from command line. + if (argc >= 2) { - pHostName = argv[1]; - nPort = atoi(argv[2]); + pAdr = argv[1]; } - if (!NetConsole()->Init(bEnableColor, pHostName, nPort)) + if (argc >= 3) + { + pKey = argv[2]; + } + + if (!NetConsole()->Init(bEnableColor, pAdr, pKey)) { return EXIT_FAILURE; } diff --git a/r5dev/netconsole/netconsole.h b/r5dev/netconsole/netconsole.h index 0d77ab48..ef2f5f91 100644 --- a/r5dev/netconsole/netconsole.h +++ b/r5dev/netconsole/netconsole.h @@ -5,8 +5,7 @@ //===========================================================================// #pragma once #include "tier1/cmd.h" -#include "protoc/cl_rcon.pb.h" -#include "protoc/sv_rcon.pb.h" +#include "protoc/netcon.pb.h" #include "engine/shared/base_rcon.h" constexpr const char* NETCON_VERSION = "2.0.0.1"; @@ -17,7 +16,7 @@ public: CNetCon(void); ~CNetCon(void); - bool Init(const bool bAnsiColor, const char* pHostName = nullptr, const int nPort = SOCKET_ERROR); + bool Init(const bool bAnsiColor, const char* pAdr = nullptr, const char* pKey = nullptr); bool Shutdown(void); void TermSetup(const bool bAnsiColor); @@ -33,11 +32,14 @@ public: inline float GetTickInterval() const { return m_flTickInterval; } static BOOL WINAPI CloseHandler(DWORD eventCode); - virtual void Disconnect(const char* szReason = nullptr); + virtual bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR) override; + virtual void Disconnect(const char* szReason = nullptr) override; + virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override; + void TrySetKey(const char* const pKey); bool Serialize(vector& vecBuf, const char* szReqBuf, - const char* szReqVal, const cl_rcon::request_t requestType) const; + const char* szReqVal, const netcon::request_e requestType) const; SocketHandle_t GetSocket(void); bool IsInitialized(void) const; @@ -47,6 +49,7 @@ private: bool m_bInitialized; bool m_bQuitting; bool m_bPromptConnect; + bool m_bEncryptFrames; float m_flTickInterval; characterset_t m_CharacterSet; diff --git a/r5dev/pluginsdk/CMakeLists.txt b/r5dev/pluginsdk/CMakeLists.txt index 47e85e8e..fc0482d5 100644 --- a/r5dev/pluginsdk/CMakeLists.txt +++ b/r5dev/pluginsdk/CMakeLists.txt @@ -23,8 +23,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE "libspdlog" "SigCache_Pb" - "SV_RCon_Pb" - "CL_RCon_Pb" + "NetCon_Pb" "Rpcrt4.lib" ) diff --git a/r5dev/pluginsystem/ipluginsystem.h b/r5dev/pluginsystem/ipluginsystem.h index 21479ec4..be46ed5d 100644 --- a/r5dev/pluginsystem/ipluginsystem.h +++ b/r5dev/pluginsystem/ipluginsystem.h @@ -13,8 +13,12 @@ struct PluginHelpWithAnything_t enum class ePluginCallback : int16_t { - CModAppSystemGroup_Create = 0, - CServer_ConnectClient + // !! - WARNING: if any existing values are changed, you must increment INTERFACEVERSION_PLUGINSYSTEM - !! + + CModAppSystemGroup_Create = 0, + CServer_ConnectClient = 1, + SV_RegisterScriptFunctions = 2, + OnReceivedChatMessage = 3, }; ePluginHelp m_nHelpID; diff --git a/r5dev/pluginsystem/pluginsystem.cpp b/r5dev/pluginsystem/pluginsystem.cpp index 8f5b2e0a..2596ff1d 100644 --- a/r5dev/pluginsystem/pluginsystem.cpp +++ b/r5dev/pluginsystem/pluginsystem.cpp @@ -131,7 +131,16 @@ CUtlVector& CPluginSystem::GetInstances() //----------------------------------------------------------------------------- void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help) { -#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast(function) +#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast(function); callback.GetCallbacks().Tail().SetModuleName(moduleName) + + if (!help->m_pFunction) + return; + + // [rexx]: This fetches the path to the module that contains the requested callback function. + // The module name is fetched so that callbacks can be identified by the plugin that they came from. + // This must use the wide-char version of this func, as file paths may contain non-ASCII characters and we don't really want those to break. + wchar_t moduleName[MAX_PATH] = {}; + GetMappedFileNameW((HANDLE)-1, help->m_pFunction, moduleName, MAX_PATH); switch (help->m_nCallbackID) { @@ -145,6 +154,11 @@ void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help) ADD_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction); break; } + case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage: + { + ADD_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction); + break; + } default: break; } @@ -160,6 +174,9 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help) { #define REMOVE_PLUGIN_CALLBACK(fn, callback, function) callback -= reinterpret_cast(function) + if (!help->m_pFunction) + return; + switch (help->m_nCallbackID) { case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create: @@ -172,6 +189,11 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help) REMOVE_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction); break; } + case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage: + { + REMOVE_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction); + break; + } default: break; } diff --git a/r5dev/pluginsystem/pluginsystem.h b/r5dev/pluginsystem/pluginsystem.h index 6b60e848..071c11d6 100644 --- a/r5dev/pluginsystem/pluginsystem.h +++ b/r5dev/pluginsystem/pluginsystem.h @@ -6,6 +6,7 @@ class CModAppSystemGroup; class CServer; class CClient; +class CPlayer; struct user_creds_s; template @@ -82,6 +83,32 @@ private: CUtlVector m_vCallbacks; }; +template +class CPluginCallback +{ + friend class CPluginSystem; +public: + CPluginCallback(T f) : function(f) {}; + + inline const T& Function() { return function; }; + inline const wchar_t* ModuleName() { return moduleName; }; + + operator bool() const + { + return function; + } + +protected: + inline void SetModuleName(wchar_t* name) + { + wcscpy_s(moduleName, name); + }; + +private: + T function; + wchar_t moduleName[MAX_PATH]; +}; + class CPluginSystem : IPluginSystem { public: @@ -120,10 +147,11 @@ public: virtual void* HelpWithAnything(PluginHelpWithAnything_t* help); -#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList& funcName() { return varName; } private: CPluginCallbackList varName; +#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList>& funcName() { return varName; } private: CPluginCallbackList> varName; CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks); CREATE_PLUGIN_CALLBACK(ConnectClientFn, bool(*)(CServer*, CClient*, user_creds_s*), GetConnectClientCallbacks, connectClientCallbacks); + CREATE_PLUGIN_CALLBACK(OnChatMessageFn, bool(*)(CPlayer*, const char*, bool), GetChatMessageCallbacks, chatMessageCallbacks); #undef CREATE_PLUGIN_CALLBACK @@ -140,4 +168,4 @@ FORCEINLINE CPluginSystem* PluginSystem() // Monitor this and performance profile this if fps drops are detected. #define CALL_PLUGIN_CALLBACKS(callback, ...) \ for (auto& cb : !callback) \ - cb(__VA_ARGS__) + cb.Function()(__VA_ARGS__) diff --git a/r5dev/protoc/CMakeLists.txt b/r5dev/protoc/CMakeLists.txt index 8e78d772..c4fce5b3 100644 --- a/r5dev/protoc/CMakeLists.txt +++ b/r5dev/protoc/CMakeLists.txt @@ -23,25 +23,13 @@ add_sources( SOURCE_GROUP "Runtime" end_sources() thirdparty_suppress_warnings() -add_module( "lib" "SV_RCon_Pb" "vpc" ${FOLDER_CONTEXT} FALSE TRUE ) +add_module( "lib" "NetCon_Pb" "vpc" ${FOLDER_CONTEXT} FALSE TRUE ) start_sources() add_sources( SOURCE_GROUP "Runtime" - "sv_rcon.pb.cc" - "sv_rcon.pb.h" -) - -end_sources() -thirdparty_suppress_warnings() - -add_module( "lib" "CL_RCon_Pb" "vpc" ${FOLDER_CONTEXT} FALSE TRUE ) - -start_sources() - -add_sources( SOURCE_GROUP "Runtime" - "cl_rcon.pb.cc" - "cl_rcon.pb.h" + "netcon.pb.cc" + "netcon.pb.h" ) end_sources() diff --git a/r5dev/protoc/cl_rcon.pb.cc b/r5dev/protoc/cl_rcon.pb.cc deleted file mode 100644 index c577a653..00000000 --- a/r5dev/protoc/cl_rcon.pb.cc +++ /dev/null @@ -1,489 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: cl_rcon.proto - -#include "cl_rcon.pb.h" - -#include - -#include -#include -#include -#include -// @@protoc_insertion_point(includes) -#include - -PROTOBUF_PRAGMA_INIT_SEG - -namespace _pb = ::PROTOBUF_NAMESPACE_ID; -namespace _pbi = _pb::internal; - -namespace cl_rcon { -PROTOBUF_CONSTEXPR request::request( - ::_pbi::ConstantInitialized): _impl_{ - /*decltype(_impl_._has_bits_)*/{} - , /*decltype(_impl_._cached_size_)*/{} - , /*decltype(_impl_.requestmsg_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} - , /*decltype(_impl_.requestval_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} - , /*decltype(_impl_.messageid_)*/0 - , /*decltype(_impl_.messagetype_)*/0 - , /*decltype(_impl_.requesttype_)*/0} {} -struct requestDefaultTypeInternal { - PROTOBUF_CONSTEXPR requestDefaultTypeInternal() - : _instance(::_pbi::ConstantInitialized{}) {} - ~requestDefaultTypeInternal() {} - union { - request _instance; - }; -}; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 requestDefaultTypeInternal _request_default_instance_; -} // namespace cl_rcon -namespace cl_rcon { -bool request_t_IsValid(int value) { - switch (value) { - case 0: - case 1: - case 2: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed request_t_strings[3] = {}; - -static const char request_t_names[] = - "SERVERDATA_REQUEST_AUTH" - "SERVERDATA_REQUEST_EXECCOMMAND" - "SERVERDATA_REQUEST_SEND_CONSOLE_LOG"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry request_t_entries[] = { - { {request_t_names + 0, 23}, 1 }, - { {request_t_names + 23, 30}, 0 }, - { {request_t_names + 53, 35}, 2 }, -}; - -static const int request_t_entries_by_number[] = { - 1, // 0 -> SERVERDATA_REQUEST_EXECCOMMAND - 0, // 1 -> SERVERDATA_REQUEST_AUTH - 2, // 2 -> SERVERDATA_REQUEST_SEND_CONSOLE_LOG -}; - -const std::string& request_t_Name( - request_t value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - request_t_entries, - request_t_entries_by_number, - 3, request_t_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - request_t_entries, - request_t_entries_by_number, - 3, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - request_t_strings[idx].get(); -} -bool request_t_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, request_t* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - request_t_entries, 3, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} - -// =================================================================== - -class request::_Internal { - public: - using HasBits = decltype(std::declval()._impl_._has_bits_); - static void set_has_messageid(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_messagetype(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_requesttype(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_requestmsg(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_requestval(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -request::request(::PROTOBUF_NAMESPACE_ID::Arena* arena, - bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { - SharedCtor(arena, is_message_owned); - // @@protoc_insertion_point(arena_constructor:cl_rcon.request) -} -request::request(const request& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite() { - request* const _this = this; (void)_this; - new (&_impl_) Impl_{ - decltype(_impl_._has_bits_){from._impl_._has_bits_} - , /*decltype(_impl_._cached_size_)*/{} - , decltype(_impl_.requestmsg_){} - , decltype(_impl_.requestval_){} - , decltype(_impl_.messageid_){} - , decltype(_impl_.messagetype_){} - , decltype(_impl_.requesttype_){}}; - - _internal_metadata_.MergeFrom(from._internal_metadata_); - _impl_.requestmsg_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.requestmsg_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (from._internal_has_requestmsg()) { - _this->_impl_.requestmsg_.Set(from._internal_requestmsg(), - _this->GetArenaForAllocation()); - } - _impl_.requestval_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.requestval_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (from._internal_has_requestval()) { - _this->_impl_.requestval_.Set(from._internal_requestval(), - _this->GetArenaForAllocation()); - } - ::memcpy(&_impl_.messageid_, &from._impl_.messageid_, - static_cast(reinterpret_cast(&_impl_.requesttype_) - - reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.requesttype_)); - // @@protoc_insertion_point(copy_constructor:cl_rcon.request) -} - -inline void request::SharedCtor( - ::_pb::Arena* arena, bool is_message_owned) { - (void)arena; - (void)is_message_owned; - new (&_impl_) Impl_{ - decltype(_impl_._has_bits_){} - , /*decltype(_impl_._cached_size_)*/{} - , decltype(_impl_.requestmsg_){} - , decltype(_impl_.requestval_){} - , decltype(_impl_.messageid_){0} - , decltype(_impl_.messagetype_){0} - , decltype(_impl_.requesttype_){0} - }; - _impl_.requestmsg_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.requestmsg_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.requestval_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.requestval_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -} - -request::~request() { - // @@protoc_insertion_point(destructor:cl_rcon.request) - if (auto *arena = _internal_metadata_.DeleteReturnArena()) { - (void)arena; - return; - } - SharedDtor(); -} - -inline void request::SharedDtor() { - GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - _impl_.requestmsg_.Destroy(); - _impl_.requestval_.Destroy(); -} - -void request::SetCachedSize(int size) const { - _impl_._cached_size_.Set(size); -} - -void request::Clear() { -// @@protoc_insertion_point(message_clear_start:cl_rcon.request) - uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - _impl_.requestmsg_.ClearNonDefaultToEmpty(); - } - if (cached_has_bits & 0x00000002u) { - _impl_.requestval_.ClearNonDefaultToEmpty(); - } - } - if (cached_has_bits & 0x0000001cu) { - ::memset(&_impl_.messageid_, 0, static_cast( - reinterpret_cast(&_impl_.requesttype_) - - reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.requesttype_)); - } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -const char* request::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - uint32_t tag; - ptr = ::_pbi::ReadTag(ptr, &tag); - switch (tag >> 3) { - // optional int32 messageID = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { - _Internal::set_has_messageid(&has_bits); - _impl_.messageid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } else - goto handle_unusual; - continue; - // optional int32 messageType = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { - _Internal::set_has_messagetype(&has_bits); - _impl_.messagetype_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } else - goto handle_unusual; - continue; - // optional .cl_rcon.request_t requestType = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { - uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); - CHK_(ptr); - _internal_set_requesttype(static_cast<::cl_rcon::request_t>(val)); - } else - goto handle_unusual; - continue; - // optional string requestMsg = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { - auto str = _internal_mutable_requestmsg(); - ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); - CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, nullptr)); - } else - goto handle_unusual; - continue; - // optional string requestVal = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 42)) { - auto str = _internal_mutable_requestval(); - ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); - CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, nullptr)); - } else - goto handle_unusual; - continue; - default: - goto handle_unusual; - } // switch - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto message_done; - } - ptr = UnknownFieldParse( - tag, - _internal_metadata_.mutable_unknown_fields(), - ptr, ctx); - CHK_(ptr != nullptr); - } // while -message_done: - _impl_._has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto message_done; -#undef CHK_ -} - -uint8_t* request::_InternalSerialize( - uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { - // @@protoc_insertion_point(serialize_to_array_start:cl_rcon.request) - uint32_t cached_has_bits = 0; - (void) cached_has_bits; - - // optional int32 messageID = 1; - if (_internal_has_messageid()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_messageid(), target); - } - - // optional int32 messageType = 2; - if (_internal_has_messagetype()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_messagetype(), target); - } - - // optional .cl_rcon.request_t requestType = 3; - if (_internal_has_requesttype()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteEnumToArray( - 3, this->_internal_requesttype(), target); - } - - // optional string requestMsg = 4; - if (_internal_has_requestmsg()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_requestmsg().data(), static_cast(this->_internal_requestmsg().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "cl_rcon.request.requestMsg"); - target = stream->WriteStringMaybeAliased( - 4, this->_internal_requestmsg(), target); - } - - // optional string requestVal = 5; - if (_internal_has_requestval()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_requestval().data(), static_cast(this->_internal_requestval().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "cl_rcon.request.requestVal"); - target = stream->WriteStringMaybeAliased( - 5, this->_internal_requestval(), target); - } - - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), - static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:cl_rcon.request) - return target; -} - -size_t request::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:cl_rcon.request) - size_t total_size = 0; - - uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional string requestMsg = 4; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->_internal_requestmsg()); - } - - // optional string requestVal = 5; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->_internal_requestval()); - } - - // optional int32 messageID = 1; - if (cached_has_bits & 0x00000004u) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messageid()); - } - - // optional int32 messageType = 2; - if (cached_has_bits & 0x00000008u) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messagetype()); - } - - // optional .cl_rcon.request_t requestType = 3; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::_pbi::WireFormatLite::EnumSize(this->_internal_requesttype()); - } - - } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); - } - int cached_size = ::_pbi::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void request::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::_pbi::DownCast( - &from)); -} - -void request::MergeFrom(const request& from) { - request* const _this = this; - // @@protoc_insertion_point(class_specific_merge_from_start:cl_rcon.request) - GOOGLE_DCHECK_NE(&from, _this); - uint32_t cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._impl_._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _this->_internal_set_requestmsg(from._internal_requestmsg()); - } - if (cached_has_bits & 0x00000002u) { - _this->_internal_set_requestval(from._internal_requestval()); - } - if (cached_has_bits & 0x00000004u) { - _this->_impl_.messageid_ = from._impl_.messageid_; - } - if (cached_has_bits & 0x00000008u) { - _this->_impl_.messagetype_ = from._impl_.messagetype_; - } - if (cached_has_bits & 0x00000010u) { - _this->_impl_.requesttype_ = from._impl_.requesttype_; - } - _this->_impl_._has_bits_[0] |= cached_has_bits; - } - _this->_internal_metadata_.MergeFrom(from._internal_metadata_); -} - -void request::CopyFrom(const request& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:cl_rcon.request) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool request::IsInitialized() const { - return true; -} - -void request::InternalSwap(request* other) { - using std::swap; - auto* lhs_arena = GetArenaForAllocation(); - auto* rhs_arena = other->GetArenaForAllocation(); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &_impl_.requestmsg_, lhs_arena, - &other->_impl_.requestmsg_, rhs_arena - ); - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &_impl_.requestval_, lhs_arena, - &other->_impl_.requestval_, rhs_arena - ); - ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(request, _impl_.requesttype_) - + sizeof(request::_impl_.requesttype_) - - PROTOBUF_FIELD_OFFSET(request, _impl_.messageid_)>( - reinterpret_cast(&_impl_.messageid_), - reinterpret_cast(&other->_impl_.messageid_)); -} - -std::string request::GetTypeName() const { - return "cl_rcon.request"; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace cl_rcon -PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::cl_rcon::request* -Arena::CreateMaybeMessage< ::cl_rcon::request >(Arena* arena) { - return Arena::CreateMessageInternal< ::cl_rcon::request >(arena); -} -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) -#include diff --git a/r5dev/protoc/cl_rcon.pb.h b/r5dev/protoc/cl_rcon.pb.h deleted file mode 100644 index 55fd5689..00000000 --- a/r5dev/protoc/cl_rcon.pb.h +++ /dev/null @@ -1,530 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: cl_rcon.proto - -#ifndef GOOGLE_PROTOBUF_INCLUDED_cl_5frcon_2eproto -#define GOOGLE_PROTOBUF_INCLUDED_cl_5frcon_2eproto - -#include -#include - -#include -#if PROTOBUF_VERSION < 3021000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#include -#define PROTOBUF_INTERNAL_EXPORT_cl_5frcon_2eproto -PROTOBUF_NAMESPACE_OPEN -namespace internal { -class AnyMetadata; -} // namespace internal -PROTOBUF_NAMESPACE_CLOSE - -// Internal implementation detail -- do not use these members. -struct TableStruct_cl_5frcon_2eproto { - static const uint32_t offsets[]; -}; -namespace cl_rcon { -class request; -struct requestDefaultTypeInternal; -extern requestDefaultTypeInternal _request_default_instance_; -} // namespace cl_rcon -PROTOBUF_NAMESPACE_OPEN -template<> ::cl_rcon::request* Arena::CreateMaybeMessage<::cl_rcon::request>(Arena*); -PROTOBUF_NAMESPACE_CLOSE -namespace cl_rcon { - -enum request_t : int { - SERVERDATA_REQUEST_EXECCOMMAND = 0, - SERVERDATA_REQUEST_AUTH = 1, - SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2, - request_t_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits::min(), - request_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits::max() -}; -bool request_t_IsValid(int value); -constexpr request_t request_t_MIN = SERVERDATA_REQUEST_EXECCOMMAND; -constexpr request_t request_t_MAX = SERVERDATA_REQUEST_SEND_CONSOLE_LOG; -constexpr int request_t_ARRAYSIZE = request_t_MAX + 1; - -const std::string& request_t_Name(request_t value); -template -inline const std::string& request_t_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function request_t_Name."); - return request_t_Name(static_cast(enum_t_value)); -} -bool request_t_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, request_t* value); -// =================================================================== - -class request final : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:cl_rcon.request) */ { - public: - inline request() : request(nullptr) {} - ~request() override; - explicit PROTOBUF_CONSTEXPR request(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); - - request(const request& from); - request(request&& from) noexcept - : request() { - *this = ::std::move(from); - } - - inline request& operator=(const request& from) { - CopyFrom(from); - return *this; - } - inline request& operator=(request&& from) noexcept { - if (this == &from) return *this; - if (GetOwningArena() == from.GetOwningArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE - && GetOwningArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE - ) { - InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - static const request& default_instance() { - return *internal_default_instance(); - } - static inline const request* internal_default_instance() { - return reinterpret_cast( - &_request_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(request& a, request& b) { - a.Swap(&b); - } - inline void Swap(request* other) { - if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetOwningArena() != nullptr && - GetOwningArena() == other->GetOwningArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP - if (GetOwningArena() == other->GetOwningArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP - InternalSwap(other); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); - } - } - void UnsafeArenaSwap(request* other) { - if (other == this) return; - GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - request* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; - void CopyFrom(const request& from); - void MergeFrom(const request& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - uint8_t* _InternalSerialize( - uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _impl_._cached_size_.Get(); } - - private: - void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(request* other); - - private: - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "cl_rcon.request"; - } - protected: - explicit request(::PROTOBUF_NAMESPACE_ID::Arena* arena, - bool is_message_owned = false); - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kRequestMsgFieldNumber = 4, - kRequestValFieldNumber = 5, - kMessageIDFieldNumber = 1, - kMessageTypeFieldNumber = 2, - kRequestTypeFieldNumber = 3, - }; - // optional string requestMsg = 4; - bool has_requestmsg() const; - private: - bool _internal_has_requestmsg() const; - public: - void clear_requestmsg(); - const std::string& requestmsg() const; - template - void set_requestmsg(ArgT0&& arg0, ArgT... args); - std::string* mutable_requestmsg(); - PROTOBUF_NODISCARD std::string* release_requestmsg(); - void set_allocated_requestmsg(std::string* requestmsg); - private: - const std::string& _internal_requestmsg() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_requestmsg(const std::string& value); - std::string* _internal_mutable_requestmsg(); - public: - - // optional string requestVal = 5; - bool has_requestval() const; - private: - bool _internal_has_requestval() const; - public: - void clear_requestval(); - const std::string& requestval() const; - template - void set_requestval(ArgT0&& arg0, ArgT... args); - std::string* mutable_requestval(); - PROTOBUF_NODISCARD std::string* release_requestval(); - void set_allocated_requestval(std::string* requestval); - private: - const std::string& _internal_requestval() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_requestval(const std::string& value); - std::string* _internal_mutable_requestval(); - public: - - // optional int32 messageID = 1; - bool has_messageid() const; - private: - bool _internal_has_messageid() const; - public: - void clear_messageid(); - int32_t messageid() const; - void set_messageid(int32_t value); - private: - int32_t _internal_messageid() const; - void _internal_set_messageid(int32_t value); - public: - - // optional int32 messageType = 2; - bool has_messagetype() const; - private: - bool _internal_has_messagetype() const; - public: - void clear_messagetype(); - int32_t messagetype() const; - void set_messagetype(int32_t value); - private: - int32_t _internal_messagetype() const; - void _internal_set_messagetype(int32_t value); - public: - - // optional .cl_rcon.request_t requestType = 3; - bool has_requesttype() const; - private: - bool _internal_has_requesttype() const; - public: - void clear_requesttype(); - ::cl_rcon::request_t requesttype() const; - void set_requesttype(::cl_rcon::request_t value); - private: - ::cl_rcon::request_t _internal_requesttype() const; - void _internal_set_requesttype(::cl_rcon::request_t value); - public: - - // @@protoc_insertion_point(class_scope:cl_rcon.request) - private: - class _Internal; - - template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; - typedef void InternalArenaConstructable_; - typedef void DestructorSkippable_; - struct Impl_ { - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr requestmsg_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr requestval_; - int32_t messageid_; - int32_t messagetype_; - int requesttype_; - }; - union { Impl_ _impl_; }; - friend struct ::TableStruct_cl_5frcon_2eproto; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// request - -// optional int32 messageID = 1; -inline bool request::_internal_has_messageid() const { - bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; - return value; -} -inline bool request::has_messageid() const { - return _internal_has_messageid(); -} -inline void request::clear_messageid() { - _impl_.messageid_ = 0; - _impl_._has_bits_[0] &= ~0x00000004u; -} -inline int32_t request::_internal_messageid() const { - return _impl_.messageid_; -} -inline int32_t request::messageid() const { - // @@protoc_insertion_point(field_get:cl_rcon.request.messageID) - return _internal_messageid(); -} -inline void request::_internal_set_messageid(int32_t value) { - _impl_._has_bits_[0] |= 0x00000004u; - _impl_.messageid_ = value; -} -inline void request::set_messageid(int32_t value) { - _internal_set_messageid(value); - // @@protoc_insertion_point(field_set:cl_rcon.request.messageID) -} - -// optional int32 messageType = 2; -inline bool request::_internal_has_messagetype() const { - bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; - return value; -} -inline bool request::has_messagetype() const { - return _internal_has_messagetype(); -} -inline void request::clear_messagetype() { - _impl_.messagetype_ = 0; - _impl_._has_bits_[0] &= ~0x00000008u; -} -inline int32_t request::_internal_messagetype() const { - return _impl_.messagetype_; -} -inline int32_t request::messagetype() const { - // @@protoc_insertion_point(field_get:cl_rcon.request.messageType) - return _internal_messagetype(); -} -inline void request::_internal_set_messagetype(int32_t value) { - _impl_._has_bits_[0] |= 0x00000008u; - _impl_.messagetype_ = value; -} -inline void request::set_messagetype(int32_t value) { - _internal_set_messagetype(value); - // @@protoc_insertion_point(field_set:cl_rcon.request.messageType) -} - -// optional .cl_rcon.request_t requestType = 3; -inline bool request::_internal_has_requesttype() const { - bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; - return value; -} -inline bool request::has_requesttype() const { - return _internal_has_requesttype(); -} -inline void request::clear_requesttype() { - _impl_.requesttype_ = 0; - _impl_._has_bits_[0] &= ~0x00000010u; -} -inline ::cl_rcon::request_t request::_internal_requesttype() const { - return static_cast< ::cl_rcon::request_t >(_impl_.requesttype_); -} -inline ::cl_rcon::request_t request::requesttype() const { - // @@protoc_insertion_point(field_get:cl_rcon.request.requestType) - return _internal_requesttype(); -} -inline void request::_internal_set_requesttype(::cl_rcon::request_t value) { - _impl_._has_bits_[0] |= 0x00000010u; - _impl_.requesttype_ = value; -} -inline void request::set_requesttype(::cl_rcon::request_t value) { - _internal_set_requesttype(value); - // @@protoc_insertion_point(field_set:cl_rcon.request.requestType) -} - -// optional string requestMsg = 4; -inline bool request::_internal_has_requestmsg() const { - bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; - return value; -} -inline bool request::has_requestmsg() const { - return _internal_has_requestmsg(); -} -inline void request::clear_requestmsg() { - _impl_.requestmsg_.ClearToEmpty(); - _impl_._has_bits_[0] &= ~0x00000001u; -} -inline const std::string& request::requestmsg() const { - // @@protoc_insertion_point(field_get:cl_rcon.request.requestMsg) - return _internal_requestmsg(); -} -template -inline PROTOBUF_ALWAYS_INLINE -void request::set_requestmsg(ArgT0&& arg0, ArgT... args) { - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.requestmsg_.Set(static_cast(arg0), args..., GetArenaForAllocation()); - // @@protoc_insertion_point(field_set:cl_rcon.request.requestMsg) -} -inline std::string* request::mutable_requestmsg() { - std::string* _s = _internal_mutable_requestmsg(); - // @@protoc_insertion_point(field_mutable:cl_rcon.request.requestMsg) - return _s; -} -inline const std::string& request::_internal_requestmsg() const { - return _impl_.requestmsg_.Get(); -} -inline void request::_internal_set_requestmsg(const std::string& value) { - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.requestmsg_.Set(value, GetArenaForAllocation()); -} -inline std::string* request::_internal_mutable_requestmsg() { - _impl_._has_bits_[0] |= 0x00000001u; - return _impl_.requestmsg_.Mutable(GetArenaForAllocation()); -} -inline std::string* request::release_requestmsg() { - // @@protoc_insertion_point(field_release:cl_rcon.request.requestMsg) - if (!_internal_has_requestmsg()) { - return nullptr; - } - _impl_._has_bits_[0] &= ~0x00000001u; - auto* p = _impl_.requestmsg_.Release(); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.requestmsg_.IsDefault()) { - _impl_.requestmsg_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - return p; -} -inline void request::set_allocated_requestmsg(std::string* requestmsg) { - if (requestmsg != nullptr) { - _impl_._has_bits_[0] |= 0x00000001u; - } else { - _impl_._has_bits_[0] &= ~0x00000001u; - } - _impl_.requestmsg_.SetAllocated(requestmsg, GetArenaForAllocation()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.requestmsg_.IsDefault()) { - _impl_.requestmsg_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - // @@protoc_insertion_point(field_set_allocated:cl_rcon.request.requestMsg) -} - -// optional string requestVal = 5; -inline bool request::_internal_has_requestval() const { - bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; - return value; -} -inline bool request::has_requestval() const { - return _internal_has_requestval(); -} -inline void request::clear_requestval() { - _impl_.requestval_.ClearToEmpty(); - _impl_._has_bits_[0] &= ~0x00000002u; -} -inline const std::string& request::requestval() const { - // @@protoc_insertion_point(field_get:cl_rcon.request.requestVal) - return _internal_requestval(); -} -template -inline PROTOBUF_ALWAYS_INLINE -void request::set_requestval(ArgT0&& arg0, ArgT... args) { - _impl_._has_bits_[0] |= 0x00000002u; - _impl_.requestval_.Set(static_cast(arg0), args..., GetArenaForAllocation()); - // @@protoc_insertion_point(field_set:cl_rcon.request.requestVal) -} -inline std::string* request::mutable_requestval() { - std::string* _s = _internal_mutable_requestval(); - // @@protoc_insertion_point(field_mutable:cl_rcon.request.requestVal) - return _s; -} -inline const std::string& request::_internal_requestval() const { - return _impl_.requestval_.Get(); -} -inline void request::_internal_set_requestval(const std::string& value) { - _impl_._has_bits_[0] |= 0x00000002u; - _impl_.requestval_.Set(value, GetArenaForAllocation()); -} -inline std::string* request::_internal_mutable_requestval() { - _impl_._has_bits_[0] |= 0x00000002u; - return _impl_.requestval_.Mutable(GetArenaForAllocation()); -} -inline std::string* request::release_requestval() { - // @@protoc_insertion_point(field_release:cl_rcon.request.requestVal) - if (!_internal_has_requestval()) { - return nullptr; - } - _impl_._has_bits_[0] &= ~0x00000002u; - auto* p = _impl_.requestval_.Release(); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.requestval_.IsDefault()) { - _impl_.requestval_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - return p; -} -inline void request::set_allocated_requestval(std::string* requestval) { - if (requestval != nullptr) { - _impl_._has_bits_[0] |= 0x00000002u; - } else { - _impl_._has_bits_[0] &= ~0x00000002u; - } - _impl_.requestval_.SetAllocated(requestval, GetArenaForAllocation()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.requestval_.IsDefault()) { - _impl_.requestval_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - // @@protoc_insertion_point(field_set_allocated:cl_rcon.request.requestVal) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ - -// @@protoc_insertion_point(namespace_scope) - -} // namespace cl_rcon - -PROTOBUF_NAMESPACE_OPEN - -template <> struct is_proto_enum< ::cl_rcon::request_t> : ::std::true_type {}; - -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) - -#include -#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_cl_5frcon_2eproto diff --git a/r5dev/protoc/netcon.pb.cc b/r5dev/protoc/netcon.pb.cc new file mode 100644 index 00000000..cc7ea65f --- /dev/null +++ b/r5dev/protoc/netcon.pb.cc @@ -0,0 +1,1235 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: netcon.proto + +#include "netcon.pb.h" + +#include + +#include +#include +#include +#include +// @@protoc_insertion_point(includes) +#include + +PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + +namespace netcon { +PROTOBUF_CONSTEXPR request::request( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.requestmsg_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.requestval_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.messageid_)*/0 + , /*decltype(_impl_.messagetype_)*/0 + , /*decltype(_impl_.requesttype_)*/0} {} +struct requestDefaultTypeInternal { + PROTOBUF_CONSTEXPR requestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~requestDefaultTypeInternal() {} + union { + request _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 requestDefaultTypeInternal _request_default_instance_; +PROTOBUF_CONSTEXPR response::response( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.responsemsg_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.responseval_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.messageid_)*/0 + , /*decltype(_impl_.messagetype_)*/0 + , /*decltype(_impl_.responsetype_)*/0} {} +struct responseDefaultTypeInternal { + PROTOBUF_CONSTEXPR responseDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~responseDefaultTypeInternal() {} + union { + response _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 responseDefaultTypeInternal _response_default_instance_; +PROTOBUF_CONSTEXPR envelope::envelope( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.nonce_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.data_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.encrypted_)*/false + , /*decltype(_impl_._cached_size_)*/{}} {} +struct envelopeDefaultTypeInternal { + PROTOBUF_CONSTEXPR envelopeDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} + ~envelopeDefaultTypeInternal() {} + union { + envelope _instance; + }; +}; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 envelopeDefaultTypeInternal _envelope_default_instance_; +} // namespace netcon +namespace netcon { +bool request_e_IsValid(int value) { + switch (value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed request_e_strings[3] = {}; + +static const char request_e_names[] = + "SERVERDATA_REQUEST_AUTH" + "SERVERDATA_REQUEST_EXECCOMMAND" + "SERVERDATA_REQUEST_SEND_CONSOLE_LOG"; + +static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry request_e_entries[] = { + { {request_e_names + 0, 23}, 1 }, + { {request_e_names + 23, 30}, 0 }, + { {request_e_names + 53, 35}, 2 }, +}; + +static const int request_e_entries_by_number[] = { + 1, // 0 -> SERVERDATA_REQUEST_EXECCOMMAND + 0, // 1 -> SERVERDATA_REQUEST_AUTH + 2, // 2 -> SERVERDATA_REQUEST_SEND_CONSOLE_LOG +}; + +const std::string& request_e_Name( + request_e value) { + static const bool dummy = + ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( + request_e_entries, + request_e_entries_by_number, + 3, request_e_strings); + (void) dummy; + int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( + request_e_entries, + request_e_entries_by_number, + 3, value); + return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : + request_e_strings[idx].get(); +} +bool request_e_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, request_e* value) { + int int_value; + bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( + request_e_entries, 3, name, &int_value); + if (success) { + *value = static_cast(int_value); + } + return success; +} +bool response_e_IsValid(int value) { + switch (value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed response_e_strings[2] = {}; + +static const char response_e_names[] = + "SERVERDATA_RESPONSE_AUTH" + "SERVERDATA_RESPONSE_CONSOLE_LOG"; + +static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry response_e_entries[] = { + { {response_e_names + 0, 24}, 0 }, + { {response_e_names + 24, 31}, 1 }, +}; + +static const int response_e_entries_by_number[] = { + 0, // 0 -> SERVERDATA_RESPONSE_AUTH + 1, // 1 -> SERVERDATA_RESPONSE_CONSOLE_LOG +}; + +const std::string& response_e_Name( + response_e value) { + static const bool dummy = + ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( + response_e_entries, + response_e_entries_by_number, + 2, response_e_strings); + (void) dummy; + int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( + response_e_entries, + response_e_entries_by_number, + 2, value); + return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : + response_e_strings[idx].get(); +} +bool response_e_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, response_e* value) { + int int_value; + bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( + response_e_entries, 2, name, &int_value); + if (success) { + *value = static_cast(int_value); + } + return success; +} + +// =================================================================== + +class request::_Internal { + public: + using HasBits = decltype(std::declval()._impl_._has_bits_); + static void set_has_messageid(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_messagetype(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_requesttype(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_requestmsg(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_requestval(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +request::request(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); + // @@protoc_insertion_point(arena_constructor:netcon.request) +} +request::request(const request& from) + : ::PROTOBUF_NAMESPACE_ID::MessageLite() { + request* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.requestmsg_){} + , decltype(_impl_.requestval_){} + , decltype(_impl_.messageid_){} + , decltype(_impl_.messagetype_){} + , decltype(_impl_.requesttype_){}}; + + _internal_metadata_.MergeFrom(from._internal_metadata_); + _impl_.requestmsg_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.requestmsg_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_requestmsg()) { + _this->_impl_.requestmsg_.Set(from._internal_requestmsg(), + _this->GetArenaForAllocation()); + } + _impl_.requestval_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.requestval_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_requestval()) { + _this->_impl_.requestval_.Set(from._internal_requestval(), + _this->GetArenaForAllocation()); + } + ::memcpy(&_impl_.messageid_, &from._impl_.messageid_, + static_cast(reinterpret_cast(&_impl_.requesttype_) - + reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.requesttype_)); + // @@protoc_insertion_point(copy_constructor:netcon.request) +} + +inline void request::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.requestmsg_){} + , decltype(_impl_.requestval_){} + , decltype(_impl_.messageid_){0} + , decltype(_impl_.messagetype_){0} + , decltype(_impl_.requesttype_){0} + }; + _impl_.requestmsg_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.requestmsg_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.requestval_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.requestval_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +request::~request() { + // @@protoc_insertion_point(destructor:netcon.request) + if (auto *arena = _internal_metadata_.DeleteReturnArena()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void request::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + _impl_.requestmsg_.Destroy(); + _impl_.requestval_.Destroy(); +} + +void request::SetCachedSize(int size) const { + _impl_._cached_size_.Set(size); +} + +void request::Clear() { +// @@protoc_insertion_point(message_clear_start:netcon.request) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _impl_.requestmsg_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + _impl_.requestval_.ClearNonDefaultToEmpty(); + } + } + if (cached_has_bits & 0x0000001cu) { + ::memset(&_impl_.messageid_, 0, static_cast( + reinterpret_cast(&_impl_.requesttype_) - + reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.requesttype_)); + } + _impl_._has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +const char* request::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional int32 messageId = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + _Internal::set_has_messageid(&has_bits); + _impl_.messageid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 messageType = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { + _Internal::set_has_messagetype(&has_bits); + _impl_.messagetype_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .netcon.request_e requestType = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { + uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_requesttype(static_cast<::netcon::request_e>(val)); + } else + goto handle_unusual; + continue; + // optional string requestMsg = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { + auto str = _internal_mutable_requestmsg(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, nullptr)); + } else + goto handle_unusual; + continue; + // optional string requestVal = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 42)) { + auto str = _internal_mutable_requestval(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, nullptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _impl_._has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* request::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:netcon.request) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // optional int32 messageId = 1; + if (_internal_has_messageid()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_messageid(), target); + } + + // optional int32 messageType = 2; + if (_internal_has_messagetype()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_messagetype(), target); + } + + // optional .netcon.request_e requestType = 3; + if (_internal_has_requesttype()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteEnumToArray( + 3, this->_internal_requesttype(), target); + } + + // optional string requestMsg = 4; + if (_internal_has_requestmsg()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_requestmsg().data(), static_cast(this->_internal_requestmsg().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "netcon.request.requestMsg"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_requestmsg(), target); + } + + // optional string requestVal = 5; + if (_internal_has_requestval()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_requestval().data(), static_cast(this->_internal_requestval().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "netcon.request.requestVal"); + target = stream->WriteStringMaybeAliased( + 5, this->_internal_requestval(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), + static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:netcon.request) + return target; +} + +size_t request::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:netcon.request) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + // optional string requestMsg = 4; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_requestmsg()); + } + + // optional string requestVal = 5; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_requestval()); + } + + // optional int32 messageId = 1; + if (cached_has_bits & 0x00000004u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messageid()); + } + + // optional int32 messageType = 2; + if (cached_has_bits & 0x00000008u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messagetype()); + } + + // optional .netcon.request_e requestType = 3; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + + ::_pbi::WireFormatLite::EnumSize(this->_internal_requesttype()); + } + + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); + } + int cached_size = ::_pbi::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void request::CheckTypeAndMergeFrom( + const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { + MergeFrom(*::_pbi::DownCast( + &from)); +} + +void request::MergeFrom(const request& from) { + request* const _this = this; + // @@protoc_insertion_point(class_specific_merge_from_start:netcon.request) + GOOGLE_DCHECK_NE(&from, _this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x00000001u) { + _this->_internal_set_requestmsg(from._internal_requestmsg()); + } + if (cached_has_bits & 0x00000002u) { + _this->_internal_set_requestval(from._internal_requestval()); + } + if (cached_has_bits & 0x00000004u) { + _this->_impl_.messageid_ = from._impl_.messageid_; + } + if (cached_has_bits & 0x00000008u) { + _this->_impl_.messagetype_ = from._impl_.messagetype_; + } + if (cached_has_bits & 0x00000010u) { + _this->_impl_.requesttype_ = from._impl_.requesttype_; + } + _this->_impl_._has_bits_[0] |= cached_has_bits; + } + _this->_internal_metadata_.MergeFrom(from._internal_metadata_); +} + +void request::CopyFrom(const request& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:netcon.request) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool request::IsInitialized() const { + return true; +} + +void request::InternalSwap(request* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.requestmsg_, lhs_arena, + &other->_impl_.requestmsg_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.requestval_, lhs_arena, + &other->_impl_.requestval_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(request, _impl_.requesttype_) + + sizeof(request::_impl_.requesttype_) + - PROTOBUF_FIELD_OFFSET(request, _impl_.messageid_)>( + reinterpret_cast(&_impl_.messageid_), + reinterpret_cast(&other->_impl_.messageid_)); +} + +std::string request::GetTypeName() const { + return "netcon.request"; +} + + +// =================================================================== + +class response::_Internal { + public: + using HasBits = decltype(std::declval()._impl_._has_bits_); + static void set_has_messageid(HasBits* has_bits) { + (*has_bits)[0] |= 4u; + } + static void set_has_messagetype(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } + static void set_has_responsetype(HasBits* has_bits) { + (*has_bits)[0] |= 16u; + } + static void set_has_responsemsg(HasBits* has_bits) { + (*has_bits)[0] |= 1u; + } + static void set_has_responseval(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } +}; + +response::response(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); + // @@protoc_insertion_point(arena_constructor:netcon.response) +} +response::response(const response& from) + : ::PROTOBUF_NAMESPACE_ID::MessageLite() { + response* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.responsemsg_){} + , decltype(_impl_.responseval_){} + , decltype(_impl_.messageid_){} + , decltype(_impl_.messagetype_){} + , decltype(_impl_.responsetype_){}}; + + _internal_metadata_.MergeFrom(from._internal_metadata_); + _impl_.responsemsg_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.responsemsg_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_responsemsg()) { + _this->_impl_.responsemsg_.Set(from._internal_responsemsg(), + _this->GetArenaForAllocation()); + } + _impl_.responseval_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.responseval_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (from._internal_has_responseval()) { + _this->_impl_.responseval_.Set(from._internal_responseval(), + _this->GetArenaForAllocation()); + } + ::memcpy(&_impl_.messageid_, &from._impl_.messageid_, + static_cast(reinterpret_cast(&_impl_.responsetype_) - + reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.responsetype_)); + // @@protoc_insertion_point(copy_constructor:netcon.response) +} + +inline void response::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.responsemsg_){} + , decltype(_impl_.responseval_){} + , decltype(_impl_.messageid_){0} + , decltype(_impl_.messagetype_){0} + , decltype(_impl_.responsetype_){0} + }; + _impl_.responsemsg_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.responsemsg_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.responseval_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.responseval_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +response::~response() { + // @@protoc_insertion_point(destructor:netcon.response) + if (auto *arena = _internal_metadata_.DeleteReturnArena()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void response::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + _impl_.responsemsg_.Destroy(); + _impl_.responseval_.Destroy(); +} + +void response::SetCachedSize(int size) const { + _impl_._cached_size_.Set(size); +} + +void response::Clear() { +// @@protoc_insertion_point(message_clear_start:netcon.response) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _impl_.responsemsg_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000002u) { + _impl_.responseval_.ClearNonDefaultToEmpty(); + } + } + if (cached_has_bits & 0x0000001cu) { + ::memset(&_impl_.messageid_, 0, static_cast( + reinterpret_cast(&_impl_.responsetype_) - + reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.responsetype_)); + } + _impl_._has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +const char* response::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + _Internal::HasBits has_bits{}; + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // optional int32 messageId = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + _Internal::set_has_messageid(&has_bits); + _impl_.messageid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional int32 messageType = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { + _Internal::set_has_messagetype(&has_bits); + _impl_.messagetype_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // optional .netcon.response_e responseType = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { + uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + _internal_set_responsetype(static_cast<::netcon::response_e>(val)); + } else + goto handle_unusual; + continue; + // optional string responseMsg = 4; + case 4: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { + auto str = _internal_mutable_responsemsg(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, nullptr)); + } else + goto handle_unusual; + continue; + // optional string responseVal = 5; + case 5: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 42)) { + auto str = _internal_mutable_responseval(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, nullptr)); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + _impl_._has_bits_.Or(has_bits); + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* response::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:netcon.response) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // optional int32 messageId = 1; + if (_internal_has_messageid()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_messageid(), target); + } + + // optional int32 messageType = 2; + if (_internal_has_messagetype()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_messagetype(), target); + } + + // optional .netcon.response_e responseType = 3; + if (_internal_has_responsetype()) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteEnumToArray( + 3, this->_internal_responsetype(), target); + } + + // optional string responseMsg = 4; + if (_internal_has_responsemsg()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_responsemsg().data(), static_cast(this->_internal_responsemsg().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "netcon.response.responseMsg"); + target = stream->WriteStringMaybeAliased( + 4, this->_internal_responsemsg(), target); + } + + // optional string responseVal = 5; + if (_internal_has_responseval()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->_internal_responseval().data(), static_cast(this->_internal_responseval().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "netcon.response.responseVal"); + target = stream->WriteStringMaybeAliased( + 5, this->_internal_responseval(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), + static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:netcon.response) + return target; +} + +size_t response::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:netcon.response) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _impl_._has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + // optional string responseMsg = 4; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_responsemsg()); + } + + // optional string responseVal = 5; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_responseval()); + } + + // optional int32 messageId = 1; + if (cached_has_bits & 0x00000004u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messageid()); + } + + // optional int32 messageType = 2; + if (cached_has_bits & 0x00000008u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messagetype()); + } + + // optional .netcon.response_e responseType = 3; + if (cached_has_bits & 0x00000010u) { + total_size += 1 + + ::_pbi::WireFormatLite::EnumSize(this->_internal_responsetype()); + } + + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); + } + int cached_size = ::_pbi::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void response::CheckTypeAndMergeFrom( + const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { + MergeFrom(*::_pbi::DownCast( + &from)); +} + +void response::MergeFrom(const response& from) { + response* const _this = this; + // @@protoc_insertion_point(class_specific_merge_from_start:netcon.response) + GOOGLE_DCHECK_NE(&from, _this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x0000001fu) { + if (cached_has_bits & 0x00000001u) { + _this->_internal_set_responsemsg(from._internal_responsemsg()); + } + if (cached_has_bits & 0x00000002u) { + _this->_internal_set_responseval(from._internal_responseval()); + } + if (cached_has_bits & 0x00000004u) { + _this->_impl_.messageid_ = from._impl_.messageid_; + } + if (cached_has_bits & 0x00000008u) { + _this->_impl_.messagetype_ = from._impl_.messagetype_; + } + if (cached_has_bits & 0x00000010u) { + _this->_impl_.responsetype_ = from._impl_.responsetype_; + } + _this->_impl_._has_bits_[0] |= cached_has_bits; + } + _this->_internal_metadata_.MergeFrom(from._internal_metadata_); +} + +void response::CopyFrom(const response& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:netcon.response) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool response::IsInitialized() const { + return true; +} + +void response::InternalSwap(response* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.responsemsg_, lhs_arena, + &other->_impl_.responsemsg_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.responseval_, lhs_arena, + &other->_impl_.responseval_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(response, _impl_.responsetype_) + + sizeof(response::_impl_.responsetype_) + - PROTOBUF_FIELD_OFFSET(response, _impl_.messageid_)>( + reinterpret_cast(&_impl_.messageid_), + reinterpret_cast(&other->_impl_.messageid_)); +} + +std::string response::GetTypeName() const { + return "netcon.response"; +} + + +// =================================================================== + +class envelope::_Internal { + public: +}; + +envelope::envelope(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned) + : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); + // @@protoc_insertion_point(arena_constructor:netcon.envelope) +} +envelope::envelope(const envelope& from) + : ::PROTOBUF_NAMESPACE_ID::MessageLite() { + envelope* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.nonce_){} + , decltype(_impl_.data_){} + , decltype(_impl_.encrypted_){} + , /*decltype(_impl_._cached_size_)*/{}}; + + _internal_metadata_.MergeFrom(from._internal_metadata_); + _impl_.nonce_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.nonce_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_nonce().empty()) { + _this->_impl_.nonce_.Set(from._internal_nonce(), + _this->GetArenaForAllocation()); + } + _impl_.data_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.data_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (!from._internal_data().empty()) { + _this->_impl_.data_.Set(from._internal_data(), + _this->GetArenaForAllocation()); + } + _this->_impl_.encrypted_ = from._impl_.encrypted_; + // @@protoc_insertion_point(copy_constructor:netcon.envelope) +} + +inline void envelope::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.nonce_){} + , decltype(_impl_.data_){} + , decltype(_impl_.encrypted_){false} + , /*decltype(_impl_._cached_size_)*/{} + }; + _impl_.nonce_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.nonce_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.data_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.data_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +} + +envelope::~envelope() { + // @@protoc_insertion_point(destructor:netcon.envelope) + if (auto *arena = _internal_metadata_.DeleteReturnArena()) { + (void)arena; + return; + } + SharedDtor(); +} + +inline void envelope::SharedDtor() { + GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); + _impl_.nonce_.Destroy(); + _impl_.data_.Destroy(); +} + +void envelope::SetCachedSize(int size) const { + _impl_._cached_size_.Set(size); +} + +void envelope::Clear() { +// @@protoc_insertion_point(message_clear_start:netcon.envelope) + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _impl_.nonce_.ClearToEmpty(); + _impl_.data_.ClearToEmpty(); + _impl_.encrypted_ = false; + _internal_metadata_.Clear(); +} + +const char* envelope::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + uint32_t tag; + ptr = ::_pbi::ReadTag(ptr, &tag); + switch (tag >> 3) { + // bool encrypted = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { + _impl_.encrypted_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bytes nonce = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { + auto str = _internal_mutable_nonce(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + // bytes data = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 26)) { + auto str = _internal_mutable_data(); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else + goto handle_unusual; + continue; + default: + goto handle_unusual; + } // switch + handle_unusual: + if ((tag == 0) || ((tag & 7) == 4)) { + CHK_(ptr); + ctx->SetLastTag(tag); + goto message_done; + } + ptr = UnknownFieldParse( + tag, + _internal_metadata_.mutable_unknown_fields(), + ptr, ctx); + CHK_(ptr != nullptr); + } // while +message_done: + return ptr; +failure: + ptr = nullptr; + goto message_done; +#undef CHK_ +} + +uint8_t* envelope::_InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:netcon.envelope) + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + // bool encrypted = 1; + if (this->_internal_encrypted() != 0) { + target = stream->EnsureSpace(target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(1, this->_internal_encrypted(), target); + } + + // bytes nonce = 2; + if (!this->_internal_nonce().empty()) { + target = stream->WriteBytesMaybeAliased( + 2, this->_internal_nonce(), target); + } + + // bytes data = 3; + if (!this->_internal_data().empty()) { + target = stream->WriteBytesMaybeAliased( + 3, this->_internal_data(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), + static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); + } + // @@protoc_insertion_point(serialize_to_array_end:netcon.envelope) + return target; +} + +size_t envelope::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:netcon.envelope) + size_t total_size = 0; + + uint32_t cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // bytes nonce = 2; + if (!this->_internal_nonce().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_nonce()); + } + + // bytes data = 3; + if (!this->_internal_data().empty()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_data()); + } + + // bool encrypted = 1; + if (this->_internal_encrypted() != 0) { + total_size += 1 + 1; + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); + } + int cached_size = ::_pbi::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void envelope::CheckTypeAndMergeFrom( + const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { + MergeFrom(*::_pbi::DownCast( + &from)); +} + +void envelope::MergeFrom(const envelope& from) { + envelope* const _this = this; + // @@protoc_insertion_point(class_specific_merge_from_start:netcon.envelope) + GOOGLE_DCHECK_NE(&from, _this); + uint32_t cached_has_bits = 0; + (void) cached_has_bits; + + if (!from._internal_nonce().empty()) { + _this->_internal_set_nonce(from._internal_nonce()); + } + if (!from._internal_data().empty()) { + _this->_internal_set_data(from._internal_data()); + } + if (from._internal_encrypted() != 0) { + _this->_internal_set_encrypted(from._internal_encrypted()); + } + _this->_internal_metadata_.MergeFrom(from._internal_metadata_); +} + +void envelope::CopyFrom(const envelope& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:netcon.envelope) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool envelope::IsInitialized() const { + return true; +} + +void envelope::InternalSwap(envelope* other) { + using std::swap; + auto* lhs_arena = GetArenaForAllocation(); + auto* rhs_arena = other->GetArenaForAllocation(); + _internal_metadata_.InternalSwap(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.nonce_, lhs_arena, + &other->_impl_.nonce_, rhs_arena + ); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( + &_impl_.data_, lhs_arena, + &other->_impl_.data_, rhs_arena + ); + swap(_impl_.encrypted_, other->_impl_.encrypted_); +} + +std::string envelope::GetTypeName() const { + return "netcon.envelope"; +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace netcon +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::netcon::request* +Arena::CreateMaybeMessage< ::netcon::request >(Arena* arena) { + return Arena::CreateMessageInternal< ::netcon::request >(arena); +} +template<> PROTOBUF_NOINLINE ::netcon::response* +Arena::CreateMaybeMessage< ::netcon::response >(Arena* arena) { + return Arena::CreateMessageInternal< ::netcon::response >(arena); +} +template<> PROTOBUF_NOINLINE ::netcon::envelope* +Arena::CreateMaybeMessage< ::netcon::envelope >(Arena* arena) { + return Arena::CreateMessageInternal< ::netcon::envelope >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include diff --git a/r5dev/protoc/netcon.pb.h b/r5dev/protoc/netcon.pb.h new file mode 100644 index 00000000..cbddcc16 --- /dev/null +++ b/r5dev/protoc/netcon.pb.h @@ -0,0 +1,1279 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: netcon.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_netcon_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_netcon_2eproto + +#include +#include + +#include +#if PROTOBUF_VERSION < 3021000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +#include +#define PROTOBUF_INTERNAL_EXPORT_netcon_2eproto +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct TableStruct_netcon_2eproto { + static const uint32_t offsets[]; +}; +namespace netcon { +class envelope; +struct envelopeDefaultTypeInternal; +extern envelopeDefaultTypeInternal _envelope_default_instance_; +class request; +struct requestDefaultTypeInternal; +extern requestDefaultTypeInternal _request_default_instance_; +class response; +struct responseDefaultTypeInternal; +extern responseDefaultTypeInternal _response_default_instance_; +} // namespace netcon +PROTOBUF_NAMESPACE_OPEN +template<> ::netcon::envelope* Arena::CreateMaybeMessage<::netcon::envelope>(Arena*); +template<> ::netcon::request* Arena::CreateMaybeMessage<::netcon::request>(Arena*); +template<> ::netcon::response* Arena::CreateMaybeMessage<::netcon::response>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +namespace netcon { + +enum request_e : int { + SERVERDATA_REQUEST_EXECCOMMAND = 0, + SERVERDATA_REQUEST_AUTH = 1, + SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2, + request_e_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits::min(), + request_e_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits::max() +}; +bool request_e_IsValid(int value); +constexpr request_e request_e_MIN = SERVERDATA_REQUEST_EXECCOMMAND; +constexpr request_e request_e_MAX = SERVERDATA_REQUEST_SEND_CONSOLE_LOG; +constexpr int request_e_ARRAYSIZE = request_e_MAX + 1; + +const std::string& request_e_Name(request_e value); +template +inline const std::string& request_e_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function request_e_Name."); + return request_e_Name(static_cast(enum_t_value)); +} +bool request_e_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, request_e* value); +enum response_e : int { + SERVERDATA_RESPONSE_AUTH = 0, + SERVERDATA_RESPONSE_CONSOLE_LOG = 1, + response_e_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits::min(), + response_e_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits::max() +}; +bool response_e_IsValid(int value); +constexpr response_e response_e_MIN = SERVERDATA_RESPONSE_AUTH; +constexpr response_e response_e_MAX = SERVERDATA_RESPONSE_CONSOLE_LOG; +constexpr int response_e_ARRAYSIZE = response_e_MAX + 1; + +const std::string& response_e_Name(response_e value); +template +inline const std::string& response_e_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function response_e_Name."); + return response_e_Name(static_cast(enum_t_value)); +} +bool response_e_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, response_e* value); +// =================================================================== + +class request final : + public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:netcon.request) */ { + public: + inline request() : request(nullptr) {} + ~request() override; + explicit PROTOBUF_CONSTEXPR request(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + request(const request& from); + request(request&& from) noexcept + : request() { + *this = ::std::move(from); + } + + inline request& operator=(const request& from) { + CopyFrom(from); + return *this; + } + inline request& operator=(request&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const request& default_instance() { + return *internal_default_instance(); + } + static inline const request* internal_default_instance() { + return reinterpret_cast( + &_request_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(request& a, request& b) { + a.Swap(&b); + } + inline void Swap(request* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(request* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + request* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; + void CopyFrom(const request& from); + void MergeFrom(const request& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(request* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "netcon.request"; + } + protected: + explicit request(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + std::string GetTypeName() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kRequestMsgFieldNumber = 4, + kRequestValFieldNumber = 5, + kMessageIdFieldNumber = 1, + kMessageTypeFieldNumber = 2, + kRequestTypeFieldNumber = 3, + }; + // optional string requestMsg = 4; + bool has_requestmsg() const; + private: + bool _internal_has_requestmsg() const; + public: + void clear_requestmsg(); + const std::string& requestmsg() const; + template + void set_requestmsg(ArgT0&& arg0, ArgT... args); + std::string* mutable_requestmsg(); + PROTOBUF_NODISCARD std::string* release_requestmsg(); + void set_allocated_requestmsg(std::string* requestmsg); + private: + const std::string& _internal_requestmsg() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_requestmsg(const std::string& value); + std::string* _internal_mutable_requestmsg(); + public: + + // optional string requestVal = 5; + bool has_requestval() const; + private: + bool _internal_has_requestval() const; + public: + void clear_requestval(); + const std::string& requestval() const; + template + void set_requestval(ArgT0&& arg0, ArgT... args); + std::string* mutable_requestval(); + PROTOBUF_NODISCARD std::string* release_requestval(); + void set_allocated_requestval(std::string* requestval); + private: + const std::string& _internal_requestval() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_requestval(const std::string& value); + std::string* _internal_mutable_requestval(); + public: + + // optional int32 messageId = 1; + bool has_messageid() const; + private: + bool _internal_has_messageid() const; + public: + void clear_messageid(); + int32_t messageid() const; + void set_messageid(int32_t value); + private: + int32_t _internal_messageid() const; + void _internal_set_messageid(int32_t value); + public: + + // optional int32 messageType = 2; + bool has_messagetype() const; + private: + bool _internal_has_messagetype() const; + public: + void clear_messagetype(); + int32_t messagetype() const; + void set_messagetype(int32_t value); + private: + int32_t _internal_messagetype() const; + void _internal_set_messagetype(int32_t value); + public: + + // optional .netcon.request_e requestType = 3; + bool has_requesttype() const; + private: + bool _internal_has_requesttype() const; + public: + void clear_requesttype(); + ::netcon::request_e requesttype() const; + void set_requesttype(::netcon::request_e value); + private: + ::netcon::request_e _internal_requesttype() const; + void _internal_set_requesttype(::netcon::request_e value); + public: + + // @@protoc_insertion_point(class_scope:netcon.request) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr requestmsg_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr requestval_; + int32_t messageid_; + int32_t messagetype_; + int requesttype_; + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_netcon_2eproto; +}; +// ------------------------------------------------------------------- + +class response final : + public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:netcon.response) */ { + public: + inline response() : response(nullptr) {} + ~response() override; + explicit PROTOBUF_CONSTEXPR response(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + response(const response& from); + response(response&& from) noexcept + : response() { + *this = ::std::move(from); + } + + inline response& operator=(const response& from) { + CopyFrom(from); + return *this; + } + inline response& operator=(response&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const response& default_instance() { + return *internal_default_instance(); + } + static inline const response* internal_default_instance() { + return reinterpret_cast( + &_response_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(response& a, response& b) { + a.Swap(&b); + } + inline void Swap(response* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(response* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + response* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; + void CopyFrom(const response& from); + void MergeFrom(const response& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(response* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "netcon.response"; + } + protected: + explicit response(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + std::string GetTypeName() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kResponseMsgFieldNumber = 4, + kResponseValFieldNumber = 5, + kMessageIdFieldNumber = 1, + kMessageTypeFieldNumber = 2, + kResponseTypeFieldNumber = 3, + }; + // optional string responseMsg = 4; + bool has_responsemsg() const; + private: + bool _internal_has_responsemsg() const; + public: + void clear_responsemsg(); + const std::string& responsemsg() const; + template + void set_responsemsg(ArgT0&& arg0, ArgT... args); + std::string* mutable_responsemsg(); + PROTOBUF_NODISCARD std::string* release_responsemsg(); + void set_allocated_responsemsg(std::string* responsemsg); + private: + const std::string& _internal_responsemsg() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_responsemsg(const std::string& value); + std::string* _internal_mutable_responsemsg(); + public: + + // optional string responseVal = 5; + bool has_responseval() const; + private: + bool _internal_has_responseval() const; + public: + void clear_responseval(); + const std::string& responseval() const; + template + void set_responseval(ArgT0&& arg0, ArgT... args); + std::string* mutable_responseval(); + PROTOBUF_NODISCARD std::string* release_responseval(); + void set_allocated_responseval(std::string* responseval); + private: + const std::string& _internal_responseval() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_responseval(const std::string& value); + std::string* _internal_mutable_responseval(); + public: + + // optional int32 messageId = 1; + bool has_messageid() const; + private: + bool _internal_has_messageid() const; + public: + void clear_messageid(); + int32_t messageid() const; + void set_messageid(int32_t value); + private: + int32_t _internal_messageid() const; + void _internal_set_messageid(int32_t value); + public: + + // optional int32 messageType = 2; + bool has_messagetype() const; + private: + bool _internal_has_messagetype() const; + public: + void clear_messagetype(); + int32_t messagetype() const; + void set_messagetype(int32_t value); + private: + int32_t _internal_messagetype() const; + void _internal_set_messagetype(int32_t value); + public: + + // optional .netcon.response_e responseType = 3; + bool has_responsetype() const; + private: + bool _internal_has_responsetype() const; + public: + void clear_responsetype(); + ::netcon::response_e responsetype() const; + void set_responsetype(::netcon::response_e value); + private: + ::netcon::response_e _internal_responsetype() const; + void _internal_set_responsetype(::netcon::response_e value); + public: + + // @@protoc_insertion_point(class_scope:netcon.response) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr responsemsg_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr responseval_; + int32_t messageid_; + int32_t messagetype_; + int responsetype_; + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_netcon_2eproto; +}; +// ------------------------------------------------------------------- + +class envelope final : + public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:netcon.envelope) */ { + public: + inline envelope() : envelope(nullptr) {} + ~envelope() override; + explicit PROTOBUF_CONSTEXPR envelope(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + + envelope(const envelope& from); + envelope(envelope&& from) noexcept + : envelope() { + *this = ::std::move(from); + } + + inline envelope& operator=(const envelope& from) { + CopyFrom(from); + return *this; + } + inline envelope& operator=(envelope&& from) noexcept { + if (this == &from) return *this; + if (GetOwningArena() == from.GetOwningArena() + #ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetOwningArena() != nullptr + #endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const envelope& default_instance() { + return *internal_default_instance(); + } + static inline const envelope* internal_default_instance() { + return reinterpret_cast( + &_envelope_default_instance_); + } + static constexpr int kIndexInFileMessages = + 2; + + friend void swap(envelope& a, envelope& b) { + a.Swap(&b); + } + inline void Swap(envelope* other) { + if (other == this) return; + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() != nullptr && + GetOwningArena() == other->GetOwningArena()) { + #else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetOwningArena() == other->GetOwningArena()) { + #endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(envelope* other) { + if (other == this) return; + GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + envelope* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { + return CreateMaybeMessage(arena); + } + void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; + void CopyFrom(const envelope& from); + void MergeFrom(const envelope& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + uint8_t* _InternalSerialize( + uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } + + private: + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(envelope* other); + + private: + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "netcon.envelope"; + } + protected: + explicit envelope(::PROTOBUF_NAMESPACE_ID::Arena* arena, + bool is_message_owned = false); + public: + + std::string GetTypeName() const final; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kNonceFieldNumber = 2, + kDataFieldNumber = 3, + kEncryptedFieldNumber = 1, + }; + // bytes nonce = 2; + void clear_nonce(); + const std::string& nonce() const; + template + void set_nonce(ArgT0&& arg0, ArgT... args); + std::string* mutable_nonce(); + PROTOBUF_NODISCARD std::string* release_nonce(); + void set_allocated_nonce(std::string* nonce); + private: + const std::string& _internal_nonce() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_nonce(const std::string& value); + std::string* _internal_mutable_nonce(); + public: + + // bytes data = 3; + void clear_data(); + const std::string& data() const; + template + void set_data(ArgT0&& arg0, ArgT... args); + std::string* mutable_data(); + PROTOBUF_NODISCARD std::string* release_data(); + void set_allocated_data(std::string* data); + private: + const std::string& _internal_data() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_data(const std::string& value); + std::string* _internal_mutable_data(); + public: + + // bool encrypted = 1; + void clear_encrypted(); + bool encrypted() const; + void set_encrypted(bool value); + private: + bool _internal_encrypted() const; + void _internal_set_encrypted(bool value); + public: + + // @@protoc_insertion_point(class_scope:netcon.envelope) + private: + class _Internal; + + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr nonce_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr data_; + bool encrypted_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; + friend struct ::TableStruct_netcon_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// request + +// optional int32 messageId = 1; +inline bool request::_internal_has_messageid() const { + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool request::has_messageid() const { + return _internal_has_messageid(); +} +inline void request::clear_messageid() { + _impl_.messageid_ = 0; + _impl_._has_bits_[0] &= ~0x00000004u; +} +inline int32_t request::_internal_messageid() const { + return _impl_.messageid_; +} +inline int32_t request::messageid() const { + // @@protoc_insertion_point(field_get:netcon.request.messageId) + return _internal_messageid(); +} +inline void request::_internal_set_messageid(int32_t value) { + _impl_._has_bits_[0] |= 0x00000004u; + _impl_.messageid_ = value; +} +inline void request::set_messageid(int32_t value) { + _internal_set_messageid(value); + // @@protoc_insertion_point(field_set:netcon.request.messageId) +} + +// optional int32 messageType = 2; +inline bool request::_internal_has_messagetype() const { + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool request::has_messagetype() const { + return _internal_has_messagetype(); +} +inline void request::clear_messagetype() { + _impl_.messagetype_ = 0; + _impl_._has_bits_[0] &= ~0x00000008u; +} +inline int32_t request::_internal_messagetype() const { + return _impl_.messagetype_; +} +inline int32_t request::messagetype() const { + // @@protoc_insertion_point(field_get:netcon.request.messageType) + return _internal_messagetype(); +} +inline void request::_internal_set_messagetype(int32_t value) { + _impl_._has_bits_[0] |= 0x00000008u; + _impl_.messagetype_ = value; +} +inline void request::set_messagetype(int32_t value) { + _internal_set_messagetype(value); + // @@protoc_insertion_point(field_set:netcon.request.messageType) +} + +// optional .netcon.request_e requestType = 3; +inline bool request::_internal_has_requesttype() const { + bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool request::has_requesttype() const { + return _internal_has_requesttype(); +} +inline void request::clear_requesttype() { + _impl_.requesttype_ = 0; + _impl_._has_bits_[0] &= ~0x00000010u; +} +inline ::netcon::request_e request::_internal_requesttype() const { + return static_cast< ::netcon::request_e >(_impl_.requesttype_); +} +inline ::netcon::request_e request::requesttype() const { + // @@protoc_insertion_point(field_get:netcon.request.requestType) + return _internal_requesttype(); +} +inline void request::_internal_set_requesttype(::netcon::request_e value) { + _impl_._has_bits_[0] |= 0x00000010u; + _impl_.requesttype_ = value; +} +inline void request::set_requesttype(::netcon::request_e value) { + _internal_set_requesttype(value); + // @@protoc_insertion_point(field_set:netcon.request.requestType) +} + +// optional string requestMsg = 4; +inline bool request::_internal_has_requestmsg() const { + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool request::has_requestmsg() const { + return _internal_has_requestmsg(); +} +inline void request::clear_requestmsg() { + _impl_.requestmsg_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; +} +inline const std::string& request::requestmsg() const { + // @@protoc_insertion_point(field_get:netcon.request.requestMsg) + return _internal_requestmsg(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void request::set_requestmsg(ArgT0&& arg0, ArgT... args) { + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.requestmsg_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.request.requestMsg) +} +inline std::string* request::mutable_requestmsg() { + std::string* _s = _internal_mutable_requestmsg(); + // @@protoc_insertion_point(field_mutable:netcon.request.requestMsg) + return _s; +} +inline const std::string& request::_internal_requestmsg() const { + return _impl_.requestmsg_.Get(); +} +inline void request::_internal_set_requestmsg(const std::string& value) { + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.requestmsg_.Set(value, GetArenaForAllocation()); +} +inline std::string* request::_internal_mutable_requestmsg() { + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.requestmsg_.Mutable(GetArenaForAllocation()); +} +inline std::string* request::release_requestmsg() { + // @@protoc_insertion_point(field_release:netcon.request.requestMsg) + if (!_internal_has_requestmsg()) { + return nullptr; + } + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.requestmsg_.Release(); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.requestmsg_.IsDefault()) { + _impl_.requestmsg_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void request::set_allocated_requestmsg(std::string* requestmsg) { + if (requestmsg != nullptr) { + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + _impl_.requestmsg_.SetAllocated(requestmsg, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.requestmsg_.IsDefault()) { + _impl_.requestmsg_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.request.requestMsg) +} + +// optional string requestVal = 5; +inline bool request::_internal_has_requestval() const { + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool request::has_requestval() const { + return _internal_has_requestval(); +} +inline void request::clear_requestval() { + _impl_.requestval_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000002u; +} +inline const std::string& request::requestval() const { + // @@protoc_insertion_point(field_get:netcon.request.requestVal) + return _internal_requestval(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void request::set_requestval(ArgT0&& arg0, ArgT... args) { + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.requestval_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.request.requestVal) +} +inline std::string* request::mutable_requestval() { + std::string* _s = _internal_mutable_requestval(); + // @@protoc_insertion_point(field_mutable:netcon.request.requestVal) + return _s; +} +inline const std::string& request::_internal_requestval() const { + return _impl_.requestval_.Get(); +} +inline void request::_internal_set_requestval(const std::string& value) { + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.requestval_.Set(value, GetArenaForAllocation()); +} +inline std::string* request::_internal_mutable_requestval() { + _impl_._has_bits_[0] |= 0x00000002u; + return _impl_.requestval_.Mutable(GetArenaForAllocation()); +} +inline std::string* request::release_requestval() { + // @@protoc_insertion_point(field_release:netcon.request.requestVal) + if (!_internal_has_requestval()) { + return nullptr; + } + _impl_._has_bits_[0] &= ~0x00000002u; + auto* p = _impl_.requestval_.Release(); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.requestval_.IsDefault()) { + _impl_.requestval_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void request::set_allocated_requestval(std::string* requestval) { + if (requestval != nullptr) { + _impl_._has_bits_[0] |= 0x00000002u; + } else { + _impl_._has_bits_[0] &= ~0x00000002u; + } + _impl_.requestval_.SetAllocated(requestval, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.requestval_.IsDefault()) { + _impl_.requestval_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.request.requestVal) +} + +// ------------------------------------------------------------------- + +// response + +// optional int32 messageId = 1; +inline bool response::_internal_has_messageid() const { + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline bool response::has_messageid() const { + return _internal_has_messageid(); +} +inline void response::clear_messageid() { + _impl_.messageid_ = 0; + _impl_._has_bits_[0] &= ~0x00000004u; +} +inline int32_t response::_internal_messageid() const { + return _impl_.messageid_; +} +inline int32_t response::messageid() const { + // @@protoc_insertion_point(field_get:netcon.response.messageId) + return _internal_messageid(); +} +inline void response::_internal_set_messageid(int32_t value) { + _impl_._has_bits_[0] |= 0x00000004u; + _impl_.messageid_ = value; +} +inline void response::set_messageid(int32_t value) { + _internal_set_messageid(value); + // @@protoc_insertion_point(field_set:netcon.response.messageId) +} + +// optional int32 messageType = 2; +inline bool response::_internal_has_messagetype() const { + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline bool response::has_messagetype() const { + return _internal_has_messagetype(); +} +inline void response::clear_messagetype() { + _impl_.messagetype_ = 0; + _impl_._has_bits_[0] &= ~0x00000008u; +} +inline int32_t response::_internal_messagetype() const { + return _impl_.messagetype_; +} +inline int32_t response::messagetype() const { + // @@protoc_insertion_point(field_get:netcon.response.messageType) + return _internal_messagetype(); +} +inline void response::_internal_set_messagetype(int32_t value) { + _impl_._has_bits_[0] |= 0x00000008u; + _impl_.messagetype_ = value; +} +inline void response::set_messagetype(int32_t value) { + _internal_set_messagetype(value); + // @@protoc_insertion_point(field_set:netcon.response.messageType) +} + +// optional .netcon.response_e responseType = 3; +inline bool response::_internal_has_responsetype() const { + bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; + return value; +} +inline bool response::has_responsetype() const { + return _internal_has_responsetype(); +} +inline void response::clear_responsetype() { + _impl_.responsetype_ = 0; + _impl_._has_bits_[0] &= ~0x00000010u; +} +inline ::netcon::response_e response::_internal_responsetype() const { + return static_cast< ::netcon::response_e >(_impl_.responsetype_); +} +inline ::netcon::response_e response::responsetype() const { + // @@protoc_insertion_point(field_get:netcon.response.responseType) + return _internal_responsetype(); +} +inline void response::_internal_set_responsetype(::netcon::response_e value) { + _impl_._has_bits_[0] |= 0x00000010u; + _impl_.responsetype_ = value; +} +inline void response::set_responsetype(::netcon::response_e value) { + _internal_set_responsetype(value); + // @@protoc_insertion_point(field_set:netcon.response.responseType) +} + +// optional string responseMsg = 4; +inline bool response::_internal_has_responsemsg() const { + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; + return value; +} +inline bool response::has_responsemsg() const { + return _internal_has_responsemsg(); +} +inline void response::clear_responsemsg() { + _impl_.responsemsg_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; +} +inline const std::string& response::responsemsg() const { + // @@protoc_insertion_point(field_get:netcon.response.responseMsg) + return _internal_responsemsg(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void response::set_responsemsg(ArgT0&& arg0, ArgT... args) { + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.responsemsg_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.response.responseMsg) +} +inline std::string* response::mutable_responsemsg() { + std::string* _s = _internal_mutable_responsemsg(); + // @@protoc_insertion_point(field_mutable:netcon.response.responseMsg) + return _s; +} +inline const std::string& response::_internal_responsemsg() const { + return _impl_.responsemsg_.Get(); +} +inline void response::_internal_set_responsemsg(const std::string& value) { + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.responsemsg_.Set(value, GetArenaForAllocation()); +} +inline std::string* response::_internal_mutable_responsemsg() { + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.responsemsg_.Mutable(GetArenaForAllocation()); +} +inline std::string* response::release_responsemsg() { + // @@protoc_insertion_point(field_release:netcon.response.responseMsg) + if (!_internal_has_responsemsg()) { + return nullptr; + } + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.responsemsg_.Release(); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.responsemsg_.IsDefault()) { + _impl_.responsemsg_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void response::set_allocated_responsemsg(std::string* responsemsg) { + if (responsemsg != nullptr) { + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + _impl_.responsemsg_.SetAllocated(responsemsg, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.responsemsg_.IsDefault()) { + _impl_.responsemsg_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.response.responseMsg) +} + +// optional string responseVal = 5; +inline bool response::_internal_has_responseval() const { + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool response::has_responseval() const { + return _internal_has_responseval(); +} +inline void response::clear_responseval() { + _impl_.responseval_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000002u; +} +inline const std::string& response::responseval() const { + // @@protoc_insertion_point(field_get:netcon.response.responseVal) + return _internal_responseval(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void response::set_responseval(ArgT0&& arg0, ArgT... args) { + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.responseval_.Set(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.response.responseVal) +} +inline std::string* response::mutable_responseval() { + std::string* _s = _internal_mutable_responseval(); + // @@protoc_insertion_point(field_mutable:netcon.response.responseVal) + return _s; +} +inline const std::string& response::_internal_responseval() const { + return _impl_.responseval_.Get(); +} +inline void response::_internal_set_responseval(const std::string& value) { + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.responseval_.Set(value, GetArenaForAllocation()); +} +inline std::string* response::_internal_mutable_responseval() { + _impl_._has_bits_[0] |= 0x00000002u; + return _impl_.responseval_.Mutable(GetArenaForAllocation()); +} +inline std::string* response::release_responseval() { + // @@protoc_insertion_point(field_release:netcon.response.responseVal) + if (!_internal_has_responseval()) { + return nullptr; + } + _impl_._has_bits_[0] &= ~0x00000002u; + auto* p = _impl_.responseval_.Release(); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.responseval_.IsDefault()) { + _impl_.responseval_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + return p; +} +inline void response::set_allocated_responseval(std::string* responseval) { + if (responseval != nullptr) { + _impl_._has_bits_[0] |= 0x00000002u; + } else { + _impl_._has_bits_[0] &= ~0x00000002u; + } + _impl_.responseval_.SetAllocated(responseval, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.responseval_.IsDefault()) { + _impl_.responseval_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.response.responseVal) +} + +// ------------------------------------------------------------------- + +// envelope + +// bool encrypted = 1; +inline void envelope::clear_encrypted() { + _impl_.encrypted_ = false; +} +inline bool envelope::_internal_encrypted() const { + return _impl_.encrypted_; +} +inline bool envelope::encrypted() const { + // @@protoc_insertion_point(field_get:netcon.envelope.encrypted) + return _internal_encrypted(); +} +inline void envelope::_internal_set_encrypted(bool value) { + + _impl_.encrypted_ = value; +} +inline void envelope::set_encrypted(bool value) { + _internal_set_encrypted(value); + // @@protoc_insertion_point(field_set:netcon.envelope.encrypted) +} + +// bytes nonce = 2; +inline void envelope::clear_nonce() { + _impl_.nonce_.ClearToEmpty(); +} +inline const std::string& envelope::nonce() const { + // @@protoc_insertion_point(field_get:netcon.envelope.nonce) + return _internal_nonce(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void envelope::set_nonce(ArgT0&& arg0, ArgT... args) { + + _impl_.nonce_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.envelope.nonce) +} +inline std::string* envelope::mutable_nonce() { + std::string* _s = _internal_mutable_nonce(); + // @@protoc_insertion_point(field_mutable:netcon.envelope.nonce) + return _s; +} +inline const std::string& envelope::_internal_nonce() const { + return _impl_.nonce_.Get(); +} +inline void envelope::_internal_set_nonce(const std::string& value) { + + _impl_.nonce_.Set(value, GetArenaForAllocation()); +} +inline std::string* envelope::_internal_mutable_nonce() { + + return _impl_.nonce_.Mutable(GetArenaForAllocation()); +} +inline std::string* envelope::release_nonce() { + // @@protoc_insertion_point(field_release:netcon.envelope.nonce) + return _impl_.nonce_.Release(); +} +inline void envelope::set_allocated_nonce(std::string* nonce) { + if (nonce != nullptr) { + + } else { + + } + _impl_.nonce_.SetAllocated(nonce, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.nonce_.IsDefault()) { + _impl_.nonce_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.envelope.nonce) +} + +// bytes data = 3; +inline void envelope::clear_data() { + _impl_.data_.ClearToEmpty(); +} +inline const std::string& envelope::data() const { + // @@protoc_insertion_point(field_get:netcon.envelope.data) + return _internal_data(); +} +template +inline PROTOBUF_ALWAYS_INLINE +void envelope::set_data(ArgT0&& arg0, ArgT... args) { + + _impl_.data_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); + // @@protoc_insertion_point(field_set:netcon.envelope.data) +} +inline std::string* envelope::mutable_data() { + std::string* _s = _internal_mutable_data(); + // @@protoc_insertion_point(field_mutable:netcon.envelope.data) + return _s; +} +inline const std::string& envelope::_internal_data() const { + return _impl_.data_.Get(); +} +inline void envelope::_internal_set_data(const std::string& value) { + + _impl_.data_.Set(value, GetArenaForAllocation()); +} +inline std::string* envelope::_internal_mutable_data() { + + return _impl_.data_.Mutable(GetArenaForAllocation()); +} +inline std::string* envelope::release_data() { + // @@protoc_insertion_point(field_release:netcon.envelope.data) + return _impl_.data_.Release(); +} +inline void envelope::set_allocated_data(std::string* data) { + if (data != nullptr) { + + } else { + + } + _impl_.data_.SetAllocated(data, GetArenaForAllocation()); +#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + if (_impl_.data_.IsDefault()) { + _impl_.data_.Set("", GetArenaForAllocation()); + } +#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + // @@protoc_insertion_point(field_set_allocated:netcon.envelope.data) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace netcon + +PROTOBUF_NAMESPACE_OPEN + +template <> struct is_proto_enum< ::netcon::request_e> : ::std::true_type {}; +template <> struct is_proto_enum< ::netcon::response_e> : ::std::true_type {}; + +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) + +#include +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_netcon_2eproto diff --git a/r5dev/protoc/sv_rcon.pb.cc b/r5dev/protoc/sv_rcon.pb.cc deleted file mode 100644 index 4ef8824c..00000000 --- a/r5dev/protoc/sv_rcon.pb.cc +++ /dev/null @@ -1,485 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: sv_rcon.proto - -#include "sv_rcon.pb.h" - -#include - -#include -#include -#include -#include -// @@protoc_insertion_point(includes) -#include - -PROTOBUF_PRAGMA_INIT_SEG - -namespace _pb = ::PROTOBUF_NAMESPACE_ID; -namespace _pbi = _pb::internal; - -namespace sv_rcon { -PROTOBUF_CONSTEXPR response::response( - ::_pbi::ConstantInitialized): _impl_{ - /*decltype(_impl_._has_bits_)*/{} - , /*decltype(_impl_._cached_size_)*/{} - , /*decltype(_impl_.responsemsg_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} - , /*decltype(_impl_.responseval_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} - , /*decltype(_impl_.messageid_)*/0 - , /*decltype(_impl_.messagetype_)*/0 - , /*decltype(_impl_.responsetype_)*/0} {} -struct responseDefaultTypeInternal { - PROTOBUF_CONSTEXPR responseDefaultTypeInternal() - : _instance(::_pbi::ConstantInitialized{}) {} - ~responseDefaultTypeInternal() {} - union { - response _instance; - }; -}; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 responseDefaultTypeInternal _response_default_instance_; -} // namespace sv_rcon -namespace sv_rcon { -bool response_t_IsValid(int value) { - switch (value) { - case 0: - case 1: - return true; - default: - return false; - } -} - -static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed response_t_strings[2] = {}; - -static const char response_t_names[] = - "SERVERDATA_RESPONSE_AUTH" - "SERVERDATA_RESPONSE_CONSOLE_LOG"; - -static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry response_t_entries[] = { - { {response_t_names + 0, 24}, 0 }, - { {response_t_names + 24, 31}, 1 }, -}; - -static const int response_t_entries_by_number[] = { - 0, // 0 -> SERVERDATA_RESPONSE_AUTH - 1, // 1 -> SERVERDATA_RESPONSE_CONSOLE_LOG -}; - -const std::string& response_t_Name( - response_t value) { - static const bool dummy = - ::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings( - response_t_entries, - response_t_entries_by_number, - 2, response_t_strings); - (void) dummy; - int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName( - response_t_entries, - response_t_entries_by_number, - 2, value); - return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() : - response_t_strings[idx].get(); -} -bool response_t_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, response_t* value) { - int int_value; - bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue( - response_t_entries, 2, name, &int_value); - if (success) { - *value = static_cast(int_value); - } - return success; -} - -// =================================================================== - -class response::_Internal { - public: - using HasBits = decltype(std::declval()._impl_._has_bits_); - static void set_has_messageid(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_messagetype(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_responsetype(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_responsemsg(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_responseval(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } -}; - -response::response(::PROTOBUF_NAMESPACE_ID::Arena* arena, - bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) { - SharedCtor(arena, is_message_owned); - // @@protoc_insertion_point(arena_constructor:sv_rcon.response) -} -response::response(const response& from) - : ::PROTOBUF_NAMESPACE_ID::MessageLite() { - response* const _this = this; (void)_this; - new (&_impl_) Impl_{ - decltype(_impl_._has_bits_){from._impl_._has_bits_} - , /*decltype(_impl_._cached_size_)*/{} - , decltype(_impl_.responsemsg_){} - , decltype(_impl_.responseval_){} - , decltype(_impl_.messageid_){} - , decltype(_impl_.messagetype_){} - , decltype(_impl_.responsetype_){}}; - - _internal_metadata_.MergeFrom(from._internal_metadata_); - _impl_.responsemsg_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.responsemsg_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (from._internal_has_responsemsg()) { - _this->_impl_.responsemsg_.Set(from._internal_responsemsg(), - _this->GetArenaForAllocation()); - } - _impl_.responseval_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.responseval_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (from._internal_has_responseval()) { - _this->_impl_.responseval_.Set(from._internal_responseval(), - _this->GetArenaForAllocation()); - } - ::memcpy(&_impl_.messageid_, &from._impl_.messageid_, - static_cast(reinterpret_cast(&_impl_.responsetype_) - - reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.responsetype_)); - // @@protoc_insertion_point(copy_constructor:sv_rcon.response) -} - -inline void response::SharedCtor( - ::_pb::Arena* arena, bool is_message_owned) { - (void)arena; - (void)is_message_owned; - new (&_impl_) Impl_{ - decltype(_impl_._has_bits_){} - , /*decltype(_impl_._cached_size_)*/{} - , decltype(_impl_.responsemsg_){} - , decltype(_impl_.responseval_){} - , decltype(_impl_.messageid_){0} - , decltype(_impl_.messagetype_){0} - , decltype(_impl_.responsetype_){0} - }; - _impl_.responsemsg_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.responsemsg_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.responseval_.InitDefault(); - #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - _impl_.responseval_.Set("", GetArenaForAllocation()); - #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -} - -response::~response() { - // @@protoc_insertion_point(destructor:sv_rcon.response) - if (auto *arena = _internal_metadata_.DeleteReturnArena()) { - (void)arena; - return; - } - SharedDtor(); -} - -inline void response::SharedDtor() { - GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - _impl_.responsemsg_.Destroy(); - _impl_.responseval_.Destroy(); -} - -void response::SetCachedSize(int size) const { - _impl_._cached_size_.Set(size); -} - -void response::Clear() { -// @@protoc_insertion_point(message_clear_start:sv_rcon.response) - uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { - if (cached_has_bits & 0x00000001u) { - _impl_.responsemsg_.ClearNonDefaultToEmpty(); - } - if (cached_has_bits & 0x00000002u) { - _impl_.responseval_.ClearNonDefaultToEmpty(); - } - } - if (cached_has_bits & 0x0000001cu) { - ::memset(&_impl_.messageid_, 0, static_cast( - reinterpret_cast(&_impl_.responsetype_) - - reinterpret_cast(&_impl_.messageid_)) + sizeof(_impl_.responsetype_)); - } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -const char* response::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { -#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - _Internal::HasBits has_bits{}; - while (!ctx->Done(&ptr)) { - uint32_t tag; - ptr = ::_pbi::ReadTag(ptr, &tag); - switch (tag >> 3) { - // optional int32 messageID = 1; - case 1: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { - _Internal::set_has_messageid(&has_bits); - _impl_.messageid_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } else - goto handle_unusual; - continue; - // optional int32 messageType = 2; - case 2: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { - _Internal::set_has_messagetype(&has_bits); - _impl_.messagetype_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); - CHK_(ptr); - } else - goto handle_unusual; - continue; - // optional .sv_rcon.response_t responseType = 3; - case 3: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { - uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); - CHK_(ptr); - _internal_set_responsetype(static_cast<::sv_rcon::response_t>(val)); - } else - goto handle_unusual; - continue; - // optional string responseMsg = 4; - case 4: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { - auto str = _internal_mutable_responsemsg(); - ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); - CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, nullptr)); - } else - goto handle_unusual; - continue; - // optional string responseVal = 5; - case 5: - if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 42)) { - auto str = _internal_mutable_responseval(); - ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); - CHK_(ptr); - CHK_(::_pbi::VerifyUTF8(str, nullptr)); - } else - goto handle_unusual; - continue; - default: - goto handle_unusual; - } // switch - handle_unusual: - if ((tag == 0) || ((tag & 7) == 4)) { - CHK_(ptr); - ctx->SetLastTag(tag); - goto message_done; - } - ptr = UnknownFieldParse( - tag, - _internal_metadata_.mutable_unknown_fields(), - ptr, ctx); - CHK_(ptr != nullptr); - } // while -message_done: - _impl_._has_bits_.Or(has_bits); - return ptr; -failure: - ptr = nullptr; - goto message_done; -#undef CHK_ -} - -uint8_t* response::_InternalSerialize( - uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { - // @@protoc_insertion_point(serialize_to_array_start:sv_rcon.response) - uint32_t cached_has_bits = 0; - (void) cached_has_bits; - - // optional int32 messageID = 1; - if (_internal_has_messageid()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_messageid(), target); - } - - // optional int32 messageType = 2; - if (_internal_has_messagetype()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_messagetype(), target); - } - - // optional .sv_rcon.response_t responseType = 3; - if (_internal_has_responsetype()) { - target = stream->EnsureSpace(target); - target = ::_pbi::WireFormatLite::WriteEnumToArray( - 3, this->_internal_responsetype(), target); - } - - // optional string responseMsg = 4; - if (_internal_has_responsemsg()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_responsemsg().data(), static_cast(this->_internal_responsemsg().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "sv_rcon.response.responseMsg"); - target = stream->WriteStringMaybeAliased( - 4, this->_internal_responsemsg(), target); - } - - // optional string responseVal = 5; - if (_internal_has_responseval()) { - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( - this->_internal_responseval().data(), static_cast(this->_internal_responseval().length()), - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, - "sv_rcon.response.responseVal"); - target = stream->WriteStringMaybeAliased( - 5, this->_internal_responseval(), target); - } - - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = stream->WriteRaw(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(), - static_cast(_internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target); - } - // @@protoc_insertion_point(serialize_to_array_end:sv_rcon.response) - return target; -} - -size_t response::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:sv_rcon.response) - size_t total_size = 0; - - uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - // optional string responseMsg = 4; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->_internal_responsemsg()); - } - - // optional string responseVal = 5; - if (cached_has_bits & 0x00000002u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->_internal_responseval()); - } - - // optional int32 messageID = 1; - if (cached_has_bits & 0x00000004u) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messageid()); - } - - // optional int32 messageType = 2; - if (cached_has_bits & 0x00000008u) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_messagetype()); - } - - // optional .sv_rcon.response_t responseType = 3; - if (cached_has_bits & 0x00000010u) { - total_size += 1 + - ::_pbi::WireFormatLite::EnumSize(this->_internal_responsetype()); - } - - } - if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - total_size += _internal_metadata_.unknown_fields(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size(); - } - int cached_size = ::_pbi::ToCachedSize(total_size); - SetCachedSize(cached_size); - return total_size; -} - -void response::CheckTypeAndMergeFrom( - const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) { - MergeFrom(*::_pbi::DownCast( - &from)); -} - -void response::MergeFrom(const response& from) { - response* const _this = this; - // @@protoc_insertion_point(class_specific_merge_from_start:sv_rcon.response) - GOOGLE_DCHECK_NE(&from, _this); - uint32_t cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._impl_._has_bits_[0]; - if (cached_has_bits & 0x0000001fu) { - if (cached_has_bits & 0x00000001u) { - _this->_internal_set_responsemsg(from._internal_responsemsg()); - } - if (cached_has_bits & 0x00000002u) { - _this->_internal_set_responseval(from._internal_responseval()); - } - if (cached_has_bits & 0x00000004u) { - _this->_impl_.messageid_ = from._impl_.messageid_; - } - if (cached_has_bits & 0x00000008u) { - _this->_impl_.messagetype_ = from._impl_.messagetype_; - } - if (cached_has_bits & 0x00000010u) { - _this->_impl_.responsetype_ = from._impl_.responsetype_; - } - _this->_impl_._has_bits_[0] |= cached_has_bits; - } - _this->_internal_metadata_.MergeFrom(from._internal_metadata_); -} - -void response::CopyFrom(const response& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:sv_rcon.response) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool response::IsInitialized() const { - return true; -} - -void response::InternalSwap(response* other) { - using std::swap; - auto* lhs_arena = GetArenaForAllocation(); - auto* rhs_arena = other->GetArenaForAllocation(); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &_impl_.responsemsg_, lhs_arena, - &other->_impl_.responsemsg_, rhs_arena - ); - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &_impl_.responseval_, lhs_arena, - &other->_impl_.responseval_, rhs_arena - ); - ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(response, _impl_.responsetype_) - + sizeof(response::_impl_.responsetype_) - - PROTOBUF_FIELD_OFFSET(response, _impl_.messageid_)>( - reinterpret_cast(&_impl_.messageid_), - reinterpret_cast(&other->_impl_.messageid_)); -} - -std::string response::GetTypeName() const { - return "sv_rcon.response"; -} - - -// @@protoc_insertion_point(namespace_scope) -} // namespace sv_rcon -PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::sv_rcon::response* -Arena::CreateMaybeMessage< ::sv_rcon::response >(Arena* arena) { - return Arena::CreateMessageInternal< ::sv_rcon::response >(arena); -} -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) -#include diff --git a/r5dev/protoc/sv_rcon.pb.h b/r5dev/protoc/sv_rcon.pb.h deleted file mode 100644 index 3d179775..00000000 --- a/r5dev/protoc/sv_rcon.pb.h +++ /dev/null @@ -1,529 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: sv_rcon.proto - -#ifndef GOOGLE_PROTOBUF_INCLUDED_sv_5frcon_2eproto -#define GOOGLE_PROTOBUF_INCLUDED_sv_5frcon_2eproto - -#include -#include - -#include -#if PROTOBUF_VERSION < 3021000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: export -#include // IWYU pragma: export -#include -// @@protoc_insertion_point(includes) -#include -#define PROTOBUF_INTERNAL_EXPORT_sv_5frcon_2eproto -PROTOBUF_NAMESPACE_OPEN -namespace internal { -class AnyMetadata; -} // namespace internal -PROTOBUF_NAMESPACE_CLOSE - -// Internal implementation detail -- do not use these members. -struct TableStruct_sv_5frcon_2eproto { - static const uint32_t offsets[]; -}; -namespace sv_rcon { -class response; -struct responseDefaultTypeInternal; -extern responseDefaultTypeInternal _response_default_instance_; -} // namespace sv_rcon -PROTOBUF_NAMESPACE_OPEN -template<> ::sv_rcon::response* Arena::CreateMaybeMessage<::sv_rcon::response>(Arena*); -PROTOBUF_NAMESPACE_CLOSE -namespace sv_rcon { - -enum response_t : int { - SERVERDATA_RESPONSE_AUTH = 0, - SERVERDATA_RESPONSE_CONSOLE_LOG = 1, - response_t_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits::min(), - response_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits::max() -}; -bool response_t_IsValid(int value); -constexpr response_t response_t_MIN = SERVERDATA_RESPONSE_AUTH; -constexpr response_t response_t_MAX = SERVERDATA_RESPONSE_CONSOLE_LOG; -constexpr int response_t_ARRAYSIZE = response_t_MAX + 1; - -const std::string& response_t_Name(response_t value); -template -inline const std::string& response_t_Name(T enum_t_value) { - static_assert(::std::is_same::value || - ::std::is_integral::value, - "Incorrect type passed to function response_t_Name."); - return response_t_Name(static_cast(enum_t_value)); -} -bool response_t_Parse( - ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, response_t* value); -// =================================================================== - -class response final : - public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:sv_rcon.response) */ { - public: - inline response() : response(nullptr) {} - ~response() override; - explicit PROTOBUF_CONSTEXPR response(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); - - response(const response& from); - response(response&& from) noexcept - : response() { - *this = ::std::move(from); - } - - inline response& operator=(const response& from) { - CopyFrom(from); - return *this; - } - inline response& operator=(response&& from) noexcept { - if (this == &from) return *this; - if (GetOwningArena() == from.GetOwningArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE - && GetOwningArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE - ) { - InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - static const response& default_instance() { - return *internal_default_instance(); - } - static inline const response* internal_default_instance() { - return reinterpret_cast( - &_response_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(response& a, response& b) { - a.Swap(&b); - } - inline void Swap(response* other) { - if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetOwningArena() != nullptr && - GetOwningArena() == other->GetOwningArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP - if (GetOwningArena() == other->GetOwningArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP - InternalSwap(other); - } else { - ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); - } - } - void UnsafeArenaSwap(response* other) { - if (other == this) return; - GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena()); - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - response* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); - } - void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final; - void CopyFrom(const response& from); - void MergeFrom(const response& from); - PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; - bool IsInitialized() const final; - - size_t ByteSizeLong() const final; - const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; - uint8_t* _InternalSerialize( - uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _impl_._cached_size_.Get(); } - - private: - void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(response* other); - - private: - friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; - static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { - return "sv_rcon.response"; - } - protected: - explicit response(::PROTOBUF_NAMESPACE_ID::Arena* arena, - bool is_message_owned = false); - public: - - std::string GetTypeName() const final; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - enum : int { - kResponseMsgFieldNumber = 4, - kResponseValFieldNumber = 5, - kMessageIDFieldNumber = 1, - kMessageTypeFieldNumber = 2, - kResponseTypeFieldNumber = 3, - }; - // optional string responseMsg = 4; - bool has_responsemsg() const; - private: - bool _internal_has_responsemsg() const; - public: - void clear_responsemsg(); - const std::string& responsemsg() const; - template - void set_responsemsg(ArgT0&& arg0, ArgT... args); - std::string* mutable_responsemsg(); - PROTOBUF_NODISCARD std::string* release_responsemsg(); - void set_allocated_responsemsg(std::string* responsemsg); - private: - const std::string& _internal_responsemsg() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_responsemsg(const std::string& value); - std::string* _internal_mutable_responsemsg(); - public: - - // optional string responseVal = 5; - bool has_responseval() const; - private: - bool _internal_has_responseval() const; - public: - void clear_responseval(); - const std::string& responseval() const; - template - void set_responseval(ArgT0&& arg0, ArgT... args); - std::string* mutable_responseval(); - PROTOBUF_NODISCARD std::string* release_responseval(); - void set_allocated_responseval(std::string* responseval); - private: - const std::string& _internal_responseval() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_responseval(const std::string& value); - std::string* _internal_mutable_responseval(); - public: - - // optional int32 messageID = 1; - bool has_messageid() const; - private: - bool _internal_has_messageid() const; - public: - void clear_messageid(); - int32_t messageid() const; - void set_messageid(int32_t value); - private: - int32_t _internal_messageid() const; - void _internal_set_messageid(int32_t value); - public: - - // optional int32 messageType = 2; - bool has_messagetype() const; - private: - bool _internal_has_messagetype() const; - public: - void clear_messagetype(); - int32_t messagetype() const; - void set_messagetype(int32_t value); - private: - int32_t _internal_messagetype() const; - void _internal_set_messagetype(int32_t value); - public: - - // optional .sv_rcon.response_t responseType = 3; - bool has_responsetype() const; - private: - bool _internal_has_responsetype() const; - public: - void clear_responsetype(); - ::sv_rcon::response_t responsetype() const; - void set_responsetype(::sv_rcon::response_t value); - private: - ::sv_rcon::response_t _internal_responsetype() const; - void _internal_set_responsetype(::sv_rcon::response_t value); - public: - - // @@protoc_insertion_point(class_scope:sv_rcon.response) - private: - class _Internal; - - template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; - typedef void InternalArenaConstructable_; - typedef void DestructorSkippable_; - struct Impl_ { - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr responsemsg_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr responseval_; - int32_t messageid_; - int32_t messagetype_; - int responsetype_; - }; - union { Impl_ _impl_; }; - friend struct ::TableStruct_sv_5frcon_2eproto; -}; -// =================================================================== - - -// =================================================================== - -#ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// response - -// optional int32 messageID = 1; -inline bool response::_internal_has_messageid() const { - bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; - return value; -} -inline bool response::has_messageid() const { - return _internal_has_messageid(); -} -inline void response::clear_messageid() { - _impl_.messageid_ = 0; - _impl_._has_bits_[0] &= ~0x00000004u; -} -inline int32_t response::_internal_messageid() const { - return _impl_.messageid_; -} -inline int32_t response::messageid() const { - // @@protoc_insertion_point(field_get:sv_rcon.response.messageID) - return _internal_messageid(); -} -inline void response::_internal_set_messageid(int32_t value) { - _impl_._has_bits_[0] |= 0x00000004u; - _impl_.messageid_ = value; -} -inline void response::set_messageid(int32_t value) { - _internal_set_messageid(value); - // @@protoc_insertion_point(field_set:sv_rcon.response.messageID) -} - -// optional int32 messageType = 2; -inline bool response::_internal_has_messagetype() const { - bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; - return value; -} -inline bool response::has_messagetype() const { - return _internal_has_messagetype(); -} -inline void response::clear_messagetype() { - _impl_.messagetype_ = 0; - _impl_._has_bits_[0] &= ~0x00000008u; -} -inline int32_t response::_internal_messagetype() const { - return _impl_.messagetype_; -} -inline int32_t response::messagetype() const { - // @@protoc_insertion_point(field_get:sv_rcon.response.messageType) - return _internal_messagetype(); -} -inline void response::_internal_set_messagetype(int32_t value) { - _impl_._has_bits_[0] |= 0x00000008u; - _impl_.messagetype_ = value; -} -inline void response::set_messagetype(int32_t value) { - _internal_set_messagetype(value); - // @@protoc_insertion_point(field_set:sv_rcon.response.messageType) -} - -// optional .sv_rcon.response_t responseType = 3; -inline bool response::_internal_has_responsetype() const { - bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; - return value; -} -inline bool response::has_responsetype() const { - return _internal_has_responsetype(); -} -inline void response::clear_responsetype() { - _impl_.responsetype_ = 0; - _impl_._has_bits_[0] &= ~0x00000010u; -} -inline ::sv_rcon::response_t response::_internal_responsetype() const { - return static_cast< ::sv_rcon::response_t >(_impl_.responsetype_); -} -inline ::sv_rcon::response_t response::responsetype() const { - // @@protoc_insertion_point(field_get:sv_rcon.response.responseType) - return _internal_responsetype(); -} -inline void response::_internal_set_responsetype(::sv_rcon::response_t value) { - _impl_._has_bits_[0] |= 0x00000010u; - _impl_.responsetype_ = value; -} -inline void response::set_responsetype(::sv_rcon::response_t value) { - _internal_set_responsetype(value); - // @@protoc_insertion_point(field_set:sv_rcon.response.responseType) -} - -// optional string responseMsg = 4; -inline bool response::_internal_has_responsemsg() const { - bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; - return value; -} -inline bool response::has_responsemsg() const { - return _internal_has_responsemsg(); -} -inline void response::clear_responsemsg() { - _impl_.responsemsg_.ClearToEmpty(); - _impl_._has_bits_[0] &= ~0x00000001u; -} -inline const std::string& response::responsemsg() const { - // @@protoc_insertion_point(field_get:sv_rcon.response.responseMsg) - return _internal_responsemsg(); -} -template -inline PROTOBUF_ALWAYS_INLINE -void response::set_responsemsg(ArgT0&& arg0, ArgT... args) { - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.responsemsg_.Set(static_cast(arg0), args..., GetArenaForAllocation()); - // @@protoc_insertion_point(field_set:sv_rcon.response.responseMsg) -} -inline std::string* response::mutable_responsemsg() { - std::string* _s = _internal_mutable_responsemsg(); - // @@protoc_insertion_point(field_mutable:sv_rcon.response.responseMsg) - return _s; -} -inline const std::string& response::_internal_responsemsg() const { - return _impl_.responsemsg_.Get(); -} -inline void response::_internal_set_responsemsg(const std::string& value) { - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.responsemsg_.Set(value, GetArenaForAllocation()); -} -inline std::string* response::_internal_mutable_responsemsg() { - _impl_._has_bits_[0] |= 0x00000001u; - return _impl_.responsemsg_.Mutable(GetArenaForAllocation()); -} -inline std::string* response::release_responsemsg() { - // @@protoc_insertion_point(field_release:sv_rcon.response.responseMsg) - if (!_internal_has_responsemsg()) { - return nullptr; - } - _impl_._has_bits_[0] &= ~0x00000001u; - auto* p = _impl_.responsemsg_.Release(); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.responsemsg_.IsDefault()) { - _impl_.responsemsg_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - return p; -} -inline void response::set_allocated_responsemsg(std::string* responsemsg) { - if (responsemsg != nullptr) { - _impl_._has_bits_[0] |= 0x00000001u; - } else { - _impl_._has_bits_[0] &= ~0x00000001u; - } - _impl_.responsemsg_.SetAllocated(responsemsg, GetArenaForAllocation()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.responsemsg_.IsDefault()) { - _impl_.responsemsg_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - // @@protoc_insertion_point(field_set_allocated:sv_rcon.response.responseMsg) -} - -// optional string responseVal = 5; -inline bool response::_internal_has_responseval() const { - bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; - return value; -} -inline bool response::has_responseval() const { - return _internal_has_responseval(); -} -inline void response::clear_responseval() { - _impl_.responseval_.ClearToEmpty(); - _impl_._has_bits_[0] &= ~0x00000002u; -} -inline const std::string& response::responseval() const { - // @@protoc_insertion_point(field_get:sv_rcon.response.responseVal) - return _internal_responseval(); -} -template -inline PROTOBUF_ALWAYS_INLINE -void response::set_responseval(ArgT0&& arg0, ArgT... args) { - _impl_._has_bits_[0] |= 0x00000002u; - _impl_.responseval_.Set(static_cast(arg0), args..., GetArenaForAllocation()); - // @@protoc_insertion_point(field_set:sv_rcon.response.responseVal) -} -inline std::string* response::mutable_responseval() { - std::string* _s = _internal_mutable_responseval(); - // @@protoc_insertion_point(field_mutable:sv_rcon.response.responseVal) - return _s; -} -inline const std::string& response::_internal_responseval() const { - return _impl_.responseval_.Get(); -} -inline void response::_internal_set_responseval(const std::string& value) { - _impl_._has_bits_[0] |= 0x00000002u; - _impl_.responseval_.Set(value, GetArenaForAllocation()); -} -inline std::string* response::_internal_mutable_responseval() { - _impl_._has_bits_[0] |= 0x00000002u; - return _impl_.responseval_.Mutable(GetArenaForAllocation()); -} -inline std::string* response::release_responseval() { - // @@protoc_insertion_point(field_release:sv_rcon.response.responseVal) - if (!_internal_has_responseval()) { - return nullptr; - } - _impl_._has_bits_[0] &= ~0x00000002u; - auto* p = _impl_.responseval_.Release(); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.responseval_.IsDefault()) { - _impl_.responseval_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - return p; -} -inline void response::set_allocated_responseval(std::string* responseval) { - if (responseval != nullptr) { - _impl_._has_bits_[0] |= 0x00000002u; - } else { - _impl_._has_bits_[0] &= ~0x00000002u; - } - _impl_.responseval_.SetAllocated(responseval, GetArenaForAllocation()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.responseval_.IsDefault()) { - _impl_.responseval_.Set("", GetArenaForAllocation()); - } -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - // @@protoc_insertion_point(field_set_allocated:sv_rcon.response.responseVal) -} - -#ifdef __GNUC__ - #pragma GCC diagnostic pop -#endif // __GNUC__ - -// @@protoc_insertion_point(namespace_scope) - -} // namespace sv_rcon - -PROTOBUF_NAMESPACE_OPEN - -template <> struct is_proto_enum< ::sv_rcon::response_t> : ::std::true_type {}; - -PROTOBUF_NAMESPACE_CLOSE - -// @@protoc_insertion_point(global_scope) - -#include -#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_sv_5frcon_2eproto diff --git a/r5dev/public/const.h b/r5dev/public/const.h index 5709c447..63535f79 100644 --- a/r5dev/public/const.h +++ b/r5dev/public/const.h @@ -26,6 +26,8 @@ #define FIXANGLE_ABSOLUTE 1 #define FIXANGLE_RELATIVE 2 +#define FL_FAKECLIENT (1<<7) // Fake client, simulated server side; don't send network messages to them + enum RenderMode_t { kRenderNormal = 0, // src @@ -64,4 +66,22 @@ enum MoveType_t MOVETYPE_ZEROG // ? }; +inline const char* const g_GameDllTargets[] = { + "server", + "client" +}; + +inline bool V_GameTargetExists(const char* const pTarget) +{ + for (size_t i = 0; i < V_ARRAYSIZE(g_GameDllTargets); i++) + { + if (V_strcmp(pTarget, g_GameDllTargets[i]) == NULL) + { + return true; + } + } + + return false; +} + #endif // CONST_H \ No newline at end of file diff --git a/r5dev/public/globalvars_base.h b/r5dev/public/globalvars_base.h index 8f234264..5bfc5e17 100644 --- a/r5dev/public/globalvars_base.h +++ b/r5dev/public/globalvars_base.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -enum GameMode_t +enum class GameMode_t { NO_MODE = 0, MP_MODE, diff --git a/r5dev/public/localize/ilocalize.h b/r5dev/public/localize/ilocalize.h index 2c145557..89f660fb 100644 --- a/r5dev/public/localize/ilocalize.h +++ b/r5dev/public/localize/ilocalize.h @@ -65,6 +65,7 @@ inline const char* const g_LanguageNames[] = { "italian", "korean", "spanish", + "mspanish", "schinese", "tchinese", "russian", @@ -73,4 +74,46 @@ inline const char* const g_LanguageNames[] = { "polish", }; +inline const char* const g_LanguageCodes[] = { + "en_US", + "de_DE", + "fr_FR", + "it_IT", + "ko_KR", + "es_ES", + "es_MX", + "zh_CN", + "zh_TW", + "ru_RU", + "ja_JP", + "pt_BR", + "pl_PL", +}; + +inline bool V_LocaleNameExists(const char* const localeName) +{ + for (size_t i = 0; i < V_ARRAYSIZE(g_LanguageNames); i++) + { + if (V_strcmp(localeName, g_LanguageNames[i]) == NULL) + { + return true; + } + } + + return false; +} + +inline bool V_LocaleCodeExists(const char* const localeCode) +{ + for (size_t i = 0; i < V_ARRAYSIZE(g_LanguageCodes); i++) + { + if (V_strcmp(localeCode, g_LanguageCodes[i]) == NULL) + { + return true; + } + } + + return false; +} + #endif // LOCALIZE_H diff --git a/r5dev/public/playerstate.h b/r5dev/public/playerstate.h index 6d5a24ef..7b71c1e3 100644 --- a/r5dev/public/playerstate.h +++ b/r5dev/public/playerstate.h @@ -25,20 +25,20 @@ public: __int64 requestedClass; __int64 onDeathClass; __int64 oldClass; - __int64 netname; + string_t netname; int fixangle; - Vector3D anglechange; + QAngle anglechange; int index; - Vector3D forceWorldViewAngle; + QAngle forceWorldViewAngle; int forceWorldViewAngleUntilTick; bool replay; char gap_5d[3]; int lastPlayerView_tickcount; Vector3D lastPlayerView_origin; - Vector3D lastPlayerView_angle; + QAngle lastPlayerView_angle; bool deadflag; char gap_7d[3]; - Vector3D m_localViewAngles; + QAngle m_localViewAngles; }; #endif // PLAYERSTATE_H \ No newline at end of file diff --git a/r5dev/public/rtech/ipakfile.h b/r5dev/public/rtech/ipakfile.h index e2c81a10..aedbbb72 100644 --- a/r5dev/public/rtech/ipakfile.h +++ b/r5dev/public/rtech/ipakfile.h @@ -1,3 +1,8 @@ +//=============================================================================// +// +// Purpose: pak file constants and types +// +//=============================================================================// #ifndef RTECH_IPACKFILE_H #define RTECH_IPACKFILE_H #include "tier0/jobthread.h" @@ -12,7 +17,7 @@ // pak header flags #define PAK_HEADER_FLAGS_HAS_MODULE (1<<0) -#define PAK_HEADER_FLAGS_HAS_MODULE_EXTENDED PAK_HEADER_FLAGS_HAS_MODULE | (1<<1) +#define PAK_HEADER_FLAGS_HAS_MODULE_EXTENDED (PAK_HEADER_FLAGS_HAS_MODULE | (1<<1)) #define PAK_HEADER_FLAGS_COMPRESSED (1<<8) @@ -20,15 +25,15 @@ #define PAK_HEADER_FLAGS_ZSTREAM_ENCODED (1<<9) // max amount of types at runtime in which assets will be tracked -#define PAK_MAX_TYPES 64 -#define PAK_MAX_TYPES_MASK (PAK_MAX_TYPES-1) +#define PAK_MAX_TRACKED_TYPES 64 +#define PAK_MAX_TRACKED_TYPES_MASK (PAK_MAX_TRACKED_TYPES-1) // max amount of global pak assets at runtime -#define PAK_MAX_ASSETS 0x40000 // TODO: rename to PAK_MAX_LOADED_ASSETS -#define PAK_MAX_ASSETS_MASK (PAK_MAX_ASSETS-1) +#define PAK_MAX_LOADED_ASSETS 0x40000 +#define PAK_MAX_LOADED_ASSETS_MASK (PAK_MAX_LOADED_ASSETS-1) // max amount of global pak assets tracked at runtime -#define PAK_MAX_TRACKED_ASSETS (PAK_MAX_ASSETS/2) +#define PAK_MAX_TRACKED_ASSETS (PAK_MAX_LOADED_ASSETS/2) #define PAK_MAX_TRACKED_ASSETS_MASK (PAK_MAX_TRACKED_ASSETS-1) // max amount of segments a pak file could have @@ -42,8 +47,8 @@ #define PAK_MAX_STREAMING_FILE_HANDLES_PER_SET 4 // max amount of paks that could be loaded at runtime -#define PAK_MAX_HANDLES 512 // TODO: rename to PAK_MAX_LOADED_PAKS -#define PAK_MAX_HANDLES_MASK (PAK_MAX_HANDLES-1) +#define PAK_MAX_LOADED_PAKS 512 +#define PAK_MAX_LOADED_PAKS_MASK (PAK_MAX_LOADED_PAKS-1) // max amount of async streaming requests that could be made per pak file, if a // pak file has more patches than this number, and is already trying to stream @@ -75,14 +80,14 @@ // base pak directory containing paks sorted in platform specific subdirectories #define PAK_BASE_PATH "paks\\" -#define PLATFORM_PAK_PATH PAK_BASE_PATH"Win64\\" +#define PAK_PLATFORM_PATH PAK_BASE_PATH"Win64\\" // pak override directory; the system will looks for pak files in this directory -// first before falling back to PLATFORM_PAK_PATH -#define PLATFORM_PAK_OVERRIDE_PATH PAK_BASE_PATH"Win64_override\\" +// first before falling back to PAK_PLATFORM_PATH +#define PAK_PLATFORM_OVERRIDE_PATH PAK_BASE_PATH"Win64_override\\" // the handle that should be returned when a pak failed to load or process -#define INVALID_PAK_HANDLE -1 // TODO: rename to PAK_INVALID_HANDLE +#define PAK_INVALID_HANDLE -1 #define PAK_MAX_DISPATCH_LOAD_JOBS 4 #define PAK_DEFAULT_JOB_GROUP_ID 0x3000 @@ -90,7 +95,7 @@ //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- -struct PakFile_t; +struct PakFile_s; //----------------------------------------------------------------------------- // Handle types @@ -101,7 +106,7 @@ typedef uint64_t PakGuid_t; //----------------------------------------------------------------------------- // Page handle types //----------------------------------------------------------------------------- -struct PakPageHeader_t +struct PakPageHeader_s { uint32_t segmentIdx; uint32_t pageAlignment; @@ -115,7 +120,7 @@ struct PakPageHeader_t #define IS_PAKPTR_VALID(pak, ptr) ((ptr)->index != UINT32_MAX && (ptr)->offset != UINT32_MAX && (ptr)->index < (pak)->GetPageCount() && (ptr)->offset <= (pak)->GetPageSize((ptr)->index)) #define ASSERT_PAKPTR_VALID(pak, ptr) Assert(IS_PAKPTR_VALID(pak, ptr), "Invalid pak page pointer") -union PakPage_t +union PakPage_u { struct { @@ -128,7 +133,7 @@ union PakPage_t //----------------------------------------------------------------------------- // Enumerations //----------------------------------------------------------------------------- -enum EPakDecodeMode : int32_t +enum PakDecodeMode_e { MODE_DISABLED = -1, @@ -137,7 +142,7 @@ enum EPakDecodeMode : int32_t MODE_ZSTD }; -enum EPakStreamSet +enum PakStreamSet_e { STREAMING_SET_MANDATORY = 0, STREAMING_SET_OPTIONAL, @@ -146,7 +151,7 @@ enum EPakStreamSet STREAMING_SET_COUNT }; -enum EPakStatus : int32_t +enum PakStatus_e { PAK_STATUS_FREED = 0, PAK_STATUS_LOAD_PENDING = 1, @@ -166,7 +171,7 @@ enum EPakStatus : int32_t PAK_STATUS_BUSY = 15 }; -struct PakAssetBinding_t +struct PakAssetBinding_s { enum EType { @@ -205,15 +210,15 @@ struct PakAssetBinding_t // [ PIXIE ]: Should be the full size across Season 0-3. }; -struct PakAsset_t +struct PakAsset_s { // the guid of this asset, which will be used to index into, and retrieve // this asset from the hash table PakGuid_t guid; uint64_t padding; // Unknown. - PakPage_t headPtr; - PakPage_t dataPtr; + PakPage_u headPtr; + PakPage_u dataPtr; // offset to the streaming data in the streaming set uint64_t streamingDataFileOffset[STREAMING_SET_COUNT]; @@ -235,11 +240,11 @@ struct PakAsset_t FORCEINLINE uint8_t HashTableIndexForAssetType() const { - return (((0x1020601 * magic) >> 24) & PAK_MAX_TYPES_MASK); + return (((0x1020601 * magic) >> 24) & PAK_MAX_TRACKED_TYPES_MASK); } }; -struct PakAssetShort_t +struct PakAssetShort_s { PakGuid_t guid; uint32_t trackerIndex; @@ -264,11 +269,11 @@ struct PakTracker_s int unk_4; int unk_8; char gap_C[644100]; - int loadedAssetIndices[PAK_MAX_HANDLES]; + int loadedAssetIndices[PAK_MAX_LOADED_PAKS]; char gap_9DC04[522240]; }; -class PakLoadedInfo_t +class PakLoadedInfo_s { public: struct StreamingInfo_t @@ -292,7 +297,7 @@ public: }; PakHandle_t handle; - EPakStatus status; + PakStatus_e status; JobID_t loadJobId; uint32_t padding_maybe; @@ -307,7 +312,7 @@ public: void* segmentBuffers[PAK_SEGMENT_BUFFER_TYPES]; _QWORD qword50; FILETIME fileTime; - PakFile_t* pakFile; + PakFile_s* pakFile; StreamingInfo_t streamInfo[STREAMING_SET_COUNT]; uint32_t fileHandle; uint8_t m_nUnk5; @@ -315,11 +320,11 @@ public: }; //Size: 0x00B8/0x00E8 -struct PakGlobals_s +struct PakGlobalState_s { // [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet. - PakAssetBinding_t assetBindings[PAK_MAX_TYPES]; - PakAssetShort_t loadedAssets[PAK_MAX_ASSETS]; + PakAssetBinding_s assetBindings[PAK_MAX_TRACKED_TYPES]; + PakAssetShort_s loadedAssets[PAK_MAX_LOADED_ASSETS]; // assets that are tracked across all asset types PakAssetTracker_s trackedAssets[PAK_MAX_TRACKED_ASSETS]; @@ -328,11 +333,11 @@ struct PakGlobals_s RHashMap loadedPakMap; // links to 'loadedPaks' // all currently loaded pak handles - PakLoadedInfo_t loadedPaks[PAK_MAX_HANDLES]; + PakLoadedInfo_s loadedPaks[PAK_MAX_LOADED_PAKS]; RMultiHashMap unkMap2; // links to 'unkIntArray' and 'unkIntArray2' int unkIntArray[PAK_MAX_TRACKED_ASSETS]; - int unkIntArray2[PAK_MAX_ASSETS]; + int unkIntArray2[PAK_MAX_LOADED_ASSETS]; // whether asset streaming (mandatory & optional) is enabled b64 useStreamingSystem; @@ -365,10 +370,10 @@ struct PakGlobals_s int16_t loadedPakCount; int16_t requestedPakCount; - PakHandle_t loadedPakHandles[PAK_MAX_HANDLES]; + PakHandle_t loadedPakHandles[PAK_MAX_LOADED_PAKS]; - JobTypeID_t assetBindJobTypes[PAK_MAX_TYPES]; - JobTypeID_t jobTypeSlots_Unused[PAK_MAX_TYPES]; + JobTypeID_t assetBindJobTypes[PAK_MAX_TRACKED_TYPES]; + JobTypeID_t jobTypeSlots_Unused[PAK_MAX_TRACKED_TYPES]; JobTypeID_t dispatchLoadJobTypes[PAK_MAX_DISPATCH_LOAD_JOBS]; uint8_t dispathLoadJobPriorities[PAK_MAX_DISPATCH_LOAD_JOBS]; // promoted to JobPriority_e @@ -390,19 +395,19 @@ struct PakGlobals_s uint8_t* patchNumbers; }; -struct PakPatchFileHeader_t +struct PakPatchFileHeader_s { uint64_t compressedSize; uint64_t decompressedSize; }; -struct PakPatchDataHeader_t +struct PakPatchDataHeader_s { uint32_t editStreamSize; uint32_t pageCount; }; -struct PakFileHeader_t +struct PakFileHeader_s { inline uint32_t GetTotalStreamingNamesBufferSize() const { @@ -420,30 +425,30 @@ struct PakFileHeader_t inline uint64_t GetTotalHeaderSize() const { - uint64_t headerSize = sizeof(PakFileHeader_t); + uint64_t headerSize = sizeof(PakFileHeader_s); // if we have patches, we should include the patch header as well if (patchIndex > 0) - headerSize += sizeof(PakPatchDataHeader_t); + headerSize += sizeof(PakPatchDataHeader_s); // the streaming file paths belong to the header as well headerSize += GetTotalStreamingNamesBufferSize(); return headerSize; } - inline EPakDecodeMode GetCompressionMode() const + inline PakDecodeMode_e GetCompressionMode() const { if (flags & PAK_HEADER_FLAGS_ZSTREAM_ENCODED) - return EPakDecodeMode::MODE_ZSTD; + return PakDecodeMode_e::MODE_ZSTD; // NOTE: this should be the first check once we rebuilt function // 14043F300 and alloc ring buffer for the flags individually instead // instead of having to define the main compress flag (which really // just means that the pak is using the RTech decoder) else if (flags & PAK_HEADER_FLAGS_COMPRESSED) - return EPakDecodeMode::MODE_RTECH; + return PakDecodeMode_e::MODE_RTECH; - return EPakDecodeMode::MODE_DISABLED; + return PakDecodeMode_e::MODE_DISABLED; } // file versions @@ -496,7 +501,7 @@ struct PakFileHeader_t uint32_t memPageOffset; uint8_t unk3[0x8]; -}; static_assert(sizeof(PakFileHeader_t) == 0x80); +}; static_assert(sizeof(PakFileHeader_s) == 0x80); // segment flags #define SF_HEAD (0) @@ -504,23 +509,23 @@ struct PakFileHeader_t #define SF_CPU (1 << 1) // 0x2 #define SF_DEV (1 << 8) // 0x80 -struct PakSegmentHeader_t +struct PakSegmentHeader_s { int typeFlags; int dataAlignment; size_t dataSize; }; -struct PakSegmentDescriptor_t +struct PakSegmentDescriptor_s { - size_t assetTypeCount[PAK_MAX_TYPES]; + size_t assetTypeCount[PAK_MAX_TRACKED_TYPES]; int64_t segmentSizes[PAK_MAX_SEGMENTS]; size_t segmentSizeForType[PAK_SEGMENT_BUFFER_TYPES]; int segmentAlignmentForType[PAK_SEGMENT_BUFFER_TYPES]; }; -struct PakDecoder_t +struct PakDecoder_s { const uint8_t* inputBuf; uint8_t* outputBuf; @@ -537,7 +542,7 @@ struct PakDecoder_t uint32_t headerOffset; // this field was unused, it now contains the decoder mode - EPakDecodeMode decodeMode; + PakDecodeMode_e decodeMode; // NOTE: unless you are in the RTech decoder, use the getter if you need to // get the current pos!!! @@ -574,13 +579,13 @@ struct PakDecoder_t }; }; -struct PakRingBufferFrame_t +struct PakRingBufferFrame_s { size_t bufIndex; size_t frameLen; }; -struct PakFileStream_t +struct PakFileStream_s { struct Descriptor { @@ -590,7 +595,7 @@ struct PakFileStream_t // NOTE: if this is set, the game sets 'PakMemoryData_t::processedPatchedDataSize' // to 'dataOffset'; else its getting set to 'sizeof(PakFileHeader_t)'. - EPakDecodeMode compressionMode; + PakDecodeMode_e compressionMode; }; _QWORD qword0; @@ -610,11 +615,11 @@ struct PakFileStream_t _QWORD bytesStreamed; }; -typedef struct PakPatchFuncs_s +struct PakPatchFuncs_s { - typedef bool (*PatchFunc_t)(PakFile_t* const pak, size_t* const numAvailableBytes); + typedef bool (*PatchFunc_t)(PakFile_s* const pak, size_t* const numAvailableBytes); - enum EPatchCommands + enum PatchCommands_e { PATCH_CMD0, PATCH_CMD1, @@ -636,9 +641,9 @@ typedef struct PakPatchFuncs_s PatchFunc_t patchFuncs[PATCH_CMD_COUNT]; -} PakPatchFuncs_t; +}; -struct PakMemoryData_t +struct PakMemoryData_s { uint64_t processedPatchedDataSize; char* patchData; // pointer to patch stream data @@ -670,37 +675,37 @@ struct PakMemoryData_t int* loadedAssetIndices; uint8_t** memPageBuffers; - PakPatchFileHeader_t* patchHeaders; + PakPatchFileHeader_s* patchHeaders; unsigned short* patchIndices; char* streamingFilePaths[STREAMING_SET_COUNT]; - PakSegmentHeader_t* segmentHeaders; - PakPageHeader_t* pageHeaders; + PakSegmentHeader_s* segmentHeaders; + PakPageHeader_s* pageHeaders; - PakPage_t* virtualPointers; - PakAsset_t* assetEntries; + PakPage_u* virtualPointers; + PakAsset_s* assetEntries; - PakPage_t* guidDescriptors; + PakPage_u* guidDescriptors; uint32_t* fileRelations; char gap5E0[32]; - PakPatchDataHeader_t* patchDataHeader; - PakAsset_t** ppAssetEntries; + PakPatchDataHeader_s* patchDataHeader; + PakAsset_s** ppAssetEntries; int someAssetCount; int numShiftedPointers; // array of sizes/offsets in the SF_HEAD segment buffer - __int64 unkAssetTypeBindingSizes[PAK_MAX_TYPES]; + __int64 unkAssetTypeBindingSizes[PAK_MAX_TRACKED_TYPES]; const char* fileName; - PakFileHeader_t pakHeader; - PakPatchFileHeader_t patchHeader; + PakFileHeader_s pakHeader; + PakPatchFileHeader_s patchHeader; }; -struct PakFile_t +struct PakFile_s { int numProcessedPointers; uint32_t processedAssetCount; @@ -710,26 +715,26 @@ struct PakFile_t uint32_t patchCount; uint32_t dword14; - PakFileStream_t fileStream; + PakFileStream_s fileStream; uint64_t inputBytePos; uint8_t byte1F8; char gap1F9[4]; uint8_t byte1FD; bool isOffsetted_MAYBE; bool isCompressed; - PakDecoder_t pakDecoder; + PakDecoder_s pakDecoder; uint8_t* decompBuffer; size_t maxCopySize; uint64_t qword298; - PakMemoryData_t memoryData; + PakMemoryData_s memoryData; inline const char* GetName() const { return memoryData.fileName; } - inline const PakFileHeader_t& GetHeader() const + inline const PakFileHeader_s& GetHeader() const { return memoryData.pakHeader; } @@ -766,7 +771,7 @@ struct PakFile_t return true; } - inline const PakPageHeader_t* GetPageHeader(const uint32_t i) const + inline const PakPageHeader_s* GetPageHeader(const uint32_t i) const { assert(i != UINT32_MAX && i < GetPageCount()); @@ -786,14 +791,14 @@ struct PakFile_t return memoryData.memPageBuffers[index] + offset; } - inline void* GetPointerForPageOffset(const PakPage_t& ptr) const + inline void* GetPointerForPageOffset(const PakPage_u& ptr) const { assert(IsPageOffsetValid(ptr.index, ptr.offset)); return memoryData.memPageBuffers[ptr.index] + ptr.offset; } - inline void* GetPointerForPageOffset(const PakPage_t* ptr) const + inline void* GetPointerForPageOffset(const PakPage_u* ptr) const { assert(IsPageOffsetValid(ptr->index, ptr->offset)); @@ -806,7 +811,7 @@ struct PakFile_t return GetHeader().virtualSegmentCount; } - inline const PakSegmentHeader_t* GetSegmentHeader(const uint32_t i) const + inline const PakSegmentHeader_s* GetSegmentHeader(const uint32_t i) const { assert(i < GetSegmentCount()); @@ -816,11 +821,11 @@ struct PakFile_t static_assert(sizeof(PakTracker_s) == 0x11D410); -static_assert(sizeof(PakFile_t) == 2224); // S3+ -static_assert(sizeof(PakLoadedInfo_t) == 184); -static_assert(sizeof(PakDecoder_t) == 136); -static_assert(sizeof(PakPatchFileHeader_t) == 16); -static_assert(sizeof(PakPatchDataHeader_t) == 8); -static_assert(sizeof(PakGlobals_s) == 0xC98A48); +static_assert(sizeof(PakFile_s) == 2224); // S3+ +static_assert(sizeof(PakLoadedInfo_s) == 184); +static_assert(sizeof(PakDecoder_s) == 136); +static_assert(sizeof(PakPatchFileHeader_s) == 16); +static_assert(sizeof(PakPatchDataHeader_s) == 8); +static_assert(sizeof(PakGlobalState_s) == 0xC98A48); #endif // RTECH_IPACKFILE_H diff --git a/r5dev/public/tier0/frametask.h b/r5dev/public/tier0/frametask.h index 01e7c2f9..9c4601a4 100644 --- a/r5dev/public/tier0/frametask.h +++ b/r5dev/public/tier0/frametask.h @@ -4,8 +4,8 @@ #include "public/iframetask.h" //=============================================================================// -// This class is set up to run before each frame (main thread). -// Committed tasks are scheduled to execute after 'i' frames. +// This class is set up to run before each frame, committed tasks are scheduled +// to execute after 'i' frames. // ---------------------------------------------------------------------------- // A use case for scheduling tasks in the main thread would be (for example) // performing a web request in a separate thread, and apply the results (such as diff --git a/r5dev/public/tier0/sigcache.h b/r5dev/public/tier0/sigcache.h index 67ff711a..13086c31 100644 --- a/r5dev/public/tier0/sigcache.h +++ b/r5dev/public/tier0/sigcache.h @@ -7,7 +7,7 @@ #define SIGDB_DICT_SIZE 20 #define SIGDB_MAJOR_VERSION 0x2 // Increment when library changes are made. -#define SIGDB_MINOR_VERSION 0xA // Increment when SDK updates are released. +#define SIGDB_MINOR_VERSION 0xB // Increment when SDK updates are released. class CSigCache { diff --git a/r5dev/public/tier1/bitbuf.h b/r5dev/public/tier1/bitbuf.h index 8581da14..02ce2868 100644 --- a/r5dev/public/tier1/bitbuf.h +++ b/r5dev/public/tier1/bitbuf.h @@ -212,6 +212,24 @@ public: int64 ReadSignedVarInt64() { return bitbuf::ZigZagDecode64(ReadVarInt64()); } void ReadBits(void* pOutData, int nBits); + + // Helper 'safe' template function that infers the size of the destination + // array. This version of the function should be preferred. + // Usage: char databuffer[100]; + // ReadBitsClamped( dataBuffer, msg->m_nLength ); + template + FORCEINLINE int ReadBitsClamped(T (&pOut)[N], int nBits) + { + const int outSizeBytes = N * sizeof(T); + const int outSizeBits = outSizeBytes * 8; + + if (nBits > outSizeBits) + nBits = outSizeBits; + + ReadBits(pOut, nBits); + return nBits; + } + bool ReadBytes(void* pOut, int nBytes); @@ -362,7 +380,7 @@ public: : CBitRead(pData, nBytes, nBits) {} bf_read(const char* pDebugName, void* pData, int nBytes, int nMaxBits = -1) - : CBitRead(pDebugName, pData, nMaxBits) {} + : CBitRead(pDebugName, pData, nBytes, nMaxBits) {} bf_read(void) : CBitRead() {} @@ -423,7 +441,9 @@ FORCEINLINE void CBitRead::GrabNextDWord(bool bOverFlowImmediately) { if (m_pDataIn > m_pBufferEnd) { - SetOverflowFlag(); + if (!IsOverflowed()) + SetOverflowFlag(); + m_nInBufWord = 0; } else diff --git a/r5dev/public/tier1/byteswap.h b/r5dev/public/tier1/byteswap.h index d6290acb..e342fc6e 100644 --- a/r5dev/public/tier1/byteswap.h +++ b/r5dev/public/tier1/byteswap.h @@ -183,7 +183,7 @@ public: inputBuffer = outputBuffer; } - // Are we already the correct endienness? ( or are we swapping 1 byte items? ) + // Are we already the correct endianness? ( or are we swapping 1 byte items? ) if (!m_bSwapBytes || (sizeof(T) == 1)) { // If we were just going to swap in place then return. diff --git a/r5dev/public/tier1/strtools.h b/r5dev/public/tier1/strtools.h index 20508762..4ea53e5a 100644 --- a/r5dev/public/tier1/strtools.h +++ b/r5dev/public/tier1/strtools.h @@ -7,6 +7,7 @@ #define INCORRECT_PATH_SEPARATOR_S "/" #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES ":/\\" #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/') +#define PATHSEPARATORW(c) ((c) == L'\\' || (c) == L'/') #elif POSIX || defined( _PS3 ) #define CORRECT_PATH_SEPARATOR '/' #define CORRECT_PATH_SEPARATOR_S "/" @@ -14,6 +15,7 @@ #define INCORRECT_PATH_SEPARATOR_S "\\" #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES "/" #define PATHSEPARATOR(c) ((c) == '/') +#define PATHSEPARATORW(c) ((c) == L'/') #endif #define COPY_ALL_CHARACTERS -1 @@ -156,6 +158,8 @@ inline void V_MakeAbsolutePath(char* pOut, size_t outLen, const char* pPath, con size_t V_StripLastDir(char* dirName, size_t maxLen); // Returns a pointer to the unqualified file name (no path) of a file name const char* V_UnqualifiedFileName(const char* in); +const wchar_t* V_UnqualifiedFileName(const wchar_t* in); + // Given a path and a filename, composes "path\filename", inserting the (OS correct) separator if necessary void V_ComposeFileName(const char* path, const char* filename, char* dest, size_t destSize); diff --git a/r5dev/public/tier2/cryptutils.h b/r5dev/public/tier2/cryptutils.h new file mode 100644 index 00000000..048ac786 --- /dev/null +++ b/r5dev/public/tier2/cryptutils.h @@ -0,0 +1,28 @@ +#ifndef TIER2_CRYPTUTILS_H +#define TIER2_CRYPTUTILS_H + +bool Plat_GenerateRandom(unsigned char* pBuffer, const uint32_t nBufLen, const char*& errorMsg); + +typedef unsigned char CryptoIV_t[16]; +typedef unsigned char CryptoKey_t[16]; + +struct CryptoContext_s +{ + CryptoContext_s(const int setKeyBits = 128) + : keyBits(setKeyBits) + { + Assert(setKeyBits == 128 || setKeyBits == 192 || setKeyBits == 256); + memset(ivData, 0, sizeof(ivData)); + } + + CryptoIV_t ivData; + int keyBits; +}; + +bool Crypto_GenerateIV(CryptoContext_s& ctx, const unsigned char* const data, const size_t size); +bool Crypto_CTREncrypt(CryptoContext_s& ctx, const unsigned char* const inBuf, unsigned char* const outBuf, + const unsigned char* const key, const size_t size); +bool Crypto_CTRDecrypt(CryptoContext_s& ctx, const unsigned char* const inBuf, unsigned char* const outBuf, + const unsigned char* const key, const size_t size); + +#endif // TIER2_CRYPTUTILS_H diff --git a/r5dev/public/utility/vdf_parser.h b/r5dev/public/utility/vdf_parser.h deleted file mode 100644 index 13d6f7ad..00000000 --- a/r5dev/public/utility/vdf_parser.h +++ /dev/null @@ -1,711 +0,0 @@ -//MIT License -// -//Copyright(c) 2016 Matthias Moeller -// -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files(the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions : -// -//The above copyright notice and this permission notice shall be included in all -//copies or substantial portions of the Software. -// -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//SOFTWARE. - -#ifndef __TYTI_STEAM_VDF_PARSER_H__ -#define __TYTI_STEAM_VDF_PARSER_H__ -#pragma warning( disable : 4996 ) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -//for wstring support -#include -#include - -// internal -#include - -//VS < 2015 has only partial C++11 support -#if defined(_MSC_VER) && _MSC_VER < 1900 -#ifndef CONSTEXPR -#define CONSTEXPR -#endif - -#ifndef NOEXCEPT -#define NOEXCEPT -#endif -#else -#ifndef CONSTEXPR -#define CONSTEXPR constexpr -#define TYTI_UNDEF_CONSTEXPR -#endif - -#ifndef NOEXCEPT -#define NOEXCEPT noexcept -#define TYTI_UNDEF_NOEXCEPT -#endif - -#endif -namespace vdf -{ - namespace detail - { - /////////////////////////////////////////////////////////////////////////// - // Helper functions selecting the right encoding (char/wchar_T) - /////////////////////////////////////////////////////////////////////////// - - template - struct literal_macro_help - { - static CONSTEXPR const char* result(const char* c, const wchar_t*) NOEXCEPT - { - return c; - } - static CONSTEXPR const char result(const char c, const wchar_t) NOEXCEPT - { - return c; - } - }; - - template <> - struct literal_macro_help - { - static CONSTEXPR const wchar_t* result(const char*, const wchar_t* wc) NOEXCEPT - { - return wc; - } - static CONSTEXPR const wchar_t result(const char, const wchar_t wc) NOEXCEPT - { - return wc; - } - }; -#define TYTI_L(type, text) vdf::detail::literal_macro_help::result(text, L##text) - - inline std::string string_converter(const std::string& w) NOEXCEPT - { - return w; - } - - // utility wrapper to adapt locale-bound facets for wstring/wbuffer convert - // from cppreference - template - struct deletable_facet : Facet - { - template - deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} - ~deletable_facet() {} - }; - - inline std::string string_converter(const std::wstring& w) //todo: use us-locale - { - std::wstring_convert>> conv1; - return conv1.to_bytes(w); - } - - /////////////////////////////////////////////////////////////////////////// - // Writer helper functions - /////////////////////////////////////////////////////////////////////////// - - template - class tabs - { - const size_t t; - - public: - explicit CONSTEXPR tabs(size_t i) NOEXCEPT : t(i) {} - std::basic_string print() const { return std::basic_string(t, TYTI_L(charT, '\t')); } - inline CONSTEXPR tabs operator+(size_t i) const NOEXCEPT - { - return tabs(t + i); - } - }; - - template - oStreamT& operator<<(oStreamT& s, const tabs t) - { - s << t.print(); - return s; - } - } // end namespace detail - - /////////////////////////////////////////////////////////////////////////// - // Interface - /////////////////////////////////////////////////////////////////////////// - - /// custom objects and their corresponding write functions - - /// basic object node. Every object has a name and can contains attributes saved as key_value pairs or childrens - template - struct basic_object - { - typedef CharT char_type; - std::basic_string name; - std::unordered_map, std::basic_string> attribs; - std::unordered_map, std::shared_ptr>> childs; - - void add_attribute(std::basic_string key, std::basic_string value) - { - attribs.emplace(std::move(key), std::move(value)); - } - void add_child(std::unique_ptr> child) - { - std::shared_ptr> obj{ child.release() }; - childs.emplace(obj->name, obj); - } - void set_name(std::basic_string n) - { - name = std::move(n); - } - }; - - template - struct basic_multikey_object - { - typedef CharT char_type; - std::basic_string name; - std::unordered_multimap, std::basic_string> attribs; - std::unordered_multimap, std::shared_ptr>> childs; - - void add_attribute(std::basic_string key, std::basic_string value) - { - attribs.emplace(std::move(key), std::move(value)); - } - void add_child(std::unique_ptr> child) - { - std::shared_ptr> obj{ child.release() }; - childs.emplace(obj->name, obj); - } - void set_name(std::basic_string n) - { - name = std::move(n); - } - }; - - typedef basic_object object; - typedef basic_object wobject; - typedef basic_multikey_object multikey_object; - typedef basic_multikey_object wmultikey_object; - - struct Options - { - bool strip_escape_symbols; - bool ignore_all_platform_conditionals; - bool ignore_includes; - - Options() : strip_escape_symbols(true), ignore_all_platform_conditionals(false), ignore_includes(false) {} - }; - - //forward decls - template - OutputT read(iStreamT& inStream, const Options& opt = Options{}); - - /** \brief writes given object tree in vdf format to given stream. - Output is prettyfied, using tabs - */ - template - void write(oStreamT& s, const T& r, - const detail::tabs tab = detail::tabs(0)) - { - typedef typename oStreamT::char_type charT; - using namespace detail; - s << tab << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tab << TYTI_L(charT, "{\n"); - for (const auto& i : r.attribs) - s << tab + 1 << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") << i.second << TYTI_L(charT, "\"\n"); - for (const auto& i : r.childs) - if (i.second) - write(s, *i.second, tab + 1); - s << tab << TYTI_L(charT, "}\n"); - } - - namespace detail - { - template - std::basic_string read_file(iStreamT& inStream) - { - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str; - inStream.seekg(0, std::ios::end); - str.resize(static_cast(inStream.tellg())); - if (str.empty()) - return str; - - inStream.seekg(0, std::ios::beg); - inStream.read(&str[0], str.size()); - return str; - } - - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is malformed, parser will read the file until no longer possible. - @param first begin iterator - @param end end iterator - @param exclude_files list of files which cant be included anymore. - prevents circular includes - - can throw: - - "std::runtime_error" if a parsing error occured - - "std::bad_alloc" if not enough memory could be allocated - */ - template - std::vector> read_internal(IterT first, const IterT last, - std::unordered_set::value_type>>& exclude_files, - const Options& opt) - { - static_assert(std::is_default_constructible::value, - "Output Type must be default constructible (provide constructor without arguments)"); - static_assert(std::is_move_constructible::value, - "Output Type must be move constructible"); - - typedef typename std::iterator_traits::value_type charT; - - const std::basic_string comment_end_str = TYTI_L(charT, "*/"); - const std::basic_string whitespaces = TYTI_L(charT, " \n\v\f\r\t"); - -#ifdef WIN32 - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$WINDOWS"); - }; -#elif __APPLE__ - // WIN32 stands for pc in general - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$OSX"); - }; - -#elif __linux__ - // WIN32 stands for pc in general - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$LINUX"); - }; -#else - std::function&)> is_platform_str = [](const std::basic_string& in) { - return false; - }; -#endif - - if (opt.ignore_all_platform_conditionals) - is_platform_str = [](const std::basic_string&) { - return false; - }; - - // function for skipping a comment block - // iter: itterate position past a '/' character - auto skip_comments = [&comment_end_str](IterT iter, const IterT& last) -> IterT { - ++iter; - if (iter != last) - { - if (*iter == TYTI_L(charT, '/')) - { - // line comment, skip whole line - iter = std::find(iter + 1, last, TYTI_L(charT, '\n')); - } - - if (*iter == '*') - { - // block comment, skip until next occurance of "*\" - iter = std::search(iter + 1, last, std::begin(comment_end_str), std::end(comment_end_str)); - iter += 2; - } - } - return iter; - }; - - auto end_quote = [](IterT iter, const IterT& last) -> IterT { - const auto begin = iter; - auto last_esc = iter; - do - { - ++iter; - iter = std::find(iter, last, TYTI_L(charT, '\"')); - if (iter == last) - break; - - last_esc = std::prev(iter); - while (last_esc != begin && *last_esc == '\\') - --last_esc; - } while (!(std::distance(last_esc, iter) % 2)); - if (iter == last) - throw std::runtime_error{ "Quote was opened but never closed" }; - return iter; - }; - - auto end_word = [&whitespaces](IterT iter, const IterT& last) -> IterT { - const auto begin = iter; - auto last_esc = iter; - do - { - ++iter; - iter = std::find_first_of(iter, last, std::begin(whitespaces), std::end(whitespaces)); - if (iter == last) - break; - - last_esc = std::prev(iter); - while (last_esc != begin && *last_esc == '\\') - --last_esc; - } while (!(std::distance(last_esc, iter) % 2)); - //if (iter == last) - // throw std::runtime_error{ "Word wasn't properly ended" }; - return iter; - }; - - auto skip_whitespaces = [&whitespaces](IterT iter, const IterT& last) -> IterT { - iter = std::find_if_not(iter, last, [&whitespaces](charT c) { - // return true if whitespace - return std::any_of(std::begin(whitespaces), std::end(whitespaces), [c](charT pc) { return pc == c; }); - }); - return iter; - }; - - std::function&)> strip_escape_symbols = [](std::basic_string& s) { - auto quote_searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\""), pos); }; - auto p = quote_searcher(0); - while (p != s.npos) - { - s.replace(p, 2, TYTI_L(charT, "\"")); - p = quote_searcher(p); - } - auto searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\\"), pos); }; - p = searcher(0); - while (p != s.npos) - { - s.replace(p, 2, TYTI_L(charT, "\\")); - p = searcher(p); - } - }; - - if (!opt.strip_escape_symbols) - strip_escape_symbols = [](std::basic_string&) {}; - - auto conditional_fullfilled = [&skip_whitespaces, &is_platform_str](IterT& iter, const IterT& last) { - iter = skip_whitespaces(iter, last); - if (*iter == '[') - { - ++iter; - const auto end = std::find(iter, last, ']'); - const bool negate = *iter == '!'; - if (negate) - ++iter; - auto conditional = std::basic_string(iter, end); - - const bool is_platform = is_platform_str(conditional); - iter = end + 1; - - return static_cast(is_platform ^ negate); - } - return true; - }; - - //read header - // first, quoted name - std::unique_ptr curObj = nullptr; - std::vector> roots; - std::stack> lvls; - auto curIter = first; - - while (curIter != last && *curIter != '\0') - { - //find first starting attrib/child, or ending - curIter = skip_whitespaces(curIter, last); - if (curIter == last || *curIter == '\0') - break; - if (*curIter == TYTI_L(charT, '/')) - { - curIter = skip_comments(curIter, last); - } - else if (*curIter != TYTI_L(charT, '}')) - { - - // get key - const auto keyEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last); - if (*curIter == TYTI_L(charT, '\"')) - ++curIter; - std::basic_string key(curIter, keyEnd); - strip_escape_symbols(key); - curIter = keyEnd + ((*keyEnd == TYTI_L(charT, '\"')) ? 1 : 0); - - curIter = skip_whitespaces(curIter, last); - - auto conditional_key = conditional_fullfilled(curIter, last); - if (!conditional_key) - continue; - - while (*curIter == TYTI_L(charT, '/')) - { - - curIter = skip_comments(curIter, last); - if (curIter == last || *curIter == '}') - throw std::runtime_error{ "Key declared without value" }; - curIter = skip_whitespaces(curIter, last); - if (curIter == last || *curIter == '}') - throw std::runtime_error{ "Key declared without value" }; - } - // get value - if (*curIter != '{') - { - const auto valueEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last); - if (*curIter == TYTI_L(charT, '\"')) - ++curIter; - - auto value = std::basic_string(curIter, valueEnd); - strip_escape_symbols(value); - curIter = valueEnd + ((*valueEnd == TYTI_L(charT, '\"')) ? 1 : 0); - - auto conditional_value = conditional_fullfilled(curIter, last); - if (!conditional_value) - continue; - - // process value - if (curObj && key != TYTI_L(charT, "#include") && key != TYTI_L(charT, "#base")) - { - curObj->add_attribute(std::move(key), std::move(value)); - } - else - { - if (!opt.ignore_includes && exclude_files.find(value) == exclude_files.end()) - { - exclude_files.insert(value); - std::basic_ifstream i(detail::string_converter(value)); - auto str = read_file(i); - auto file_objs = read_internal(str.begin(), str.end(), exclude_files, opt); - for (auto& n : file_objs) - { - if (curObj) - curObj->add_child(std::move(n)); - else - roots.push_back(std::move(n)); - } - exclude_files.erase(value); - } - } - } - else if (*curIter == '{') - { - if (curObj) - lvls.push(std::move(curObj)); - curObj = std::make_unique(); - curObj->set_name(std::move(key)); - ++curIter; - } - } - //end of new object - else if (*curIter == TYTI_L(charT, '}')) - { - if (!lvls.empty()) - { - //get object before - std::unique_ptr prev{ std::move(lvls.top()) }; - lvls.pop(); - - // add finished obj to obj before and release it from processing - prev->add_child(std::move(curObj)); - curObj = std::move(prev); - } - else - { - roots.push_back(std::move(curObj)); - curObj.reset(); - } - ++curIter; - } - } - return roots; - } - - } // namespace detail - - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is malformed, parser will read the file until no longer possible. - @param first begin iterator - @param end end iterator - - can thow: - - "std::runtime_error" if a parsing error occurred - - "std::bad_alloc" if not enough memory coup be allocated - */ - template - OutputT read(IterT first, const IterT last, const Options& opt = Options{}) - { - auto exclude_files = std::unordered_set::value_type>>{}; - auto roots = detail::read_internal(first, last, exclude_files, opt); - - OutputT result; - if (roots.size() > 1) - { - for (auto& i : roots) - result.add_child(std::move(i)); - } - else if (roots.size() == 1) - result = std::move(*roots[0]); - - return result; - } - - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is malformed, parser will read the file until no longer possible. - @param first begin iterator - @param end end iterator - @param ec output bool. 0 if ok, otherwise, holds an system error code - - Possible error codes: - std::errc::protocol_error: file is malformed - std::errc::not_enough_memory: not enough space - std::errc::invalid_argument: iterators throws e.g. out of range - */ - template - OutputT read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT - - { - ec.clear(); - OutputT r{}; - try - { - r = read(first, last, opt); - } - catch (std::runtime_error&) - { - ec = std::make_error_code(std::errc::protocol_error); - } - catch (std::bad_alloc&) - { - ec = std::make_error_code(std::errc::not_enough_memory); - } - catch (...) - { - ec = std::make_error_code(std::errc::invalid_argument); - } - return r; - } - - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is malformed, parser will read the file until no longer possible. - @param first begin iterator - @param end end iterator - @param ok output bool. true, if parser successed, false, if parser failed - */ - template - OutputT read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT - { - std::error_code ec; - auto r = read(first, last, ec, opt); - if (ok) - *ok = !ec; - return r; - } - - template - inline auto read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT -> basic_object::value_type> - { - return read::value_type>>(first, last, ok, opt); - } - - template - inline auto read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT - -> basic_object::value_type> - { - return read::value_type>>(first, last, ec, opt); - } - - template - inline auto read(IterT first, const IterT last, const Options& opt = Options{}) - -> basic_object::value_type> - { - return read::value_type>>(first, last, opt); - } - - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - */ - template - OutputT read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) - { - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str = detail::read_file(inStream); - - // parse it - return read(str.begin(), str.end(), ec, opt); - } - - template - inline basic_object read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) - { - return read>(inStream, ec, opt); - } - - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - ok == false, if a parsing error occured - */ - template - OutputT read(iStreamT& inStream, bool* ok, const Options& opt = Options{}) - { - std::error_code ec; - const auto r = read(inStream, ec, opt); - if (ok) - *ok = !ec; - return r; - } - - template - inline basic_object read(iStreamT& inStream, bool* ok, const Options& opt = Options{}) - { - return read>(inStream, ok, opt); - } - - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - throws "std::runtime_error" if a parsing error occured - */ - template - OutputT read(iStreamT& inStream, const Options& opt) - { - - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str = detail::read_file(inStream); - // parse it - return read(str.begin(), str.end(), opt); - } - - template - inline basic_object read(iStreamT& inStream, const Options& opt = Options{}) - { - return read>(inStream, opt); - } - -} // namespace vdf - -#ifndef TYTI_NO_L_UNDEF -#undef TYTI_L -#endif - -#ifdef TYTI_UNDEF_CONSTEXPR -#undef CONSTEXPR -#undef TYTI_NO_L_UNDEF -#endif - -#ifdef TYTI_UNDEF_NOTHROW -#undef NOTHROW -#undef TYTI_UNDEF_NOTHROW -#endif - -#endif //__TYTI_STEAM_VDF_PARSER_H__ diff --git a/r5dev/public/vscript/ivscript.h b/r5dev/public/vscript/ivscript.h index 2d9960b8..4cf0ee93 100644 --- a/r5dev/public/vscript/ivscript.h +++ b/r5dev/public/vscript/ivscript.h @@ -17,6 +17,15 @@ typedef void* ScriptFunctionBindingStorageType_t; //--------------------------------------------------------- +enum ScriptStatus_t +{ + SCRIPT_ERROR = -1, + SCRIPT_DONE, + SCRIPT_RUNNING, +}; + +//--------------------------------------------------------- + enum ExtendedFieldType { FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT, diff --git a/r5dev/resource/batch/clean_sdk.bat b/r5dev/resource/batch/clean_sdk.bat index 4da73a6c..a3fe7ee4 100644 --- a/r5dev/resource/batch/clean_sdk.bat +++ b/r5dev/resource/batch/clean_sdk.bat @@ -3,6 +3,7 @@ rd /S /Q "%~dp0..\platform\depot" REM Remove log files ('log' is no longer used. 'logs' contains current logs, these get automatically cleaned if they exceed 10mb). rd /S /Q "%~dp0..\platform\log" rd /S /Q "%~dp0..\platform\logs" +rd /S /Q "%~dp0..\platform\liveapi\logs" REM Remove old NavMesh files which where included as an attempt to debug/suppress warnings. rd /S /Q "%~dp0..\maps" rd /S /Q "%~dp0..\platform\maps\graphs" @@ -15,6 +16,12 @@ del /Q "%~dp0..\r5reloaded.exe" del /Q "%~dp0..\r5apexsdkd64.dll" del /Q "%~dp0..\r5detours.dll" del /Q "%~dp0..\r5dev.dll" +del /Q "%~dp0..\bin\naveditor.exe" +del /Q "%~dp0..\bin\netcon32.exe" +del /Q "%~dp0..\platform\cfg\englishclient_build_vpk.cfg" +del /Q "%~dp0..\platform\cfg\englishclient_extract_vpk.cfg" +del /Q "%~dp0..\platform\cfg\englishserver_build_vpk.cfg" +del /Q "%~dp0..\platform\cfg\englishserver_extract_vpk.cfg" REM Remove deprecated pak files (these are no longer used). del /Q "%~dp0..\paks\Win32\common_empty.rpak" del /Q "%~dp0..\paks\Win32\common_sdk2.rpak" diff --git a/r5dev/resource/batch/nav_build.bat b/r5dev/resource/batch/nav_build.bat index 4774e8fc..c0901f5d 100644 --- a/r5dev/resource/batch/nav_build.bat +++ b/r5dev/resource/batch/nav_build.bat @@ -1,16 +1,16 @@ REM Build NavMesh for all levels. -naveditor -console levels\mp_lobby.obj 1 -naveditor -console levels\mp_rr_aqueduct.obj 1 -naveditor -console levels\mp_rr_arena_composite.obj 1 -naveditor -console levels\mp_rr_arena_skygarden.obj 1 -naveditor -console levels\mp_rr_ashs_redemption.obj 1 -naveditor -console levels\mp_rr_canyonlands_64k_x_64k.obj 1 -naveditor -console levels\mp_rr_canyonlands_mu1.obj 1 -naveditor -console levels\mp_rr_canyonlands_mu1_night.obj 1 -naveditor -console levels\mp_rr_canyonlands_staging.obj 1 -naveditor -console levels\mp_rr_desertlands_64k_x_64k.obj 1 -naveditor -console levels\mp_rr_desertlands_64k_x_64k_tt.obj 1 -naveditor -console levels\mp_rr_party_crasher.obj 1 +recast -console levels\mp_lobby.obj 1 +recast -console levels\mp_rr_aqueduct.obj 1 +recast -console levels\mp_rr_arena_composite.obj 1 +recast -console levels\mp_rr_arena_skygarden.obj 1 +recast -console levels\mp_rr_ashs_redemption.obj 1 +recast -console levels\mp_rr_canyonlands_64k_x_64k.obj 1 +recast -console levels\mp_rr_canyonlands_mu1.obj 1 +recast -console levels\mp_rr_canyonlands_mu1_night.obj 1 +recast -console levels\mp_rr_canyonlands_staging.obj 1 +recast -console levels\mp_rr_desertlands_64k_x_64k.obj 1 +recast -console levels\mp_rr_desertlands_64k_x_64k_tt.obj 1 +recast -console levels\mp_rr_party_crasher.obj 1 REM Copy NavMesh for identical levels. copy /y /v %~dp0..\maps\navmesh\mp_rr_aqueduct_small.nm %~dp0..\maps\navmesh\mp_rr_aqueduct_night_small.nm diff --git a/r5dev/resource/batch/vpk_build.bat b/r5dev/resource/batch/vpk_build.bat new file mode 100644 index 00000000..ae691fb4 --- /dev/null +++ b/r5dev/resource/batch/vpk_build.bat @@ -0,0 +1,33 @@ +start /ABOVENORMAL revpk "pack" "english" "server" "mp_common" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_aqueduct" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_aqueduct_night" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_arena_composite" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_arena_phase_runner" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_arena_skygarden" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_ashs_redemption" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_canyonlands_64k_x_64k" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_canyonlands_mu1" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_canyonlands_mu1_night" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_canyonlands_mu2" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_canyonlands_staging" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_desertlands_64k_x_64k" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_desertlands_64k_x_64k_nx" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_desertlands_64k_x_64k_tt" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "server" "mp_rr_party_crasher" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "frontend" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_common" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_aqueduct" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_aqueduct_night" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_arena_composite" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_arena_phase_runner" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_arena_skygarden" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_ashs_redemption" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_canyonlands_64k_x_64k" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_canyonlands_mu1" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_canyonlands_mu1_night" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_canyonlands_mu2" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_canyonlands_staging" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_desertlands_64k_x_64k" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_desertlands_64k_x_64k_nx" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_desertlands_64k_x_64k_tt" "../ship/" "../vpk/" +start /ABOVENORMAL revpk "pack" "english" "client" "mp_rr_party_crasher" "../ship/" "../vpk/" diff --git a/r5dev/resource/cfg/liveapi.cfg b/r5dev/resource/cfg/liveapi.cfg new file mode 100644 index 00000000..f1a76873 --- /dev/null +++ b/r5dev/resource/cfg/liveapi.cfg @@ -0,0 +1,18 @@ +///////////////// LiveAPI system configuration file. +// This file is executed automatically on startup. + +liveapi_enabled "0" // Enable LiveAPI functionality. +liveapi_session_name "" // LiveAPI session name to identify this connection. + +liveapi_websocket_enabled "0" // Whether to use WebSocket to transmit LiveAPI events. +liveapi_servers "" // Comma separated list of addresses to connect to; format: ws://domain.suffix:port. +liveapi_retry_count "5" // Amount of times to retry connecting before marking the connection as unavailable. +liveapi_retry_time "30" // Amount of time between each retry. + +liveapi_timeout "300" // WebSocket connection timeout in seconds. +liveapi_keepalive "30" // Interval of time to send Pong to any connected server. +liveapi_lax_ssl "1" // Skip SSL certificate validation for all WSS connections (allows the use of self-signed certificates). + +liveapi_print_enabled "0" // Whether to enable the printing of all events to a LiveAPI JSON file. +liveapi_print_pretty "0" // Whether to print events in a formatted manner to the LiveAPI JSON file. +liveapi_print_primitive "0" // Whether to print primitive event fields to the LiveAPI JSON file. diff --git a/r5dev/resource/cfg/system/autoexec_client_dev.cfg b/r5dev/resource/cfg/system/autoexec_client_dev.cfg index 652de307..978e9f1d 100644 --- a/r5dev/resource/cfg/system/autoexec_client_dev.cfg +++ b/r5dev/resource/cfg/system/autoexec_client_dev.cfg @@ -72,3 +72,9 @@ cl_ent_absbox "1" // Display entity abs bo 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! ). + +////////////////////////// +//// SOUND //// +////////////////////////// +//miles_debug "1" // Enable miles debug ( !slower! ). +miles_warnings "1" // Enable miles warnings. diff --git a/r5dev/resource/cfg/system/startup_client_dev.cfg b/r5dev/resource/cfg/system/startup_client_dev.cfg index 805a07b5..0c121a99 100644 --- a/r5dev/resource/cfg/system/startup_client_dev.cfg +++ b/r5dev/resource/cfg/system/startup_client_dev.cfg @@ -1,3 +1,4 @@ +-noserverdll -ansicolor -dev -devsdk diff --git a/r5dev/resource/cfg/system/startup_client_retail.cfg b/r5dev/resource/cfg/system/startup_client_retail.cfg index c72584ea..43871141 100644 --- a/r5dev/resource/cfg/system/startup_client_retail.cfg +++ b/r5dev/resource/cfg/system/startup_client_retail.cfg @@ -1,3 +1,4 @@ +-noserverdll -fnf -showdevmenu -playlistfile "playlists_r5_patch.txt" diff --git a/r5dev/resource/cfg/tools/build_all_vpk.cfg b/r5dev/resource/cfg/tools/build_all_vpk.cfg deleted file mode 100644 index 7f0f56e4..00000000 --- a/r5dev/resource/cfg/tools/build_all_vpk.cfg +++ /dev/null @@ -1,2 +0,0 @@ -exec "tools/englishserver_pack_vpk.cfg" -exec "tools/englishclient_pack_vpk.cfg" diff --git a/r5dev/resource/cfg/tools/englishclient_pack_vpk.cfg b/r5dev/resource/cfg/tools/englishclient_pack_vpk.cfg deleted file mode 100644 index 2c448176..00000000 --- a/r5dev/resource/cfg/tools/englishclient_pack_vpk.cfg +++ /dev/null @@ -1,15 +0,0 @@ -fs_vpk_pack "english" "client" "frontend" -fs_vpk_pack "english" "client" "mp_common" -fs_vpk_pack "english" "client" "mp_rr_aqueduct" -fs_vpk_pack "english" "client" "mp_rr_aqueduct_night" -fs_vpk_pack "english" "client" "mp_rr_arena_composite" -fs_vpk_pack "english" "client" "mp_rr_arena_skygarden" -fs_vpk_pack "english" "client" "mp_rr_ashs_redemption" -fs_vpk_pack "english" "client" "mp_rr_canyonlands_64k_x_64k" -fs_vpk_pack "english" "client" "mp_rr_canyonlands_mu1" -fs_vpk_pack "english" "client" "mp_rr_canyonlands_mu1_night" -fs_vpk_pack "english" "client" "mp_rr_canyonlands_staging" -fs_vpk_pack "english" "client" "mp_rr_desertlands_64k_x_64k" -fs_vpk_pack "english" "client" "mp_rr_desertlands_64k_x_64k_nx" -fs_vpk_pack "english" "client" "mp_rr_desertlands_64k_x_64k_tt" -fs_vpk_pack "english" "client" "mp_rr_party_crasher" diff --git a/r5dev/resource/cfg/tools/englishclient_unpack_vpk.cfg b/r5dev/resource/cfg/tools/englishclient_unpack_vpk.cfg deleted file mode 100644 index e4e533bc..00000000 --- a/r5dev/resource/cfg/tools/englishclient_unpack_vpk.cfg +++ /dev/null @@ -1,15 +0,0 @@ -fs_vpk_unpack "vpk/englishclient_frontend.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_common.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_aqueduct.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_aqueduct_night.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_arena_composite.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_arena_skygarden.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_ashs_redemption.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_canyonlands_64k_x_64k.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_canyonlands_mu1.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_canyonlands_mu1_night.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_canyonlands_staging.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_desertlands_64k_x_64k.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_desertlands_64k_x_64k_nx.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_desertlands_64k_x_64k_tt.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishclient_mp_rr_party_crasher.bsp.pak000_dir.vpk" diff --git a/r5dev/resource/cfg/tools/englishserver_pack_vpk.cfg b/r5dev/resource/cfg/tools/englishserver_pack_vpk.cfg deleted file mode 100644 index f275d5b5..00000000 --- a/r5dev/resource/cfg/tools/englishserver_pack_vpk.cfg +++ /dev/null @@ -1,14 +0,0 @@ -fs_vpk_pack "english" "server" "mp_common" -fs_vpk_pack "english" "server" "mp_rr_aqueduct" -fs_vpk_pack "english" "server" "mp_rr_aqueduct_night" -fs_vpk_pack "english" "server" "mp_rr_arena_composite" -fs_vpk_pack "english" "server" "mp_rr_arena_skygarden" -fs_vpk_pack "english" "server" "mp_rr_ashs_redemption" -fs_vpk_pack "english" "server" "mp_rr_canyonlands_64k_x_64k" -fs_vpk_pack "english" "server" "mp_rr_canyonlands_mu1" -fs_vpk_pack "english" "server" "mp_rr_canyonlands_mu1_night" -fs_vpk_pack "english" "server" "mp_rr_canyonlands_staging" -fs_vpk_pack "english" "server" "mp_rr_desertlands_64k_x_64k" -fs_vpk_pack "english" "server" "mp_rr_desertlands_64k_x_64k_nx" -fs_vpk_pack "english" "server" "mp_rr_desertlands_64k_x_64k_tt" -fs_vpk_pack "english" "server" "mp_rr_party_crasher" diff --git a/r5dev/resource/cfg/tools/englishserver_unpack_vpk.cfg b/r5dev/resource/cfg/tools/englishserver_unpack_vpk.cfg deleted file mode 100644 index 1962fb42..00000000 --- a/r5dev/resource/cfg/tools/englishserver_unpack_vpk.cfg +++ /dev/null @@ -1,14 +0,0 @@ -fs_vpk_unpack "vpk/englishserver_mp_common.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_aqueduct.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_aqueduct_night.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_arena_composite.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_arena_skygarden.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_ashs_redemption.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_canyonlands_64k_x_64k.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_canyonlands_mu1.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_canyonlands_mu1_night.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_canyonlands_staging.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_desertlands_64k_x_64k.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_desertlands_64k_x_64k_nx.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_desertlands_64k_x_64k_tt.bsp.pak000_dir.vpk" -fs_vpk_unpack "vpk/englishserver_mp_rr_party_crasher.bsp.pak000_dir.vpk" diff --git a/r5dev/resource/cfg/tools/rcon_client.cfg b/r5dev/resource/cfg/tools/rcon_client.cfg index 21b6b565..25c439e2 100644 --- a/r5dev/resource/cfg/tools/rcon_client.cfg +++ b/r5dev/resource/cfg/tools/rcon_client.cfg @@ -3,4 +3,5 @@ // See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for more information regarding RCON. // NOTE: This implementation is custom and differs slightly from Valve's implementation. -rcon_address "localhost" // The RCON system will attempt to connect to this address when 'rcon' command is issued. +cl_rcon_address "" // The RCON system will attempt to connect to this address when 'rcon' command is issued. Example [::FFFF:127.0.0.1]:37015 (counts for IPv4 and IPv6). +rcon_key "" // Base64 encoded AES-128 key that will be used to encrypt rcon traffic, leave this empty for a random key that gets printed to the console. diff --git a/r5dev/resource/cfg/tools/rcon_client_dev.cfg b/r5dev/resource/cfg/tools/rcon_client_dev.cfg index 22b16a0a..6118c755 100644 --- a/r5dev/resource/cfg/tools/rcon_client_dev.cfg +++ b/r5dev/resource/cfg/tools/rcon_client_dev.cfg @@ -3,4 +3,5 @@ // See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for more information regarding RCON. // NOTE: This implementation is custom and differs slightly from Valve's implementation. -rcon_address "localhost" // The RCON system will attempt to connect to this address when 'rcon' command is issued. +cl_rcon_address "" // The RCON system will attempt to connect to this address when 'rcon' command is issued. Example [::FFFF:127.0.0.1]:37015 (counts for IPv4 and IPv6). +rcon_key "WDNWLmJYQ2ZlM0VoTid3Yg==" // Base64 encoded AES-128 key that will be used to encrypt rcon traffic, leave this empty for a random key that gets printed to the console. diff --git a/r5dev/resource/cfg/tools/rcon_server.cfg b/r5dev/resource/cfg/tools/rcon_server.cfg index 1f016c15..1c62f561 100644 --- a/r5dev/resource/cfg/tools/rcon_server.cfg +++ b/r5dev/resource/cfg/tools/rcon_server.cfg @@ -3,5 +3,6 @@ // See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for more information regarding RCON. // NOTE: This implementation is custom and differs slightly from Valve's implementation. -rcon_password "" // !! WARNING !! Keep empty to disable RCON. Only enable this if you plan on using RCON. -sv_rcon_whitelist_address "" // This IP will never get disconnected or banned. Enter your own IP address in the same format here (counts for IPv4 and IPv6). +sv_rcon_password "" // !! WARNING !! Keep empty to disable RCON. Only enable this if you plan on using RCON. +sv_rcon_whitelistaddress "" // This IP will never get disconnected or banned. Example [::FFFF:127.0.0.1]:37005 (counts for IPv4 and IPv6). +rcon_key "" // Base64 encoded AES-128 key that will be used to encrypt rcon traffic, leave this empty for a random key that gets printed to the console. diff --git a/r5dev/resource/cfg/tools/rcon_server_dev.cfg b/r5dev/resource/cfg/tools/rcon_server_dev.cfg index 734e5216..eecc34db 100644 --- a/r5dev/resource/cfg/tools/rcon_server_dev.cfg +++ b/r5dev/resource/cfg/tools/rcon_server_dev.cfg @@ -3,10 +3,12 @@ // See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for more information regarding RCON. // NOTE: This implementation is custom and differs slightly from Valve's implementation. -rcon_password "" // !! WARNING !! Keep empty to disable RCON. Only enable this if you plan on using RCON. -sv_rcon_debug "1" // Show RCON debug information ( ! slower! ). -sv_rcon_banpenalty "1" // Number of minutes to ban IP before removing from ban vector. -sv_rcon_maxfailures "5" // Max number of tomes a user can ignore RCON authentication before being banned. -sv_rcon_maxignores "5" // Max number of times a user can ignore the no-auth message before being banned. -sv_rcon_maxsockets "2" // Max number of accepted sockets before the server starts closing redundant sockets. -sv_rcon_whitelist_address "" // This IP will never get disconnected or banned. Enter your own IP address in the same format here (counts for IPv4 and IPv6). +sv_rcon_password "" // !! WARNING !! Keep empty to disable RCON. Only enable this if you plan on using RCON. +sv_rcon_banpenalty "1" // Number of minutes to ban IP before removing from ban vector. +sv_rcon_maxfailures "5" // Max number of tomes a user can ignore RCON authentication before being banned. +sv_rcon_maxignores "5" // Max number of times a user can ignore the no-auth message before being banned. +sv_rcon_maxsockets "2" // Max number of accepted sockets before the server starts closing redundant sockets. +sv_rcon_whitelistaddress "" // This IP will never get disconnected or banned. Example [::FFFF:127.0.0.1]:37005 (counts for IPv4 and IPv6). + +rcon_debug "1" // Show RCON debug information ( ! slower! ). +rcon_key "WDNWLmJYQ2ZlM0VoTid3Yg==" // Base64 encoded AES-128 key that will be used to encrypt rcon traffic, leave this empty for a random key that gets printed to the console. diff --git a/r5dev/resource/docs/liveapi_readme.txt b/r5dev/resource/docs/liveapi_readme.txt new file mode 100644 index 00000000..db17343c --- /dev/null +++ b/r5dev/resource/docs/liveapi_readme.txt @@ -0,0 +1,96 @@ +# Quick Start + +This API is built on top of WebSockets and Google's Protocol Buffer (protobuf) technology. All gameplay events and +requests supported by the LiveAPI are documented in the `events.proto` protobuf file that lives in this directory. +If you're not familiar with protobuf, visit https://developers.google.com/protocol-buffers to learn more. + +Protobuf bindings can be easily generated for your language of choice after you obtain the Protobuf Compiler `protoc`. +For example, to generate bindings for Python, use: +`protoc.exe --proto_path= --python_out= events.proto` + +The bindings can then be included into your app code. In order to consume the events, your app will have to open a +WebSocket server that the running game server can connect and send events to. + +# Configuration + +The game server must also be running with additional configurations to activate the LiveAPI and connect to the app. +The configuration file is located in `platform/cfg/liveapi.cfg` (relative from the game executable `r5apex_ds.exe`). + +For example, if the app has a websocket server in port 7777 of the same machine the game server is running on, the +following settings can be applied in the aforementioned configuration file to connect the game server to the app: + +liveapi_enabled "1" +liveapi_websocket_enabled "1" +liveapi_servers "ws://127.0.0.1:7777" + +Upon launching with these parameters, the game server will connect to the WebSocket server at 127.0.0.1 in port 7777. +Gameplay events are sent to the WebSocket server app once the game server has started. + +The game can also be configured to write events to a local JSON file on the disk. The event logs will be located in +`platform/liveapi/logs//match_.json` (relative from the game executable `r5apex_ds.exe`). + +The following settings can be applied in the aforementioned configuration file to log events to a local JSON file: + +liveapi_enabled "1" +liveapi_print_enabled "1" +liveapi_print_pretty "1" + +- You can run the WebSocket and local JSON logging simultaneously. + +# Scripting + +The Squirrel scripting API of the LiveAPI is quite simple, there are 5 main functions: + +LiveAPI_IsValidToRun() +- Whether the LiveAPI system was initialized and is currently able to run, check on this before calling the functions + `LiveAPI_WriteLogUsingDefinedFields()` and `LiveAPI_WriteLogUsingCustomFields()`to save unnecessary load on the game + server. + +LiveAPI_StartLogging() +- This is used to start the logging of LiveAPI events to a local JSON file, if a log session is already active by the + time this function is called, the previous log session will be closed and a new one will be started. The new session + will be written to a new json file. +- Needs ConVar `liveapi_enabled` and `liveapi_print_enabled` set to 1, else this function will not do anything. + +LiveAPI_StopLogging() +- This is used to stop the logging of LiveAPI events to a local JSON file. Calling this will finish off the file and + stop the logging of new events. + +LiveAPI_WriteLogUsingDefinedFields() +- This function takes 3 parameters, an event type (must be one registered in the 'eLiveAPI_EventTypes' enum, see + the file `src/game/server/liveapi/liveapi.cpp` for available event types, or alternatively, see the events.proto + file, event names must start with a lower case !!!), an array of data, and an array of field indices. The order of + the 2 arrays are important, as the entries in the data array map directly to the data in the field indices array; if + event type is eLiveAPI_EventTypes.playerKilled, and if the first entry of the data array is "someString", and the + first entry in the field indices array is '3', then "someString" will be set to the third field index of the + PlayerKilled event message. Make sure to study the event messages, and their respective field numbers in the + `events.proto` file before assigning new events! + +NOTE: Since there was a high demand for custom events, we added an event named `CustomEvent` which can be used to send +game data in any structure from the game's scripting API. This is useful if you wish to log your own data from the +game (e.g. a custom gamemode that has something the current protocol doesn't support). The following function utilizes +this special event message: + +LiveAPI_WriteLogUsingCustomFields() +- This function takes 3 parameters, an event name (can be any string, the purpose of this is to identify your custom + event!), an array of data, and an array of field names. You can entirely define the structure of the data yourself; + if entry 6 in data array is "world!", and entry 6 in the field names array is "hello", then message variable "hello" + becomes "world!". The data array can take any of the following types: bool|int|float|string|vector|array|table. + NOTE: with tables, the key must be a string as this will be used to determine the custom field names, the values can + be any of the aforementioned types. +- Tables and arrays cannot be nested into them selfs as this would cause infinite recursion, and the maximum nesting + depth of a table or array is 64. + +For more technical information about the scripting API of the system, see the file +`platform/scripts/vscripts/_live_api.gnut` (relative from the game executable `r5apex_ds.exe`). + +# Technical Information + +By popular demand, we tried our best to keep the protocol and documentation the same as that of the retail version of +the game to maintain compatibility with existing apps. As of the release of this build, the file `events.proto` is +synced with the retail build `R5pc_r5-201_J29_CL6350311_EX6402312_6403685_2024_03_22`. + +# Contact & Feedback + +If you have a question, suggestion, or encountered an issue in the system, you can send me (Kawe Mazidjatari) an email +at `amos@r5reloaded.com`. diff --git a/r5dev/resource/patch/r5apex_ds.patch b/r5dev/resource/patch/r5apex_ds.patch index 43b5a3dc..ce2e5cdb 100644 --- a/r5dev/resource/patch/r5apex_ds.patch +++ b/r5dev/resource/patch/r5apex_ds.patch @@ -27,3 +27,10 @@ // since the dedicated server doesn't use model or texture streaming, and as a // result the files aren't shipped. 0x44BE87: "mov ecx, 0x1" --> "mov ecx, 0x0" + +// Prevent this global bool from being set, as setting this enables CMaterialRenderContext code which shouldn't run on the dedicated server. +0x1E4CE0: "mov cs:byte_165C4D15B, al" --> "mov cs:byte_165C4D15B, 0x0" + +// Prevent VFTable global pointer from being initialized to HardwareConfigDX11, which disables additional DX/Render code. +0x44A460: "lea rax, ds:off_141F03730" --> "nop" +0x44A467: "mov ds:off_141F03730, rax" --> "nop" \ No newline at end of file diff --git a/r5dev/resource/protobuf/cl_rcon.proto b/r5dev/resource/protobuf/cl_rcon.proto deleted file mode 100644 index c0a0907c..00000000 --- a/r5dev/resource/protobuf/cl_rcon.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package cl_rcon; -option optimize_for = LITE_RUNTIME; - -enum request_t -{ - SERVERDATA_REQUEST_EXECCOMMAND = 0; - SERVERDATA_REQUEST_AUTH = 1; - SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2; -} - -message request -{ - optional int32 messageID = 1; - optional int32 messageType = 2; - optional request_t requestType = 3; - optional string requestMsg = 4; - optional string requestVal = 5; -} diff --git a/r5dev/resource/protobuf/generate.bat b/r5dev/resource/protobuf/generate.bat index e179f451..428f2219 100644 --- a/r5dev/resource/protobuf/generate.bat +++ b/r5dev/resource/protobuf/generate.bat @@ -1,4 +1,3 @@ -protoc64 --cpp_out=. sig_map.proto -protoc64 --cpp_out=. sv_rcon.proto -protoc64 --cpp_out=. cl_rcon.proto -protoc64 --cpp_out=. events.proto +protoc --cpp_out=. sig_map.proto +protoc --cpp_out=. netcon.proto +protoc --cpp_out=. events.proto diff --git a/r5dev/resource/protobuf/netcon.proto b/r5dev/resource/protobuf/netcon.proto new file mode 100644 index 00000000..2b684f90 --- /dev/null +++ b/r5dev/resource/protobuf/netcon.proto @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////// +// R5Sdk netconsole protocol +////////////////////////////////////////////////////////////////////// +syntax = "proto3"; +package netcon; +option optimize_for = LITE_RUNTIME; + +////////////////////////////////////////////////////////////////////// +// Request from netconsole +////////////////////////////////////////////////////////////////////// + +enum request_e +{ + SERVERDATA_REQUEST_EXECCOMMAND = 0; + SERVERDATA_REQUEST_AUTH = 1; + SERVERDATA_REQUEST_SEND_CONSOLE_LOG = 2; +} + +message request +{ + optional int32 messageId = 1; + optional int32 messageType = 2; + optional request_e requestType = 3; + optional string requestMsg = 4; + optional string requestVal = 5; +} + +////////////////////////////////////////////////////////////////////// +// Response to netconsole +////////////////////////////////////////////////////////////////////// + +enum response_e +{ + SERVERDATA_RESPONSE_AUTH = 0; + SERVERDATA_RESPONSE_CONSOLE_LOG = 1; +} + +message response +{ + optional int32 messageId = 1; + optional int32 messageType = 2; + optional response_e responseType = 3; + optional string responseMsg = 4; + optional string responseVal = 5; +} + +////////////////////////////////////////////////////////////////////// +// Message envelope +////////////////////////////////////////////////////////////////////// + +message envelope +{ + bool encrypted = 1; + bytes nonce = 2; + bytes data = 3; +} diff --git a/r5dev/resource/protobuf/sv_rcon.proto b/r5dev/resource/protobuf/sv_rcon.proto deleted file mode 100644 index 3a64cfbc..00000000 --- a/r5dev/resource/protobuf/sv_rcon.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package sv_rcon; -option optimize_for = LITE_RUNTIME; - -enum response_t -{ - SERVERDATA_RESPONSE_AUTH = 0; - SERVERDATA_RESPONSE_CONSOLE_LOG = 1; -} - -message response -{ - optional int32 messageID = 1; - optional int32 messageType = 2; - optional response_t responseType = 3; - optional string responseMsg = 4; - optional string responseVal = 5; -} diff --git a/r5dev/revpk/revpk.cpp b/r5dev/revpk/revpk.cpp index bdf5c40c..5434d36d 100644 --- a/r5dev/revpk/revpk.cpp +++ b/r5dev/revpk/revpk.cpp @@ -13,6 +13,8 @@ #include "windows/console.h" #include "vpklib/packedstore.h" +#include "public/const.h" +#include "localize/ilocalize.h" #include "vstdlib/keyvaluessystem.h" #include "filesystem/filesystem_std.h" @@ -25,7 +27,7 @@ #define FRONTEND_ENABLE_FILE "enable.txt" static CKeyValuesSystem s_KeyValuesSystem; -static CFileSystem_Stdio g_FullFileSystem; +static CFileSystem_Stdio s_FullFileSystem; static bool s_bUseAnsiColors = true; //----------------------------------------------------------------------------- @@ -41,7 +43,7 @@ IKeyValuesSystem* KeyValuesSystem() //----------------------------------------------------------------------------- CFileSystem_Stdio* FileSystem() { - return &g_FullFileSystem; + return &s_FullFileSystem; } //----------------------------------------------------------------------------- @@ -49,12 +51,17 @@ CFileSystem_Stdio* FileSystem() //----------------------------------------------------------------------------- static void ReVPK_Init() { - CheckCPUforSSE2(); + CheckSystemCPUForSSE2(); + + // Init time. + Plat_FloatTime(); g_CoreMsgVCallback = EngineLoggerSink; lzham_enable_fail_exceptions(true); - Console_Init(s_bUseAnsiColors); + if (s_bUseAnsiColors) + Console_ColorInit(); + SpdLog_Init(s_bUseAnsiColors); } @@ -78,8 +85,8 @@ static void ReVPK_Usage() usage.Format( "ReVPK instructions and options:\n" "For packing; run 'revpk %s' with the following parameters:\n" - "\t<%s>\t- locale prefix for the directory tree file\n" - "\t<%s>\t- context scope for the VPK files [\"server\", \"client\"]\n" + "\t<%s>\t- locale prefix for the directory file ( defaults to \"%s\" )\n" + "\t<%s>\t- context scope for the VPK files [\"%s\", \"%s\"]\n" "\t<%s>\t- level name for the VPK files\n" "\t<%s>\t- ( optional ) path to the workspace containing the manifest file\n" "\t<%s>\t- ( optional ) path in which the VPK files will be built\n" @@ -87,12 +94,15 @@ static void ReVPK_Usage() "\t<%s>\t- ( optional ) the level of compression [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"]\n\n" "For unpacking; run 'revpk %s' with the following parameters:\n" - "\t<%s>\t- path and name of the target directory tree or data block file\n" + "\t<%s>\t- path and name of the target VPK files\n" "\t<%s>\t- ( optional ) path in which the VPK files will be unpacked\n" - "\t<%s>\t- ( optional ) whether to parse the directory tree file name from the data block file name\n", + "\t<%s>\t- ( optional ) whether to parse the directory file name from the pack file name\n", PACK_COMMAND, // Pack parameters: - "locale", "context", "levelName", "workspacePath", "buildPath", + "locale", g_LanguageNames[0], + "context", g_GameDllTargets[0], g_GameDllTargets[1], + + "levelName", "workspacePath", "buildPath", "numThreads", // Num helper threads. -1, LZHAM_MAX_HELPER_THREADS, -1, @@ -101,7 +111,7 @@ static void ReVPK_Usage() "fastest", "faster", "default", "better", "uber", UNPACK_COMMAND,// Unpack parameters: - "fileName", "inputDir", "sanitize" + "fileName", "outPath", "sanitize" ); Warning(eDLL_T::FS, "%s", usage.Get()); @@ -168,7 +178,7 @@ static void ReVPK_Pack(const CCommand& args) // For clients, we need an enable file which the engine uses to determine // whether or not to mount the front-end VPK file. - if (V_strcmp(contextName, DIR_TARGET[EPackedStoreTargets::STORE_TARGET_CLIENT]) == NULL) + if (V_strcmp(contextName, g_GameDllTargets[EPackedStoreTargets::STORE_TARGET_CLIENT]) == NULL) { ReVPK_WriteEnableFile(buildPath); } diff --git a/r5dev/rtech/async/asyncio.cpp b/r5dev/rtech/async/asyncio.cpp index 0c945233..05cc7cb8 100644 --- a/r5dev/rtech/async/asyncio.cpp +++ b/r5dev/rtech/async/asyncio.cpp @@ -23,7 +23,7 @@ int FS_OpenAsyncFile(const char* const filePath, const int logLevel, size_t* con if (fileToLoad && *fileToLoad) { // is this a pak file and do we have an override - if (strstr(fileToLoad, PLATFORM_PAK_PATH) && + if (strstr(fileToLoad, PAK_PLATFORM_PATH) && Pak_FileOverrideExists(fileToLoad, overridePath, sizeof(overridePath))) { fileToLoad = overridePath; diff --git a/r5dev/rtech/pak/pakalloc.cpp b/r5dev/rtech/pak/pakalloc.cpp index b3fb82b1..0533bded 100644 --- a/r5dev/rtech/pak/pakalloc.cpp +++ b/r5dev/rtech/pak/pakalloc.cpp @@ -10,14 +10,14 @@ //----------------------------------------------------------------------------- // aligns the segment headers for each asset type //----------------------------------------------------------------------------- -void Pak_AlignSegmentHeaders(PakFile_t* const pak, PakSegmentDescriptor_t* const desc) +void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc) { uint64_t headersSize = 0; uint8_t headerSegmentAlignment = static_cast(desc->segmentAlignmentForType[SF_HEAD]); - for (uint8_t i = 0; i < PAK_MAX_TYPES; ++i) + for (uint8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i) { - const PakAssetBinding_t& binding = g_pakGlobals->assetBindings[i]; + const PakAssetBinding_s& binding = g_pakGlobals->assetBindings[i]; if (desc->assetTypeCount[i]) { @@ -41,11 +41,11 @@ void Pak_AlignSegmentHeaders(PakFile_t* const pak, PakSegmentDescriptor_t* const //----------------------------------------------------------------------------- // aligns each individual non-header segment //----------------------------------------------------------------------------- -void Pak_AlignSegments(PakFile_t* const pak, PakSegmentDescriptor_t* const desc) +void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc) { for (uint16_t i = 0; i < pak->GetSegmentCount(); ++i) { - const PakSegmentHeader_t* const segHeader = pak->GetSegmentHeader(i); + const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(i); const uint8_t segmentType = segHeader->typeFlags & (SF_TEMP | SF_CPU); @@ -71,14 +71,14 @@ void Pak_AlignSegments(PakFile_t* const pak, PakSegmentDescriptor_t* const desc) //----------------------------------------------------------------------------- // copy's pages into pre-allocated and aligned segments //----------------------------------------------------------------------------- -void Pak_CopyPagesToSegments(PakFile_t* const pak, PakLoadedInfo_t* const loadedInfo, PakSegmentDescriptor_t* const desc) +void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc) { for (uint32_t i = 0; i < pak->GetPageCount(); ++i) { - const PakPageHeader_t* const pageHeader = pak->GetPageHeader(i); + const PakPageHeader_s* const pageHeader = pak->GetPageHeader(i); const uint32_t segmentIndex = pageHeader->segmentIdx; - const PakSegmentHeader_t* const segHeader = pak->GetSegmentHeader(segmentIndex); + const PakSegmentHeader_s* const segHeader = pak->GetSegmentHeader(segmentIndex); const int typeFlags = segHeader->typeFlags; // check if header page diff --git a/r5dev/rtech/pak/pakalloc.h b/r5dev/rtech/pak/pakalloc.h index 9d2b2a81..58d06382 100644 --- a/r5dev/rtech/pak/pakalloc.h +++ b/r5dev/rtech/pak/pakalloc.h @@ -2,12 +2,12 @@ #define RTECH_PAKALLOC_H #include "rtech/ipakfile.h" -extern void Pak_AlignSegmentHeaders(PakFile_t* const pak, PakSegmentDescriptor_t* const desc); -extern void Pak_AlignSegments(PakFile_t* const pak, PakSegmentDescriptor_t* const desc); -extern void Pak_CopyPagesToSegments(PakFile_t* const pak, PakLoadedInfo_t* const loadedInfo, PakSegmentDescriptor_t* const desc); +extern void Pak_AlignSegmentHeaders(PakFile_s* const pak, PakSegmentDescriptor_s* const desc); +extern void Pak_AlignSegments(PakFile_s* const pak, PakSegmentDescriptor_s* const desc); +extern void Pak_CopyPagesToSegments(PakFile_s* const pak, PakLoadedInfo_s* const loadedInfo, PakSegmentDescriptor_s* const desc); // something with sorting pages? -inline void (*sub_140442740)(PakAsset_t** assetEntries, PakAsset_t** assetEntry, __int64 idx, PakFile_t* pak); +inline void (*sub_140442740)(PakAsset_s** assetEntries, PakAsset_s** assetEntry, __int64 idx, PakFile_s* pak); /////////////////////////////////////////////////////////////////////////////// class V_PakAlloc : public IDetour diff --git a/r5dev/rtech/pak/pakdecode.cpp b/r5dev/rtech/pak/pakdecode.cpp index cbbf229c..c9075521 100644 --- a/r5dev/rtech/pak/pakdecode.cpp +++ b/r5dev/rtech/pak/pakdecode.cpp @@ -135,7 +135,7 @@ static const unsigned char /*141313180*/ s_defaultDecoderLUT[] = //----------------------------------------------------------------------------- // checks if we have enough output buffer room to decode the data stream //----------------------------------------------------------------------------- -bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_t* const decoder, const size_t outLen) +bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_s* const decoder, const size_t outLen) { // make sure caller has copied all data out the ring buffer first before // overwriting it with new decoded data @@ -146,7 +146,7 @@ bool Pak_HasEnoughDecodeBufferAvailable(PakDecoder_t* const decoder, const size_ //----------------------------------------------------------------------------- // checks if we have enough source data streamed to decode the next block //----------------------------------------------------------------------------- -bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_t* const decoder, const size_t inLen) +bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_s* const decoder, const size_t inLen) { // the decoder needs at least this amount of input data streamed in order // to decode the rest of the pak file, as this is where reading has stopped @@ -160,9 +160,9 @@ bool Pak_HasEnoughStreamedDataForDecode(PakDecoder_t* const decoder, const size_ // gets the frame for the data in the ring buffer, the frame returned is always // ending to the end of the ring buffer, or the end of the data itself //----------------------------------------------------------------------------- -PakRingBufferFrame_t Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen) +PakRingBufferFrame_s Pak_DetermineRingBufferFrame(const uint64_t bufMask, const size_t seekPos, const size_t dataLen) { - PakRingBufferFrame_t ring; + PakRingBufferFrame_s ring; ring.bufIndex = seekPos & bufMask; // the total amount of bytes used and available in this frame @@ -178,7 +178,7 @@ PakRingBufferFrame_t Pak_DetermineRingBufferFrame(const uint64_t bufMask, const //----------------------------------------------------------------------------- // initializes the RTech decoder //----------------------------------------------------------------------------- -size_t Pak_RTechDecoderInit(PakDecoder_t* const decoder, const uint8_t* const fileBuffer, +size_t Pak_RTechDecoderInit(PakDecoder_s* const decoder, const uint8_t* const fileBuffer, const uint64_t inputMask, const size_t dataSize, const size_t dataOffset, const size_t headerSize) { uint64_t frameHeader = *(_QWORD*)((inputMask & (dataOffset + headerSize)) + fileBuffer); @@ -218,7 +218,7 @@ size_t Pak_RTechDecoderInit(PakDecoder_t* const decoder, const uint8_t* const fi const uint64_t finalPos = inputMask & decoder->inBufBytePos; decoder->headerOffset = (currbits >> 3) + 1; decoder->inBufBytePos += (currbits >> 3) + 1; - decoder->bufferSizeNeeded = *(_QWORD*)(finalPos + fileBuffer) & ((1i64 << (8 * ((uint8_t)(currbits >> 3) + 1))) - 1);; + decoder->bufferSizeNeeded = *(_QWORD*)(finalPos + fileBuffer) & ((1i64 << (8 * ((uint8_t)(currbits >> 3) + 1))) - 1); } decoder->bufferSizeNeeded += dataOffset; @@ -243,7 +243,7 @@ size_t Pak_RTechDecoderInit(PakDecoder_t* const decoder, const uint8_t* const fi //----------------------------------------------------------------------------- // decodes the RTech data stream up to available buffer or data //----------------------------------------------------------------------------- -bool Pak_RTechStreamDecode(PakDecoder_t* const decoder, const size_t inLen, const size_t outLen) +bool Pak_RTechStreamDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen) { bool result; // al uint64_t outBufBytePos; // r15 @@ -570,7 +570,7 @@ LABEL_69: //----------------------------------------------------------------------------- // initializes the ZStd decoder //----------------------------------------------------------------------------- -size_t Pak_ZStdDecoderInit(PakDecoder_t* const decoder, const uint8_t* frameHeader, +size_t Pak_ZStdDecoderInit(PakDecoder_s* const decoder, const uint8_t* frameHeader, const size_t dataSize, const size_t headerSize) { ZSTD_DStream* const dctx = ZSTD_createDStream(); @@ -608,7 +608,7 @@ size_t Pak_ZStdDecoderInit(PakDecoder_t* const decoder, const uint8_t* frameHead // decodes the ZStd data stream up to available buffer or data, whichever ends // first //----------------------------------------------------------------------------- -bool Pak_ZStdStreamDecode(PakDecoder_t* const decoder, const PakRingBufferFrame_t& outFrame, const PakRingBufferFrame_t& inFrame) +bool Pak_ZStdStreamDecode(PakDecoder_s* const decoder, const PakRingBufferFrame_s& outFrame, const PakRingBufferFrame_s& inFrame) { ZSTD_outBuffer outBuffer = { &decoder->outputBuf[outFrame.bufIndex], @@ -620,7 +620,8 @@ bool Pak_ZStdStreamDecode(PakDecoder_t* const decoder, const PakRingBufferFrame_ inFrame.frameLen, NULL }; - const size_t ret = ZSTD_decompressStream(decoder->zstreamContext, &outBuffer, &inBuffer); + ZSTD_DStream* const dctx = decoder->zstreamContext; + const size_t ret = ZSTD_decompressStream(dctx, &outBuffer, &inBuffer); if (ZSTD_isError(ret)) { @@ -646,14 +647,14 @@ bool Pak_ZStdStreamDecode(PakDecoder_t* const decoder, const PakRingBufferFrame_ // // if the input stream has fully decoded, this should equal the size of the // encoded pak file - decoder->bufferSizeNeeded = decoder->inBufBytePos; + decoder->bufferSizeNeeded = decoder->inBufBytePos + ZSTD_nextSrcSizeToDecompress(dctx); const bool decoded = ret == NULL; // zstd decoder no longer necessary at this point, deallocate if (decoded) { - ZSTD_freeDStream(decoder->zstreamContext); + ZSTD_freeDStream(dctx); decoder->zstreamContext = nullptr; } @@ -663,9 +664,9 @@ bool Pak_ZStdStreamDecode(PakDecoder_t* const decoder, const PakRingBufferFrame_ //----------------------------------------------------------------------------- // initializes the decoder //----------------------------------------------------------------------------- -size_t Pak_InitDecoder(PakDecoder_t* const decoder, const uint8_t* const inputBuf, uint8_t* const outputBuf, +size_t Pak_InitDecoder(PakDecoder_s* const decoder, const uint8_t* const inputBuf, uint8_t* const outputBuf, const uint64_t inputMask, const uint64_t outputMask, const size_t dataSize, const size_t dataOffset, - const size_t headerSize, const EPakDecodeMode decodeMode) + const size_t headerSize, const PakDecodeMode_e decodeMode) { // buffer size must be power of two as we index into buffers using a bit // mask rather than a modulo, the mask provided must be bufferSize-1 @@ -696,7 +697,7 @@ size_t Pak_InitDecoder(PakDecoder_t* const decoder, const uint8_t* const inputBu // if we use the default RTech decoder, return from here as the stuff below // is handled by the RTech decoder internally - if (decodeMode == EPakDecodeMode::MODE_RTECH) + if (decodeMode == PakDecodeMode_e::MODE_RTECH) return Pak_RTechDecoderInit(decoder, inputBuf, inputMask, dataSize, dataOffset, headerSize); // NOTE: on RTech encoded paks this data is parsed out of the frame header, @@ -721,7 +722,7 @@ size_t Pak_InitDecoder(PakDecoder_t* const decoder, const uint8_t* const inputBu // from where the base pak had ended as patch pak files are considered part of // the pak file that's currently getting loaded //----------------------------------------------------------------------------- -bool Pak_StreamToBufferDecode(PakDecoder_t* const decoder, const size_t inLen, const size_t outLen, const EPakDecodeMode decodeMode) +bool Pak_StreamToBufferDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen, const PakDecodeMode_e decodeMode) { if (!Pak_HasEnoughStreamedDataForDecode(decoder, inLen)) return false; @@ -729,7 +730,7 @@ bool Pak_StreamToBufferDecode(PakDecoder_t* const decoder, const size_t inLen, c if (!Pak_HasEnoughDecodeBufferAvailable(decoder, outLen)) return false; - if (decodeMode == EPakDecodeMode::MODE_RTECH) + if (decodeMode == PakDecodeMode_e::MODE_RTECH) return Pak_RTechStreamDecode(decoder, inLen, outLen); // must have a decoder at this point @@ -739,8 +740,8 @@ bool Pak_StreamToBufferDecode(PakDecoder_t* const decoder, const size_t inLen, c // this position in code assert(decoder->zstreamContext && decoder->inBufBytePos <= inLen); - const PakRingBufferFrame_t outFrame = Pak_DetermineRingBufferFrame(decoder->outputMask, decoder->outBufBytePos , outLen); - const PakRingBufferFrame_t inFrame = Pak_DetermineRingBufferFrame(decoder->inputMask, decoder->inBufBytePos, inLen); + const PakRingBufferFrame_s outFrame = Pak_DetermineRingBufferFrame(decoder->outputMask, decoder->outBufBytePos , outLen); + const PakRingBufferFrame_s inFrame = Pak_DetermineRingBufferFrame(decoder->inputMask, decoder->inBufBytePos, inLen); return Pak_ZStdStreamDecode(decoder, outFrame, inFrame); } @@ -748,14 +749,14 @@ bool Pak_StreamToBufferDecode(PakDecoder_t* const decoder, const size_t inLen, c //----------------------------------------------------------------------------- // decodes buffered input pak data //----------------------------------------------------------------------------- -bool Pak_BufferToBufferDecode(uint8_t* const inBuf, uint8_t* const outBuf, const size_t pakSize, const EPakDecodeMode decodeMode) +bool Pak_BufferToBufferDecode(uint8_t* const inBuf, uint8_t* const outBuf, const size_t pakSize, const PakDecodeMode_e decodeMode) { - assert(decodeMode != EPakDecodeMode::MODE_DISABLED); + assert(decodeMode != PakDecodeMode_e::MODE_DISABLED); - PakDecoder_t decoder{}; - const size_t decompressedSize = Pak_InitDecoder(&decoder, inBuf, outBuf, UINT64_MAX, UINT64_MAX, pakSize, NULL, sizeof(PakFileHeader_t), decodeMode); + PakDecoder_s decoder{}; + const size_t decompressedSize = Pak_InitDecoder(&decoder, inBuf, outBuf, UINT64_MAX, UINT64_MAX, pakSize, NULL, sizeof(PakFileHeader_s), decodeMode); - PakFileHeader_t* const inHeader = reinterpret_cast(inBuf); + PakFileHeader_s* const inHeader = reinterpret_cast(inBuf); if (decompressedSize != inHeader->decompressedSize) { @@ -774,7 +775,7 @@ bool Pak_BufferToBufferDecode(uint8_t* const inBuf, uint8_t* const outBuf, const return false; } - PakFileHeader_t* const outHeader = reinterpret_cast(outBuf); + PakFileHeader_s* const outHeader = reinterpret_cast(outBuf); // copy the header over to the decoded buffer *outHeader = *inHeader; @@ -826,7 +827,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile const size_t fileSize = inPakStream.GetSize(); - if (fileSize <= sizeof(PakFileHeader_t)) + if (fileSize <= sizeof(PakFileHeader_s)) { Error(eDLL_T::RTECH, NO_ERROR, "%s: pak '%s' appears truncated!\n", __FUNCTION__, inPakFile); @@ -840,7 +841,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile inPakStream.Read(inPakBuf, fileSize); inPakStream.Close(); - PakFileHeader_t* const inHeader = reinterpret_cast(inPakBuf); + PakFileHeader_s* const inHeader = reinterpret_cast(inPakBuf); if (inHeader->magic != PAK_HEADER_MAGIC || inHeader->version != PAK_HEADER_VERSION) { @@ -850,9 +851,9 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile return false; } - const EPakDecodeMode decodeMode = inHeader->GetCompressionMode(); + const PakDecodeMode_e decodeMode = inHeader->GetCompressionMode(); - if (decodeMode == EPakDecodeMode::MODE_DISABLED) + if (decodeMode == PakDecodeMode_e::MODE_DISABLED) { Error(eDLL_T::RTECH, NO_ERROR, "%s: pak '%s' is already decompressed!\n", __FUNCTION__, inPakFile); @@ -881,7 +882,7 @@ bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile return false; } - const PakFileHeader_t* const outHeader = reinterpret_cast(outPakBuf); + const PakFileHeader_s* const outHeader = reinterpret_cast(outPakBuf); // NOTE: if the paks this particular pak patches have different sizes than // current sizes in the patch header, the runtime will crash! diff --git a/r5dev/rtech/pak/pakdecode.h b/r5dev/rtech/pak/pakdecode.h index 2008b012..40e6782b 100644 --- a/r5dev/rtech/pak/pakdecode.h +++ b/r5dev/rtech/pak/pakdecode.h @@ -2,12 +2,12 @@ #define RTECH_PAKDECODE_H #include "rtech/ipakfile.h" -extern size_t Pak_InitDecoder(PakDecoder_t* const decoder, const uint8_t* const inputBuf, uint8_t* const outputBuf, +extern size_t Pak_InitDecoder(PakDecoder_s* const decoder, const uint8_t* const inputBuf, uint8_t* const outputBuf, const uint64_t inputMask, const uint64_t outputMask, const size_t dataSize, const size_t dataOffset, - const size_t headerSize, const EPakDecodeMode decodeMode); + const size_t headerSize, const PakDecodeMode_e decodeMode); -extern bool Pak_StreamToBufferDecode(PakDecoder_t* const decoder, const size_t inLen, const size_t outLen, const EPakDecodeMode decodeMode); -extern bool Pak_BufferToBufferDecode(uint8_t* const inBuf, uint8_t* const outBuf, const size_t pakSize, const EPakDecodeMode decodeMode); +extern bool Pak_StreamToBufferDecode(PakDecoder_s* const decoder, const size_t inLen, const size_t outLen, const PakDecodeMode_e decodeMode); +extern bool Pak_BufferToBufferDecode(uint8_t* const inBuf, uint8_t* const outBuf, const size_t pakSize, const PakDecodeMode_e decodeMode); extern bool Pak_DecodePakFile(const char* const inPakFile, const char* const outPakFile); diff --git a/r5dev/rtech/pak/pakencode.cpp b/r5dev/rtech/pak/pakencode.cpp index 99df0017..8f9fb70c 100644 --- a/r5dev/rtech/pak/pakencode.cpp +++ b/r5dev/rtech/pak/pakencode.cpp @@ -35,7 +35,7 @@ bool Pak_BufferToBufferEncode(const uint8_t* const inBuf, const uint64_t inLen, { // offset to the actual pak data, the main file header shouldn't be // compressed - const size_t dataOffset = sizeof(PakFileHeader_t); + const size_t dataOffset = sizeof(PakFileHeader_s); uint8_t* const dstBuf = outBuf + dataOffset; const size_t dstLen = outLen - dataOffset; @@ -55,7 +55,7 @@ bool Pak_BufferToBufferEncode(const uint8_t* const inBuf, const uint64_t inLen, return false; } - PakFileHeader_t* const outHeader = reinterpret_cast(outBuf); + PakFileHeader_s* const outHeader = reinterpret_cast(outBuf); // the compressed size includes the entire buffer, even the data we didn't // compress like the file header @@ -105,7 +105,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile const size_t fileSize = inPakStream.GetSize(); // file appears truncated - if (fileSize <= sizeof(PakFileHeader_t)) + if (fileSize <= sizeof(PakFileHeader_s)) { Error(eDLL_T::RTECH, NO_ERROR, "%s: pak '%s' appears truncated!\n", __FUNCTION__, inPakFile); @@ -119,7 +119,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile inPakStream.Read(inPakBuf, fileSize); inPakStream.Close(); - const PakFileHeader_t* const inHeader = reinterpret_cast(inPakBuf); + const PakFileHeader_s* const inHeader = reinterpret_cast(inPakBuf); if (inHeader->magic != PAK_HEADER_MAGIC || inHeader->version != PAK_HEADER_VERSION) { @@ -129,7 +129,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile return false; } - if (inHeader->GetCompressionMode() != EPakDecodeMode::MODE_DISABLED) + if (inHeader->GetCompressionMode() != PakDecodeMode_e::MODE_DISABLED) { Error(eDLL_T::RTECH, NO_ERROR, "%s: pak '%s' is already compressed!\n", __FUNCTION__, inPakFile); @@ -158,7 +158,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile std::unique_ptr outPakBufContainer(new uint8_t[outBufSize]); uint8_t* const outPakBuf = outPakBufContainer.get(); - PakFileHeader_t* const outHeader = reinterpret_cast(outPakBuf); + PakFileHeader_s* const outHeader = reinterpret_cast(outPakBuf); // copy the header over *outHeader = *inHeader; @@ -172,7 +172,7 @@ bool Pak_EncodePakFile(const char* const inPakFile, const char* const outPakFile return false; } - const PakFileHeader_t* const outPakHeader = reinterpret_cast(outPakBuf); + const PakFileHeader_s* const outPakHeader = reinterpret_cast(outPakBuf); Pak_ShowHeaderDetails(outPakHeader); diff --git a/r5dev/rtech/pak/pakparse.cpp b/r5dev/rtech/pak/pakparse.cpp index cfad8e3d..bc81c767 100644 --- a/r5dev/rtech/pak/pakparse.cpp +++ b/r5dev/rtech/pak/pakparse.cpp @@ -19,7 +19,7 @@ static ConVar pak_debugrelations("pak_debugrelations", "0", FCVAR_DEVELOPMENTONL //----------------------------------------------------------------------------- // resolve the target guid from lookuo table //----------------------------------------------------------------------------- -static bool Pak_ResolveAssetDependency(const PakFile_t* const pak, PakGuid_t currentGuid, +static bool Pak_ResolveAssetDependency(const PakFile_s* const pak, PakGuid_t currentGuid, const PakGuid_t targetGuid, int& currentIndex, const bool shouldCheckTwo) { while (true) @@ -32,10 +32,10 @@ static bool Pak_ResolveAssetDependency(const PakFile_t* const pak, PakGuid_t cur currentIndex++; - if (currentIndex >= PAK_MAX_ASSETS) + if (currentIndex >= PAK_MAX_LOADED_ASSETS) return false; - currentIndex &= PAK_MAX_ASSETS_MASK; + currentIndex &= PAK_MAX_LOADED_ASSETS_MASK; currentGuid = g_pakGlobals->loadedAssets[currentIndex].guid; if (currentGuid == targetGuid) @@ -48,10 +48,10 @@ static bool Pak_ResolveAssetDependency(const PakFile_t* const pak, PakGuid_t cur //----------------------------------------------------------------------------- // resolve guid relations for asset //----------------------------------------------------------------------------- -void Pak_ResolveAssetRelations(PakFile_t* const pak, const PakAsset_t* const asset) +void Pak_ResolveAssetRelations(PakFile_s* const pak, const PakAsset_s* const asset) { - PakPage_t* const pGuidDescriptors = &pak->memoryData.guidDescriptors[asset->dependenciesIndex]; - uint32_t* const v5 = (uint32_t*)g_pakGlobals->loadedPaks[pak->memoryData.pakId & PAK_MAX_HANDLES_MASK].qword50; + PakPage_u* const pGuidDescriptors = &pak->memoryData.guidDescriptors[asset->dependenciesIndex]; + uint32_t* const v5 = (uint32_t*)g_pakGlobals->loadedPaks[pak->memoryData.pakId & PAK_MAX_LOADED_PAKS_MASK].qword50; if (pak_debugrelations.GetBool()) Msg(eDLL_T::RTECH, "Resolving relations for asset: '0x%-16llX', dependencies: %-4u; in pak '%s'\n", @@ -65,7 +65,7 @@ void Pak_ResolveAssetRelations(PakFile_t* const pak, const PakAsset_t* const ass const PakGuid_t targetGuid = reinterpret_cast(*pCurrentGuid); // get asset index - int currentIndex = targetGuid & PAK_MAX_ASSETS_MASK; + int currentIndex = targetGuid & PAK_MAX_LOADED_ASSETS_MASK; const PakGuid_t currentGuid = g_pakGlobals->loadedAssets[currentIndex].guid; const int64_t v9 = 2i64 * InterlockedExchangeAdd(v5, 1u); @@ -77,7 +77,7 @@ void Pak_ResolveAssetRelations(PakFile_t* const pak, const PakAsset_t* const ass // are we some special asset with the guid 2? if (!Pak_ResolveAssetDependency(pak, currentGuid, targetGuid, currentIndex, true)) { - PakAsset_t* assetEntries = pak->memoryData.assetEntries; + PakAsset_s* assetEntries = pak->memoryData.assetEntries; uint64_t a = 0; for (; assetEntries->guid != targetGuid; a++, assetEntries++) @@ -111,13 +111,13 @@ void Pak_ResolveAssetRelations(PakFile_t* const pak, const PakAsset_t* const ass } } -uint32_t Pak_ProcessRemainingPagePointers(PakFile_t* const pak) +uint32_t Pak_ProcessRemainingPagePointers(PakFile_s* const pak) { uint32_t processedPointers = 0; for (processedPointers = pak->numProcessedPointers; processedPointers < pak->GetPointerCount(); ++processedPointers) { - PakPage_t* const curPage = &pak->memoryData.virtualPointers[processedPointers]; + PakPage_u* const curPage = &pak->memoryData.virtualPointers[processedPointers]; int curCount = curPage->index - pak->firstPageIdx; if (curCount < 0) @@ -126,14 +126,14 @@ uint32_t Pak_ProcessRemainingPagePointers(PakFile_t* const pak) if (curCount >= pak->processedPageCount) break; - PakPage_t* const ptr = reinterpret_cast(pak->GetPointerForPageOffset(curPage)); + PakPage_u* const ptr = reinterpret_cast(pak->GetPointerForPageOffset(curPage)); ptr->ptr = pak->memoryData.memPageBuffers[ptr->index] + ptr->offset; } return processedPointers; } -void Pak_RunAssetLoadingJobs(PakFile_t* const pak) +void Pak_RunAssetLoadingJobs(PakFile_s* const pak) { pak->numProcessedPointers = Pak_ProcessRemainingPagePointers(pak); @@ -142,7 +142,7 @@ void Pak_RunAssetLoadingJobs(PakFile_t* const pak) if (numAssets == pak->memoryData.pakHeader.assetCount) return; - PakAsset_t* pakAsset = &pak->memoryData.assetEntries[numAssets]; + PakAsset_s* pakAsset = &pak->memoryData.assetEntries[numAssets]; if (pakAsset->pageEnd > pak->processedPageCount) return; @@ -192,14 +192,14 @@ void Pak_RunAssetLoadingJobs(PakFile_t* const pak) //----------------------------------------------------------------------------- PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const allocator, const int nIdx, const bool bUnk) { - PakHandle_t pakId = INVALID_PAK_HANDLE; + PakHandle_t pakId = PAK_INVALID_HANDLE; if (Pak_FileExists(fileName)) { Msg(eDLL_T::RTECH, "Loading pak file: '%s'\n", fileName); pakId = v_Pak_LoadAsync(fileName, allocator, nIdx, bUnk); - if (pakId == INVALID_PAK_HANDLE) + if (pakId == PAK_INVALID_HANDLE) Error(eDLL_T::RTECH, NO_ERROR, "%s: Failed read '%s' results '%d'\n", __FUNCTION__, fileName, pakId); } else @@ -215,7 +215,7 @@ PakHandle_t Pak_LoadAsync(const char* const fileName, CAlignedMemAlloc* const al //----------------------------------------------------------------------------- void Pak_UnloadAsync(PakHandle_t handle) { - const PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(handle); + const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(handle); if (pakInfo->fileName) Msg(eDLL_T::RTECH, "Unloading pak file: '%s'\n", pakInfo->fileName); @@ -232,13 +232,13 @@ static const int s_patchCmdToBytesToProcess[] = { CMD_INVALID, CMD_INVALID, CMD_ // loads and processes a pak file (handles decompression and patching) // TODO: !!! FINISH REBUILD !!! //---------------------------------------------------------------------------------- -bool Pak_ProcessPakFile(PakFile_t* const pak) +bool Pak_ProcessPakFile(PakFile_s* const pak) { - PakFileStream_t* const fileStream = &pak->fileStream; - PakMemoryData_t* const memoryData = &pak->memoryData; + PakFileStream_s* const fileStream = &pak->fileStream; + PakMemoryData_s* const memoryData = &pak->memoryData; // first request is always just the header? - size_t readStart = sizeof(PakFileHeader_t); + size_t readStart = sizeof(PakFileHeader_s); if (fileStream->numDataChunks > 0) readStart = fileStream->numDataChunks * PAK_READ_DATA_CHUNK_SIZE; @@ -261,19 +261,19 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) fileStream->bytesStreamed += bytesProcessed; if (v8) { - const PakFileHeader_t* pakHeader = &pak->memoryData.pakHeader; + const PakFileHeader_s* pakHeader = &pak->memoryData.pakHeader; const uint64_t v16 = fileStream->numDataChunksProcessed * PAK_READ_DATA_CHUNK_SIZE; if (v8 == 2) { fileStream->bytesStreamed = bytesProcessed + v16; - pakHeader = (PakFileHeader_t*)&fileStream->buffer[v16 & fileStream->bufferMask]; + pakHeader = (PakFileHeader_s*)&fileStream->buffer[v16 & fileStream->bufferMask]; } const uint8_t fileIndex = fileStream->numLoadedFiles++ & PAK_MAX_ASYNC_STREAMED_LOAD_REQUESTS_MASK; //printf("v16: %lld\n", v16); - fileStream->descriptors[fileIndex].dataOffset = v16 + sizeof(PakFileHeader_t); + fileStream->descriptors[fileIndex].dataOffset = v16 + sizeof(PakFileHeader_s); fileStream->descriptors[fileIndex].compressedSize = v16 + pakHeader->compressedSize; fileStream->descriptors[fileIndex].decompressedSize = pakHeader->decompressedSize; fileStream->descriptors[fileIndex].compressionMode = pakHeader->GetCompressionMode(); @@ -285,18 +285,18 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) for (; pak->byte1F8 != fileStream->numLoadedFiles; pak->byte1F8++) { - PakFileStream_t::Descriptor* v22 = &fileStream->descriptors[pak->byte1F8 & PAK_MAX_ASYNC_STREAMED_LOAD_REQUESTS_MASK]; + PakFileStream_s::Descriptor* v22 = &fileStream->descriptors[pak->byte1F8 & PAK_MAX_ASYNC_STREAMED_LOAD_REQUESTS_MASK]; if (pak->byte1FD) { pak->byte1FD = false; pak->inputBytePos = v22->dataOffset; - if (v22->compressionMode != EPakDecodeMode::MODE_DISABLED) + if (v22->compressionMode != PakDecodeMode_e::MODE_DISABLED) { pak->isOffsetted_MAYBE = false; pak->isCompressed = true; - memoryData->processedPatchedDataSize = sizeof(PakFileHeader_t); + memoryData->processedPatchedDataSize = sizeof(PakFileHeader_s); } else { @@ -311,8 +311,8 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) const size_t decompressedSize = Pak_InitDecoder(&pak->pakDecoder, fileStream->buffer, pak->decompBuffer, PAK_DECODE_IN_RING_BUFFER_MASK, PAK_DECODE_OUT_RING_BUFFER_MASK, - v22->compressedSize - (v22->dataOffset - sizeof(PakFileHeader_t)), - v22->dataOffset - sizeof(PakFileHeader_t), sizeof(PakFileHeader_t), v22->compressionMode); + v22->compressedSize - (v22->dataOffset - sizeof(PakFileHeader_s)), + v22->dataOffset - sizeof(PakFileHeader_s), sizeof(PakFileHeader_s), v22->compressionMode); if (decompressedSize != v22->decompressedSize) Error(eDLL_T::RTECH, EXIT_FAILURE, @@ -450,7 +450,7 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) if (pak->patchCount >= pak->memoryData.pakHeader.patchIndex) { FS_CloseAsyncFile(fileStream->fileHandle); - fileStream->fileHandle = INVALID_PAK_HANDLE; + fileStream->fileHandle = PAK_INVALID_HANDLE; fileStream->qword0 = 0; fileStream->finishedLoadingPatches = true; @@ -461,7 +461,7 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) return memoryData->patchSrcSize == 0; char pakPatchPath[MAX_PATH] = {}; - sprintf(pakPatchPath, PLATFORM_PAK_PATH"%s", pak->memoryData.fileName); + sprintf(pakPatchPath, PAK_PLATFORM_PATH"%s", pak->memoryData.fileName); // get path of next patch rpak to load if (pak->memoryData.patchIndices[pak->patchCount]) @@ -520,7 +520,7 @@ bool Pak_ProcessPakFile(PakFile_t* const pak) // sets patch variables for copying the next unprocessed page into the relevant segment buffer // if this is a header page, fetch info from the next unprocessed asset and copy over the asset's header -bool SetupNextPageForPatching(PakLoadedInfo_t* a1, PakFile_t* pak) +bool SetupNextPageForPatching(PakLoadedInfo_s* a1, PakFile_s* pak) { Pak_RunAssetLoadingJobs(pak); @@ -538,7 +538,7 @@ bool SetupNextPageForPatching(PakLoadedInfo_t* a1, PakFile_t* pak) if (highestProcessedPageIdx < pak->GetPageCount()) v26 = highestProcessedPageIdx; - const PakPageHeader_t* const nextMemPageHeader = &pak->memoryData.pageHeaders[v26]; + const PakPageHeader_s* const nextMemPageHeader = &pak->memoryData.pageHeaders[v26]; if ((pak->memoryData.segmentHeaders[nextMemPageHeader->segmentIdx].typeFlags & (SF_TEMP | SF_CPU)) != 0) { pak->memoryData.patchSrcSize = nextMemPageHeader->dataSize; @@ -549,7 +549,7 @@ bool SetupNextPageForPatching(PakLoadedInfo_t* a1, PakFile_t* pak) } // headers - PakAsset_t* pakAsset = pak->memoryData.ppAssetEntries[pak->memoryData.someAssetCount]; + PakAsset_s* pakAsset = pak->memoryData.ppAssetEntries[pak->memoryData.someAssetCount]; pak->memoryData.patchSrcSize = pakAsset->headerSize; int assetTypeIdx = pakAsset->HashTableIndexForAssetType(); @@ -560,9 +560,9 @@ bool SetupNextPageForPatching(PakLoadedInfo_t* a1, PakFile_t* pak) return true; } -bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) +bool Pak_ProcessAssets(PakLoadedInfo_s* const a1) { - PakFile_t* const pak = a1->pakFile; + PakFile_s* const pak = a1->pakFile; while (pak->processedAssetCount != pak->GetAssetCount()) { // TODO: invert condition and make the branch encompass the whole loop @@ -603,7 +603,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) break; } - PakAsset_t* asset = pak->memoryData.ppAssetEntries[pak->memoryData.someAssetCount]; + PakAsset_s* asset = pak->memoryData.ppAssetEntries[pak->memoryData.someAssetCount]; const uint32_t headPageOffset = asset->headPtr.offset; char* v8 = pak->memoryData.patchDstPtr - asset->headerSize; @@ -616,7 +616,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) for (uint32_t i = pak->memoryData.numShiftedPointers; i < pak->GetPointerCount(); pak->memoryData.numShiftedPointers = i) { - PakPage_t* ptr = &pak->memoryData.virtualPointers[i]; + PakPage_u* ptr = &pak->memoryData.virtualPointers[i]; ASSERT_PAKPTR_VALID(pak, ptr); @@ -627,7 +627,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) if (offsetToPointer >= asset->headerSize) break; - PakPage_t* pagePtr = reinterpret_cast(v8 + offsetToPointer); + PakPage_u* pagePtr = reinterpret_cast(v8 + offsetToPointer); ASSERT_PAKPTR_VALID(pak, ptr); @@ -641,7 +641,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) for (uint32_t j = 0; j < asset->dependenciesCount; ++j) { - PakPage_t* descriptor = &pak->memoryData.guidDescriptors[asset->dependenciesIndex + j]; + PakPage_u* descriptor = &pak->memoryData.guidDescriptors[asset->dependenciesIndex + j]; if (descriptor->index == shiftedPageIndex) descriptor->offset += offsetSize; @@ -649,7 +649,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) const uint32_t v16 = ++pak->memoryData.someAssetCount; - PakAsset_t* v17 = nullptr; + PakAsset_s* v17 = nullptr; if (v16 < pak->GetAssetCount() && (v17 = pak->memoryData.ppAssetEntries[v16], v17->headPtr.index == shiftedPageIndex)) { pak->memoryData.field_2A8 = v17->headPtr.offset - headPageOffset - asset->headerSize; @@ -675,9 +675,9 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) return false; uint32_t i = 0; - PakAsset_t* pAsset = nullptr; + PakAsset_s* pAsset = nullptr; - for (int j = pak->memoryData.pakId & PAK_MAX_HANDLES_MASK; i < pak->GetHeader().assetCount; a1->assetGuids[i - 1] = pAsset->guid) + for (int j = pak->memoryData.pakId & PAK_MAX_LOADED_PAKS_MASK; i < pak->GetHeader().assetCount; a1->assetGuids[i - 1] = pAsset->guid) { pAsset = &pak->memoryData.assetEntries[i]; if (pAsset->numRemainingDependencies) @@ -686,7 +686,7 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) Pak_ResolveAssetRelations(pak, pAsset); const int assetIndex = pak->memoryData.loadedAssetIndices[i]; - const PakAssetShort_t& loadedAsset = g_pakGlobals->loadedAssets[assetIndex]; + const PakAssetShort_s& loadedAsset = g_pakGlobals->loadedAssets[assetIndex]; if (g_pakGlobals->trackedAssets[loadedAsset.trackerIndex].loadedPakIndex == j) { @@ -733,24 +733,24 @@ bool Pak_ProcessAssets(PakLoadedInfo_t* const a1) if (g_pakGlobals->pakTracker) sub_14043D870(a1, 0); - a1->status = EPakStatus::PAK_STATUS_LOADED; + a1->status = PakStatus_e::PAK_STATUS_LOADED; return true; } -void Pak_StubInvalidAssetBinds(PakFile_t* const pak, PakSegmentDescriptor_t* const desc) +void Pak_StubInvalidAssetBinds(PakFile_s* const pak, PakSegmentDescriptor_s* const desc) { for (uint32_t i = 0; i < pak->GetAssetCount(); ++i) { - PakAsset_t* const asset = &pak->memoryData.assetEntries[i]; + PakAsset_s* const asset = &pak->memoryData.assetEntries[i]; pak->memoryData.ppAssetEntries[i] = asset; const uint8_t assetTypeIndex = asset->HashTableIndexForAssetType(); desc->assetTypeCount[assetTypeIndex]++; - PakAssetBinding_t* const assetBinding = &g_pakGlobals->assetBindings[assetTypeIndex]; + PakAssetBinding_s* const assetBinding = &g_pakGlobals->assetBindings[assetTypeIndex]; - if (assetBinding->type == PakAssetBinding_t::NONE) + if (assetBinding->type == PakAssetBinding_s::NONE) { assetBinding->extension = asset->magic; assetBinding->version = asset->version; @@ -762,7 +762,7 @@ void Pak_StubInvalidAssetBinds(PakFile_t* const pak, PakSegmentDescriptor_t* con assetBinding->headerSize = asset->headerSize; assetBinding->nativeClassSize = asset->headerSize; assetBinding->headerAlignment = pak->memoryData.pageHeaders[asset->headPtr.index].pageAlignment; - assetBinding->type = PakAssetBinding_t::STUB; + assetBinding->type = PakAssetBinding_s::STUB; } // this is dev only because it could spam a lot on older paks @@ -784,14 +784,14 @@ void Pak_StubInvalidAssetBinds(PakFile_t* const pak, PakSegmentDescriptor_t* con } } -bool Pak_StartLoadingPak(PakLoadedInfo_t* const loadedInfo) +bool Pak_StartLoadingPak(PakLoadedInfo_s* const loadedInfo) { - PakFile_t* const pakFile = loadedInfo->pakFile; + PakFile_s* const pakFile = loadedInfo->pakFile; if (pakFile->memoryData.patchSrcSize && !Pak_ProcessPakFile(pakFile)) return false; - PakSegmentDescriptor_t pakDescriptor = {}; + PakSegmentDescriptor_s pakDescriptor = {}; Pak_StubInvalidAssetBinds(pakFile, &pakDescriptor); @@ -823,7 +823,7 @@ bool Pak_StartLoadingPak(PakLoadedInfo_t* const loadedInfo) Pak_CopyPagesToSegments(pakFile, loadedInfo, &pakDescriptor); - const PakFileHeader_t& pakHdr = pakFile->GetHeader(); + const PakFileHeader_s& pakHdr = pakFile->GetHeader(); if (Pak_StreamingEnabled()) Pak_LoadStreamingData(loadedInfo); @@ -833,12 +833,12 @@ bool Pak_StartLoadingPak(PakLoadedInfo_t* const loadedInfo) pakFile->dword14 = 1; - PakMemoryData_t& memoryData = pakFile->memoryData; + PakMemoryData_s& memoryData = pakFile->memoryData; memoryData.patchSrcSize = pakFile->memoryData.qword2D0 - patchDestOffset; memoryData.patchDstPtr = (char*)&pakHdr + patchDestOffset; - loadedInfo->status = EPakStatus::PAK_STATUS_LOAD_PAKHDR; + loadedInfo->status = PakStatus_e::PAK_STATUS_LOAD_PAKHDR; return true; } @@ -1089,7 +1089,7 @@ bool Pak_StartLoadingPak(PakLoadedInfo_t* const loadedInfo) // virtualSegmentCount = pakHdr.virtualSegmentCount; // v32 = *(unsigned int*)&pakHdr.unk2[4]; // -// loadedInfo->assetGuids = (PakGuid_t*)loadedInfo->allocator->Alloc(sizeof(PakGuid_t) * asset_entry_count_var, 8);; +// loadedInfo->assetGuids = (PakGuid_t*)loadedInfo->allocator->Alloc(sizeof(PakGuid_t) * asset_entry_count_var, 8); // // size_t streamingFilesBuifSize = pakHdr.streamingFilesBufSize[STREAMING_SET_OPTIONAL] + pakHdr.streamingFilesBufSize[STREAMING_SET_MANDATORY]; // diff --git a/r5dev/rtech/pak/pakparse.h b/r5dev/rtech/pak/pakparse.h index 30a176fe..dc05407c 100644 --- a/r5dev/rtech/pak/pakparse.h +++ b/r5dev/rtech/pak/pakparse.h @@ -11,22 +11,22 @@ inline PakHandle_t(*v_Pak_Initialize)(int mode); inline PakHandle_t(*v_Pak_LoadAsync)(const char* fileName, CAlignedMemAlloc* allocator, int nIdx, bool bUnk); -inline EPakStatus(*v_Pak_WaitAsync)(PakHandle_t handle, void* finishCallback); +inline PakStatus_e(*v_Pak_WaitAsync)(PakHandle_t handle, void* finishCallback); inline void(*v_Pak_UnloadAsync)(PakHandle_t handle); inline void(*v_Pak_RegisterAsset)(int, int, const char*, void*, void*, void*, void*, int, int, uint32_t, int, int); -inline bool(*v_Pak_StartLoadingPak)(PakLoadedInfo_t* loadedInfo); -inline bool(*v_Pak_ProcessPakFile)(PakFile_t* const pak); -inline bool(*v_Pak_ProcessAssets)(PakLoadedInfo_t* pakInfo); -inline void(*v_Pak_ResolveAssetRelations)(PakFile_t* const pak, const PakAsset_t* const asset); +inline bool(*v_Pak_StartLoadingPak)(PakLoadedInfo_s* loadedInfo); +inline bool(*v_Pak_ProcessPakFile)(PakFile_s* const pak); +inline bool(*v_Pak_ProcessAssets)(PakLoadedInfo_s* pakInfo); +inline void(*v_Pak_ResolveAssetRelations)(PakFile_s* const pak, const PakAsset_s* const asset); -inline void (*v_Pak_RunAssetLoadingJobs)(PakFile_t* pak); -inline void (*Pak_ProcessAssetRelationsAndResolveDependencies)(PakFile_t* pak_arg, PakAsset_t* asset_arg, unsigned int asset_idx_arg, unsigned int a4); +inline void (*v_Pak_RunAssetLoadingJobs)(PakFile_s* pak); +inline void (*Pak_ProcessAssetRelationsAndResolveDependencies)(PakFile_s* pak_arg, PakAsset_s* asset_arg, unsigned int asset_idx_arg, unsigned int a4); -inline int (*Pak_TrackAsset)(PakFile_t* const a1, PakAsset_t* a2); +inline int (*Pak_TrackAsset)(PakFile_s* const a1, PakAsset_s* a2); // TODO: name these! -inline void (*sub_14043D870)(PakLoadedInfo_t* a1, int a2); +inline void (*sub_14043D870)(PakLoadedInfo_s* a1, int a2); /////////////////////////////////////////////////////////////////////////////// class V_PakParse : public IDetour diff --git a/r5dev/rtech/pak/pakpatch.cpp b/r5dev/rtech/pak/pakpatch.cpp index 75075a14..55259520 100644 --- a/r5dev/rtech/pak/pakpatch.cpp +++ b/r5dev/rtech/pak/pakpatch.cpp @@ -6,7 +6,7 @@ #include "rtech/ipakfile.h" #include "pakpatch.h" -bool PATCH_CMD_0(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_0(PakFile_s* const pak, size_t* const numAvailableBytes) { unsigned __int64 m_numBytesToProcess_maybe; // r9 unsigned __int64 v4; // rdi @@ -83,7 +83,7 @@ bool PATCH_CMD_0(PakFile_t* const pak, size_t* const numAvailableBytes) return pak->memoryData.numBytesToProcess_maybe == 0; } -bool PATCH_CMD_1(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_1(PakFile_s* const pak, size_t* const numAvailableBytes) { unsigned __int64 m_numBytesToProcess_maybe; // r8 size_t v3; // r9 @@ -111,7 +111,7 @@ bool PATCH_CMD_1(PakFile_t* const pak, size_t* const numAvailableBytes) } } -bool PATCH_CMD_2(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_2(PakFile_s* const pak, size_t* const numAvailableBytes) { NOTE_UNUSED(numAvailableBytes); @@ -153,7 +153,7 @@ bool PATCH_CMD_2(PakFile_t* const pak, size_t* const numAvailableBytes) return pak->memoryData.numBytesToProcess_maybe == 0; } -bool PATCH_CMD_3(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_3(PakFile_s* const pak, size_t* const numAvailableBytes) { size_t patchSrcSize = pak->memoryData.patchSrcSize; @@ -172,7 +172,7 @@ bool PATCH_CMD_3(PakFile_t* const pak, size_t* const numAvailableBytes) return pak->memoryData.numBytesToProcess_maybe == 0; } -bool PATCH_CMD_4_5(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_4_5(PakFile_s* const pak, size_t* const numAvailableBytes) { const size_t v2 = *numAvailableBytes; if (!v2) @@ -188,7 +188,7 @@ bool PATCH_CMD_4_5(PakFile_t* const pak, size_t* const numAvailableBytes) return PATCH_CMD_0(pak, numAvailableBytes); } -bool PATCH_CMD_6(PakFile_t* const pak, size_t* const numAvailableBytes) +bool PATCH_CMD_6(PakFile_s* const pak, size_t* const numAvailableBytes) { const size_t v2 = *numAvailableBytes; size_t v3 = 2; @@ -238,7 +238,7 @@ bool PATCH_CMD_6(PakFile_t* const pak, size_t* const numAvailableBytes) return false; } -const PakPatchFuncs_t g_pakPatchApi +const PakPatchFuncs_s g_pakPatchApi { PATCH_CMD_0, PATCH_CMD_1, diff --git a/r5dev/rtech/pak/pakpatch.h b/r5dev/rtech/pak/pakpatch.h index 287416f0..7b85f9b4 100644 --- a/r5dev/rtech/pak/pakpatch.h +++ b/r5dev/rtech/pak/pakpatch.h @@ -2,6 +2,6 @@ #define RTECH_PATCHAPI_H #include "rtech/ipakfile.h" -extern const PakPatchFuncs_t g_pakPatchApi; +extern const PakPatchFuncs_s g_pakPatchApi; #endif // RTECH_PATCHAPI_H diff --git a/r5dev/rtech/pak/pakstate.cpp b/r5dev/rtech/pak/pakstate.cpp index 496d855d..0a51cd5b 100644 --- a/r5dev/rtech/pak/pakstate.cpp +++ b/r5dev/rtech/pak/pakstate.cpp @@ -24,9 +24,9 @@ static void Pak_ListPaks_f() for (int16_t i = 0, n = g_pakGlobals->loadedPakCount; i < n; ++i) { - const PakLoadedInfo_t& info = g_pakGlobals->loadedPaks[i]; + const PakLoadedInfo_s& info = g_pakGlobals->loadedPaks[i]; - if (info.status == EPakStatus::PAK_STATUS_FREED) + if (info.status == PakStatus_e::PAK_STATUS_FREED) continue; const char* szRpakStatus = Pak_StatusToString(info.status); @@ -52,9 +52,9 @@ static void Pak_ListTypes_f() uint32_t nRegistered = 0; - for (int8_t i = 0; i < PAK_MAX_TYPES; ++i) + for (int8_t i = 0; i < PAK_MAX_TRACKED_TYPES; ++i) { - PakAssetBinding_t* type = &g_pakGlobals->assetBindings[i]; + PakAssetBinding_s* type = &g_pakGlobals->assetBindings[i]; if (!type->description) continue; @@ -85,7 +85,7 @@ static void Pak_RequestUnload_f(const CCommand& args) if (args.HasOnlyDigits(1)) { const PakHandle_t pakHandle = atoi(args.Arg(1)); - const PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(pakHandle); + const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(pakHandle); if (!pakInfo) { @@ -98,7 +98,7 @@ static void Pak_RequestUnload_f(const CCommand& args) } else { - const PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(args.Arg(1)); + const PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(args.Arg(1)); if (!pakInfo) { Warning(eDLL_T::RTECH, "Found no pak entry for specified name.\n"); @@ -135,8 +135,8 @@ static void Pak_Swap_f(const CCommand& args) const char* pakName = nullptr; - PakHandle_t pakHandle = INVALID_PAK_HANDLE; - const PakLoadedInfo_t* pakInfo = nullptr; + PakHandle_t pakHandle = PAK_INVALID_HANDLE; + const PakLoadedInfo_s* pakInfo = nullptr; if (args.HasOnlyDigits(1)) { @@ -168,7 +168,7 @@ static void Pak_Swap_f(const CCommand& args) Msg(eDLL_T::RTECH, "Requested pak swap for handle '%d'\n", pakHandle); g_pakLoadApi->UnloadAsync(pakHandle); - while (pakInfo->status != EPakStatus::PAK_STATUS_FREED) // Wait till this slot gets free'd. + while (pakInfo->status != PakStatus_e::PAK_STATUS_FREED) // Wait till this slot gets free'd. std::this_thread::sleep_for(std::chrono::seconds(1)); g_pakLoadApi->LoadAsync(pakName, AlignedMemAlloc(), NULL, 0); @@ -208,8 +208,8 @@ static void Pak_Decompress_f(const CCommand& args) return; } - CFmtStr1024 inPakFile(PLATFORM_PAK_PATH "%s", args.Arg(1)); - CFmtStr1024 outPakFile(PLATFORM_PAK_OVERRIDE_PATH "%s", args.Arg(1)); + CFmtStr1024 inPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); + CFmtStr1024 outPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); if (!Pak_DecodePakFile(inPakFile.String(), outPakFile.String())) { @@ -233,8 +233,8 @@ static void Pak_Compress_f(const CCommand& args) return; } - CFmtStr1024 inPakFile(PLATFORM_PAK_OVERRIDE_PATH "%s", args.Arg(1)); - CFmtStr1024 outPakFile(PLATFORM_PAK_PATH "%s", args.Arg(1)); + CFmtStr1024 inPakFile(PAK_PLATFORM_OVERRIDE_PATH "%s", args.Arg(1)); + CFmtStr1024 outPakFile(PAK_PLATFORM_PATH "%s", args.Arg(1)); // NULL means default compress level const int compressLevel = args.ArgC() > 2 ? atoi(args.Arg(2)) : NULL; @@ -246,7 +246,7 @@ static void Pak_Compress_f(const CCommand& args) } } -static ConCommand pak_strtoguid("pak_strtoguid", Pak_StringToGUID_f, "Calculates the GUID from input data", FCVAR_DEVELOPMENTONLY); +static ConCommand pak_stringtoguid("pak_stringtoguid", Pak_StringToGUID_f, "Calculates the GUID from input text", FCVAR_DEVELOPMENTONLY); static ConCommand pak_compress("pak_compress", Pak_Compress_f, "Compresses specified RPAK file", FCVAR_DEVELOPMENTONLY, RTech_PakCompress_f_CompletionFunc); static ConCommand pak_decompress("pak_decompress", Pak_Decompress_f, "Decompresses specified RPAK file", FCVAR_DEVELOPMENTONLY, RTech_PakDecompress_f_CompletionFunc); diff --git a/r5dev/rtech/pak/pakstate.h b/r5dev/rtech/pak/pakstate.h index c2c08f28..09cc4e17 100644 --- a/r5dev/rtech/pak/pakstate.h +++ b/r5dev/rtech/pak/pakstate.h @@ -18,7 +18,7 @@ struct PakLoadFuncs_s char unknown2[16]; void* Func7; void* Func8; - EPakStatus(*WaitAsync)(PakHandle_t handle, void* finishCallback); + PakStatus_e(*WaitAsync)(PakHandle_t handle, void* finishCallback); void* Func10; void* Func11; void* FindByGUID; @@ -47,7 +47,7 @@ struct PakLoadFuncs_s void* Func33; }; -inline PakGlobals_s* g_pakGlobals; +inline PakGlobalState_s* g_pakGlobals; extern PakLoadFuncs_s* g_pakLoadApi; inline JobHelpCallback_t g_pPakFifoLockWrapper; // Pointer to functor that takes the global pak fifolock as argument. @@ -72,7 +72,7 @@ class V_PakState : public IDetour virtual void GetFun(void) const { } virtual void GetVar(void) const { - g_pakGlobals = g_GameDll.FindPatternSIMD("48 8D 1D ?? ?? ?? ?? 45 8D 5A 0E").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_pakGlobals = g_GameDll.FindPatternSIMD("48 8D 1D ?? ?? ?? ?? 45 8D 5A 0E").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); g_pakLoadApi = CMemory(v_LauncherMain).Offset(0x820).FindPatternSelf("48 89").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); const CMemory jtBase(JT_HelpWithAnything); diff --git a/r5dev/rtech/pak/pakstream.cpp b/r5dev/rtech/pak/pakstream.cpp index f530c722..b9f9e948 100644 --- a/r5dev/rtech/pak/pakstream.cpp +++ b/r5dev/rtech/pak/pakstream.cpp @@ -45,12 +45,12 @@ static bool Pak_OptionalStreamingDataDownloaded() //----------------------------------------------------------------------------- // opens all associated streaming assets for this pak //----------------------------------------------------------------------------- -void Pak_OpenAssociatedStreamingFiles(PakLoadedInfo_t* const loadedInfo, PakLoadedInfo_t::StreamingInfo_t& streamInfo, - const uint16_t fileNamesBufSize, const EPakStreamSet set) +void Pak_OpenAssociatedStreamingFiles(PakLoadedInfo_s* const loadedInfo, PakLoadedInfo_s::StreamingInfo_t& streamInfo, + const uint16_t fileNamesBufSize, const PakStreamSet_e set) { assert(set < STREAMING_SET_COUNT); - const PakMemoryData_t& memoryData = loadedInfo->pakFile->memoryData; + const PakMemoryData_s& memoryData = loadedInfo->pakFile->memoryData; uint16_t numStreamFiles = 0; // load all streaming sets @@ -83,7 +83,7 @@ void Pak_OpenAssociatedStreamingFiles(PakLoadedInfo_t* const loadedInfo, PakLoad //----------------------------------------------------------------------------- // allocates the pak string to be used for embedded streaming data //----------------------------------------------------------------------------- -void Pak_EnableEmbeddedStreamingData(PakLoadedInfo_t* const loadedInfo, PakLoadedInfo_t::StreamingInfo_t& streamInfo) +void Pak_EnableEmbeddedStreamingData(PakLoadedInfo_s* const loadedInfo, PakLoadedInfo_s::StreamingInfo_t& streamInfo) { const char* const baseName = V_UnqualifiedFileName(loadedInfo->fileName); const size_t baseNameLen = strlen(baseName); @@ -113,13 +113,13 @@ void Pak_EnableEmbeddedStreamingData(PakLoadedInfo_t* const loadedInfo, PakLoade //----------------------------------------------------------------------------- // parse and open all streaming files //----------------------------------------------------------------------------- -void Pak_LoadStreamingData(PakLoadedInfo_t* const loadedInfo) +void Pak_LoadStreamingData(PakLoadedInfo_s* const loadedInfo) { - const PakFileHeader_t& pakHeader = loadedInfo->pakFile->GetHeader(); + const PakFileHeader_s& pakHeader = loadedInfo->pakFile->GetHeader(); for (int i = 0; i < STREAMING_SET_COUNT; i++) { - PakLoadedInfo_t::StreamingInfo_t& streamInfo = loadedInfo->streamInfo[i]; + PakLoadedInfo_s::StreamingInfo_t& streamInfo = loadedInfo->streamInfo[i]; streamInfo.Reset(); const bool optional = (i == STREAMING_SET_OPTIONAL); @@ -141,7 +141,7 @@ void Pak_LoadStreamingData(PakLoadedInfo_t* const loadedInfo) // external streaming files; mistake while building the pak? assert(!embeddedStreamingDataSize); - Pak_OpenAssociatedStreamingFiles(loadedInfo, streamInfo, filesBufLen, EPakStreamSet(i)); + Pak_OpenAssociatedStreamingFiles(loadedInfo, streamInfo, filesBufLen, PakStreamSet_e(i)); } else if (embeddedStreamingDataSize > 0) { diff --git a/r5dev/rtech/pak/pakstream.h b/r5dev/rtech/pak/pakstream.h index 7667acd2..5b3e2bc4 100644 --- a/r5dev/rtech/pak/pakstream.h +++ b/r5dev/rtech/pak/pakstream.h @@ -3,11 +3,11 @@ #include "rtech/ipakfile.h" #include "pakstate.h" -extern void Pak_OpenAssociatedStreamingFiles(PakLoadedInfo_t* const loadedInfo, PakLoadedInfo_t::StreamingInfo_t& streamInfo, - const uint16_t fileNamesBufSize, const EPakStreamSet set); +extern void Pak_OpenAssociatedStreamingFiles(PakLoadedInfo_s* const loadedInfo, PakLoadedInfo_s::StreamingInfo_t& streamInfo, + const uint16_t fileNamesBufSize, const PakStreamSet_e set); -extern void Pak_EnableEmbeddedStreamingData(PakLoadedInfo_t* const loadedInfo, PakLoadedInfo_t::StreamingInfo_t& streamInfo); -extern void Pak_LoadStreamingData(PakLoadedInfo_t* const loadedInfo); +extern void Pak_EnableEmbeddedStreamingData(PakLoadedInfo_s* const loadedInfo, PakLoadedInfo_s::StreamingInfo_t& streamInfo); +extern void Pak_LoadStreamingData(PakLoadedInfo_s* const loadedInfo); // the current download progress of optional streaming assets inline float* g_pStreamingDownloadProgress = nullptr; diff --git a/r5dev/rtech/pak/paktools.cpp b/r5dev/rtech/pak/paktools.cpp index f33038b3..5283597d 100644 --- a/r5dev/rtech/pak/paktools.cpp +++ b/r5dev/rtech/pak/paktools.cpp @@ -14,7 +14,7 @@ //---------------------------------------------------------------------------------- bool Pak_BasePathExists() { - return IsDirectory(PLATFORM_PAK_PATH); + return IsDirectory(PAK_PLATFORM_PATH); } //---------------------------------------------------------------------------------- @@ -26,7 +26,7 @@ bool Pak_CreateBasePath() if (Pak_BasePathExists()) return true; - return CreateDirHierarchy(PLATFORM_PAK_PATH) == 0; + return CreateDirHierarchy(PAK_PLATFORM_PATH) == 0; } //---------------------------------------------------------------------------------- @@ -34,7 +34,7 @@ bool Pak_CreateBasePath() //---------------------------------------------------------------------------------- bool Pak_OverridePathExists() { - return IsDirectory(PLATFORM_PAK_OVERRIDE_PATH); + return IsDirectory(PAK_PLATFORM_OVERRIDE_PATH); } //---------------------------------------------------------------------------------- @@ -46,7 +46,7 @@ bool Pak_CreateOverridePath() if (Pak_OverridePathExists()) return true; - return CreateDirHierarchy(PLATFORM_PAK_OVERRIDE_PATH) == 0; + return CreateDirHierarchy(PAK_PLATFORM_OVERRIDE_PATH) == 0; } //---------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ bool Pak_CreateOverridePath() bool Pak_FileOverrideExists(const char* const pakFilePath, char* const outPath, const size_t outBufLen) { // check the overrides path - snprintf(outPath, outBufLen, PLATFORM_PAK_OVERRIDE_PATH"%s", V_UnqualifiedFileName(pakFilePath)); + snprintf(outPath, outBufLen, PAK_PLATFORM_OVERRIDE_PATH"%s", V_UnqualifiedFileName(pakFilePath)); return FileExists(outPath); } @@ -69,7 +69,7 @@ int Pak_FileExists(const char* const pakFilePath) return true; // check the platform's default path - snprintf(fullPath, sizeof(fullPath), PLATFORM_PAK_PATH"%s", pakFilePath); + snprintf(fullPath, sizeof(fullPath), PAK_PLATFORM_PATH"%s", pakFilePath); return FileExists(fullPath); } @@ -77,26 +77,26 @@ int Pak_FileExists(const char* const pakFilePath) //----------------------------------------------------------------------------- // returns pak status as string //----------------------------------------------------------------------------- -const char* Pak_StatusToString(const EPakStatus status) +const char* Pak_StatusToString(const PakStatus_e status) { switch (status) { - case EPakStatus::PAK_STATUS_FREED: return "PAK_STATUS_FREED"; - case EPakStatus::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING"; - case EPakStatus::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING"; - case EPakStatus::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE"; - case EPakStatus::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING"; - case EPakStatus::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR"; - case EPakStatus::PAK_STATUS_LOAD_PATCH_INIT: return "PAK_STATUS_LOAD_PATCH_INIT"; - case EPakStatus::PAK_STATUS_LOAD_PATCH_EDIT_STREAM: return "PAK_STATUS_LOAD_PATCH_EDIT_STREAM"; - case EPakStatus::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS"; - case EPakStatus::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED"; - case EPakStatus::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING"; - case EPakStatus::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING"; - case EPakStatus::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING"; - case EPakStatus::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR"; - case EPakStatus::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE"; - case EPakStatus::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY"; + case PakStatus_e::PAK_STATUS_FREED: return "PAK_STATUS_FREED"; + case PakStatus_e::PAK_STATUS_LOAD_PENDING: return "PAK_STATUS_LOAD_PENDING"; + case PakStatus_e::PAK_STATUS_REPAK_RUNNING: return "PAK_STATUS_REPAK_RUNNING"; + case PakStatus_e::PAK_STATUS_REPAK_DONE: return "PAK_STATUS_REPAK_DONE"; + case PakStatus_e::PAK_STATUS_LOAD_STARTING: return "PAK_STATUS_LOAD_STARTING"; + case PakStatus_e::PAK_STATUS_LOAD_PAKHDR: return "PAK_STATUS_LOAD_PAKHDR"; + case PakStatus_e::PAK_STATUS_LOAD_PATCH_INIT: return "PAK_STATUS_LOAD_PATCH_INIT"; + case PakStatus_e::PAK_STATUS_LOAD_PATCH_EDIT_STREAM: return "PAK_STATUS_LOAD_PATCH_EDIT_STREAM"; + case PakStatus_e::PAK_STATUS_LOAD_ASSETS: return "PAK_STATUS_LOAD_ASSETS"; + case PakStatus_e::PAK_STATUS_LOADED: return "PAK_STATUS_LOADED"; + case PakStatus_e::PAK_STATUS_UNLOAD_PENDING: return "PAK_STATUS_UNLOAD_PENDING"; + case PakStatus_e::PAK_STATUS_FREE_PENDING: return "PAK_STATUS_FREE_PENDING"; + case PakStatus_e::PAK_STATUS_CANCELING: return "PAK_STATUS_CANCELING"; + case PakStatus_e::PAK_STATUS_ERROR: return "PAK_STATUS_ERROR"; + case PakStatus_e::PAK_STATUS_INVALID_PAKHANDLE: return "PAK_STATUS_INVALID_PAKHANDLE"; + case PakStatus_e::PAK_STATUS_BUSY: return "PAK_STATUS_BUSY"; default: return "PAK_STATUS_UNKNOWN"; } } @@ -104,12 +104,12 @@ const char* Pak_StatusToString(const EPakStatus status) //----------------------------------------------------------------------------- // returns pak decoder as string //----------------------------------------------------------------------------- -const char* Pak_DecoderToString(const EPakDecodeMode mode) +const char* Pak_DecoderToString(const PakDecodeMode_e mode) { switch (mode) { - case EPakDecodeMode::MODE_RTECH: return "RTech"; - case EPakDecodeMode::MODE_ZSTD: return "ZStd"; + case PakDecodeMode_e::MODE_RTECH: return "RTech"; + case PakDecodeMode_e::MODE_ZSTD: return "ZStd"; } UNREACHABLE(); @@ -253,19 +253,19 @@ PakGuid_t Pak_StringToGuid(const char* const string) //----------------------------------------------------------------------------- // gets information about loaded pak file via pak id //----------------------------------------------------------------------------- -PakLoadedInfo_t* Pak_GetPakInfo(const PakHandle_t pakId) +PakLoadedInfo_s* Pak_GetPakInfo(const PakHandle_t pakId) { - return &g_pakGlobals->loadedPaks[pakId & PAK_MAX_HANDLES_MASK]; + return &g_pakGlobals->loadedPaks[pakId & PAK_MAX_LOADED_PAKS_MASK]; } //----------------------------------------------------------------------------- // gets information about loaded pak file via pak name //----------------------------------------------------------------------------- -const PakLoadedInfo_t* Pak_GetPakInfo(const char* const pakName) +const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName) { for (int16_t i = 0; i < g_pakGlobals->loadedPakCount; ++i) { - const PakLoadedInfo_t* const info = &g_pakGlobals->loadedPaks[i]; + const PakLoadedInfo_s* const info = &g_pakGlobals->loadedPaks[i]; if (!info) continue; @@ -285,27 +285,27 @@ const PakLoadedInfo_t* Pak_GetPakInfo(const char* const pakName) //----------------------------------------------------------------------------- // returns a pointer to the patch data header //----------------------------------------------------------------------------- -PakPatchDataHeader_t* Pak_GetPatchDataHeader(PakFileHeader_t* const pakHeader) +PakPatchDataHeader_s* Pak_GetPatchDataHeader(PakFileHeader_s* const pakHeader) { // shouldn't be called if the pak doesn1't have patches! assert(pakHeader->patchIndex > 0); - return reinterpret_cast(reinterpret_cast(pakHeader) + sizeof(PakFileHeader_t)); + return reinterpret_cast(reinterpret_cast(pakHeader) + sizeof(PakFileHeader_s)); } //----------------------------------------------------------------------------- // returns a pointer to the patch file header //----------------------------------------------------------------------------- -PakPatchFileHeader_t* Pak_GetPatchFileHeader(PakFileHeader_t* const pakHeader, const int index) +PakPatchFileHeader_s* Pak_GetPatchFileHeader(PakFileHeader_s* const pakHeader, const int index) { assert(pakHeader->patchIndex > 0 && index < pakHeader->patchIndex); uint8_t* address = reinterpret_cast(pakHeader); // skip the file header - address += sizeof(PakFileHeader_t); + address += sizeof(PakFileHeader_s); // skip the patch data header, the patch file headers start from there - address += sizeof(PakPatchDataHeader_t); - PakPatchFileHeader_t* const patchHeaders = reinterpret_cast(address); + address += sizeof(PakPatchDataHeader_s); + PakPatchFileHeader_s* const patchHeaders = reinterpret_cast(address); return &patchHeaders[index]; } @@ -313,13 +313,13 @@ PakPatchFileHeader_t* Pak_GetPatchFileHeader(PakFileHeader_t* const pakHeader, c //----------------------------------------------------------------------------- // returns the patch number belonging to the index provided //----------------------------------------------------------------------------- -short Pak_GetPatchNumberForIndex(PakFileHeader_t* const pakHeader, const int index) +short Pak_GetPatchNumberForIndex(PakFileHeader_s* const pakHeader, const int index) { assert(pakHeader->patchIndex > 0 && index < pakHeader->patchIndex); const uint8_t* patchHeader = reinterpret_cast(Pak_GetPatchFileHeader(pakHeader, pakHeader->patchIndex - 1)); // skip the last patch file header, the patch number start from there - patchHeader += sizeof(PakPatchFileHeader_t); + patchHeader += sizeof(PakPatchFileHeader_s); const short* patchNumber = reinterpret_cast(patchHeader); return patchNumber[index]; @@ -347,7 +347,7 @@ bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile) // NOTE: we modify the in buffer as the patch headers belong to the // compressed section - PakFileHeader_t* const inHeader = reinterpret_cast(inBuf); + PakFileHeader_s* const inHeader = reinterpret_cast(inBuf); // update each patch header for (uint16_t i = 0; i < inHeader->patchIndex; i++) @@ -371,13 +371,13 @@ bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile) const size_t fileSize = inPatch.GetSize(); // pak appears truncated - if (fileSize <= sizeof(PakFileHeader_t)) + if (fileSize <= sizeof(PakFileHeader_s)) return false; DevMsg(eDLL_T::RTECH, "%s: updating patch header for pak '%s', new size = %zu\n", __FUNCTION__, patchFile, fileSize); - PakPatchFileHeader_t* const patchHeader = Pak_GetPatchFileHeader(inHeader, i); + PakPatchFileHeader_s* const patchHeader = Pak_GetPatchFileHeader(inHeader, i); patchHeader->compressedSize = fileSize; } @@ -387,7 +387,7 @@ bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile) //----------------------------------------------------------------------------- // prints the pak header details to the console //----------------------------------------------------------------------------- -void Pak_ShowHeaderDetails(const PakFileHeader_t* const pakHeader) +void Pak_ShowHeaderDetails(const PakFileHeader_s* const pakHeader) { SYSTEMTIME systemTime; FileTimeToSystemTime(&pakHeader->fileTime, &systemTime); diff --git a/r5dev/rtech/pak/paktools.h b/r5dev/rtech/pak/paktools.h index cd9e5780..becc39a2 100644 --- a/r5dev/rtech/pak/paktools.h +++ b/r5dev/rtech/pak/paktools.h @@ -12,20 +12,20 @@ extern bool Pak_FileOverrideExists(const char* const pakFilePath, char* const ou extern int Pak_FileExists(const char* const pakFilePath); -extern const char* Pak_StatusToString(const EPakStatus status); -const char* Pak_DecoderToString(const EPakDecodeMode mode); +extern const char* Pak_StatusToString(const PakStatus_e status); +const char* Pak_DecoderToString(const PakDecodeMode_e mode); extern PakGuid_t Pak_StringToGuid(const char* const string); -extern PakLoadedInfo_t* Pak_GetPakInfo(const PakHandle_t pakId); -extern const PakLoadedInfo_t* Pak_GetPakInfo(const char* const pakName); +extern PakLoadedInfo_s* Pak_GetPakInfo(const PakHandle_t pakId); +extern const PakLoadedInfo_s* Pak_GetPakInfo(const char* const pakName); -extern PakPatchDataHeader_t* Pak_GetPatchDataHeader(PakFileHeader_t* const pakHeader); -extern PakPatchFileHeader_t* Pak_GetPatchFileHeader(PakFileHeader_t* const pakHeader, const int index); -extern short Pak_GetPatchNumberForIndex(PakFileHeader_t* const pakHeader, const int index); +extern PakPatchDataHeader_s* Pak_GetPatchDataHeader(PakFileHeader_s* const pakHeader); +extern PakPatchFileHeader_s* Pak_GetPatchFileHeader(PakFileHeader_s* const pakHeader, const int index); +extern short Pak_GetPatchNumberForIndex(PakFileHeader_s* const pakHeader, const int index); extern bool Pak_UpdatePatchHeaders(uint8_t* const inBuf, const char* const outPakFile); -extern void Pak_ShowHeaderDetails(const PakFileHeader_t* const pakHeader); +extern void Pak_ShowHeaderDetails(const PakFileHeader_s* const pakHeader); #endif // !RTECH_PAKTOOLS_H diff --git a/r5dev/sdklauncher/CMakeLists.txt b/r5dev/sdklauncher/CMakeLists.txt index 634648ea..1113729e 100644 --- a/r5dev/sdklauncher/CMakeLists.txt +++ b/r5dev/sdklauncher/CMakeLists.txt @@ -3,7 +3,26 @@ add_module( "exe" "sdklauncher" "" ${FOLDER_CONTEXT} TRUE TRUE ) start_sources() +add_sources( SOURCE_GROUP "Foundation" + "${ENGINE_SOURCE_DIR}/tier0/plat_time.cpp" + "${ENGINE_SOURCE_DIR}/public/tier0/platform.h" +) + add_sources( SOURCE_GROUP "Core" + "${ENGINE_SOURCE_DIR}/core/logger.cpp" + "${ENGINE_SOURCE_DIR}/core/logger.h" + "${ENGINE_SOURCE_DIR}/core/logdef.cpp" + "${ENGINE_SOURCE_DIR}/core/logdef.h" + "${ENGINE_SOURCE_DIR}/core/termutil.cpp" + "${ENGINE_SOURCE_DIR}/core/termutil.h" +) + +add_sources( SOURCE_GROUP "Windows" + "${ENGINE_SOURCE_DIR}/windows/console.cpp" + "${ENGINE_SOURCE_DIR}/windows/console.h" +) + +add_sources( SOURCE_GROUP "App" "sdklauncher.cpp" "sdklauncher.h" "sdklauncher_const.h" @@ -41,16 +60,21 @@ set_target_properties( ${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/" ) target_compile_definitions( ${PROJECT_NAME} PRIVATE + "_TOOLS" "SDKLAUNCHER" ) target_precompile_headers( ${PROJECT_NAME} PRIVATE "sdklauncher_pch.h" ) +target_link_options( ${PROJECT_NAME} PRIVATE "/SUBSYSTEM:WINDOWS" ) target_link_libraries( ${PROJECT_NAME} PRIVATE "tier0" "tier1" "tier2" + "filesystem_std" + "vstdlib" + "libdetours" "libcppkore" "libspdlog" diff --git a/r5dev/sdklauncher/advanced_surface.cpp b/r5dev/sdklauncher/advanced_surface.cpp index 8cfd35ad..4b740c3e 100644 --- a/r5dev/sdklauncher/advanced_surface.cpp +++ b/r5dev/sdklauncher/advanced_surface.cpp @@ -6,7 +6,35 @@ #include "advanced_surface.h" #include "sdklauncher.h" #include "mathlib/bits.h" -#include "utility/vdf_parser.h" +#include "vpklib/packedstore.h" +#include "vstdlib/keyvaluessystem.h" +#include "filesystem/filesystem_std.h" +#include "tier2/fileutils.h" + +extern CFileSystem_Stdio* FileSystem(); + +//----------------------------------------------------------------------------- +// Purpose: creates a font by name +//----------------------------------------------------------------------------- +HFONT CreateFontByName(const char* const name, const int size) +{ + return CreateFont( + size, // Height of font + 0, // Width of font + 0, // Angle of escapement + 0, // Orientation angle + FW_NORMAL, // Font weight + FALSE, // Italic + FALSE, // Underline + FALSE, // Strikeout + DEFAULT_CHARSET, // Character set identifier + OUT_DEFAULT_PRECIS, // Output precision + CLIP_DEFAULT_PRECIS, // Clipping precision + DEFAULT_QUALITY, // Output quality + DEFAULT_PITCH | FF_DONTCARE, // Pitch and family + TEXT(name) // Font name + ); +} //----------------------------------------------------------------------------- // Purpose: creates the surface layout @@ -17,6 +45,9 @@ void CAdvancedSurface::Init() const INT WindowX = 800; const INT WindowY = 353; + const HFONT font = (HFONT)CreateFontByName("Microsoft Sans Serif", -11); + this->SetFont(new Drawing::Font(this->_Handle, font, true)); + this->SuspendLayout(); this->SetAutoScaleDimensions({ 6, 13 }); this->SetAutoScaleMode(Forms::AutoScaleMode::Font); @@ -29,7 +60,7 @@ void CAdvancedSurface::Init() this->SetBackColor(Drawing::Color(47, 54, 61)); this->Load += &OnLoad; - this->FormClosing += &OnClose; + this->Closing += &OnClose; // ######################################################################## // GAME @@ -64,6 +95,7 @@ void CAdvancedSurface::Init() this->m_MapCombo->SetLocation({ 15, 25 }); this->m_MapCombo->SetTabIndex(0); this->m_MapCombo->SetSelectedIndex(0); + this->m_MapCombo->DropDownOpened += ReloadMaplists; this->m_MapCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_MapCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList); this->m_GameGroup->AddControl(this->m_MapCombo); @@ -82,6 +114,7 @@ void CAdvancedSurface::Init() this->m_PlaylistCombo->SetLocation({ 15, 50 }); this->m_PlaylistCombo->SetTabIndex(0); this->m_PlaylistCombo->SetSelectedIndex(0); + this->m_PlaylistCombo->DropDownOpened += ReloadPlaylists; this->m_PlaylistCombo->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_PlaylistCombo->SetDropDownStyle(Forms::ComboBoxStyle::DropDownList); this->m_GameGroup->AddControl(this->m_PlaylistCombo); @@ -106,6 +139,11 @@ void CAdvancedSurface::Init() this->m_ConsoleToggle->SetSize({ 110, 18 }); this->m_ConsoleToggle->SetLocation({ 290, 7 }); this->m_ConsoleToggle->SetTabIndex(0); +#ifdef DEDI_LAUNCHER + this->m_ConsoleToggle->SetChecked(true); +#else // For client builds, don't show the console by default + this->m_ConsoleToggle->SetChecked(false); +#endif // DEDI_LAUNCHER this->m_ConsoleToggle->SetText("Show console"); this->m_ConsoleToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_GameGroupExt->AddControl(this->m_ConsoleToggle); @@ -125,7 +163,6 @@ void CAdvancedSurface::Init() this->m_PlaylistFileTextBox->SetTabIndex(0); this->m_PlaylistFileTextBox->SetText("playlists_r5_patch.txt"); this->m_PlaylistFileTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); - this->m_PlaylistFileTextBox->LostFocus += &ReloadPlaylists; this->m_GameGroupExt->AddControl(this->m_PlaylistFileTextBox); this->m_PlaylistFileLabel = new UIX::UIXLabel(); @@ -133,7 +170,7 @@ void CAdvancedSurface::Init() this->m_PlaylistFileLabel->SetLocation({ 311, 32 }); this->m_PlaylistFileLabel->SetTabIndex(0); this->m_PlaylistFileLabel->SetText("Playlists file"); - this->m_PlaylistFileLabel->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left); + this->m_PlaylistFileLabel->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_GameGroupExt->AddControl(this->m_PlaylistFileLabel); // ######################################################################## @@ -379,7 +416,6 @@ void CAdvancedSurface::Init() this->m_WindowedToggle->SetSize({ 105, 18 }); this->m_WindowedToggle->SetLocation({ 15, 7 }); this->m_WindowedToggle->SetTabIndex(0); - this->m_WindowedToggle->SetChecked(true); this->m_WindowedToggle->SetText("Windowed"); this->m_WindowedToggle->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_EngineVideoGroup->AddControl(this->m_WindowedToggle); @@ -416,7 +452,7 @@ void CAdvancedSurface::Init() this->m_WidthTextBox->SetTabIndex(0); this->m_WidthTextBox->SetReadOnly(false); this->m_WidthTextBox->SetText(""); - this->m_WidthTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right); + this->m_WidthTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_EngineVideoGroup->AddControl(this->m_WidthTextBox); this->m_HeightTextBox = new UIX::UIXTextBox(); @@ -425,7 +461,7 @@ void CAdvancedSurface::Init() this->m_HeightTextBox->SetTabIndex(0); this->m_HeightTextBox->SetReadOnly(false); this->m_HeightTextBox->SetText(""); - this->m_HeightTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Right); + this->m_HeightTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_EngineVideoGroup->AddControl(this->m_HeightTextBox); this->m_ResolutionLabel = new UIX::UIXLabel(); @@ -445,7 +481,7 @@ void CAdvancedSurface::Init() this->m_ConsoleGroup->SetLocation({ 359, 160 }); this->m_ConsoleGroup->SetTabIndex(0); this->m_ConsoleGroup->SetText("Console"); - this->m_ConsoleGroup->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleGroup->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->AddControl(this->m_ConsoleGroup); this->m_ConsoleGroupExt = new UIX::UIXGroupBox(); @@ -453,7 +489,7 @@ void CAdvancedSurface::Init() this->m_ConsoleGroupExt->SetLocation({ 359, 174 }); this->m_ConsoleGroupExt->SetTabIndex(0); this->m_ConsoleGroupExt->SetText(""); - this->m_ConsoleGroupExt->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleGroupExt->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->AddControl(this->m_ConsoleGroupExt); this->m_ConsoleListView = new UIX::UIXListView(); @@ -461,7 +497,7 @@ void CAdvancedSurface::Init() this->m_ConsoleListView->SetLocation({ 1, -23 }); // HACK: hide columns this->m_ConsoleListView->SetTabIndex(0); this->m_ConsoleListView->SetBackColor(Drawing::Color(29, 33, 37)); - this->m_ConsoleListView->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left | Forms::AnchorStyles::Right); + this->m_ConsoleListView->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleListView->SetView(Forms::View::Details); this->m_ConsoleListView->SetVirtualMode(true); this->m_ConsoleListView->SetFullRowSelect(true); @@ -477,7 +513,7 @@ void CAdvancedSurface::Init() this->m_ConsoleCommandTextBox->SetTabIndex(0); this->m_ConsoleCommandTextBox->SetReadOnly(false); this->m_ConsoleCommandTextBox->SetText(""); - this->m_ConsoleCommandTextBox->SetAnchor(Forms::AnchorStyles::Bottom | Forms::AnchorStyles::Left); + this->m_ConsoleCommandTextBox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleGroupExt->AddControl(this->m_ConsoleCommandTextBox); this->m_ConsoleSendCommand = new UIX::UIXButton(); @@ -486,7 +522,7 @@ void CAdvancedSurface::Init() this->m_ConsoleSendCommand->SetTabIndex(0); this->m_ConsoleSendCommand->SetText("Send"); this->m_ConsoleSendCommand->SetBackColor(Drawing::Color(3, 102, 214)); - this->m_ConsoleSendCommand->SetAnchor(Forms::AnchorStyles::None); + this->m_ConsoleSendCommand->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left); this->m_ConsoleSendCommand->Click += &ForwardCommandToGame; this->m_ConsoleGroupExt->AddControl(this->m_ConsoleSendCommand); @@ -494,6 +530,8 @@ void CAdvancedSurface::Init() this->PerformLayout(); // END DESIGNER CODE + + this->Setup(); } //----------------------------------------------------------------------------- @@ -501,6 +539,8 @@ void CAdvancedSurface::Init() //----------------------------------------------------------------------------- void CAdvancedSurface::Setup() { + // Already parse these out since you can scroll select in a combo box + // without uncollapsing it. this->ParseMaps(); this->ParsePlaylists(); @@ -522,97 +562,60 @@ void CAdvancedSurface::Setup() //----------------------------------------------------------------------------- void CAdvancedSurface::LoadSettings() { - const fs::path settingsPath(Format("platform/%s/%s", SDK_SYSTEM_CFG_PATH, LAUNCHER_SETTING_FILE)); - if (!fs::exists(settingsPath)) + CUtlString settingsPath; + settingsPath.Format("platform/" SDK_SYSTEM_CFG_PATH "%s", LAUNCHER_SETTING_FILE); + + const char* pSettingsPath = settingsPath.String(); + + if (!FileSystem()->FileExists(pSettingsPath)) + return; + + KeyValues kv("LauncherSettings"); + + if (!kv.LoadFromFile(FileSystem(), pSettingsPath, nullptr)) { + printf("%s: Failed to parse VDF file: '%s'\n", __FUNCTION__, pSettingsPath); return; } - bool success{ }; - std::ifstream fileStream(settingsPath, fstream::in); - vdf::object vRoot = vdf::read(fileStream, &success); + const int settingsVersion = kv.GetInt("version", -1); - if (!success) - { - printf("%s: Failed to parse VDF file: '%s'\n", __FUNCTION__, - settingsPath.u8string().c_str()); + if (settingsVersion != SDK_LAUNCHER_VERSION) return; - } - try + KeyValues* sv = kv.FindKey("vars"); + + if (!sv) { - string& attributeView = vRoot.attribs["version"]; - - int settingsVersion = atoi(attributeView.c_str()); - if (settingsVersion != SDK_LAUNCHER_VERSION) - return; - - vdf::object* pSubKey = vRoot.childs["vars"].get(); - if (!pSubKey) - return; - - // Game. - attributeView = pSubKey->attribs["playlistsFile"]; - this->m_PlaylistFileTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["enableCheats"]; - this->m_CheatsToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["enableDeveloper"]; - this->m_DeveloperToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["enableConsole"]; - this->m_ConsoleToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["colorConsole"]; - this->m_ColorConsoleToggle->SetChecked(attributeView != "0"); - - // Engine. - attributeView = pSubKey->attribs["reservedCoreCount"]; - this->m_ReservedCoresTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["workerThreadCount"]; - this->m_WorkerThreadsTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["processorAffinity"]; - this->m_ProcessorAffinityTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["noAsync"]; // No-async - this->m_NoAsyncJobsToggle->SetChecked(attributeView != "0"); - - // Network. - attributeView = pSubKey->attribs["encryptPackets"]; - this->m_NetEncryptionToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["randomNetKey"]; - this->m_NetRandomKeyToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["queuedPackets"]; - this->m_QueuedPacketThread->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["noTimeOut"]; - this->m_NoTimeOutToggle->SetChecked(attributeView != "0"); - - // Video. - attributeView = pSubKey->attribs["windowed"]; - this->m_WindowedToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["borderless"]; - this->m_NoBorderToggle->SetChecked(attributeView != "0"); - - attributeView = pSubKey->attribs["maxFPS"]; - this->m_FpsTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["width"]; - this->m_WidthTextBox->SetText(attributeView.data()); - - attributeView = pSubKey->attribs["height"]; - this->m_HeightTextBox->SetText(attributeView.data()); - } - catch (const std::exception& e) - { - printf("%s: Exception while parsing VDF file: %s\n", __FUNCTION__, e.what()); + printf("%s: VDF file '%s' lacks subkey: '%s'\n", __FUNCTION__, pSettingsPath, "vars"); + return; // No settings to apply } + + // Game. + this->m_PlaylistFileTextBox->SetText(sv->GetString("playlistsFile")); + this->m_CheatsToggle->SetChecked(sv->GetBool("enableCheats")); + this->m_DeveloperToggle->SetChecked(sv->GetBool("enableDeveloper")); + this->m_ConsoleToggle->SetChecked(sv->GetBool("enableConsole")); + this->m_ColorConsoleToggle->SetChecked(sv->GetBool("colorConsole")); + + // Engine. + this->m_ReservedCoresTextBox->SetText(sv->GetString("reservedCoreCount", "-1")); + this->m_WorkerThreadsTextBox->SetText(sv->GetString("workerThreadCount", "-1")); + this->m_ProcessorAffinityTextBox->SetText(sv->GetString("processorAffinity", "0")); + this->m_NoAsyncJobsToggle->SetChecked(sv->GetBool("noAsync")); + + // Network. + this->m_NetEncryptionToggle->SetChecked(sv->GetBool("encryptPackets", true)); + this->m_NetRandomKeyToggle->SetChecked(sv->GetBool("randomNetKey", true)); + this->m_QueuedPacketThread->SetChecked(sv->GetBool("queuedPackets", true)); + this->m_NoTimeOutToggle->SetChecked(sv->GetBool("noTimeOut")); + + // Video. + this->m_WindowedToggle->SetChecked(sv->GetBool("windowed")); + this->m_NoBorderToggle->SetChecked(sv->GetBool("borderless")); + this->m_FpsTextBox->SetText(sv->GetString("fpsMax", "-1")); + this->m_WidthTextBox->SetText(sv->GetString("width")); + this->m_HeightTextBox->SetText(sv->GetString("height")); } //----------------------------------------------------------------------------- @@ -620,60 +623,69 @@ void CAdvancedSurface::LoadSettings() //----------------------------------------------------------------------------- void CAdvancedSurface::SaveSettings() { - const fs::path settingsPath(Format("platform/%s/%s", SDK_SYSTEM_CFG_PATH, LAUNCHER_SETTING_FILE)); - const fs::path parentPath = settingsPath.parent_path(); + CUtlString settingsPath; + settingsPath.Format("platform/" SDK_SYSTEM_CFG_PATH "%s", LAUNCHER_SETTING_FILE); - if (!fs::exists(parentPath) && !fs::create_directories(parentPath)) + CUtlString settingsDir = settingsPath.DirName(); + + const char* pSettingsPath = settingsPath.String(); + const char* pSettingsDir = settingsDir.String(); + + FileSystem()->CreateDirHierarchy(pSettingsDir); + + if (!FileSystem()->IsDirectory(pSettingsDir)) { - printf("%s: Failed to create directory: '%s'\n", __FUNCTION__, - parentPath.relative_path().u8string().c_str()); + printf("%s: Failed to create directory: '%s'\n", __FUNCTION__, pSettingsPath); return; } - std::ofstream fileStream(settingsPath, fstream::out); - if (!fileStream) + KeyValues kv("LauncherSettings"); + kv.SetInt("version", SDK_LAUNCHER_VERSION); + + KeyValues* sv = new KeyValues("vars"); + + if (!sv) { - printf("%s: Failed to create VDF file: '%s'\n", __FUNCTION__, - settingsPath.u8string().c_str()); - return; + printf("%s: Failed to allocate subkey: '%s'\n", __FUNCTION__, "vars"); + return; // No settings to apply } - vdf::object vRoot; - vRoot.set_name("LauncherSettings"); - vRoot.add_attribute("version", std::to_string(SDK_LAUNCHER_VERSION)); - - vdf::object* vVars = new vdf::object(); - vVars->set_name("vars"); + kv.AddSubKey(sv); // Game. - vVars->add_attribute("playlistsFile", GetControlValue(this->m_PlaylistFileTextBox)); - vVars->add_attribute("enableCheats", GetControlValue(this->m_CheatsToggle)); - vVars->add_attribute("enableDeveloper", GetControlValue(this->m_DeveloperToggle)); - vVars->add_attribute("enableConsole", GetControlValue(this->m_ConsoleToggle)); - vVars->add_attribute("colorConsole", GetControlValue(this->m_ColorConsoleToggle)); + sv->SetString("playlistsFile", this->m_PlaylistFileTextBox->Text().ToCString()); + sv->SetBool("enableCheats", this->m_CheatsToggle->Checked()); + sv->SetBool("enableDeveloper", this->m_DeveloperToggle->Checked()); + sv->SetBool("enableConsole", this->m_ConsoleToggle->Checked()); + sv->SetBool("colorConsole", this->m_ColorConsoleToggle->Checked()); // Engine. - vVars->add_attribute("reservedCoreCount", GetControlValue(this->m_ReservedCoresTextBox)); - vVars->add_attribute("workerThreadCount", GetControlValue(this->m_WorkerThreadsTextBox)); - vVars->add_attribute("processorAffinity", GetControlValue(this->m_ProcessorAffinityTextBox)); - vVars->add_attribute("noAsync", GetControlValue(this->m_NoAsyncJobsToggle)); + sv->SetString("reservedCoreCount", this->m_ReservedCoresTextBox->Text().ToCString()); + sv->SetString("workerThreadCount", this->m_WorkerThreadsTextBox->Text().ToCString()); + sv->SetString("processorAffinity", this->m_ProcessorAffinityTextBox->Text().ToCString()); + sv->SetBool("noAsync", this->m_NoAsyncJobsToggle->Checked()); // Network. - vVars->add_attribute("encryptPackets", GetControlValue(this->m_NetEncryptionToggle)); - vVars->add_attribute("randomNetKey", GetControlValue(this->m_NetRandomKeyToggle)); - vVars->add_attribute("queuedPackets", GetControlValue(this->m_QueuedPacketThread)); - vVars->add_attribute("noTimeOut", GetControlValue(this->m_NoTimeOutToggle)); + sv->SetBool("encryptPackets", this->m_NetEncryptionToggle->Checked()); + sv->SetBool("randomNetKey", this->m_NetRandomKeyToggle->Checked()); + sv->SetBool("queuedPackets", this->m_QueuedPacketThread->Checked()); + sv->SetBool("noTimeOut", this->m_NoTimeOutToggle->Checked()); // Video. - vVars->add_attribute("windowed", GetControlValue(this->m_WindowedToggle)); - vVars->add_attribute("borderless", GetControlValue(this->m_NoBorderToggle)); - vVars->add_attribute("maxFPS", GetControlValue(this->m_FpsTextBox)); - vVars->add_attribute("width", GetControlValue(this->m_WidthTextBox)); - vVars->add_attribute("height", GetControlValue(this->m_HeightTextBox)); + sv->SetBool("windowed", this->m_WindowedToggle->Checked()); + sv->SetBool("borderless", this->m_NoBorderToggle->Checked()); + sv->SetString("fpsMax", this->m_FpsTextBox->Text().ToCString()); + sv->SetString("width", this->m_WidthTextBox->Text().ToCString()); + sv->SetString("height", this->m_HeightTextBox->Text().ToCString()); - vRoot.add_child(std::unique_ptr(vVars)); + CUtlBuffer outBuf(ssize_t(0), 0, CUtlBuffer::TEXT_BUFFER); + kv.RecursiveSaveToFile(outBuf, 0); - vdf::write(fileStream, vRoot); + if (!FileSystem()->WriteFile(pSettingsPath, "PLATFORM", outBuf)) + { + printf("%s: Failed to create VDF file: '%s'\n", __FUNCTION__, pSettingsPath); + return; + } } //----------------------------------------------------------------------------- @@ -700,10 +712,7 @@ void CAdvancedSurface::OnClose(const std::unique_ptr& /*pE //----------------------------------------------------------------------------- void CAdvancedSurface::CleanSDK(Forms::Control* pSender) { - CAdvancedSurface* pSurface = reinterpret_cast(pSender->FindForm()); - pSurface->m_LogList.push_back(LogList_t(spdlog::level::info, "Running cleaner for SDK installation\n")); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - + Msg(eDLL_T::COMMON, "Running cleaner for SDK installation\n"); std::system("bin\\clean_sdk.bat"); } @@ -713,10 +722,7 @@ void CAdvancedSurface::CleanSDK(Forms::Control* pSender) //----------------------------------------------------------------------------- void CAdvancedSurface::UpdateSDK(Forms::Control* pSender) { - CAdvancedSurface* pSurface = reinterpret_cast(pSender->FindForm()); - pSurface->m_LogList.push_back(LogList_t(spdlog::level::info, "Running updater for SDK installation\n")); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - + Msg(eDLL_T::COMMON, "Running updater for SDK installation\n"); std::system("bin\\update_sdk.bat"); } @@ -726,20 +732,16 @@ void CAdvancedSurface::UpdateSDK(Forms::Control* pSender) //----------------------------------------------------------------------------- void CAdvancedSurface::LaunchGame(Forms::Control* pSender) { - CAdvancedSurface* pSurface = reinterpret_cast(pSender->FindForm()); - - pSurface->m_LogList.clear(); // Clear console. - pSurface->m_ConsoleListView->SetVirtualListSize(0); - pSurface->m_ConsoleListView->Refresh(); - + CSurface* pSurface = reinterpret_cast(pSender->FindForm()); string svParameter; + pSurface->AppendParameterInternal(svParameter, "-launcher"); - eLaunchMode launchMode = pSurface->BuildParameter(svParameter); + eLaunchMode launchMode = SDKLauncher()->BuildParameter(svParameter); uint64_t nProcessorAffinity = pSurface->GetProcessorAffinity(svParameter); - if (g_pLauncher->CreateLaunchContext(launchMode, nProcessorAffinity, svParameter.c_str(), "startup_launcher.cfg")) - g_pLauncher->LaunchProcess(); + if (SDKLauncher()->CreateLaunchContext(launchMode, nProcessorAffinity, svParameter.c_str(), "startup_launcher.cfg")) + SDKLauncher()->LaunchProcess(); } //----------------------------------------------------------------------------- @@ -747,29 +749,33 @@ void CAdvancedSurface::LaunchGame(Forms::Control* pSender) //----------------------------------------------------------------------------- void CAdvancedSurface::ParseMaps() { + if (!m_MapCombo->Items.Contains("")) + m_MapCombo->Items.Add(""); + const fs::path vpkPath("vpk"); + if (!fs::exists(vpkPath)) { return; } fs::directory_iterator directoryIterator(vpkPath); - std::regex archiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" }; - std::smatch regexMatches; + std::cmatch regexMatches; - m_MapCombo->Items.Add(""); for (const fs::directory_entry& directoryEntry : directoryIterator) { std::string fileName = directoryEntry.path().u8string(); - std::regex_search(fileName, regexMatches, archiveRegex); + std::regex_search(fileName.c_str(), regexMatches, g_VpkDirFileRegex); if (!regexMatches.empty()) { - if (regexMatches[1].str().compare("frontend") == 0) + const std::sub_match& match = regexMatches[2]; + + if (match.compare("frontend") == 0) { continue; } - else if (regexMatches[1].str().compare("mp_common") == 0) + else if (match.compare("mp_common") == 0) { if (!this->m_MapCombo->Items.Contains("mp_lobby")) { @@ -777,9 +783,14 @@ void CAdvancedSurface::ParseMaps() } continue; } - else if (!this->m_MapCombo->Items.Contains(regexMatches[1].str().c_str())) + else { - this->m_MapCombo->Items.Add(regexMatches[1].str().c_str()); + const string mapName = match.str(); + + if (!this->m_MapCombo->Items.Contains(match.str().c_str())) + { + this->m_MapCombo->Items.Add(match.str().c_str()); + } } } } @@ -790,41 +801,53 @@ void CAdvancedSurface::ParseMaps() //----------------------------------------------------------------------------- void CAdvancedSurface::ParsePlaylists() { - fs::path playlistPath(Format("platform\\%s", this->m_PlaylistFileTextBox->Text().ToCString())); - m_PlaylistCombo->Items.Add(""); + if (!m_PlaylistCombo->Items.Contains("")) + m_PlaylistCombo->Items.Add(""); - if (!fs::exists(playlistPath)) + CUtlString playlistPath; + playlistPath.Format("platform\\%s", this->m_PlaylistFileTextBox->Text().ToCString()); + + const char* pPlaylistPath = playlistPath.String(); + + if (!FileSystem()->FileExists(pPlaylistPath)) + return; + + KeyValues kv("playlists"); + + if (!kv.LoadFromFile(FileSystem(), pPlaylistPath, nullptr)) { + printf("%s: Failed to parse playlists file: '%s'\n", __FUNCTION__, pPlaylistPath); return; } - bool success{ }; - std::ifstream iFile(playlistPath); - vdf::object vRoot = vdf::read(iFile, &success); + KeyValues* playlists = kv.FindKey("Playlists"); - if (!success) - { - printf("%s: Failed to parse VDF file: '%s'\n", __FUNCTION__, - playlistPath.u8string().c_str()); - return; - } + if (!playlists) + return; // Empty playlists - try + for (KeyValues* pSubKey = playlists->GetFirstTrueSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextTrueSubKey()) { - const auto& vcPlaylists = vRoot.childs.at("Playlists"); - for (auto [id, it] = std::tuplechilds.begin())> - { 1, vcPlaylists->childs.begin() }; it != vcPlaylists->childs.end(); id++, it++) + const char* keyName = pSubKey->GetName(); + + if (!this->m_PlaylistCombo->Items.Contains(keyName)) { - if (!this->m_PlaylistCombo->Items.Contains(it->first.c_str())) - { - this->m_PlaylistCombo->Items.Add(it->first.c_str()); - } + this->m_PlaylistCombo->Items.Add(keyName); } } - catch (const std::exception& e) - { - printf("%s: Exception while parsing VDF file: %s\n", __FUNCTION__, e.what()); - } +} + +//----------------------------------------------------------------------------- +// Purpose: clears the form and reloads the map list +// Input : *pSender - +//----------------------------------------------------------------------------- +void CSurface::ReloadMaplists(Forms::Control* pSender) +{ + CSurface* pSurface = reinterpret_cast(pSender->FindForm()); + + pSurface->m_MapCombo->Items.Clear(); + pSurface->m_MapCombo->OnSizeChanged(); + + pSurface->ParseMaps(); } //----------------------------------------------------------------------------- @@ -837,9 +860,30 @@ void CAdvancedSurface::ReloadPlaylists(Forms::Control* pSender) pSurface->m_PlaylistCombo->Items.Clear(); pSurface->m_PlaylistCombo->OnSizeChanged(); + pSurface->ParsePlaylists(); } +//----------------------------------------------------------------------------- +// Purpose: adds a log to the surface console +// Input : type - +// Input : *pszText - +//----------------------------------------------------------------------------- +void CSurface::AddLog(const LogType_t type, const char* const pszText) +{ + m_LogList.push_back(LogList_t(type, pszText)); + + // Clamp the log list size, as we cannot fit more elements than + // 8 in the console window. + while (m_LogList.size() > 8) + { + m_LogList.erase(m_LogList.begin()); + } + + m_ConsoleListView->SetVirtualListSize(static_cast(m_LogList.size())); + m_ConsoleListView->Refresh(); +} + //----------------------------------------------------------------------------- // Purpose: copies selected virtual items to clipboard // Input : &pEventArgs - @@ -880,30 +924,34 @@ void CAdvancedSurface::GetVirtualItem(const std::unique_ptrSubItemIndex) { case 0: - pEventArgs->Style.ForeColor = cColor[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; - pEventArgs->Text = svLevel[pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; + pEventArgs->Style.ForeColor = cColor[(int)pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; + pEventArgs->Text = svLevel[(int)pSurface->m_LogList[pEventArgs->ItemIndex].m_nLevel]; break; case 1: pEventArgs->Text = pSurface->m_LogList[pEventArgs->ItemIndex].m_svText; @@ -926,7 +974,11 @@ void CAdvancedSurface::ForwardCommandToGame(Forms::Control* pSender) if (vecHandles.empty()) return; - const string kzCommand = pSurface->m_ConsoleCommandTextBox->Text().ToCString(); + const String kzCommand = pSurface->m_ConsoleCommandTextBox->Text(); + + if (String::IsNullOrEmpty(kzCommand)) + return; + bool bSuccess = false; for (const HWND hWindow : vecHandles) @@ -934,7 +986,7 @@ void CAdvancedSurface::ForwardCommandToGame(Forms::Control* pSender) char szWindowName[256]; GetWindowTextA(hWindow, szWindowName, 256); - COPYDATASTRUCT cData = { 0, (DWORD)(std::min)(kzCommand.size(), (size_t)259) + 1, (void*)kzCommand.c_str() }; + COPYDATASTRUCT cData = { 0, (DWORD)(std::min)(kzCommand.Length(), (uint32_t)259) + 1, (void*)kzCommand.ToCString() }; bool bProcessingMessage = SendMessageA(hWindow, WM_COPYDATA, NULL, (LPARAM)&cData); // WM_COPYDATA will only return 0 or 1, that's why we use a boolean. if (bProcessingMessage && !bSuccess) { @@ -944,9 +996,7 @@ void CAdvancedSurface::ForwardCommandToGame(Forms::Control* pSender) if (bSuccess) // At least one game instance received the command. { - pSurface->m_LogList.push_back(LogList_t((spdlog::level::level_enum)2, kzCommand)); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - pSurface->m_ConsoleListView->Refresh(); + pSurface->AddLog(LogType_t::LOG_INFO, Format("Sent command: %s\n", kzCommand.ToCString()).c_str()); pSurface->m_ConsoleCommandTextBox->SetText(""); } } @@ -994,6 +1044,8 @@ void CAdvancedSurface::AppendConsoleParameters(string& svParameters) { if (this->m_ConsoleToggle->Checked()) AppendParameterInternal(svParameters, "-wconsole"); + else + AppendParameterInternal(svParameters, "-noconsole"); if (this->m_ColorConsoleToggle->Checked()) AppendParameterInternal(svParameters, "-ansicolor"); @@ -1275,33 +1327,67 @@ uint64_t CAdvancedSurface::GetProcessorAffinity(string& svParameters) return nProcessorAffinity; } -//----------------------------------------------------------------------------- -// Purpose: gets the control item value -// Input : *pControl - -//----------------------------------------------------------------------------- -const char* CAdvancedSurface::GetControlValue(Forms::Control* pControl) -{ - switch (pControl->GetType()) - { - case Forms::ControlTypes::CheckBox: - case Forms::ControlTypes::RadioButton: - { - return reinterpret_cast(pControl)->Checked() ? "1" : "0"; - } - default: - { - return pControl->Text().ToCString(); - } - } -} - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CAdvancedSurface::CAdvancedSurface() : Forms::Form() { - this->Init(); - this->Setup(); -} + // Game. + m_GameGroup = nullptr; + m_GameGroupExt = nullptr; + m_MapLabel = nullptr; + m_MapCombo = nullptr; + m_PlaylistLabel = nullptr; + m_PlaylistCombo = nullptr; + m_CheatsToggle = nullptr; + m_DeveloperToggle = nullptr; + m_ConsoleToggle = nullptr; + m_ColorConsoleToggle = nullptr; + m_PlaylistFileTextBox = nullptr; + m_PlaylistFileLabel = nullptr; -CAdvancedSurface* g_pMainUI; \ No newline at end of file + // Main. + m_MainGroup = nullptr; + m_MainGroupExt = nullptr; + m_ModeCombo = nullptr; + m_ModeLabel = nullptr; + m_HostNameTextBox = nullptr; + m_HostNameLabel = nullptr; + m_VisibilityCombo = nullptr; + m_VisibilityLabel = nullptr; + m_LaunchArgsTextBox = nullptr; + m_LaunchArgsLabel = nullptr; + m_CleanSDK = nullptr; + m_UpdateSDK = nullptr; + m_LaunchSDK = nullptr; + + // Engine. + m_EngineBaseGroup = nullptr; + m_EngineNetworkGroup = nullptr; + m_EngineVideoGroup = nullptr; + m_ReservedCoresTextBox = nullptr; + m_ReservedCoresLabel = nullptr; + m_WorkerThreadsTextBox = nullptr; + m_WorkerThreadsLabel = nullptr; + m_ProcessorAffinityTextBox = nullptr; + m_ProcessorAffinityLabel = nullptr; + m_NoAsyncJobsToggle = nullptr; + m_NetEncryptionToggle = nullptr; + m_NetRandomKeyToggle = nullptr; + m_QueuedPacketThread = nullptr; + m_NoTimeOutToggle = nullptr; + m_WindowedToggle = nullptr; + m_NoBorderToggle = nullptr; + m_FpsTextBox = nullptr; + m_FpsLabel = nullptr; + m_WidthTextBox = nullptr; + m_HeightTextBox = nullptr; + m_ResolutionLabel = nullptr; + + // Console. + m_ConsoleGroup = nullptr; + m_ConsoleGroupExt = nullptr; + m_ConsoleListView = nullptr; + m_ConsoleCommandTextBox = nullptr; + m_ConsoleSendCommand = nullptr; +} diff --git a/r5dev/sdklauncher/advanced_surface.h b/r5dev/sdklauncher/advanced_surface.h index 3f13903f..ef56fae5 100644 --- a/r5dev/sdklauncher/advanced_surface.h +++ b/r5dev/sdklauncher/advanced_surface.h @@ -2,13 +2,13 @@ struct LogList_t { - LogList_t(const spdlog::level::level_enum nLevel, const string& svText) + LogList_t(const LogType_t nLevel, const string& svText) { m_nLevel = nLevel; m_svText = svText; } - spdlog::level::level_enum m_nLevel; + LogType_t m_nLevel; string m_svText; }; @@ -19,8 +19,12 @@ public: UIX::UIXListView* ConsoleListView() const { return m_ConsoleListView; }; std::vector m_LogList; -private: void Init(); + void AddLog(const LogType_t type, const char* const pszText); + + eLaunchMode BuildParameter(string& svParameter); + +private: void Setup(); void LoadSettings(); void SaveSettings(); @@ -33,16 +37,16 @@ private: static void LaunchGame(Forms::Control* pSender); static void CleanSDK(Forms::Control* pSender); static void UpdateSDK(Forms::Control* pSender); + + static void ReloadMaplists(Forms::Control* pSender); static void ReloadPlaylists(Forms::Control* pSender); + static void VirtualItemToClipboard(const std::unique_ptr& pEventArgs, Forms::Control* pSender); static void GetVirtualItem(const std::unique_ptr& pEventArgs, Forms::Control* pSender); static void ForwardCommandToGame(Forms::Control* pSender); - const char* GetControlValue(Forms::Control* pControl); uint64_t GetProcessorAffinity(string& szParameter); - eLaunchMode BuildParameter(string& svParameter); - void AppendParameterInternal(string& svParameterList, const char* szParameter, const char* szArgument = nullptr); void AppendProcessorParameters(string& svParameter); void AppendConsoleParameters(string& svParameter); diff --git a/r5dev/sdklauncher/sdklauncher.cpp b/r5dev/sdklauncher/sdklauncher.cpp index ec8ebb25..b577de44 100644 --- a/r5dev/sdklauncher/sdklauncher.cpp +++ b/r5dev/sdklauncher/sdklauncher.cpp @@ -3,6 +3,9 @@ // Purpose: SDK launcher implementation. // //=============================================================================// +#include "core/logger.h" +#include "core/logdef.h" +#include "tier0/cpu.h" #include "tier0/binstream.h" #include "tier1/fmtstr.h" #include "base_surface.h" @@ -10,6 +13,51 @@ #include "sdklauncher.h" #include "sdklauncher_utils.h" +#include "windows/console.h" +#include "vstdlib/keyvaluessystem.h" +#include "filesystem/filesystem_std.h" + +static CKeyValuesSystem s_KeyValuesSystem; +static CFileSystem_Stdio s_FullFileSystem; +static CLauncher s_Launcher; + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: keyvalues singleton accessor +/////////////////////////////////////////////////////////////////////////////// +IKeyValuesSystem* KeyValuesSystem() +{ + return &s_KeyValuesSystem; +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: filesystem singleton accessor +/////////////////////////////////////////////////////////////////////////////// +CFileSystem_Stdio* FileSystem() +{ + return &s_FullFileSystem; +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: launcher singleton accessor. +/////////////////////////////////////////////////////////////////////////////// +CLauncher* SDKLauncher() +{ + return &s_Launcher; +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: launcher logger sink +/////////////////////////////////////////////////////////////////////////////// +void LauncherLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context, + const char* pszLogger, const char* pszFormat, va_list args, + const UINT exitCode /*= NO_ERROR*/, const char* pszUptimeOverride /*= nullptr*/) +{ + const string buffer = FormatV(pszFormat, args); + + SDKLauncher()->AddLog(logType, buffer.c_str()); + EngineLoggerSink(logType, logLevel, context, pszLogger, pszFormat, args, exitCode, pszUptimeOverride); +} + /////////////////////////////////////////////////////////////////////////////// // Purpose: initializes and runs the user interface /////////////////////////////////////////////////////////////////////////////// @@ -18,30 +66,42 @@ void CLauncher::RunSurface() Forms::Application::EnableVisualStyles(); UIX::UIXTheme::InitializeRenderer(new Themes::KoreTheme()); - m_pSurface = new CBaseSurface(); - Forms::Application::Run(g_pLauncher->m_pSurface); + m_pSurface = new CAdvancedSurface(); + m_pSurface->Init(); + + Forms::Application::Run(m_pSurface, true); UIX::UIXTheme::ShutdownRenderer(); } /////////////////////////////////////////////////////////////////////////////// -// Purpose: initializes the console (development only) +// Purpose: initializes the launcher /////////////////////////////////////////////////////////////////////////////// -void CLauncher::InitConsole() +void CLauncher::Init() { - AllocConsole(); - freopen("conin$", "r", stdin); - freopen("conout$", "w", stdout); - freopen("conout$", "w", stderr); + g_CoreMsgVCallback = &LauncherLoggerSink; // Setup logger callback sink. + + // Init time. + Plat_FloatTime(); + SpdLog_Init(true); } /////////////////////////////////////////////////////////////////////////////// -// Purpose: initializes the logger +// Purpose: de-initializes the launcher /////////////////////////////////////////////////////////////////////////////// -void CLauncher::InitLogger() +void CLauncher::Shutdown() { - m_pLogger->set_pattern("[%^%l%$] %v"); - m_pLogger->set_level(spdlog::level::trace); - spdlog::set_default_logger(m_pLogger); // Set as default. + SpdLog_Shutdown(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Purpose: adds a log to the surface console +/////////////////////////////////////////////////////////////////////////////// +void CLauncher::AddLog(const LogType_t level, const char* szText) +{ + if (m_pSurface) + { + m_pSurface->AddLog(level, szText); + } } /////////////////////////////////////////////////////////////////////////////// @@ -105,13 +165,13 @@ int CLauncher::HandleCommandLine(int argc, char* argv[]) /////////////////////////////////////////////////////////////////////////////// int CLauncher::HandleInput() { - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::warn, "The '%s' options are for development purposes; use the '%s' options for default usage.\n", "DEV", "PROD"); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::info, "%-6s ('0' = %s | '1' = %s).\n", "GAME", "DEV", "PROD"); - AddLog(spdlog::level::level_enum::info, "%-6s ('2' = %s | '3' = %s).\n", "SERVER", "DEV", "PROD"); - AddLog(spdlog::level::level_enum::info, "%-6s ('4' = %s | '5' = %s).\n", "CLIENT", "DEV", "PROD"); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Warning(eDLL_T::COMMON, "The '%s' options are for development purposes; use the '%s' options for default usage.\n", "DEV", "PROD"); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Msg(eDLL_T::COMMON, "%-6s ('0' = %s | '1' = %s).\n", "GAME", "DEV", "PROD"); + Msg(eDLL_T::COMMON, "%-6s ('2' = %s | '3' = %s).\n", "SERVER", "DEV", "PROD"); + Msg(eDLL_T::COMMON, "%-6s ('4' = %s | '5' = %s).\n", "CLIENT", "DEV", "PROD"); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); std::cout << "User input: "; std::string input; @@ -127,17 +187,24 @@ int CLauncher::HandleInput() } else { - AddLog(spdlog::level::level_enum::err, "Invalid mode (range 0-5).\n"); + Error(eDLL_T::COMMON, 0, "Invalid mode (range 0-5).\n"); + Sleep(2500); + return EXIT_FAILURE; } } catch (const std::exception& e) { - AddLog(spdlog::level::level_enum::err, "SDK Launcher only takes numerical input (error = %s).\n", e.what()); + Error(eDLL_T::COMMON, 0, "SDK Launcher only takes numerical input (error = %s).\n", e.what()); + Sleep(2500); + return EXIT_FAILURE; } } - AddLog(spdlog::level::level_enum::err, "SDK Launcher requires numerical input.\n"); + + Error(eDLL_T::COMMON, 0, "SDK Launcher requires numerical input.\n"); + Sleep(2500); + return EXIT_FAILURE; } @@ -214,14 +281,13 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, uint64_t nProcessorAffini } default: { - AddLog(spdlog::level::level_enum::err, "No launch mode specified.\n"); + Error(eDLL_T::COMMON, 0, "No launch mode specified.\n"); return false; } } SetupLaunchContext(szConfig, szGameDLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING %s [%s] ***\n", - szContext, szLevel); + Msg(eDLL_T::COMMON, "*** LAUNCHING %s [%s] ***\n", szContext, szLevel); return true; } @@ -236,20 +302,19 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, uint64_t nProcessorAffini void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, const char* szCommandLine) { CIOStream cfgFile; + + CFmtStrN<1024> cfgFileName; CFmtStrMax commandLine; if (szConfig && szConfig[0]) { - commandLine.Format(GAME_CFG_PATH"%s", szConfig); + cfgFileName.Format(GAME_CFG_PATH"%s", szConfig); - if (cfgFile.Open(commandLine.String(), CIOStream::READ)) + if (cfgFile.Open(cfgFileName.String(), CIOStream::READ)) { - // Reuse the stack string for the actual command line buffer. - commandLine.Clear(); - if (!cfgFile.ReadString(commandLine.Access(), commandLine.GetMaxLength())) { - AddLog(spdlog::level::level_enum::err, "Failed to read file '%s'!\n", szConfig); + Error(eDLL_T::COMMON, 0, "Failed to read file '%s'!\n", szConfig); } else { @@ -258,7 +323,7 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, } else // Failed to open config file. { - AddLog(spdlog::level::level_enum::err, "Failed to open file '%s'!\n", szConfig); + Error(eDLL_T::COMMON, 0, "Failed to open file '%s'!\n", szConfig); } } @@ -272,11 +337,11 @@ void CLauncher::SetupLaunchContext(const char* szConfig, const char* szGameDll, /////////////////////////////////////////////////////////////////////////// // Print the file paths and arguments. - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::debug, "- CWD: %s\n", m_svCurrentDir.c_str()); - AddLog(spdlog::level::level_enum::debug, "- EXE: %s\n", m_svGameDll.c_str()); - AddLog(spdlog::level::level_enum::debug, "- CLI: %s\n", commandLine.String()); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); + Msg(eDLL_T::COMMON, "- CWD: %s\n", m_svCurrentDir.c_str()); + Msg(eDLL_T::COMMON, "- EXE: %s\n", m_svGameDll.c_str()); + Msg(eDLL_T::COMMON, "- CLI: %s\n", commandLine.String()); + Msg(eDLL_T::NONE, "--------------------------------------------------------------------------------------------------------------\n"); } /////////////////////////////////////////////////////////////////////////////// @@ -435,40 +500,47 @@ void RunGUI() /////////////////////////////////////////////////////////////////////////////// // EntryPoint. /////////////////////////////////////////////////////////////////////////////// -int main(int argc, char* argv[]/*, char* envp[]*/) +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) { + CheckSystemCPUForSSE2(); + // Only 1 instance at a time. if (SDKLauncher_ForceExistingInstanceOnTop()) { return EXIT_SUCCESS; } - g_pLauncher->InitLogger(); - if (argc < 2) + if (__argc < 2) { - RunGUI(); +#ifdef _DEBUG + Console_Init(true); +#endif // _DEBUG + SDKLauncher()->Init(); + SDKLauncher()->RunSurface(); + SDKLauncher()->Shutdown(); +#ifdef _DEBUG + Console_Shutdown(); +#endif // _DEBUG } else { - int results = g_pLauncher->HandleCommandLine(argc, argv); - if (results == -1) - { - return g_pLauncher->HandleInput(); - } - else if (results == -2) - { - RunGUI(); - } - else - { - return results; - } + if (!Console_Init(true)) + return EXIT_FAILURE; + + SDKLauncher()->Init(); + + int cmdRet = SDKLauncher()->HandleCommandLine(__argc, __argv); + + if (cmdRet == -1) + cmdRet = SDKLauncher()->HandleInput(); + + SDKLauncher()->Shutdown(); + + if (!Console_Shutdown()) + return EXIT_FAILURE; + + return cmdRet; } return EXIT_SUCCESS; } - -/////////////////////////////////////////////////////////////////////////////// -// Singleton Launcher. -/////////////////////////////////////////////////////////////////////////////// -CLauncher* g_pLauncher(new CLauncher("win_console")); diff --git a/r5dev/sdklauncher/sdklauncher.h b/r5dev/sdklauncher/sdklauncher.h index d96c59c7..dc6c29b2 100644 --- a/r5dev/sdklauncher/sdklauncher.h +++ b/r5dev/sdklauncher/sdklauncher.h @@ -6,43 +6,22 @@ class CLauncher { public: - CLauncher(const char* pszLoggerName) + CLauncher() { - m_pSurface = nullptr; - m_pLogger = spdlog::stdout_color_mt(pszLoggerName); + m_pSurface = nullptr; m_ProcessorAffinity = NULL; m_svCurrentDir = fs::current_path().u8string(); } ~CLauncher() { - if (m_pSurface) - { - delete m_pSurface; - } - } - - void AddLog(spdlog::level::level_enum nLevel, const char* szFormat, ...) - { - string svBuffer; - va_list args; - va_start(args, szFormat); - svBuffer = FormatV(szFormat, args); - va_end(args); - - m_pLogger->log(nLevel, svBuffer); - m_pLogger->flush(); - - //if (m_pSurface) - //{ - // m_pSurface->m_LogList.push_back(LogList_t(nLevel, svBuffer)); - // m_pSurface->ConsoleListView()->SetVirtualListSize(static_cast(m_pSurface->m_LogList.size())); - // m_pSurface->ConsoleListView()->Refresh(); - //} } void RunSurface(); - void InitConsole(); - void InitLogger(); + + void Init(); + void Shutdown(); + + void AddLog(const LogType_t level, const char* szText); int HandleCommandLine(int argc, char* argv[]); int HandleInput(); @@ -52,11 +31,10 @@ public: bool LaunchProcess() const; bool LaunchGameDefault() const; - CBaseSurface* GetMainSurface() const { return m_pSurface; } + eLaunchMode BuildParameter(string& parameterList) { return m_pSurface->BuildParameter(parameterList); } private: - CBaseSurface* m_pSurface; - std::shared_ptr m_pLogger; + CAdvancedSurface* m_pSurface; uint64_t m_ProcessorAffinity; @@ -67,4 +45,4 @@ private: BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam); -extern CLauncher* g_pLauncher; +extern CLauncher* SDKLauncher(); diff --git a/r5dev/sdklauncher/sdklauncher_const.h b/r5dev/sdklauncher/sdklauncher_const.h index 67d6f07f..0d655a50 100644 --- a/r5dev/sdklauncher/sdklauncher_const.h +++ b/r5dev/sdklauncher/sdklauncher_const.h @@ -1,7 +1,7 @@ #pragma once // Change this each time the settings format has changed. -#define SDK_LAUNCHER_VERSION 1 +#define SDK_LAUNCHER_VERSION 3 // Uncomment this line to compile the launcher for dedicated server builds. //#define DEDI_LAUNCHER diff --git a/r5dev/thirdparty/cppnet/cppkore/Application.cpp b/r5dev/thirdparty/cppnet/cppkore/Application.cpp index b69886eb..d01b8801 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Application.cpp +++ b/r5dev/thirdparty/cppnet/cppkore/Application.cpp @@ -11,7 +11,7 @@ namespace Forms std::atomic Application::IsGdipInitialized = false; ULONG_PTR Application::GdipToken = NULL; - void Application::Run(Form* MainWindow) + void Application::Run(Form* MainWindow, bool DeleteWindow) { if (MainWindow == nullptr) return; @@ -27,7 +27,7 @@ namespace Forms // Execute on the main loop Application::RunMainLoop(MainWindow); - if (MainWindow) + if (MainWindow && DeleteWindow) delete MainWindow; // Shutdown COM diff --git a/r5dev/thirdparty/cppnet/cppkore/Application.h b/r5dev/thirdparty/cppnet/cppkore/Application.h index 8ab073fb..df1e32d7 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Application.h +++ b/r5dev/thirdparty/cppnet/cppkore/Application.h @@ -12,7 +12,7 @@ namespace Forms public: // Begins running a standard application message loop on the current // thread, and makes the specified form visible. - static void Run(Form* MainWindow); + static void Run(Form* MainWindow, bool DeleteWindow); // Begins running a dialog application loop on the // current thread, you MUST clean up the dialog after use. diff --git a/r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp b/r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp index a9b1dcfe..a0e7669d 100644 --- a/r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp +++ b/r5dev/thirdparty/cppnet/cppkore/ComboBox.cpp @@ -283,6 +283,11 @@ namespace Forms SelectedIndexChanged.RaiseEvent(this); } + void ComboBox::OnDropDownOpened() + { + DropDownOpened.RaiseEvent(this); + } + void ComboBox::OnDropDownClosed() { DropDownClosed.RaiseEvent(this); @@ -412,6 +417,8 @@ namespace Forms OnSelectedIndexChanged(); OnSelectedItemChanged(); break; + case CBN_DROPDOWN: + OnDropDownOpened(); case CBN_CLOSEUP: OnDropDownClosed(); break; diff --git a/r5dev/thirdparty/cppnet/cppkore/ComboBox.h b/r5dev/thirdparty/cppnet/cppkore/ComboBox.h index d5632b50..538a168d 100644 --- a/r5dev/thirdparty/cppnet/cppkore/ComboBox.h +++ b/r5dev/thirdparty/cppnet/cppkore/ComboBox.h @@ -134,11 +134,13 @@ namespace Forms virtual void OnHandleCreated(); virtual void OnSelectedItemChanged(); virtual void OnSelectedIndexChanged(); + virtual void OnDropDownOpened(); virtual void OnDropDownClosed(); // We must define event handlers here EventBase SelectedItemChanged; EventBase SelectedIndexChanged; + EventBase DropDownOpened; EventBase DropDownClosed; // Override WndProc for specific combo box messages. diff --git a/r5dev/thirdparty/cppnet/cppkore/Control.cpp b/r5dev/thirdparty/cppnet/cppkore/Control.cpp index e52fa063..d3ce62e5 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Control.cpp +++ b/r5dev/thirdparty/cppnet/cppkore/Control.cpp @@ -231,8 +231,13 @@ namespace Forms SetWindowLongPtrA(this->_Handle, GWLP_USERDATA, (intptr_t)this); // Setup the default font if none was previously set + if (this->_Font == nullptr) - this->_Font = std::make_unique(this->_Handle, (HFONT)GetStockObject(DEFAULT_GUI_FONT)); + if (this->_Parent && this->_Parent->_Font) + this->_Font = std::make_unique(this->_Handle, this->_Parent->_Font.get()->GetFontHandle()); + else + this->_Font = std::make_unique(this->_Handle, (HFONT)GetStockObject(DEFAULT_GUI_FONT)); + // Notify the window of the font selection SendMessageA(this->_Handle, WM_SETFONT, (WPARAM)this->_Font->GetFontHandle(), NULL); @@ -720,6 +725,11 @@ namespace Forms return this->_RTTI; } + uint32_t Control::GetControlCount() + { + return this->_Controls->Count(); + } + Control* Control::FindForm() { auto Cur = this; diff --git a/r5dev/thirdparty/cppnet/cppkore/Control.h b/r5dev/thirdparty/cppnet/cppkore/Control.h index 15a19e50..978b70c2 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Control.h +++ b/r5dev/thirdparty/cppnet/cppkore/Control.h @@ -146,7 +146,7 @@ namespace Forms // Retrieves the current font for this control. Drawing::Font* GetFont(); - // Retrieves the current font for this control. + // Sets the current font for this control. void SetFont(Drawing::Font* Font); // The parent of this control. @@ -209,6 +209,8 @@ namespace Forms HWND GetHandle(); // Returns the type of this control ControlTypes GetType(); + // Returns the number of child controls + uint32_t GetControlCount(); // Retrieves the form that the control is on. Control* FindForm(); diff --git a/r5dev/thirdparty/cppnet/cppkore/Font.cpp b/r5dev/thirdparty/cppnet/cppkore/Font.cpp index c3739fb7..0b5a7aa2 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Font.cpp +++ b/r5dev/thirdparty/cppnet/cppkore/Font.cpp @@ -3,8 +3,8 @@ namespace Drawing { - Font::Font(HWND Handle, const HFONT hFont) - : _Handle(Handle), _NativeFont(hFont), _OwnsFont(false) + Font::Font(HWND Handle, const HFONT hFont, const bool OwnsFont) + : _Handle(Handle), _NativeFont(hFont), _OwnsFont(OwnsFont) { } diff --git a/r5dev/thirdparty/cppnet/cppkore/Font.h b/r5dev/thirdparty/cppnet/cppkore/Font.h index c8fdaf23..e616ab5c 100644 --- a/r5dev/thirdparty/cppnet/cppkore/Font.h +++ b/r5dev/thirdparty/cppnet/cppkore/Font.h @@ -10,7 +10,7 @@ namespace Drawing { public: Font() = default; - Font(HWND Handle, const HFONT hFont); + Font(HWND Handle, const HFONT hFont, const bool OwnsFont = false); Font(HWND Handle, const Gdiplus::Font& FontObject); virtual ~Font(); diff --git a/r5dev/thirdparty/imgui/misc/imgui_logger.cpp b/r5dev/thirdparty/imgui/misc/imgui_logger.cpp index 4e3721ed..88696a26 100644 --- a/r5dev/thirdparty/imgui/misc/imgui_logger.cpp +++ b/r5dev/thirdparty/imgui/misc/imgui_logger.cpp @@ -765,6 +765,7 @@ void CTextLogger::Render() ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); ImGuiWindow* const pWindow = ImGui::GetCurrentWindow(); + const ImGuiStyle& style = ImGui::GetStyle(); const ImGuiID activeID = ImGui::GetActiveID(); const ImGuiID hoveredID = ImGui::GetHoveredID(); @@ -878,7 +879,8 @@ void CTextLogger::Render() // This dummy is here to let Dear ImGui know where the last character of // the line had ended, so that it could properly process the horizontal // scrollbar - ImGui::Dummy(ImVec2((longest + 2), m_Lines.size() * m_CharAdvance.y)); + const float additional = pWindow->ScrollbarY ? style.ScrollbarSize : 0.0f; + ImGui::Dummy(ImVec2(longest + additional, m_Lines.size() * m_CharAdvance.y)); m_bScrolledToStart = ImGui::GetScrollX() == 0.0f; diff --git a/r5dev/thirdparty/zstd/CMakeLists.txt b/r5dev/thirdparty/zstd/CMakeLists.txt index 9f500816..36e490ee 100644 --- a/r5dev/thirdparty/zstd/CMakeLists.txt +++ b/r5dev/thirdparty/zstd/CMakeLists.txt @@ -94,5 +94,6 @@ thirdparty_suppress_warnings() target_compile_definitions( ${PROJECT_NAME} PRIVATE "ZSTD_MULTITHREAD" + "ZSTD_NO_FORWARD_PROGRESS_MAX=1024" "DEBUGLEVEL=0" ) diff --git a/r5dev/tier0/cpu.cpp b/r5dev/tier0/cpu.cpp index 7393b4bd..82df6979 100644 --- a/r5dev/tier0/cpu.cpp +++ b/r5dev/tier0/cpu.cpp @@ -575,7 +575,7 @@ const CPUInformation& GetCPUInformation(void) return pi; } -void CheckSystemCPU() +void CheckSystemCPUForSSE2() { const CPUInformation& pi = GetCPUInformation(); @@ -586,6 +586,12 @@ void CheckSystemCPU() TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF); } } +} + +void CheckSystemCPUForSSE3() +{ + const CPUInformation& pi = GetCPUInformation(); + if (!pi.m_bSSE3) { if (MessageBoxA(NULL, "SSE3 is required.", "Unsupported CPU", MB_ICONERROR | MB_OK)) @@ -593,6 +599,12 @@ void CheckSystemCPU() TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF); } } +} + +void CheckSystemCPUForSupplementalSSE3() +{ + const CPUInformation& pi = GetCPUInformation(); + if (!pi.m_bSSSE3) { if (MessageBoxA(NULL, "SSSE3 (Supplemental SSE3 Instructions) is required.", "Unsupported CPU", MB_ICONERROR | MB_OK)) @@ -600,6 +612,12 @@ void CheckSystemCPU() TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF); } } +} + +void CheckSystemCPUForPopCount() +{ + const CPUInformation& pi = GetCPUInformation(); + if (!pi.m_bPOPCNT) { if (MessageBoxA(NULL, "POPCNT is required.", "Unsupported CPU", MB_ICONERROR | MB_OK)) @@ -608,3 +626,11 @@ void CheckSystemCPU() } } } + +void CheckSystemCPU() +{ + CheckSystemCPUForSSE2(); + CheckSystemCPUForSSE3(); + CheckSystemCPUForSupplementalSSE3(); + CheckSystemCPUForPopCount(); +} diff --git a/r5dev/tier0/cpu.h b/r5dev/tier0/cpu.h index 4425c486..0e03beb4 100644 --- a/r5dev/tier0/cpu.h +++ b/r5dev/tier0/cpu.h @@ -130,6 +130,11 @@ const char* GetProcessorBrand(bool bRemovePadding); const CPUInformation& GetCPUInformation(void); +void CheckSystemCPUForSSE2(); +void CheckSystemCPUForSSE3(); +void CheckSystemCPUForSupplementalSSE3(); +void CheckSystemCPUForPopCount(); + void CheckSystemCPU(); #endif // CPU_H diff --git a/r5dev/tier1/NetKey.cpp b/r5dev/tier1/NetKey.cpp index b84f4f3a..38bdf48f 100644 --- a/r5dev/tier1/NetKey.cpp +++ b/r5dev/tier1/NetKey.cpp @@ -10,6 +10,5 @@ ////////////////////////////////////////////////////////////////////// const char* CNetKey::GetBase64NetKey(void) const { - // TODO: should we not acquire lock for m_Mutex here? return m_szBase64; } diff --git a/r5dev/tier1/strtools.cpp b/r5dev/tier1/strtools.cpp index 59e76e79..885fe152 100644 --- a/r5dev/tier1/strtools.cpp +++ b/r5dev/tier1/strtools.cpp @@ -503,8 +503,15 @@ int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes cchResult = wcstombs(pUTF8, pUnicode, cubDestSizeInBytes); #endif - if (cubDestSizeInBytes > 0) - pUTF8[cubDestSizeInBytes - 1] = 0; + if (cchResult <= 0 || cchResult > cubDestSizeInBytes) + { + if (cchResult != cubDestSizeInBytes || pUTF8[cubDestSizeInBytes - 1] != '\0') + { + *pUTF8 = '\0'; + } + } + else + pUTF8[cchResult] = '\0'; return cchResult; } @@ -1248,6 +1255,26 @@ const char* V_UnqualifiedFileName(const char* in) return out; } +const wchar_t* V_UnqualifiedFileName(const wchar_t* in) +{ + Assert(in); + + const wchar_t* out = in; + + while (*in) + { + if (PATHSEPARATORW(*in)) + { + // +1 to skip the slash + out = in + 1; + } + + in++; + } + + return out; +} + //----------------------------------------------------------------------------- // Purpose: Composes a path and filename together, inserting a path separator // if need be diff --git a/r5dev/tier2/CMakeLists.txt b/r5dev/tier2/CMakeLists.txt index 3cff30a8..8d3b33ed 100644 --- a/r5dev/tier2/CMakeLists.txt +++ b/r5dev/tier2/CMakeLists.txt @@ -4,6 +4,7 @@ add_module( "lib" "tier2" "vpc" ${FOLDER_CONTEXT} TRUE TRUE ) start_sources() add_sources( SOURCE_GROUP "Utility" + "cryptutils.cpp" "curlutils.cpp" "fileutils.cpp" "meshutils.cpp" @@ -22,11 +23,12 @@ add_sources( SOURCE_GROUP "Public" end_sources() target_include_directories( ${PROJECT_NAME} PRIVATE - "${ENGINE_SOURCE_DIR}/tier0/" + "${ENGINE_SOURCE_DIR}/tier0/" "${ENGINE_SOURCE_DIR}/tier1/" ) target_include_directories( ${PROJECT_NAME} PRIVATE + "${THIRDPARTY_SOURCE_DIR}/mbedtls/include" "${THIRDPARTY_SOURCE_DIR}/dirtysdk/include/" "${THIRDPARTY_SOURCE_DIR}/ea/" ) diff --git a/r5dev/tier2/cryptutils.cpp b/r5dev/tier2/cryptutils.cpp new file mode 100644 index 00000000..18b28ed4 --- /dev/null +++ b/r5dev/tier2/cryptutils.cpp @@ -0,0 +1,88 @@ +//===========================================================================// +// +// Purpose: A set of utilities to perform encryption/decryption +// +//===========================================================================// +#include "mbedtls/aes.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/gcm.h" + +#include "tier2/cryptutils.h" + +static BCRYPT_ALG_HANDLE s_algorithmProvider; +bool Plat_GenerateRandom(unsigned char* buffer, const uint32_t bufferSize, const char*& errorMsg) +{ + if (!s_algorithmProvider && (BCryptOpenAlgorithmProvider(&s_algorithmProvider, L"RNG", 0, 0) < 0)) + { + errorMsg = "Failed to open rng algorithm"; + return false; + } + + if (BCryptGenRandom(s_algorithmProvider, buffer, bufferSize, 0) < 0) + { + errorMsg = "Failed to generate random data"; + return false; + } + + return true; +} + +bool Crypto_GenerateIV(CryptoContext_s& ctx, const unsigned char* const data, const size_t size) +{ + mbedtls_entropy_context entropy; + mbedtls_entropy_init(&entropy); + + mbedtls_ctr_drbg_context drbg; + mbedtls_ctr_drbg_init(&drbg); + + const int seedRet = mbedtls_ctr_drbg_seed(&drbg, mbedtls_entropy_func, &entropy, data, size); + int randRet = MBEDTLS_ERR_ERROR_GENERIC_ERROR; + + if (seedRet == 0) + { + randRet = mbedtls_ctr_drbg_random(&drbg, ctx.ivData, sizeof(ctx.ivData)); + } + + mbedtls_ctr_drbg_free(&drbg); + mbedtls_entropy_free(&entropy); + + return randRet == 0; +} + +static bool Crypto_CTRCrypt(CryptoContext_s& ctx, const unsigned char* const inBuf, + unsigned char* const outBuf, const unsigned char* const key, const size_t size) +{ + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + + int cryptRet = MBEDTLS_ERR_ERROR_GENERIC_ERROR; + const int setRet = mbedtls_aes_setkey_enc(&aes, key, ctx.keyBits); + + if (setRet == 0) + { + unsigned char nonceCounter[16]; + unsigned char streamBlock[16]; + + size_t offset = 0; + memcpy(nonceCounter, ctx.ivData, sizeof(nonceCounter)); + + cryptRet = mbedtls_aes_crypt_ctr(&aes, size, &offset, nonceCounter, streamBlock, inBuf, outBuf); + } + + mbedtls_aes_free(&aes); + return cryptRet == 0; +} + +bool Crypto_CTREncrypt(CryptoContext_s& ctx, const unsigned char* const inBuf, unsigned char* const outBuf, + const unsigned char* const key, const size_t size) +{ + return Crypto_CTRCrypt(ctx, inBuf, outBuf, key, size); +} + +bool Crypto_CTRDecrypt(CryptoContext_s& ctx, const unsigned char* const inBuf, unsigned char* const outBuf, + const unsigned char* const key, const size_t size) +{ + return Crypto_CTRCrypt(ctx, inBuf, outBuf, key, size); +} diff --git a/r5dev/tier2/renderutils.cpp b/r5dev/tier2/renderutils.cpp index 67e5addc..05cabcec 100644 --- a/r5dev/tier2/renderutils.cpp +++ b/r5dev/tier2/renderutils.cpp @@ -69,7 +69,7 @@ void DebugDrawCylinder(const Vector3D& vOrigin, const QAngle& vAngles, float flR float flDegrees = 360.f / float(nSides); QAngle vComposed; Vector3D vForward; - vector vvPoints; + CUtlVector vecPoints(0, nSides); AngleVectors(vAngles, &vForward); @@ -79,13 +79,13 @@ void DebugDrawCylinder(const Vector3D& vOrigin, const QAngle& vAngles, float flR AngleCompose(vAngles, { 0.f, 0.f, flDegrees * i }, vComposed); AngleVectors(vComposed, nullptr, &right, nullptr); - vvPoints.push_back(vOrigin + (right * flRadius)); + vecPoints.AddToTail(vOrigin + (right * flRadius)); } for (int i = 0; i < nSides; i++) { - Vector3D vStart = vvPoints[i]; - Vector3D vEnd = i == 0 ? vvPoints[nSides - 1] : vvPoints[i - 1]; + Vector3D vStart = vecPoints[i]; + Vector3D vEnd = i == 0 ? vecPoints[nSides - 1] : vecPoints[i - 1]; v_RenderLine(vStart, vEnd, color, bZBuffer); v_RenderLine(vStart + (vForward * flHeight), vEnd + (vForward * flHeight), color, bZBuffer); diff --git a/r5dev/vpklib/packedstore.cpp b/r5dev/vpklib/packedstore.cpp index 29a402cf..0b86d005 100644 --- a/r5dev/vpklib/packedstore.cpp +++ b/r5dev/vpklib/packedstore.cpp @@ -35,9 +35,6 @@ extern CFileSystem_Stdio* FileSystem(); -static const std::regex s_DirFileRegex{ R"((?:.*\/)?([^_]*)(?:_)(.*)(.bsp.pak000_dir).*)" }; -static const std::regex s_BlockFileRegex{ R"(pak000_([0-9]{3}))" }; - //----------------------------------------------------------------------------- // Purpose: gets the LZHAM compression level // output : lzham_compress_level @@ -98,7 +95,7 @@ CUtlString PackedStore_GetDirBaseName(const CUtlString& dirFileName) const char* baseFileName = V_UnqualifiedFileName(dirFileName.String()); std::cmatch regexMatches; - std::regex_search(baseFileName, regexMatches, s_DirFileRegex); + std::regex_search(baseFileName, regexMatches, g_VpkDirFileRegex); CUtlString result; result.Format("%s_%s", regexMatches[1].str().c_str(), regexMatches[2].str().c_str()); @@ -117,7 +114,7 @@ CUtlString PackedStore_GetDirNameParts(const CUtlString& dirFileName, const int const char* baseFileName = V_UnqualifiedFileName(dirFileName.String()); std::cmatch regexMatches; - std::regex_search(baseFileName, regexMatches, s_DirFileRegex); + std::regex_search(baseFileName, regexMatches, g_VpkDirFileRegex); return regexMatches[nCaptureGroup].str().c_str(); } @@ -463,7 +460,7 @@ void CPackedStoreBuilder::PackStore(const VPKPair_t& vpkPair, const char* worksp return; } - std::unique_ptr pEntryBuffer(new uint8_t[ENTRY_MAX_LEN]); + std::unique_ptr pEntryBuffer(new uint8_t[VPK_ENTRY_MAX_LEN]); if (!pEntryBuffer) { @@ -587,8 +584,8 @@ void CPackedStoreBuilder::UnpackStore(const VPKDir_t& vpkDir, const char* worksp workspacePath.AppendSlash(); workspacePath.FixSlashes('/'); - std::unique_ptr pDestBuffer(new uint8_t[ENTRY_MAX_LEN]); - std::unique_ptr pSourceBuffer(new uint8_t[ENTRY_MAX_LEN]); + std::unique_ptr pDestBuffer(new uint8_t[VPK_ENTRY_MAX_LEN]); + std::unique_ptr pSourceBuffer(new uint8_t[VPK_ENTRY_MAX_LEN]); if (!pDestBuffer || !pSourceBuffer) { @@ -652,7 +649,7 @@ void CPackedStoreBuilder::UnpackStore(const VPKDir_t& vpkDir, const char* worksp continue; } - size_t nDstLen = ENTRY_MAX_LEN; + size_t nDstLen = VPK_ENTRY_MAX_LEN; assert(fragment.m_nCompressedSize <= nDstLen); if (fragment.m_nCompressedSize > nDstLen) @@ -747,13 +744,13 @@ VPKEntryBlock_t::VPKEntryBlock_t(const uint8_t* pData, size_t nLen, int64_t nOff m_EntryPath.FixSlashes('/'); - size_t nFragmentCount = (nLen + ENTRY_MAX_LEN - 1) / ENTRY_MAX_LEN; + size_t nFragmentCount = (nLen + VPK_ENTRY_MAX_LEN - 1) / VPK_ENTRY_MAX_LEN; size_t nFileSize = nLen; int64_t nCurrentOffset = nOffset; for (size_t i = 0; i < nFragmentCount; i++) // Fragment data into 1 MiB chunks. { - size_t nSize = std::min(ENTRY_MAX_LEN, nFileSize); + size_t nSize = std::min(VPK_ENTRY_MAX_LEN, nFileSize); nFileSize -= nSize; m_Fragments.AddToTail(VPKChunkDescriptor_t(nLoadFlags, nTextureFlags, nCurrentOffset, nSize, nSize)); nCurrentOffset += nSize; @@ -802,15 +799,7 @@ VPKChunkDescriptor_t::VPKChunkDescriptor_t(uint32_t nLoadFlags, uint16_t nTextur //----------------------------------------------------------------------------- VPKPair_t::VPKPair_t(const char* pLocale, const char* pTarget, const char* pLevel, int nPatch) { - bool bFoundLocale = false; - - for (size_t i = 0; i < SDK_ARRAYSIZE(g_LanguageNames); i++) - { - if (V_strcmp(pLocale, g_LanguageNames[i]) == NULL) - { - bFoundLocale = true; - } - } + const bool bFoundLocale = V_LocaleNameExists(pLocale); if (!bFoundLocale) { @@ -818,20 +807,12 @@ VPKPair_t::VPKPair_t(const char* pLocale, const char* pTarget, const char* pLeve pLocale = g_LanguageNames[0]; } - bool bFoundTarget = false; - - for (size_t i = 0; i < SDK_ARRAYSIZE(DIR_TARGET); i++) - { - if (V_strcmp(pTarget, DIR_TARGET[i]) == NULL) - { - bFoundTarget = true; - } - } + const bool bFoundTarget = V_GameTargetExists(pTarget); if (!bFoundTarget) { - Warning(eDLL_T::FS, "Target '%s' not supported; using default '%s'\n", pTarget, DIR_TARGET[STORE_TARGET_SERVER]); - pTarget = DIR_TARGET[STORE_TARGET_SERVER]; + Warning(eDLL_T::FS, "Target '%s' not supported; using default '%s'\n", pTarget, g_GameDllTargets[STORE_TARGET_SERVER]); + pTarget = g_GameDllTargets[STORE_TARGET_SERVER]; } m_PackName.Format("%s_%s.bsp.pak000_%03d.vpk", pTarget, pLevel, nPatch); @@ -862,7 +843,7 @@ VPKDir_t::VPKDir_t(const CUtlString& dirFilePath, bool bSanitizeName) } std::cmatch regexMatches; - std::regex_search(dirFilePath.String(), regexMatches, s_BlockFileRegex); + std::regex_search(dirFilePath.String(), regexMatches, g_VpkPackFileRegex); if (regexMatches.empty()) // Not a block file, or not following the naming scheme. { @@ -902,9 +883,9 @@ VPKDir_t::VPKDir_t(const CUtlString& dirFilePath, bool bSanitizeName) CUtlString packDirToSearch; packDirToSearch.Append(g_LanguageNames[i]); - for (size_t j = 0; j < SDK_ARRAYSIZE(DIR_TARGET); j++) + for (size_t j = 0; j < SDK_ARRAYSIZE(g_GameDllTargets); j++) { - const char* targetName = DIR_TARGET[j]; + const char* targetName = g_GameDllTargets[j]; if (sanitizedName.Find(targetName) != -1) { diff --git a/r5dev/vpklib/packedstore.h b/r5dev/vpklib/packedstore.h index d065f24a..aa79feea 100644 --- a/r5dev/vpklib/packedstore.h +++ b/r5dev/vpklib/packedstore.h @@ -1,6 +1,4 @@ -#ifndef PACKEDSTORE_H -#define PACKEDSTORE_H -/******************************************************************* +/******************************************************************* * ██████╗ ██╗ ██╗ ██╗██████╗ ██╗ ██╗ ██╗ ██╗██████╗ * * ██╔══██╗███║ ██║ ██║██╔══██╗██║ ██╔╝ ██║ ██║██╔══██╗ * * ██████╔╝╚██║ ██║ ██║██████╔╝█████╔╝ ██║ ██║██████╔╝ * @@ -8,6 +6,10 @@ * ██║ ██║ ██║ ╚████╔╝ ██║ ██║ ██╗ ███████╗██║██████╔╝ * * ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝╚═════╝ * *******************************************************************/ +#ifndef PACKEDSTORE_H +#define PACKEDSTORE_H + +#include "public/const.h" #include "public/ipackedstore.h" #include "public/ifilesystem.h" #include "public/tier1/strtools.h" @@ -19,17 +21,14 @@ constexpr unsigned int VPK_HEADER_MARKER = 0x55AA1234; constexpr unsigned int VPK_MAJOR_VERSION = 2; constexpr unsigned int VPK_MINOR_VERSION = 3; constexpr unsigned int VPK_DICT_SIZE = 20; -constexpr int ENTRY_MAX_LEN = 1024 * 1024; +constexpr unsigned int VPK_ENTRY_MAX_LEN = 1024 * 1024; constexpr int PACKFILEPATCH_MAX = 512; constexpr int PACKFILEINDEX_SEP = 0x0; constexpr int PACKFILEINDEX_END = 0xffff; constexpr const char VPK_IGNORE_FILE[] = ".vpkignore"; -static const char* const DIR_TARGET[] -{ - "server", - "client" -}; +static const std::regex g_VpkDirFileRegex{ R"((?:.*\/)?([^_]*)(?:_)(.*)(.bsp.pak000_dir).*)" }; +static const std::regex g_VpkPackFileRegex{ R"(pak000_([0-9]{3}))" }; //----------------------------------------------------------------------------- // KeyValues structure for the VPK manifest file. This struct gets populated by @@ -131,6 +130,15 @@ struct VPKDirHeader_t uint16_t m_nMinorVersion; // Vpk minor version. uint32_t m_nDirectorySize; // Directory tree size. uint32_t m_nSignatureSize; // Directory signature. + + VPKDirHeader_t() + { + m_nHeaderMarker = 0; + m_nMajorVersion = 0; + m_nMinorVersion = 0; + m_nDirectorySize = 0; + m_nSignatureSize = 0; + } }; //----------------------------------------------------------------------------- diff --git a/r5dev/vscript/CMakeLists.txt b/r5dev/vscript/CMakeLists.txt index f7c28ec1..ff13f9a6 100644 --- a/r5dev/vscript/CMakeLists.txt +++ b/r5dev/vscript/CMakeLists.txt @@ -23,6 +23,7 @@ add_sources( SOURCE_GROUP "Squirrel_RE/squirrel" "languages/squirrel_re/squirrel/sqstring.cpp" "languages/squirrel_re/squirrel/sqtable.cpp" "languages/squirrel_re/squirrel/sqmem.cpp" + "languages/squirrel_re/squirrel/sqstate.cpp" "languages/squirrel_re/squirrel/sqvm.cpp" ) diff --git a/r5dev/vscript/languages/squirrel_re/include/sqstate.h b/r5dev/vscript/languages/squirrel_re/include/sqstate.h index 1adbf85a..1d6c600f 100644 --- a/r5dev/vscript/languages/squirrel_re/include/sqstate.h +++ b/r5dev/vscript/languages/squirrel_re/include/sqstate.h @@ -13,6 +13,10 @@ struct RefTable { SQUnsignedInteger refs; struct RefNode* next; }; + void AddRef(SQObject& obj); + SQBool Release(SQObject& obj); + + RefTable::RefNode* Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add); private: SQUnsignedInteger _numofslots; SQUnsignedInteger _slotused; @@ -71,13 +75,13 @@ struct SQBufState { const SQChar* buf; const SQChar* bufTail; - const SQChar* bufCopy; + const SQChar* bufPos; SQBufState(const SQChar* code) { buf = code; bufTail = code + strlen(code); - bufCopy = code; + bufPos = code; } }; #endif // SQSTATE_H \ No newline at end of file diff --git a/r5dev/vscript/languages/squirrel_re/include/squirrel.h b/r5dev/vscript/languages/squirrel_re/include/squirrel.h index 6b5c5b64..74a268cb 100644 --- a/r5dev/vscript/languages/squirrel_re/include/squirrel.h +++ b/r5dev/vscript/languages/squirrel_re/include/squirrel.h @@ -47,6 +47,9 @@ to the following restrictions: #define _SC(a) a +#define SQTrue (1) +#define SQFalse (0) + typedef long SQInteger; typedef unsigned long SQUnsignedInteger; typedef short SQShort; @@ -64,6 +67,8 @@ typedef SQInteger SQRESULT; typedef int ScriptDataType_t; typedef struct SQVM* HSQUIRRELVM; +//typedef SQObject HSQOBJECT; + struct SQBufState; typedef char SQChar; @@ -170,6 +175,8 @@ SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* thread); SQRESULT sq_getstring(HSQUIRRELVM v, SQInteger idx, const SQChar** c); SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx); SQInteger sq_gettop(HSQUIRRELVM v); +SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po); +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop); SQRESULT sq_pushroottable(HSQUIRRELVM v); void sq_pushbool(HSQUIRRELVM v, SQBool b); void sq_pushstring(HSQUIRRELVM v, const SQChar* string, SQInteger len); @@ -180,12 +187,15 @@ void sq_newtable(HSQUIRRELVM v); SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx); SQRESULT sq_arrayappend(HSQUIRRELVM v, SQInteger idx); SQRESULT sq_pushstructure(HSQUIRRELVM v, const SQChar* name, const SQChar* member, const SQChar* codeclass1, const SQChar* codeclass2); -SQRESULT sq_compilebuffer(HSQUIRRELVM v, SQBufState* bufferState, const SQChar* buffer, SQInteger context); +SQRESULT sq_compilebuffer(HSQUIRRELVM v, SQBufState* bufferState, const SQChar* buffer, SQInteger context, SQBool raiseerror); SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror); SQRESULT sq_startconsttable(HSQUIRRELVM v); SQRESULT sq_endconsttable(HSQUIRRELVM v); +void sq_addref(HSQUIRRELVM v, SQObject* po); +SQBool sq_release(HSQUIRRELVM v, SQObject* po); + /*UTILITY MACRO*/ #define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) #define sq_istable(o) ((o)._type==OT_TABLE) @@ -218,7 +228,7 @@ inline void(*v_sq_newtable)(HSQUIRRELVM v); inline SQRESULT(*v_sq_newslot)(HSQUIRRELVM v, SQInteger idx); inline SQRESULT(*v_sq_arrayappend)(HSQUIRRELVM v, SQInteger idx); inline SQRESULT(*v_sq_pushstructure)(HSQUIRRELVM v, const SQChar* name, const SQChar* member, const SQChar* codeclass1, const SQChar* codeclass2); -inline SQRESULT(*v_sq_compilebuffer)(HSQUIRRELVM v, SQBufState* bufferstate, const SQChar* buffer, SQInteger level); +inline SQRESULT(*v_sq_compilebuffer)(HSQUIRRELVM v, SQBufState* bufferstate, const SQChar* buffer, SQInteger level, SQBool raiseerror); inline SQRESULT(*v_sq_call)(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror); inline SQRESULT(*v_sq_get)(HSQUIRRELVM v, SQInteger idx); @@ -227,6 +237,12 @@ inline SQRESULT (*v_sq_endconsttable)(HSQUIRRELVM v); inline SQString* (*v_StringTable__Add)(void* a1, const SQChar* str, SQInteger len); +// returns: RefTable::RefNode* +// thisp = RefTable* +// prev = RefTable::RefNode* +inline void* (*v_RefTable__Get)(void* thisp, SQObject* obj, SQHash* mainpos, void* prev, bool add); +inline SQBool(*v_RefTable__Release)(void* thisp, SQObject* obj); + /////////////////////////////////////////////////////////////////////////////// class VSquirrelAPI : public IDetour { @@ -250,6 +266,9 @@ class VSquirrelAPI : public IDetour LogFunAdr("sq_endconsttable", v_sq_endconsttable); LogFunAdr("StringTable::Add", v_StringTable__Add); + + LogFunAdr("RefTable::Get", v_RefTable__Get); + LogFunAdr("RefTable::Release", v_RefTable__Release); } virtual void GetFun(void) const { @@ -271,6 +290,9 @@ class VSquirrelAPI : public IDetour g_GameDll.FindPatternSIMD("8B 41 78 45 33 C0 FF C8 8B D0 89 41 78 48 C1 E2 04 48 03 91 ?? ?? ?? ?? 8B 02 48 C7 02 ?? ?? ?? ?? 25 ?? ?? ?? ?? 74 15").GetPtr(v_sq_endconsttable); g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 41 8D 4D FF").FollowNearCallSelf().GetPtr(v_StringTable__Add); + + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? FF 40 10 FF C6").FollowNearCallSelf().GetPtr(v_RefTable__Get); + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 84 7D BC").FollowNearCallSelf().GetPtr(v_RefTable__Release); } virtual void GetVar(void) const { } virtual void GetCon(void) const { } diff --git a/r5dev/vscript/languages/squirrel_re/include/sqvm.h b/r5dev/vscript/languages/squirrel_re/include/sqvm.h index 7f82b708..0bcbd025 100644 --- a/r5dev/vscript/languages/squirrel_re/include/sqvm.h +++ b/r5dev/vscript/languages/squirrel_re/include/sqvm.h @@ -20,6 +20,9 @@ struct SQVM : public CHAINABLE_OBJ { void PrintObjVal(const SQObject* oin, SQObject* oout); + void Pop(); + void Pop(SQInteger n); + // push sqobjectptr on to the stack void Push(const SQObjectPtr& o); @@ -59,6 +62,7 @@ static_assert(offsetof(SQVM, _top) == 0x78); static_assert(offsetof(SQVM, _nnativecalls) == 0x130); inline SQObjectPtr& stack_get(HSQUIRRELVM v, SQInteger idx) { return ((idx >= 0) ? (v->_stackbase[idx-1]) : (v->GetUp(idx))); } +#define _ss(_vm_) (_vm_)->_sharedstate /* ==== SQUIRREL ======================================================================================================================================================== */ inline SQRESULT(*v_SQVM_PrintFunc)(HSQUIRRELVM v, SQChar* fmt, ...); diff --git a/r5dev/vscript/languages/squirrel_re/squirrel/sqapi.cpp b/r5dev/vscript/languages/squirrel_re/squirrel/sqapi.cpp index 707df29f..b0ce42a1 100644 --- a/r5dev/vscript/languages/squirrel_re/squirrel/sqapi.cpp +++ b/r5dev/vscript/languages/squirrel_re/squirrel/sqapi.cpp @@ -94,6 +94,20 @@ SQInteger sq_gettop(HSQUIRRELVM v) return (v->_top - v->_bottom); } +//--------------------------------------------------------------------------------- +SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po) +{ + *po = stack_get(v, idx); + return SQ_OK; +} + +//--------------------------------------------------------------------------------- +void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) +{ + Assert(v->_top >= nelemstopop); + v->Pop(nelemstopop); +} + //--------------------------------------------------------------------------------- SQRESULT sq_pushroottable(HSQUIRRELVM v) { @@ -163,9 +177,9 @@ SQRESULT sq_pushstructure(HSQUIRRELVM v, const SQChar* name, const SQChar* membe } //--------------------------------------------------------------------------------- -SQRESULT sq_compilebuffer(HSQUIRRELVM v, SQBufState* bufferState, const SQChar* buffer, SQInteger level) +SQRESULT sq_compilebuffer(HSQUIRRELVM v, SQBufState* bufferState, const SQChar* buffer, SQInteger level, SQBool raiseerror) { - return v_sq_compilebuffer(v, bufferState, buffer, level); + return v_sq_compilebuffer(v, bufferState, buffer, level, raiseerror); } //--------------------------------------------------------------------------------- @@ -174,16 +188,32 @@ SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerr return v_sq_call(v, params, retval, raiseerror); } +//--------------------------------------------------------------------------------- SQRESULT sq_startconsttable(HSQUIRRELVM v) { return v_sq_startconsttable(v); } +//--------------------------------------------------------------------------------- SQRESULT sq_endconsttable(HSQUIRRELVM v) { return v_sq_endconsttable(v); } +//--------------------------------------------------------------------------------- +void sq_addref(HSQUIRRELVM v, SQObject* po) +{ + if (!ISREFCOUNTED(sq_type(*po))) return; + _ss(v)->_refs_table.AddRef(*po); +} + +//--------------------------------------------------------------------------------- +SQBool sq_release(HSQUIRRELVM v, SQObject* po) +{ + if (!ISREFCOUNTED(sq_type(*po))) return SQTrue; + return _ss(v)->_refs_table.Release(*po); +} + void VSquirrelAPI::Detour(const bool bAttach) const { DetourSetup(&v_sq_pushroottable, &sq_pushroottable, bAttach); diff --git a/r5dev/vscript/languages/squirrel_re/squirrel/sqstate.cpp b/r5dev/vscript/languages/squirrel_re/squirrel/sqstate.cpp new file mode 100644 index 00000000..bd7d6077 --- /dev/null +++ b/r5dev/vscript/languages/squirrel_re/squirrel/sqstate.cpp @@ -0,0 +1,22 @@ +/* + see copyright notice in squirrel.h +*/ +#include "sqstate.h" + +void RefTable::AddRef(SQObject& obj) +{ + SQHash mainpos; + RefNode* prev; + RefNode* ref = Get(obj, mainpos, &prev, true); + ref->refs++; +} + +SQBool RefTable::Release(SQObject& obj) +{ + return v_RefTable__Release(this, &obj); +} + +RefTable::RefNode* RefTable::Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add) +{ + return (RefTable::RefNode*)v_RefTable__Get(this, &obj, &mainpos, prev, add); +} diff --git a/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp b/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp index ae478ea1..c24d234b 100644 --- a/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp +++ b/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp @@ -174,6 +174,16 @@ void SQVM_LogicError(SQBool bPrompt) v_SQVM_LogicError(bPrompt); } +void SQVM::Pop() { + _stack[--_top] = _null_; +} + +void SQVM::Pop(SQInteger n) { + for (SQInteger i = 0; i < n; i++) { + _stack[--_top] = _null_; + } +} + void SQVM::Push(const SQObjectPtr& o) { _stack[_top++] = o; } SQObjectPtr& SQVM::Top() { return _stack[_top - 1]; } SQObjectPtr& SQVM::PopGet() { return _stack[--_top]; } diff --git a/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp b/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp index a7b6fb3d..89452193 100644 --- a/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp +++ b/r5dev/vscript/languages/squirrel_re/vsquirrel.cpp @@ -101,14 +101,58 @@ SQRESULT CSquirrelVM::RegisterConstant(const SQChar* name, SQInteger value) return CSquirrelVM__RegisterConstant(this, name, value); } +//--------------------------------------------------------------------------------- +// Purpose: runs text as script on the VM +// Input : *script - +// Output : true on success, false otherwise +//--------------------------------------------------------------------------------- +bool CSquirrelVM::Run(const SQChar* const script) +{ + Assert(m_hVM); + + bool success = false; + SQBufState bufState(script); + + if (SQ_SUCCEEDED(sq_compilebuffer(m_hVM, &bufState, "unnamed", -1, SQTrue))) + { + SQObject hScript; + sq_getstackobj(m_hVM, -1, &hScript); + + sq_addref(m_hVM, &hScript); + sq_pop(m_hVM, 1); + + if (ExecuteFunction((HSCRIPT)&hScript, NULL, 0, NULL, NULL) == SCRIPT_DONE) + success = true; + + sq_release(m_hVM, &hScript); + } + + return success; +} + +//--------------------------------------------------------------------------------- +// Purpose: executes a function by handle +// Input : hFunction - +// *pArgs - +// nArgs - +// *pReturn - +// hScope - +// Output : SCRIPT_DONE on success, SCRIPT_ERROR otherwise +//--------------------------------------------------------------------------------- +ScriptStatus_t CSquirrelVM::ExecuteFunction(HSCRIPT hFunction, void** pArgs, unsigned int nArgs, void* pReturn, HSCRIPT hScope) +{ + // NOTE: pArgs and pReturn are most likely of type 'ScriptVariant_t', needs to be reversed. + return CSquirrelVM__ExecuteFunction(this, hFunction, pArgs, nArgs, pReturn, hScope); +} + //--------------------------------------------------------------------------------- // Purpose: executes a code callback // Input : *name - // Output : true on success, false otherwise //--------------------------------------------------------------------------------- -bool CSquirrelVM::ExecuteCodeCallback(const SQChar* const callbackName) +bool CSquirrelVM::ExecuteCodeCallback(const SQChar* const name) { - return CSquirrelVM__ExecuteCodeCallback(this, callbackName); + return CSquirrelVM__ExecuteCodeCallback(this, name); } //--------------------------------------------------------------------------------- diff --git a/r5dev/vscript/languages/squirrel_re/vsquirrel.h b/r5dev/vscript/languages/squirrel_re/vsquirrel.h index 6928195a..212d075b 100644 --- a/r5dev/vscript/languages/squirrel_re/vsquirrel.h +++ b/r5dev/vscript/languages/squirrel_re/vsquirrel.h @@ -25,12 +25,15 @@ public: SQRESULT RegisterFunction(const SQChar* scriptname, const SQChar* nativename, const SQChar* helpstring, const SQChar* returntype, const SQChar* parameters, void* functor); SQRESULT RegisterConstant(const SQChar* name, SQInteger value); - bool ExecuteCodeCallback(const SQChar* const callbackName); - FORCEINLINE HSQUIRRELVM GetVM() const { return m_hVM; } FORCEINLINE SQCONTEXT GetContext() const { return m_iContext; } FORCEINLINE eDLL_T GetNativeContext() const { return (eDLL_T)GetContext(); } + bool Run(const SQChar* const script); + + ScriptStatus_t ExecuteFunction(HSCRIPT hFunction, void** pArgs, unsigned int nArgs, void* pReturn, HSCRIPT hScope); + bool ExecuteCodeCallback(const SQChar* const name); + private: bool unk_00; SQChar pad0[7]; @@ -78,7 +81,9 @@ inline bool(*CSquirrelVM__PrecompileClientScripts)(CSquirrelVM* vm, SQCONTEXT co #ifndef CLIENT_DLL inline bool(*CSquirrelVM__PrecompileServerScripts)(CSquirrelVM* vm, SQCONTEXT context, char** scriptArray, int scriptCount); #endif +inline ScriptStatus_t(*CSquirrelVM__ExecuteFunction)(CSquirrelVM* s, HSCRIPT hFunction, void** pArgs, unsigned int nArgs, void* pReturn, HSCRIPT hScope); inline bool(*CSquirrelVM__ExecuteCodeCallback)(CSquirrelVM* s, const SQChar* callbackName); + inline bool(*CSquirrelVM__ThrowError)(CSquirrelVM* vm, HSQUIRRELVM v); #ifndef CLIENT_DLL @@ -136,6 +141,7 @@ class VSquirrel : public IDetour #ifndef DEDICATED LogFunAdr("CSquirrelVM::PrecompileClientScripts", CSquirrelVM__PrecompileClientScripts); #endif // !DEDICATED + LogFunAdr("CSquirrelVM::ExecuteFunction", CSquirrelVM__ExecuteFunction); LogFunAdr("CSquirrelVM::ExecuteCodeCallback", CSquirrelVM__ExecuteCodeCallback); LogFunAdr("CSquirrelVM::ThrowError", CSquirrelVM__ThrowError); } @@ -155,6 +161,7 @@ class VSquirrel : public IDetour // cl/ui scripts.rson compiling g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 44 0F B6 F0 48 85 DB").FollowNearCallSelf().GetPtr(CSquirrelVM__PrecompileClientScripts); #endif + g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 83 FB 5C").FollowNearCallSelf().GetPtr(CSquirrelVM__ExecuteFunction); g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? C6 47 1C 01").FollowNearCallSelf().GetPtr(CSquirrelVM__ExecuteCodeCallback); g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? BB ?? ?? ?? ?? 8B C3").FollowNearCallSelf().GetPtr(CSquirrelVM__ThrowError); } diff --git a/r5dev/vscript/vscript.cpp b/r5dev/vscript/vscript.cpp index 8fcec3b4..ab0de695 100644 --- a/r5dev/vscript/vscript.cpp +++ b/r5dev/vscript/vscript.cpp @@ -145,24 +145,17 @@ void Script_Execute(const SQChar* code, const SQCONTEXT context) } HSQUIRRELVM v = s->GetVM(); + if (!v) { Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to run %s script while VM isn't initialized\n", contextName); return; } - SQBufState bufState = SQBufState(code); - SQRESULT compileResult = sq_compilebuffer(v, &bufState, "console", -1); - - if (SQ_SUCCEEDED(compileResult)) + if (!s->Run(code)) { - sq_pushroottable(v); - SQRESULT callResult = sq_call(v, 1, false, false); - - if (!SQ_SUCCEEDED(callResult)) - { - Error(eDLL_T::ENGINE, NO_ERROR, "Failed to execute %s script \"%s\"\n", contextName, code); - } + Error(eDLL_T::ENGINE, NO_ERROR, "Failed to run %s script \"%s\"\n", contextName, code); + return; } } diff --git a/r5dev/windows/console.cpp b/r5dev/windows/console.cpp index a0008c46..4752ae99 100644 --- a/r5dev/windows/console.cpp +++ b/r5dev/windows/console.cpp @@ -77,23 +77,27 @@ void FlashConsoleBackground(int nFlashCount, int nFlashInterval, COLORREF color) //----------------------------------------------------------------------------- // Purpose: terminal window setup // Input : bAnsiColor - +// Output : true on success, false otherwise //----------------------------------------------------------------------------- -void Console_Init(const bool bAnsiColor) +bool Console_Init(const bool bAnsiColor) { -#ifndef _TOOLS + char msgBuf[2048]; + /////////////////////////////////////////////////////////////////////////// // Create the console window if (AllocConsole() == FALSE) { - char szBuf[2048]; - snprintf(szBuf, sizeof(szBuf), "Failed to create console window! [%s]\n", std::system_category().message(static_cast(::GetLastError())).c_str()); + snprintf(msgBuf, sizeof(msgBuf), "Failed to create console window! [%s]\n", + std::system_category().message(static_cast(::GetLastError())).c_str()); - OutputDebugStringA(szBuf); - return; + OutputDebugStringA(msgBuf); + return false; } +#ifndef _TOOLS //-- Set the window title SetConsoleTitleA("R5"); +#endif // !_TOOLS //-- Open input/output streams FILE* fDummy; @@ -101,6 +105,7 @@ void Console_Init(const bool bAnsiColor) freopen_s(&fDummy, "CONOUT$", "w", stdout); freopen_s(&fDummy, "CONOUT$", "w", stderr); +#ifndef _TOOLS //-- Create a worker thread to process console commands DWORD dwThreadId = NULL; DWORD __stdcall ProcessConsoleWorker(LPVOID); @@ -112,44 +117,65 @@ void Console_Init(const bool bAnsiColor) } #endif // !_TOOLS - HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD dwMode = NULL; - if (bAnsiColor) { - GetConsoleMode(hOutput, &dwMode); - dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING; - - if (!SetConsoleMode(hOutput, dwMode)) // Some editions of Windows have 'VirtualTerminalLevel' disabled by default. + if (!Console_ColorInit()) { - // Warn the user if 'VirtualTerminalLevel' could not be set on users environment. - MessageBoxA(NULL, "Failed to set console mode 'VirtualTerminalLevel'; please disable ansi-colors and restart the program if output logging appears distorted.", "SDK Warning", MB_ICONEXCLAMATION | MB_OK); - } + Assert(0); + //snprintf(msgBuf, sizeof(msgBuf), "Failed to set color console mode! [%s]\n", + // std::system_category().message(static_cast(::GetLastError())).c_str()); - SetConsoleBackgroundColor(0x00000000); - AnsiColors_Init(); + //MessageBoxA(NULL, msgBuf, "SDK Warning", MB_ICONEXCLAMATION | MB_OK); + } } #ifndef _TOOLS SetConsoleCtrlHandler(ConsoleHandlerRoutine, true); #endif // !_TOOLS + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: terminal color setup +// Output : true on success, false otherwise +//----------------------------------------------------------------------------- +bool Console_ColorInit() +{ + HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwMode = NULL; + + GetConsoleMode(hOutput, &dwMode); // Some editions of Windows have 'VirtualTerminalLevel' disabled by default. + dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING; + + if (!SetConsoleMode(hOutput, dwMode)) + return false; // Failure. + + SetConsoleBackgroundColor(0x00000000); + AnsiColors_Init(); + + return true; } //----------------------------------------------------------------------------- // Purpose: terminal window shutdown +// Output : true on success, false otherwise //----------------------------------------------------------------------------- -void Console_Shutdown() +bool Console_Shutdown() { /////////////////////////////////////////////////////////////////////////// // Destroy the console window if (FreeConsole() == FALSE) { char szBuf[2048]; - snprintf(szBuf, sizeof(szBuf), "Failed to destroy console window! [%s]\n", std::system_category().message(static_cast(::GetLastError())).c_str()); + snprintf(szBuf, sizeof(szBuf), "Failed to destroy console window! [%s]\n", + std::system_category().message(static_cast(::GetLastError())).c_str()); OutputDebugStringA(szBuf); - return; + return false; } + + return true; } #ifndef _TOOLS diff --git a/r5dev/windows/console.h b/r5dev/windows/console.h index 6a0e4d41..609f9bb3 100644 --- a/r5dev/windows/console.h +++ b/r5dev/windows/console.h @@ -3,5 +3,6 @@ void SetConsoleBackgroundColor(COLORREF color); void FlashConsoleBackground(int nFlashCount, int nFlashInterval, COLORREF color); -void Console_Init(const bool bAnsiColor); -void Console_Shutdown(); +bool Console_Init(const bool bAnsiColor); +bool Console_ColorInit(); +bool Console_Shutdown();