Merge branch 'indev' into launcher_rework

This commit is contained in:
Kawe Mazidjatari 2024-06-01 12:02:06 +02:00
commit 02303d0ffc
174 changed files with 6235 additions and 4252 deletions

View File

@ -70,29 +70,6 @@ NVIDIA NvAPI
// the above Disclaimer (as applicable) and U.S. Government End Users Notice. // 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 Google protocol buffers
************************************************************************************ ************************************************************************************
@ -131,6 +108,29 @@ Google protocol buffers
// support library is itself covered by the above license. // 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 Dear ImGui
************************************************************************************ ************************************************************************************
@ -299,33 +299,6 @@ Format {fmt}
// without including the above copyright and permission notices. // 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 RapidJSON
************************************************************************************ ************************************************************************************
@ -788,6 +761,7 @@ LZHAM
// THE SOFTWARE. // THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
************************************************************************************ ************************************************************************************
CRC32 CRC32
************************************************************************************ ************************************************************************************

View File

@ -11,6 +11,8 @@ add_sources( SOURCE_GROUP "Bink"
add_sources( SOURCE_GROUP "Miles" add_sources( SOURCE_GROUP "Miles"
"miles/miles_impl.cpp" "miles/miles_impl.cpp"
"miles/miles_impl.h" "miles/miles_impl.h"
"miles/miles_shim.cpp"
"miles/miles_shim.h"
"miles/miles_types.h" # TODO[ AMOS ]: move to public! "miles/miles_types.h" # TODO[ AMOS ]: move to public!
"miles/radshal_wasapi.h" "miles/radshal_wasapi.h"
) )

View File

@ -1,11 +1,13 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "miles_impl.h"
#include "tier0/fasttimer.h" #include "tier0/fasttimer.h"
#include "tier0/commandline.h" #include "tier0/commandline.h"
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "filesystem/filesystem.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 // 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() bool Miles_Initialize()
{ {
const char* pszLanguage = miles_language->GetString(); const char* pszLanguage = HEbisuSDK_GetLanguage();
if (!pszLanguage[0]) const bool isDefaultLanguage = _stricmp(pszLanguage, MILES_DEFAULT_LANGUAGE) == 0;
pszLanguage = MILES_DEFAULT_LANGUAGE;
const bool isEnglishLanguage = _stricmp(pszLanguage, "english") == 0; if (!isDefaultLanguage)
if (!isEnglishLanguage)
{ {
const bool useShipSound = !CommandLine()->FindParm("-devsound") || CommandLine()->FindParm("-shipsound"); const bool useShipSound = !CommandLine()->FindParm("-devsound") || CommandLine()->FindParm("-shipsound");
const std::string baseStreamFilePath = Format("%s/general_%s.mstr", useShipSound ? "audio/ship" : "audio/dev", pszLanguage); 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 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 english and the file is still not found, we can let it hit the regular engine error, since that is not recoverable // 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())) 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; pszLanguage = MILES_DEFAULT_LANGUAGE;
miles_language->SetValue(pszLanguage); miles_language->SetValue(pszLanguage);
@ -82,7 +82,7 @@ void MilesBankPatch(Miles::Bank* bank, char* streamPatch, char* localizedStreamP
if (header->bankIndex >= header->project->bankCount) if (header->bankIndex >= header->project->bankCount)
Error(eDLL_T::AUDIO, EXIT_FAILURE, 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__, __FUNCTION__,
bank->GetBankName(), bank->GetBankName(),
header->bankIndex, header->bankIndex,
@ -99,11 +99,14 @@ void CSOM_AddEventToQueue(const char* eventName)
v_CSOM_AddEventToQueue(eventName); v_CSOM_AddEventToQueue(eventName);
if (miles_warnings.GetBool())
{
if (g_milesGlobals->queuedEventHash == 1) if (g_milesGlobals->queuedEventHash == 1)
Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName); Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName);
if (g_milesGlobals->queuedEventHash == 2) if (g_milesGlobals->queuedEventHash == 2)
Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName); Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName);
}
}; };

View File

@ -6,6 +6,7 @@ inline void(*v_AIL_LogFunc)(int64_t nLogLevel, const char* pszMessage);
inline bool(*v_Miles_Initialize)(); inline bool(*v_Miles_Initialize)();
inline void(*v_MilesQueueEventRun)(Miles::Queue*, const char*); inline void(*v_MilesQueueEventRun)(Miles::Queue*, const char*);
inline void(*v_MilesBankPatch)(Miles::Bank*, char*, 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); inline void(*v_CSOM_AddEventToQueue)(const char* eventName);
struct MilesBankList_t struct MilesBankList_t
@ -54,6 +55,7 @@ class MilesCore : public IDetour
LogFunAdr("Miles_Initialize", v_Miles_Initialize); LogFunAdr("Miles_Initialize", v_Miles_Initialize);
LogFunAdr("MilesQueueEventRun", v_MilesQueueEventRun); LogFunAdr("MilesQueueEventRun", v_MilesQueueEventRun);
LogFunAdr("MilesBankPatch", v_MilesBankPatch); LogFunAdr("MilesBankPatch", v_MilesBankPatch);
LogFunAdr("MilesSampleSetSourceRaw", v_MilesSampleSetSourceRaw);
LogFunAdr("CSOM_AddEventToQueue", v_CSOM_AddEventToQueue); LogFunAdr("CSOM_AddEventToQueue", v_CSOM_AddEventToQueue);
LogVarAdr("g_milesGlobals", g_milesGlobals); LogVarAdr("g_milesGlobals", g_milesGlobals);
} }
@ -69,6 +71,7 @@ class MilesCore : public IDetour
g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun").GetPtr(v_MilesQueueEventRun); g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun").GetPtr(v_MilesQueueEventRun);
g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch").GetPtr(v_MilesBankPatch); g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch").GetPtr(v_MilesBankPatch);
g_RadAudioSystemDll.GetExportedSymbol("MilesSampleSetSourceRaw").GetPtr(v_MilesSampleSetSourceRaw);
} }
virtual void GetVar(void) const { } virtual void GetVar(void) const { }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }

View File

@ -31,7 +31,7 @@ namespace Miles
// internal project data structure // internal project data structure
struct IntProjectData_t struct IntProjectData_t
{ {
char gap0[0xCF0]; char gap0[0xE28];
int bankCount; int bankCount;
BankHeader_t** loadedBanks; BankHeader_t** loadedBanks;
}; };

View File

@ -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);
}

View File

@ -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

View File

@ -10,6 +10,7 @@
#include "tier0/fasttimer.h" #include "tier0/fasttimer.h"
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "tier1/fmtstr.h" #include "tier1/fmtstr.h"
#include "engine/shared/shared_rcon.h"
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
#include "engine/server/sv_rcon.h" #include "engine/server/sv_rcon.h"
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
@ -227,33 +228,6 @@ void VPK_Unmount_f(const CCommand& args)
FileSystem()->UnmountVPKFile(args.Arg(1)); 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) void LanguageChanged_f(IConVar* pConVar, const char* pOldString)
{ {
if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName())) if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName()))

View File

@ -14,7 +14,6 @@ void VPK_Pack_f(const CCommand& args);
void VPK_Unpack_f(const CCommand& args); void VPK_Unpack_f(const CCommand& args);
void VPK_Mount_f(const CCommand& args); void VPK_Mount_f(const CCommand& args);
void VPK_Unmount_f(const CCommand& args); void VPK_Unmount_f(const CCommand& args);
void NET_UseSocketsForLoopbackChanged_f(IConVar* pConVar, const char* pOldString);
#ifndef DEDICATED #ifndef DEDICATED
void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString); void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString);

View File

@ -63,6 +63,14 @@ ConVar* eula_version_accepted = nullptr;
ConVar* language_cvar = nullptr; ConVar* language_cvar = nullptr;
ConVar* voice_noxplat = nullptr;
ConVar* platform_user_id = nullptr;
#ifndef DEDICATED
ConVar* name_cvar = nullptr;
#endif // !DEDICATED
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SERVER | // SERVER |
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
@ -73,6 +81,7 @@ ConVar* sv_forceChatToTeamOnly = nullptr;
ConVar* sv_single_core_dedi = nullptr; ConVar* sv_single_core_dedi = nullptr;
ConVar* sv_maxunlag = nullptr; ConVar* sv_maxunlag = nullptr;
ConVar* sv_lagpushticks = nullptr;
ConVar* sv_clockcorrection_msecs = nullptr; ConVar* sv_clockcorrection_msecs = nullptr;
ConVar* sv_updaterate_sp = nullptr; ConVar* sv_updaterate_sp = nullptr;
@ -85,7 +94,13 @@ ConVar* sv_voiceEcho = nullptr;
ConVar* sv_voiceenable = nullptr; ConVar* sv_voiceenable = nullptr;
ConVar* sv_alltalk = nullptr; ConVar* sv_alltalk = nullptr;
ConVar* sv_clampPlayerFrameTime = nullptr;
ConVar* playerframetimekick_margin = nullptr;
ConVar* playerframetimekick_decayrate = nullptr;
ConVar* player_userCmdsQueueWarning = nullptr; ConVar* player_userCmdsQueueWarning = nullptr;
ConVar* player_disallow_negative_frametime = nullptr;
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
ConVar* sv_cheats = nullptr; ConVar* sv_cheats = nullptr;
@ -146,7 +161,10 @@ void ConVar_InitShipped(void)
eula_version_accepted = g_pCVar->FindVar("eula_version_accepted"); 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 #ifndef DEDICATED
name_cvar = g_pCVar->FindVar("name");
cl_updaterate_mp = g_pCVar->FindVar("cl_updaterate_mp"); cl_updaterate_mp = g_pCVar->FindVar("cl_updaterate_mp");
cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup"); cl_threaded_bone_setup = g_pCVar->FindVar("cl_threaded_bone_setup");
#endif // !DEDICATED #endif // !DEDICATED
@ -195,6 +213,7 @@ void ConVar_InitShipped(void)
sv_stats = g_pCVar->FindVar("sv_stats"); sv_stats = g_pCVar->FindVar("sv_stats");
sv_maxunlag = g_pCVar->FindVar("sv_maxunlag"); sv_maxunlag = g_pCVar->FindVar("sv_maxunlag");
sv_lagpushticks = g_pCVar->FindVar("sv_lagpushticks");
sv_clockcorrection_msecs = g_pCVar->FindVar("sv_clockcorrection_msecs"); sv_clockcorrection_msecs = g_pCVar->FindVar("sv_clockcorrection_msecs");
sv_updaterate_sp = g_pCVar->FindVar("sv_updaterate_sp"); 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_voiceenable = g_pCVar->FindVar("sv_voiceenable");
sv_voiceEcho = g_pCVar->FindVar("sv_voiceEcho"); sv_voiceEcho = g_pCVar->FindVar("sv_voiceEcho");
sv_alltalk = g_pCVar->FindVar("sv_alltalk"); 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_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_sp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
sv_updaterate_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY); sv_updaterate_mp->RemoveFlags(FCVAR_DEVELOPMENTONLY);
@ -232,6 +258,7 @@ void ConVar_InitShipped(void)
origin_disconnectWhenOffline->RemoveFlags(FCVAR_DEVELOPMENTONLY); origin_disconnectWhenOffline->RemoveFlags(FCVAR_DEVELOPMENTONLY);
discord_updatePresence->RemoveFlags(FCVAR_DEVELOPMENTONLY); discord_updatePresence->RemoveFlags(FCVAR_DEVELOPMENTONLY);
#endif // !DEDICATED #endif // !DEDICATED
fps_max->AddFlags(FCVAR_ARCHIVE);
fps_max_vsync->RemoveFlags(FCVAR_DEVELOPMENTONLY); fps_max_vsync->RemoveFlags(FCVAR_DEVELOPMENTONLY);
base_tickinterval_sp->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->RemoveChangeCallback(mp_gamemode->m_fnChangeCallbacks[0]);
mp_gamemode->InstallChangeCallback(MP_GameMode_Changed_f, false); mp_gamemode->InstallChangeCallback(MP_GameMode_Changed_f, false);
net_usesocketsforloopback->RemoveFlags(FCVAR_DEVELOPMENTONLY); net_usesocketsforloopback->RemoveFlags(FCVAR_DEVELOPMENTONLY);
net_usesocketsforloopback->InstallChangeCallback(NET_UseSocketsForLoopbackChanged_f, false);
#ifndef DEDICATED #ifndef DEDICATED
language_cvar->InstallChangeCallback(LanguageChanged_f, false); language_cvar->InstallChangeCallback(LanguageChanged_f, false);
#endif // !DEDICATED #endif // !DEDICATED
@ -377,7 +403,6 @@ void ConCommand_InitShipped(void)
"connectAsSpectator", "connectAsSpectator",
"connectWithKey", "connectWithKey",
"silentconnect", "silentconnect",
"set",
"ping", "ping",
#endif // !DEDICATED #endif // !DEDICATED
"launchplaylist", "launchplaylist",
@ -385,6 +410,7 @@ void ConCommand_InitShipped(void)
"exit", "exit",
"reload", "reload",
"restart", "restart",
"set",
"status", "status",
"version", "version",
}; };

View File

@ -50,6 +50,14 @@ extern ConVar* eula_version_accepted;
extern ConVar* language_cvar; extern ConVar* language_cvar;
extern ConVar* voice_noxplat;
extern ConVar* platform_user_id;
#ifndef DEDICATED
extern ConVar* name_cvar;
#endif // !DEDICATED
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// SERVER | // SERVER |
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
@ -60,6 +68,7 @@ extern ConVar* sv_forceChatToTeamOnly;
extern ConVar* sv_single_core_dedi; extern ConVar* sv_single_core_dedi;
extern ConVar* sv_maxunlag; extern ConVar* sv_maxunlag;
extern ConVar* sv_lagpushticks;
extern ConVar* sv_clockcorrection_msecs; extern ConVar* sv_clockcorrection_msecs;
extern ConVar* sv_updaterate_sp; extern ConVar* sv_updaterate_sp;
@ -72,7 +81,13 @@ extern ConVar* sv_voiceEcho;
extern ConVar* sv_voiceenable; extern ConVar* sv_voiceenable;
extern ConVar* sv_alltalk; extern ConVar* sv_alltalk;
extern ConVar* sv_clampPlayerFrameTime;
extern ConVar* playerframetimekick_margin;
extern ConVar* playerframetimekick_decayrate;
extern ConVar* player_userCmdsQueueWarning; extern ConVar* player_userCmdsQueueWarning;
extern ConVar* player_disallow_negative_frametime;
#endif // CLIENT_DLL #endif // CLIENT_DLL
extern ConVar* sv_cheats; extern ConVar* sv_cheats;

View File

@ -372,6 +372,70 @@ public:
void* m_DataOut; 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<void**>(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<bool>(NetMessageVtbl::Process, this);
};
virtual bool ReadFromBuffer(bf_read* buffer)
{
return CallVFunc<bool>(NetMessageVtbl::ReadFromBuffer, this, buffer);
}
virtual bool WriteToBuffer(bf_write* buffer)
{
return CallVFunc<bool>(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 class SVC_PlaylistOverrides : public CNetMessage
{ {
private: private:
@ -385,6 +449,29 @@ private:
// Client messages: // 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 class CLC_ClientTick : public CNetMessage
{ {
public: public:

View File

@ -59,8 +59,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
"SigCache_Pb" "SigCache_Pb"
"LiveAPI_Pb" "LiveAPI_Pb"
"SV_RCon_Pb" "NetCon_Pb"
"CL_RCon_Pb"
"rson" "rson"
"rtech_game" "rtech_game"
@ -81,6 +80,10 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
"EAThread" "EAThread"
"DirtySDK" "DirtySDK"
"libmbedcrypto"
"libmbedtls"
"libmbedx509"
"networksystem" "networksystem"
"pluginsystem" "pluginsystem"
"filesystem" "filesystem"
@ -115,9 +118,6 @@ endif()
if( NOT ${PROJECT_NAME} STREQUAL "client" ) if( NOT ${PROJECT_NAME} STREQUAL "client" )
target_link_libraries( ${PROJECT_NAME} PRIVATE target_link_libraries( ${PROJECT_NAME} PRIVATE
"libmbedcrypto"
"libmbedtls"
"libmbedx509"
"libjwt" "libjwt"
) )
endif() endif()

View File

@ -30,7 +30,9 @@ bool g_bSdkInitCallInitiated = false;
bool g_bSdkShutdownCallInitiated = false; bool g_bSdkShutdownCallInitiated = false;
bool g_bSdkShutdownInitiatedFromConsoleHandler = false; bool g_bSdkShutdownInitiatedFromConsoleHandler = false;
HMODULE s_hModuleHandle = NULL;
static bool s_bConsoleInitialized = false;
static HMODULE s_hModuleHandle = NULL;
//############################################################################# //#############################################################################
// UTILITY // UTILITY
@ -116,9 +118,11 @@ void SDK_Init()
#ifndef DEDICATED #ifndef DEDICATED
if (CommandLine()->CheckParm("-wconsole")) if (CommandLine()->CheckParm("-wconsole"))
#else
if (!CommandLine()->CheckParm("-noconsole"))
#endif // !DEDICATED #endif // !DEDICATED
{ {
Console_Init(bAnsiColor); s_bConsoleInitialized = Console_Init(bAnsiColor);
} }
SpdLog_Init(bAnsiColor); SpdLog_Init(bAnsiColor);
@ -186,7 +190,7 @@ void SDK_Shutdown()
// If the shutdown was initiated from the console window itself, don't // If the shutdown was initiated from the console window itself, don't
// shutdown the console as it would otherwise deadlock in FreeConsole! // shutdown the console as it would otherwise deadlock in FreeConsole!
if (!g_bSdkShutdownInitiatedFromConsoleHandler) if (s_bConsoleInitialized && !g_bSdkShutdownInitiatedFromConsoleHandler)
Console_Shutdown(); Console_Shutdown();
g_bSdkInitialized = false; g_bSdkInitialized = false;

View File

@ -35,6 +35,7 @@
#ifndef DEDICATED #ifndef DEDICATED
#include "codecs/bink/bink_impl.h" #include "codecs/bink/bink_impl.h"
#include "codecs/miles/miles_impl.h" #include "codecs/miles/miles_impl.h"
#include "codecs/miles/miles_shim.h"
#include "codecs/miles/radshal_wasapi.h" #include "codecs/miles/radshal_wasapi.h"
#endif // !DEDICATED #endif // !DEDICATED
#include "vphysics/physics_collide.h" #include "vphysics/physics_collide.h"
@ -135,6 +136,8 @@
#include "game/server/detour_impl.h" #include "game/server/detour_impl.h"
#include "game/server/gameinterface.h" #include "game/server/gameinterface.h"
#include "game/server/movehelper_server.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/physics_main.h"
#include "game/server/vscript_server.h" #include "game/server/vscript_server.h"
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
@ -523,6 +526,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
// Codecs // Codecs
REGISTER(BinkCore); // REGISTER CLIENT ONLY! REGISTER(BinkCore); // REGISTER CLIENT ONLY!
REGISTER(MilesCore); // REGISTER CLIENT ONLY! REGISTER(MilesCore); // REGISTER CLIENT ONLY!
REGISTER(MilesShim);
REGISTER(VRadShal); REGISTER(VRadShal);
#endif // !DEDICATED #endif // !DEDICATED
@ -663,6 +667,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VBaseEntity); REGISTER(VBaseEntity);
REGISTER(VBaseAnimating); REGISTER(VBaseAnimating);
REGISTER(VPlayer); REGISTER(VPlayer);
REGISTER(VPlayerMove);
#endif // !CLIENT_DLL #endif // !CLIENT_DLL

View File

@ -284,9 +284,9 @@ void EngineLoggerSink(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
if (bToConsole) if (bToConsole)
{ {
#ifndef CLIENT_DLL #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)); int(context), int(logType));
} }
#endif // !CLIENT_DLL #endif // !CLIENT_DLL

View File

@ -176,7 +176,7 @@ struct studioanimcache_t
const char* rigName; const char* rigName;
int unk0; int unk0;
int numSequences; int numSequences;
PakPage_t sequences; PakPage_u sequences;
int unk1; int unk1;
int unk2; int unk2;
}; };

View File

@ -1,19 +1,95 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "tier0/commandline.h"
#include "ebisusdk/EbisuSDK.h" #include "ebisusdk/EbisuSDK.h"
#include "engine/server/sv_main.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() 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_EbisuSDKInit = true;
*g_EbisuProfileInit = true; // <- 2nd EbisuSDK *g_EbisuProfileInit = true;
*g_NucleusID = 9990000; // <- 3rd EbisuSDK *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 // Purpose: checks if the EbisuSDK is initialized
@ -57,3 +133,9 @@ bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen)
size_t pos = strspn(pszName, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"); size_t pos = strspn(pszName, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
return pszName[pos] == '\0'; return pszName[pos] == '\0';
} }
void VEbisuSDK::Detour(const bool bAttach) const
{
DetourSetup(&EbisuSDK_RunFrame, &HEbisuSDK_RunFrame, bAttach);
DetourSetup(&EbisuSDK_GetLanguage, &HEbisuSDK_GetLanguage, bAttach);
}

View File

@ -1,19 +1,28 @@
#pragma once #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_Tier0_Init)(void);
inline void(*EbisuSDK_CVar_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 uint64_t* g_NucleusID = nullptr;
inline char* g_NucleusToken = nullptr; /*SIZE = 1024*/ inline char* g_NucleusToken = nullptr; /*SIZE = 1024*/
inline char* g_OriginAuthCode = nullptr; /*SIZE = 256*/ inline char* g_OriginAuthCode = nullptr; /*SIZE = 256*/
inline char* g_PersonaName = nullptr; /*SIZE = 64*/
inline int* g_OriginErrorLevel = nullptr; inline int* g_OriginErrorLevel = nullptr;
inline bool* g_EbisuSDKInit = nullptr; inline bool* g_EbisuSDKInit = nullptr;
inline bool* g_EbisuProfileInit = nullptr; inline bool* g_EbisuProfileInit = nullptr;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void HEbisuSDK_Init(); void HEbisuSDK_Init();
const char* HEbisuSDK_GetLanguage();
bool IsOriginDisabled();
bool IsOriginInitialized(); bool IsOriginInitialized();
bool IsValidPersonaName(const char* pszName, int nMinLen, int nMaxLen); 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_Tier0_Init", EbisuSDK_Tier0_Init);
LogFunAdr("EbisuSDK_CVar_Init", EbisuSDK_CVar_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_NucleusID", g_NucleusID);
LogVarAdr("g_NucleusToken", g_NucleusToken); LogVarAdr("g_NucleusToken", g_NucleusToken);
LogVarAdr("g_OriginAuthCode", g_OriginAuthCode); LogVarAdr("g_OriginAuthCode", g_OriginAuthCode);
LogVarAdr("g_PersonaName", g_PersonaName);
LogVarAdr("g_OriginErrorLevel", g_OriginErrorLevel); LogVarAdr("g_OriginErrorLevel", g_OriginErrorLevel);
LogVarAdr("g_EbisuProfileInit", g_EbisuProfileInit); LogVarAdr("g_EbisuProfileInit", g_EbisuProfileInit);
LogVarAdr("g_EbisuSDKInit", g_EbisuSDKInit); 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("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("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 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<uint64_t*>(); g_NucleusID = CMemory(EbisuSDK_CVar_Init).Offset(0x20).FindPatternSelf("4C 89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<uint64_t*>();
g_NucleusToken = CMemory(EbisuSDK_SetState).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<char*>(); g_NucleusToken = CMemory(EbisuSDK_RunFrame).Offset(0x1EF).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<char*>();
g_OriginAuthCode = CMemory(EbisuSDK_SetState).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>(); g_OriginAuthCode = CMemory(EbisuSDK_RunFrame).Offset(0x1BF).FindPatternSelf("0F B6", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
g_OriginErrorLevel = CMemory(EbisuSDK_SetState).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>(); g_PersonaName = CMemory(EbisuSDK_CVar_Init).Offset(0x120).FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<char*>();
g_OriginErrorLevel = CMemory(EbisuSDK_RunFrame).Offset(0x20).FindPatternSelf("89 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
g_EbisuProfileInit = CMemory(EbisuSDK_CVar_Init).Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>(); g_EbisuProfileInit = CMemory(EbisuSDK_CVar_Init).Offset(0x12A).FindPatternSelf("C6 05", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
g_EbisuSDKInit = CMemory(EbisuSDK_Tier0_Init).Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>(); g_EbisuSDKInit = CMemory(EbisuSDK_Tier0_Init).Offset(0x0).FindPatternSelf("80 3D", CMemory::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
} }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const { } virtual void Detour(const bool bAttach) const;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -47,6 +47,12 @@ public:
const static int index = 28; const static int index = 28;
return CallVFunc<CUserCmd*>(index, this, sequenceNumber); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 44 8B C2*/ return CallVFunc<CUserCmd*>(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<bool>(index, this, msgType, msgData);
}
}; };
/* ==== CHLCLIENT ======================================================================================================================================================= */ /* ==== CHLCLIENT ======================================================================================================================================================= */

View File

@ -29,13 +29,12 @@ void CL_MoveEx()
if (!v_Host_ShouldRun()) if (!v_Host_ShouldRun())
return; return;
int commandTick = -1; const int commandTick = cl->m_CurrFrameSnapshot
? cl->m_CurrFrameSnapshot->m_TickUpdate.m_nCommandTick
if (cl->m_CurrFrameSnapshot) : -1;
commandTick = cl->m_CurrFrameSnapshot->m_TickUpdate.m_nCommandTick;
bool sendPacket = true; 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, // Only perform clamping and packeting if the timescale value is default,
// else the timescale change won't be handled in the player's movement. // else the timescale change won't be handled in the player's movement.

View File

@ -7,8 +7,7 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "tier1/cmd.h" #include "tier1/cmd.h"
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "engine/client/cl_rcon.h" #include "engine/client/cl_rcon.h"
#include "engine/shared/shared_rcon.h" #include "engine/shared/shared_rcon.h"
#include "engine/net.h" #include "engine/net.h"
@ -19,16 +18,18 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: console variables // 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 // Purpose: console commands
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void RCON_Disconnect_f();
static void RCON_CmdQuery_f(const CCommand& args); 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 \"<query>\""); static ConCommand rcon("rcon", RCON_CmdQuery_f, "Forward RCON message to remote server", FCVAR_CLIENTDLL | FCVAR_RELEASE, nullptr, "rcon \"<message>\"");
static ConCommand rcon_disconnect("rcon_disconnect", RCON_Disconnect_f, "Disconnect from RCON server", FCVAR_CLIENTDLL | FCVAR_RELEASE);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: // Purpose:
@ -51,8 +52,9 @@ CRConClient::~CRConClient(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: NETCON systems init // Purpose: NETCON systems init
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConClient::Init(void) void CRConClient::Init(const char* pNetKey)
{ {
SetKey(pNetKey);
m_bInitialized = true; m_bInitialized = true;
} }
@ -105,18 +107,17 @@ void CRConClient::Disconnect(const char* szReason)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen) bool CRConClient::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
sv_rcon::response response; netcon::response response;
bool bSuccess = Decode(&response, pMsgBuf, nMsgLen);
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; return false;
} }
switch (response.responsetype()) switch (response.responsetype())
{ {
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: case netcon::response_e::SERVERDATA_RESPONSE_AUTH:
{ {
if (!response.responseval().empty()) 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()); Msg(eDLL_T::NETCON, "%s", response.responsemsg().c_str());
break; break;
} }
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG: case netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG:
{ {
NetMsg(static_cast<LogType_t>(response.messagetype()), NetMsg(static_cast<LogType_t>(response.messagetype()),
static_cast<eDLL_T>(response.messageid()), static_cast<eDLL_T>(response.messageid()),
@ -165,7 +166,7 @@ void CRConClient::RequestConsoleLog(const bool bWantLog)
const SocketHandle_t hSocket = GetSocket(); const SocketHandle_t hSocket = GetSocket();
vector<char> vecMsg; vector<char> 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()))) if (ret && !Send(hSocket, vecMsg.data(), int(vecMsg.size())))
{ {
@ -181,9 +182,10 @@ void CRConClient::RequestConsoleLog(const bool bWantLog)
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConClient::Serialize(vector<char>& vecBuf, const char* szReqBuf, bool CRConClient::Serialize(vector<char>& 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); 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 // Purpose: returns whether or not we should receive logs from the server
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -254,6 +245,56 @@ CRConClient* RCONClient() // Singleton RCON Client.
return &s_RCONClient; 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 RCON_CmdQuery_f
@ -268,14 +309,8 @@ static void RCON_CmdQuery_f(const CCommand& args)
if (argCount < 2) if (argCount < 2)
{ {
const char* pszAddress = rcon_address.GetString(); Warning(eDLL_T::CLIENT, "Failed to issue command to RCON server: %s\n", "no command provided");
return;
if (RCONClient()->IsInitialized()
&& !RCONClient()->IsConnected()
&& pszAddress[0])
{
RCONClient()->Connect(pszAddress);
}
} }
else else
{ {
@ -290,15 +325,15 @@ static void RCON_CmdQuery_f(const CCommand& args)
bool bSuccess = false; bool bSuccess = false;
const SocketHandle_t hSocket = RCONClient()->GetSocket(); 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) 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 <password>)
{ {
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; 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. else if (strcmp(args.Arg(1), "disconnect") == 0) // Disconnect from RCON server.
{ {
RCONClient()->Disconnect("issued by user"); RCONClient()->Disconnect("ordered by user");
return; 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) if (bSuccess)
{ {
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size())); 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");
}
}

View File

@ -1,8 +1,7 @@
#pragma once #pragma once
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "engine/shared/base_rcon.h" #include "engine/shared/base_rcon.h"
class CRConClient : public CNetConBase class CRConClient : public CNetConBase
@ -11,7 +10,7 @@ public:
CRConClient(void); CRConClient(void);
~CRConClient(void); ~CRConClient(void);
void Init(void); void Init(const char* pNetKey = nullptr);
void Shutdown(void); void Shutdown(void);
void RunFrame(void); void RunFrame(void);
@ -19,7 +18,7 @@ public:
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
bool Serialize(vector<char>& vecBuf, const char* szReqBuf, bool Serialize(vector<char>& 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); void RequestConsoleLog(const bool bWantLog);
bool ShouldReceive(void); bool ShouldReceive(void);

View File

@ -133,7 +133,7 @@ class VSplitScreen : public IDetour
virtual void GetFun(void) const { } virtual void GetFun(void) const { }
virtual void GetVar(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"; const char* const pszInstruction = "48 8D";
g_pSplitScreenMgr = g_GameDll.FindPatternSIMD(pszPattern).FindPatternSelf(pszInstruction).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CSplitScreen*>(); g_pSplitScreenMgr = g_GameDll.FindPatternSIMD(pszPattern).FindPatternSelf(pszInstruction).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CSplitScreen*>();

View File

@ -9,6 +9,7 @@
// //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include "core/stdafx.h" #include "core/stdafx.h"
#include "mathlib/bitvec.h"
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "tier1/strtools.h" #include "tier1/strtools.h"
#include "engine/server/server.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, bool CClient::VConnect(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer,
CUtlVector<NET_SetConVar::cvar_t>* conVars, char* szMessage, int nMessageSize) CUtlVector<NET_SetConVar::cvar_t>* 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; 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 void VClient::Detour(const bool bAttach) const
{ {
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
@ -536,5 +624,7 @@ void VClient::Detour(const bool bAttach) const
DetourSetup(&CClient__ProcessStringCmd, &CClient::VProcessStringCmd, bAttach); DetourSetup(&CClient__ProcessStringCmd, &CClient::VProcessStringCmd, bAttach);
DetourSetup(&CClient__ProcessSetConVar, &CClient::VProcessSetConVar, bAttach); DetourSetup(&CClient__ProcessSetConVar, &CClient::VProcessSetConVar, bAttach);
DetourSetup(&CClient__ProcessVoiceData, &CClient::VProcessVoiceData, bAttach);
DetourSetup(&CClient__ProcessDurangoVoiceData, &CClient::VProcessDurangoVoiceData, bAttach);
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
} }

View File

@ -69,6 +69,7 @@ public:
inline edict_t GetHandle(void) const { return m_nHandle; } inline edict_t GetHandle(void) const { return m_nHandle; }
inline int GetUserID(void) const { return m_nUserID; } inline int GetUserID(void) const { return m_nUserID; }
inline NucleusID_t GetNucleusID(void) const { return m_nNucleusID; } 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 SIGNONSTATE GetSignonState(void) const { return m_nSignonState; }
inline PERSISTENCE GetPersistenceState(void) const { return m_nPersistenceState; } inline PERSISTENCE GetPersistenceState(void) const { return m_nPersistenceState; }
@ -79,7 +80,11 @@ public:
CClientExtended* GetClientExtended(void) const; CClientExtended* GetClientExtended(void) const;
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
inline int GetDeltaTick(void) const { return m_nDeltaTick; }
inline int GetCommandTick(void) const { return m_nCommandTick; } 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* GetServerName(void) const { return m_szServerName; }
inline const char* GetClientName(void) const { return m_szClientName; } 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 VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg);
static bool VProcessSetConVar(CClient* pClient, NET_SetConVar* 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: private:
// Stub reimplementation to avoid the 'no overrider' compiler errors in the // Stub reimplementation to avoid the 'no overrider' compiler errors in the
@ -197,14 +204,26 @@ private:
bool m_bReceivedPacket; bool m_bReceivedPacket;
bool m_bLowViolence; bool m_bLowViolence;
bool m_bFullyAuthenticated; 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; PERSISTENCE m_nPersistenceState;
char pad_05C0[48]; char pad_05C0[48];
char SnapshotBuffer_AndSomeUnknowns[98344]; // TODO: needs to be reversed further.
int m_XPlatID;
char pad_30758[196964];
ServerDataBlock m_DataBlock; ServerDataBlock m_DataBlock;
char pad_4A3D8[60]; char pad_4A3D8[60];
int m_LastMovementTick; int m_LastMovementTick;
char pad_4A418[86]; 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); static_assert(sizeof(CClient) == 0x4A4C0);
@ -230,6 +249,7 @@ public:
m_flNetProcessTimeBase = 0.0; m_flNetProcessTimeBase = 0.0;
m_flStringCommandQuotaTimeStart = 0.0; m_flStringCommandQuotaTimeStart = 0.0;
m_nStringCommandQuotaCount = NULL; m_nStringCommandQuotaCount = NULL;
m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
m_bInitialConVarsSet = false; m_bInitialConVarsSet = false;
} }
@ -247,6 +267,12 @@ public: // Inlines:
inline void SetStringCommandQuotaCount(const int iCount) { m_nStringCommandQuotaCount = iCount; } inline void SetStringCommandQuotaCount(const int iCount) { m_nStringCommandQuotaCount = iCount; }
inline int GetStringCommandQuotaCount(void) const { return m_nStringCommandQuotaCount; } 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: private:
// Measure how long this client's packets took to process. // Measure how long this client's packets took to process.
double m_flNetProcessingTimeMsecs; double m_flNetProcessingTimeMsecs;
@ -256,6 +282,9 @@ private:
double m_flStringCommandQuotaTimeStart; double m_flStringCommandQuotaTimeStart;
int m_nStringCommandQuotaCount; 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 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 void(*CClient__WriteDataBlock)(CClient* pClient, bf_write& buf);
inline bool(*CClient__ProcessStringCmd)(CClient* pClient, NET_StringCmd* pMsg); inline bool(*CClient__ProcessStringCmd)(CClient* pClient, NET_StringCmd* pMsg);
inline bool(*CClient__ProcessSetConVar)(CClient* pClient, NET_SetConVar* 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 class VClient : public IDetour
@ -286,6 +317,8 @@ class VClient : public IDetour
LogFunAdr("CClient::WriteDataBlock", CClient__WriteDataBlock); LogFunAdr("CClient::WriteDataBlock", CClient__WriteDataBlock);
LogFunAdr("CClient::ProcessStringCmd", CClient__ProcessStringCmd); LogFunAdr("CClient::ProcessStringCmd", CClient__ProcessStringCmd);
LogFunAdr("CClient::ProcessSetConVar", CClient__ProcessSetConVar); LogFunAdr("CClient::ProcessSetConVar", CClient__ProcessSetConVar);
LogFunAdr("CClient::ProcessVoiceData", CClient__ProcessVoiceData);
LogFunAdr("CClient::ProcessDurangoVoiceData", CClient__ProcessDurangoVoiceData);
} }
virtual void GetFun(void) const 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 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 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 GetVar(void) const { }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }

View File

@ -9,6 +9,7 @@
// //
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "core/stdafx.h" #include "core/stdafx.h"
#include "mathlib/bitvec.h"
#include "tier0/frametask.h" #include "tier0/frametask.h"
#include "engine/common.h" #include "engine/common.h"
#include "engine/host.h" #include "engine/host.h"
@ -24,6 +25,36 @@
#include <ebisusdk/EbisuSDK.h> #include <ebisusdk/EbisuSDK.h>
#include <engine/cmd.h> #include <engine/cmd.h>
//------------------------------------------------------------------------------
// 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 // 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; 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_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"); 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__ProcessStringCmd, &CClientState::_ProcessStringCmd, bAttach);
DetourSetup(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick, bAttach); DetourSetup(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick, bAttach);
DetourSetup(&CClientState__ProcessCreateStringTable, &CClientState::_ProcessCreateStringTable, bAttach); DetourSetup(&CClientState__ProcessCreateStringTable, &CClientState::_ProcessCreateStringTable, bAttach);
DetourSetup(&CClientState__ProcessUserMessage, &CClientState::_ProcessUserMessage, bAttach);
DetourSetup(&CClientState__Connect, &CClientState::VConnect, bAttach); DetourSetup(&CClientState__Connect, &CClientState::VConnect, bAttach);
} }

View File

@ -40,6 +40,7 @@ public: // Hook statics.
static bool _ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg); static bool _ProcessStringCmd(CClientState* thisptr, NET_StringCmd* msg);
static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg); static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg);
static bool _ProcessCreateStringTable(CClientState* thisptr, SVC_CreateStringTable* 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); static void VConnect(CClientState* thisptr, connectparams_t* connectParams);
@ -100,7 +101,7 @@ public:
_BYTE field_149; _BYTE field_149;
int m_nDeltaTick; int m_nDeltaTick;
int m_nStringTableAckTick; int m_nStringTableAckTick;
int m_nProcesseedDeltaTick; int m_nProcessedDeltaTick;
int m_nProcessedStringTableAckTick; int m_nProcessedStringTableAckTick;
bool m_bPendingTicksAvailable; bool m_bPendingTicksAvailable;
_BYTE field_15D; _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__ProcessStringCmd)(CClientState* thisptr, NET_StringCmd* msg);
inline bool(*CClientState__ProcessServerTick)(CClientState* thisptr, SVC_ServerTick* msg); inline bool(*CClientState__ProcessServerTick)(CClientState* thisptr, SVC_ServerTick* msg);
inline bool(*CClientState__ProcessCreateStringTable)(CClientState* thisptr, SVC_CreateStringTable* msg); inline bool(*CClientState__ProcessCreateStringTable)(CClientState* thisptr, SVC_CreateStringTable* msg);
inline bool(*CClientState__ProcessUserMessage)(CClientState* thisptr, SVC_UserMessage* msg);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class VClientState : public IDetour class VClientState : public IDetour
@ -242,6 +244,7 @@ class VClientState : public IDetour
LogFunAdr("CClientState::ProcessStringCmd", CClientState__ProcessStringCmd); LogFunAdr("CClientState::ProcessStringCmd", CClientState__ProcessStringCmd);
LogFunAdr("CClientState::ProcessServerTick", CClientState__ProcessServerTick); LogFunAdr("CClientState::ProcessServerTick", CClientState__ProcessServerTick);
LogFunAdr("CClientState::ProcessCreateStringTable", CClientState__ProcessCreateStringTable); LogFunAdr("CClientState::ProcessCreateStringTable", CClientState__ProcessCreateStringTable);
LogFunAdr("CClientState::ProcessUserMessage", CClientState__ProcessUserMessage);
LogVarAdr("g_ClientState", g_pClientState); LogVarAdr("g_ClientState", g_pClientState);
LogVarAdr("g_ClientState_Shifted", g_pClientState_Shifted); 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 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("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 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 virtual void GetVar(void) const
{ {

View File

@ -110,6 +110,79 @@ bool Cmd_ForwardToServer(const CCommand* args)
#endif // DEDICATED #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<ConVar*>(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 void VCmd::Detour(const bool bAttach) const
{ {

View File

@ -26,6 +26,10 @@ FORCEINLINE ECommandTarget_t Cbuf_GetCurrentPlayer(void)
extern bool Cbuf_HasRoomForExecutionMarkers(const int cExecutionMarkers); extern bool Cbuf_HasRoomForExecutionMarkers(const int cExecutionMarkers);
extern bool Cbuf_AddTextWithMarkers(const char* text, const ECmdExecutionMarker markerLeft, const ECmdExecutionMarker markerRight); 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 ================================================================================================================================================== */ /* ==== COMMAND_BUFFER ================================================================================================================================================== */
inline void(*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_source_t cmdSource); inline void(*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_source_t cmdSource);
inline void(*Cbuf_AddExecutionMarker)(ECommandTarget_t target, ECmdExecutionMarker marker); inline void(*Cbuf_AddExecutionMarker)(ECommandTarget_t target, ECmdExecutionMarker marker);

View File

@ -9,6 +9,7 @@
#include "tier0/memstd.h" #include "tier0/memstd.h"
#include "tier0/jobthread.h" #include "tier0/jobthread.h"
#include "tier1/fmtstr.h" #include "tier1/fmtstr.h"
#include "tier1/keyvalues.h"
#include "tier2/fileutils.h" #include "tier2/fileutils.h"
#include "engine/sys_dll2.h" #include "engine/sys_dll2.h"
#include "engine/host_cmd.h" #include "engine/host_cmd.h"
@ -19,7 +20,7 @@
#include "rtech/pak/paktools.h" #include "rtech/pak/paktools.h"
#include "rtech/pak/pakstream.h" #include "rtech/pak/pakstream.h"
#include "tier1/keyvalues.h" #include "vpklib/packedstore.h"
#include "datacache/mdlcache.h" #include "datacache/mdlcache.h"
#include "filesystem/filesystem.h" #include "filesystem/filesystem.h"
#ifndef DEDICATED #ifndef DEDICATED
@ -29,8 +30,6 @@
CUtlVector<CUtlString> g_InstalledMaps; CUtlVector<CUtlString> g_InstalledMaps;
CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName; CFmtStrN<MAX_MAP_NAME> s_CurrentLevelName;
static std::regex s_ArchiveRegex{ R"([^_]*_(.*)(.bsp.pak000_dir).*)" };
static CustomPakData_t s_customPakData; static CustomPakData_t s_customPakData;
static KeyValues* s_pLevelSetKV = nullptr; static KeyValues* s_pLevelSetKV = nullptr;
@ -42,13 +41,13 @@ PakHandle_t CustomPakData_t::LoadAndAddPak(const char* const pakFile)
if (numHandles >= MAX_CUSTOM_PAKS) 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); 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); const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
// failure, don't add and return the invalid handle. // failure, don't add and return the invalid handle.
if (pakId == INVALID_PAK_HANDLE) if (pakId == PAK_INVALID_HANDLE)
return pakId; return pakId;
handles[numHandles++] = pakId; handles[numHandles++] = pakId;
@ -64,14 +63,14 @@ void CustomPakData_t::UnloadAndRemoveAll()
{ {
const PakHandle_t pakId = handles[numHandles-1]; 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 assert(0); // invalid handles should not be inserted
return; return;
} }
g_pakLoadApi->UnloadAsync(pakId); 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); const PakHandle_t pakId = g_pakLoadApi->LoadAsync(pakFile, AlignedMemAlloc(), 4, 0);
// the file is most likely missing // the file is most likely missing
assert(pakId != INVALID_PAK_HANDLE); assert(pakId != PAK_INVALID_HANDLE);
handles[type] = pakId; handles[type] = pakId;
return pakId; return pakId;
@ -97,10 +96,10 @@ void CustomPakData_t::UnloadBasePak(const EPakType type)
const PakHandle_t pakId = handles[type]; const PakHandle_t pakId = handles[type];
// only unload if it was actually successfully loaded // only unload if it was actually successfully loaded
if (pakId != INVALID_PAK_HANDLE) if (pakId != PAK_INVALID_HANDLE)
{ {
g_pakLoadApi->UnloadAsync(pakId); 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/'. // slash, as the files are loaded from 'vpk/'.
Assert(pFileName); Assert(pFileName);
std::regex_search(pFileName, regexMatches, s_ArchiveRegex); std::regex_search(pFileName, regexMatches, g_VpkDirFileRegex);
if (!regexMatches.empty()) if (!regexMatches.empty())
{ {
const std::sub_match<const char*>& match = regexMatches[1]; const std::sub_match<const char*>& match = regexMatches[2];
if (match.compare("frontend") == 0) if (match.compare("frontend") == 0)
continue; // Frontend contains no BSP's. continue; // Frontend contains no BSP's.
@ -155,6 +154,7 @@ void Mod_GetAllInstalledMaps()
else else
{ {
const string mapName = match.str(); const string mapName = match.str();
if (!g_InstalledMaps.HasElement(mapName.c_str())) if (!g_InstalledMaps.HasElement(mapName.c_str()))
g_InstalledMaps.AddToTail(mapName.c_str()); g_InstalledMaps.AddToTail(mapName.c_str());
} }
@ -236,8 +236,8 @@ void Mod_QueuedPakCacheFrame()
{ {
if (*data->pakName) if (*data->pakName)
{ {
PakLoadedInfo_t* const pakInfo = Pak_GetPakInfo(data->pakId); PakLoadedInfo_s* const pakInfo = Pak_GetPakInfo(data->pakId);
EPakStatus status; PakStatus_e status;
// TODO: revisit this, this appears incorrect but also the way // TODO: revisit this, this appears incorrect but also the way
// respawn does this. it this always supposed to be true on // respawn does this. it this always supposed to be true on
@ -313,7 +313,7 @@ void Mod_QueuedPakCacheFrame()
data->keepLoaded = false; data->keepLoaded = false;
data->pakName[0] = '\0'; data->pakName[0] = '\0';
data->pakId = INVALID_PAK_HANDLE; data->pakId = PAK_INVALID_HANDLE;
} }
--numLeftToProcess; --numLeftToProcess;
--data; --data;
@ -352,7 +352,7 @@ void Mod_QueuedPakCacheFrame()
if (*commonData->pakName) if (*commonData->pakName)
break; break;
commonData->pakId = INVALID_PAK_HANDLE; commonData->pakId = PAK_INVALID_HANDLE;
LOOP_AGAIN_OR_FINISH: LOOP_AGAIN_OR_FINISH:
++it; ++it;
@ -421,9 +421,9 @@ void Mod_QueuedPakCacheFrame()
CHECK_FOR_FAILURE: 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) 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()); snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName());
const PakHandle_t nPakId = s_customPakData.LoadAndAddPak(szPathBuffer); 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); Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId);
} }
} }

View File

@ -39,7 +39,7 @@ struct CommonPakData_t
void Reset() void Reset()
{ {
pakId = INVALID_PAK_HANDLE; pakId = PAK_INVALID_HANDLE;
keepLoaded = false; keepLoaded = false;
basePakName = nullptr; basePakName = nullptr;
@ -83,14 +83,14 @@ struct CustomPakData_t
// the absolute max number of custom paks, note that the engine's limit // 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 // could still be reached before this number as game scripts and other
// code still loads paks such as gladiator cards or load screens // 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() CustomPakData_t()
{ {
for (size_t i = 0; i < V_ARRAYSIZE(handles); i++) 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 // the first # handles are reserved for base SDK paks

View File

@ -57,10 +57,10 @@
#include "game/shared/vscript_shared.h" #include "game/shared/vscript_shared.h"
#ifndef CLIENT_DLL #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 host_statusRefreshRate("host_statusRefreshRate", "0.5", FCVAR_RELEASE, "Host status refresh rate (seconds).", true, 0.f, false, 0.f);
static ConVar sv_pylonRefreshRate("sv_pylonRefreshRate", "5.0", FCVAR_DEVELOPMENTONLY, "Pylon host refresh rate (seconds).");
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 #endif // !CLIENT_DLL
#ifdef DEDICATED #ifdef DEDICATED
@ -136,6 +136,24 @@ static void HostState_KeepAlive()
} }
#endif // DEDICATED #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 // Purpose: state machine's main processing loop
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -299,13 +317,6 @@ void CHostState::Setup(void)
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
ConVar_PurgeHostNames(); ConVar_PurgeHostNames();
#ifndef CLIENT_DLL
RCONServer()->Init();
#endif // !CLIENT_DLL
#ifndef DEDICATED
RCONClient()->Init();
#endif // !DEDICATED
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
LiveAPISystem()->Init(); LiveAPISystem()->Init();
#endif // !CLIENT_DLL #endif // !CLIENT_DLL
@ -350,14 +361,10 @@ void CHostState::Think(void) const
#endif // DEDICATED #endif // DEDICATED
bInitialized = true; bInitialized = true;
} }
if (sv_autoReloadRate.GetBool())
{ HostState_HandleAutoReload();
if (g_ServerGlobalVariables->m_flCurTime > sv_autoReloadRate.GetFloat())
{ if (statsTimer.GetDurationInProgress().GetSeconds() > host_statusRefreshRate.GetFloat())
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "reload\n", cmd_source_t::kCommandSrcCode);
}
}
if (statsTimer.GetDurationInProgress().GetSeconds() > sv_statusRefreshRate.GetFloat())
{ {
SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d)", SetConsoleTitleA(Format("%s - %d/%d Players (%s on %s) - %d%% Server CPU (%.3f msec on frame %d)",
hostname->GetString(), g_pServer->GetNumClients(), 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); Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec tools/rcon_client_dev.cfg\n", cmd_source_t::kCommandSrcCode);
#endif // !DEDICATED #endif // !DEDICATED
} }
#ifndef CLIENT_DLL
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec liveapi.cfg\n", cmd_source_t::kCommandSrcCode);
#endif //!CLIENT_DLL
#ifndef DEDICATED #ifndef DEDICATED
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec bind.cfg\n", cmd_source_t::kCommandSrcCode); Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec bind.cfg\n", cmd_source_t::kCommandSrcCode);
#endif // !DEDICATED #endif // !DEDICATED
@ -551,3 +561,7 @@ void VHostState::Detour(const bool bAttach) const
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
CHostState* g_pHostState = nullptr; CHostState* g_pHostState = nullptr;
#ifndef CLIENT_DLL
bool g_hostReloadState = false;
#endif // !CLIENT_DLL

View File

@ -58,6 +58,9 @@ inline void(*v_HostState_ChangeLevelMP)(char const* pNewLevel, char const* pLand
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
extern CHostState* g_pHostState; extern CHostState* g_pHostState;
#ifndef CLIENT_DLL
extern bool g_hostReloadState;
#endif // !CLIENT_DLL
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class VHostState : public IDetour class VHostState : public IDetour

View File

@ -8,6 +8,7 @@
#include "engine/net.h" #include "engine/net.h"
#ifndef _TOOLS #ifndef _TOOLS
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "tier2/cryptutils.h"
#include "mathlib/color.h" #include "mathlib/color.h"
#include "net.h" #include "net.h"
#include "net_chan.h" #include "net_chan.h"
@ -202,21 +203,16 @@ void NET_GenerateKey()
return; // Change callback will handle this. return; // Change callback will handle this.
} }
BCRYPT_ALG_HANDLE hAlgorithm; uint8_t keyBuf[AES_128_KEY_SIZE];
if (BCryptOpenAlgorithmProvider(&hAlgorithm, L"RNG", 0, 0) < 0) 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; return;
} }
uint8_t pBuffer[AES_128_KEY_SIZE]; NET_SetKey(Base64Encode(string(reinterpret_cast<char*>(&keyBuf), 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<char*>(&pBuffer), AES_128_KEY_SIZE)));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -1,5 +1,9 @@
#pragma once #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 #ifndef _TOOLS
#include "engine/net_chan.h" #include "engine/net_chan.h"
#include "tier1/lzss.h" #include "tier1/lzss.h"
@ -14,10 +18,6 @@
#define NETMSG_LENGTH_BITS 12 // 512 bytes (11 in Valve Source, 256 bytes). #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 #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 ======================================================================================================================================================== */ /* ==== CNETCHAN ======================================================================================================================================================== */
inline void*(*v_NET_Init)(bool bDeveloper); inline void*(*v_NET_Init)(bool bDeveloper);
inline void(*v_NET_SetKey)(netkey_t* pKey, const char* szHash); inline void(*v_NET_SetKey)(netkey_t* pKey, const char* szHash);

View File

@ -127,6 +127,8 @@ public:
inline float GetTimeoutSeconds(void) const { return m_Timeout; } inline float GetTimeoutSeconds(void) const { return m_Timeout; }
inline int GetSocket(void) const { return m_Socket; } inline int GetSocket(void) const { return m_Socket; }
inline const bf_write& GetStreamVoice(void) const { return m_StreamVoice; } 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; } inline const netadr_t& GetRemoteAddress(void) const { return remote_address; }
int GetNumBitsWritten(const bool bReliable); int GetNumBitsWritten(const bool bReliable);

View File

@ -23,7 +23,6 @@ public:
struct ServerDataBlock struct ServerDataBlock
{ {
char blockBuffer[295312]; // this might be wrong !!!
void* userData; void* userData;
char gapC0008[56]; char gapC0008[56];
ServerDataBlockSender sender; ServerDataBlockSender sender;

View File

@ -10,6 +10,7 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "core/stdafx.h" #include "core/stdafx.h"
#include "common/protocol.h" #include "common/protocol.h"
#include "tier0/frametask.h"
#include "tier1/cvar.h" #include "tier1/cvar.h"
#include "tier1/strtools.h" #include "tier1/strtools.h"
#include "engine/server/sv_main.h" #include "engine/server/sv_main.h"
@ -25,10 +26,12 @@
// Console variables // Console variables
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
ConVar sv_showconnecting("sv_showconnecting", "1", FCVAR_RELEASE, "Logs information about the connecting client to the console"); 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_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_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); 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()) 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"); pClient->Disconnect(REP_MARK_BAD, "#Valve_Reject_Banned");
return nullptr; return nullptr;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "tier0/frametask.h"
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "networksystem/pylon.h" #include "networksystem/pylon.h"
#include "engine/client/client.h" #include "engine/client/client.h"
@ -111,19 +112,21 @@ static_assert(sizeof(CServer) == 0x25264C0);
extern CServer* g_pServer; extern CServer* g_pServer;
extern ConVar sv_showconnecting;
extern ConVar sv_pylonVisibility;
extern ConVar sv_pylonRefreshRate;
extern ConVar sv_globalBanlist; extern ConVar sv_globalBanlist;
extern ConVar sv_banlistRefreshRate; extern ConVar sv_banlistRefreshRate;
extern ConVar sv_statusRefreshRate;
extern ConVar sv_showconnecting;
/* ==== CSERVER ========================================================================================================================================================= */ /* ==== CSERVER ========================================================================================================================================================= */
inline void(*CServer__FrameJob)(double flFrameTime, bool bRunOverlays, bool bUpdateFrame); inline void(*CServer__FrameJob)(double flFrameTime, bool bRunOverlays, bool bUpdateFrame);
inline void(*CServer__RunFrame)(CServer* pServer); inline void(*CServer__RunFrame)(CServer* pServer);
inline CClient*(*CServer__ConnectClient)(CServer* pServer, user_creds_s* pCreds); 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__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 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 class VServer : public IDetour
@ -136,6 +139,7 @@ class VServer : public IDetour
LogFunAdr("CServer::ConnectClient", CServer__ConnectClient); LogFunAdr("CServer::ConnectClient", CServer__ConnectClient);
LogFunAdr("CServer::RejectConnection", CServer__RejectConnection); LogFunAdr("CServer::RejectConnection", CServer__RejectConnection);
LogFunAdr("CServer::BroadcastMessage", CServer__BroadcastMessage); LogFunAdr("CServer::BroadcastMessage", CServer__BroadcastMessage);
LogFunAdr("CServer::SpawnServer", CServer__SpawnServer);
LogVarAdr("g_Server", g_pServer); LogVarAdr("g_Server", g_pServer);
#endif // !CLIENT_DLL #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("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 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("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 #endif // !CLIENT_DLL
} }
virtual void GetVar(void) const virtual void GetVar(void) const

View File

@ -162,19 +162,39 @@ bool SV_ActivateServer()
return v_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()) if (!sv_voiceenable->GetBool())
return; return false;
if (g_ServerGlobalVariables->m_nMaxClients <= 0) 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; return;
SVC_VoiceData voiceData(cl->GetUserID(), nBytes, data); SVC_VoiceData voiceData(cl->GetUserID(), nBytes, data);
for (int i = 0; i < g_ServerGlobalVariables->m_nMaxClients; i++) 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) if (!pClient)
continue; 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()) if (pClient->GetTeamNum() != cl->GetTeamNum() && !sv_alltalk->GetBool())
continue; continue;
// there's also supposed to be some xplat checks here //if (voice_noxplat->GetBool() && cl->GetXPlatID() != pClient->GetXPlatID())
// but since r5r is only on PC, there's no point in implementing them here //{
// if ((cl->GetXPlatID() -1) > 1 || (pClient->GetXPlatID() -1) > 1)
// continue;
//}
CNetChan* pNetChan = pClient->GetNetChan(); CNetChan* const pNetChan = pClient->GetNetChan();
if (!pNetChan) if (!pNetChan)
continue; continue;
@ -204,3 +227,69 @@ void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data
pClient->SendNetMsgEx(&voiceData, false, false, true); 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);
}
}

View File

@ -8,7 +8,6 @@ class CClient;
class CClient; class CClient;
/* ==== SV_MAIN ======================================================================================================================================================= */ /* ==== SV_MAIN ======================================================================================================================================================= */
inline bool(*CGameServer__SpawnServer)(void* thisptr, const char* pszMapName, const char* pszMapGroupName);
inline void(*v_SV_InitGameDLL)(void); inline void(*v_SV_InitGameDLL)(void);
inline void(*v_SV_ShutdownGameDLL)(void); inline void(*v_SV_ShutdownGameDLL)(void);
inline bool(*v_SV_ActivateServer)(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_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. // Returns true if this is a dedicated server.
inline bool IsDedicated() inline bool IsDedicated()
{ {
return *s_bIsDedicated; 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_InitGameDLL();
void SV_ShutdownGameDLL(); void SV_ShutdownGameDLL();
bool SV_ActivateServer(); bool SV_ActivateServer();
void SV_BroadcastVoiceData(CClient* const cl, const int nBytes, char* const data); 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_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); void SV_CheckClientsForBan(const CBanSystem::BannedList_t* const pBannedVec = nullptr);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -38,17 +76,16 @@ class HSV_Main : public IDetour
{ {
virtual void GetAdr(void) const virtual void GetAdr(void) const
{ {
LogFunAdr("CGameServer::SpawnServer", CGameServer__SpawnServer);
LogFunAdr("SV_InitGameDLL", v_SV_InitGameDLL); LogFunAdr("SV_InitGameDLL", v_SV_InitGameDLL);
LogFunAdr("SV_ShutdownGameDLL", v_SV_ShutdownGameDLL); LogFunAdr("SV_ShutdownGameDLL", v_SV_ShutdownGameDLL);
LogFunAdr("SV_ActivateServer", v_SV_ActivateServer); LogFunAdr("SV_ActivateServer", v_SV_ActivateServer);
LogFunAdr("SV_CreateBaseline", v_SV_CreateBaseline); LogFunAdr("SV_CreateBaseline", v_SV_CreateBaseline);
LogFunAdr("SV_BroadcastVoiceData", v_SV_BroadcastVoiceData); LogFunAdr("SV_BroadcastVoiceData", v_SV_BroadcastVoiceData);
LogVarAdr("s_bIsDedicated", s_bIsDedicated); LogVarAdr("s_bIsDedicated", s_bIsDedicated);
} }
virtual void GetFun(void) const 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 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 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); 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") 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<bool*>(); .FindPatternSelf("40 38 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
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 { } virtual void GetCon(void) const { }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -10,11 +10,13 @@
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "engine/cmd.h" #include "engine/cmd.h"
#include "engine/net.h" #include "engine/net.h"
#include "engine/shared/shared_rcon.h"
#include "engine/server/sv_rcon.h" #include "engine/server/sv_rcon.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "common/igameserverdata.h" #include "common/igameserverdata.h"
#include "mbedtls/include/mbedtls/sha512.h" #include "mbedtls/include/mbedtls/sha512.h"
#include "mbedtls/aes.h"
#include "mbedtls/ctr_drbg.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: constants // Purpose: constants
@ -27,15 +29,13 @@ static const char s_BannedMessage[] = "Go away.\n";
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: console variables // 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_WhiteListAddresChanged_f(IConVar* pConVar, const char* pOldString);
static void RCON_ConnectionCountChanged_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_password("sv_rcon_password", "", FCVAR_RELEASE, "Remote server access password (rcon server is disabled if empty)", &RCON_PasswordChanged_f);
static ConVar sv_rcon_debug("sv_rcon_debug", "0", FCVAR_RELEASE, "Show rcon debug information ( !slower! )");
static ConVar sv_rcon_sendlogs("sv_rcon_sendlogs", "0", FCVAR_RELEASE, "Network console logs to connected and authenticated sockets"); 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_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); 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_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_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_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_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_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: // Purpose:
@ -54,6 +56,7 @@ CRConServer::CRConServer(void)
, m_nAuthConnections(0) , m_nAuthConnections(0)
, m_bInitialized(false) , m_bInitialized(false)
{ {
memset(m_PasswordHash, 0, sizeof(m_PasswordHash));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -62,18 +65,20 @@ CRConServer::CRConServer(void)
CRConServer::~CRConServer(void) CRConServer::~CRConServer(void)
{ {
// NOTE: do not call Shutdown() from the destructor as the OS's socket // 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 // shutdown code instead
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: NETCON systems init // Purpose: NETCON systems init
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Init(void) void CRConServer::Init(const char* pPassword, const char* pNetKey)
{ {
if (!m_bInitialized) if (!m_bInitialized)
{ {
if (!SetPassword(rcon_password.GetString())) SetKey(pNetKey);
if (!SetPassword(pPassword))
{ {
return; return;
} }
@ -84,12 +89,14 @@ void CRConServer::Init(void)
return; 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_Address.SetFromString(Format("[%s]:%i", pszAddress, hostport->GetInt()).c_str(), true);
m_Socket.CreateListenSocket(m_Address); 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; 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); 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 // Purpose: run tasks for the RCON server
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -232,14 +252,14 @@ void CRConServer::RunFrame(void)
if (CheckForBan(data)) if (CheckForBan(data))
{ {
SendEncode(data.m_hSocket, s_BannedMessage, "", SendEncoded(data.m_hSocket, s_BannedMessage, "",
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, int(eDLL_T::NETCON));
Disconnect("banned"); Disconnect("banned");
continue; 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 - // nMessageType -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::SendEncode(const char* pResponseMsg, const char* pResponseVal, bool CRConServer::SendEncoded(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
{ {
vector<char> vecMsg; vector<char> vecMsg;
if (!Serialize(vecMsg, pResponseMsg, pResponseVal, if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
@ -320,8 +340,8 @@ bool CRConServer::SendEncode(const char* pResponseMsg, const char* pResponseVal,
// nMessageType - // nMessageType -
// Output: true on success, false otherwise // Output: true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::SendEncode(const SocketHandle_t hSocket, const char* pResponseMsg, const char* pResponseVal, bool CRConServer::SendEncoded(const SocketHandle_t hSocket, 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
{ {
vector<char> vecMsg; vector<char> vecMsg;
if (!Serialize(vecMsg, pResponseMsg, pResponseVal, if (!Serialize(vecMsg, pResponseMsg, pResponseVal,
@ -349,26 +369,10 @@ bool CRConServer::SendEncode(const SocketHandle_t hSocket, const char* pResponse
// Output : serialized results as string // Output : serialized results as string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, bool CRConServer::Serialize(vector<char>& 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; return SV_NetConSerialize(this, vecBuf, pResponseMsg, pResponseVal, responseType, nMessageId, nMessageType,
rcon_encryptframes.GetBool(), rcon_debug.GetBool());
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;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -376,7 +380,7 @@ bool CRConServer::Serialize(vector<char>& vecBuf, const char* pResponseMsg, cons
// Input : &request - // Input : &request -
// &data - // &data -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Authenticate(const cl_rcon::request& request, CConnectedNetConsoleData& data) void CRConServer::Authenticate(const netcon::request& request, CConnectedNetConsoleData& data)
{ {
if (data.m_bAuthorized) 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"; const char* pSendLogs = (!sv_rcon_sendlogs.GetBool() || data.m_bInputOnly) ? "0" : "1";
SendEncode(data.m_hSocket, s_AuthMessage, pSendLogs, SendEncoded(data.m_hSocket, s_AuthMessage, pSendLogs,
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
} }
else // Bad password. else // Bad password.
{ {
const netadr_t& netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex); 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()); Msg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString());
} }
SendEncode(data.m_hSocket, s_WrongPwMessage, "", SendEncoded(data.m_hSocket, s_WrongPwMessage, "",
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
data.m_bAuthorized = false; data.m_bAuthorized = false;
data.m_bValidated = 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) bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex); netcon::request request;
cl_rcon::request request; if (!SH_NetConUnpackEnvelope(this, pMsgBuf, nMsgLen, &request, rcon_debug.GetBool()))
if (!Decode(&request, pMsgBuf, nMsgLen))
{ {
Error(eDLL_T::SERVER, NO_ERROR, "Failed to decode RCON buffer\n"); Disconnect("received invalid message");
return false; return false;
} }
CConnectedNetConsoleData& data = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!data.m_bAuthorized && 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. // Notify netconsole that authentication is required.
SendEncode(data.m_hSocket, s_NoAuthMessage, "", SendEncoded(data.m_hSocket, s_NoAuthMessage, "",
sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)); netcon::response_e::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON));
data.m_bValidated = false; data.m_bValidated = false;
data.m_nIgnoredMessage++; data.m_nIgnoredMessage++;
@ -464,12 +469,12 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
} }
switch (request.requesttype()) switch (request.requesttype())
{ {
case cl_rcon::request_t::SERVERDATA_REQUEST_AUTH: case netcon::request_e::SERVERDATA_REQUEST_AUTH:
{ {
Authenticate(request, data); Authenticate(request, data);
break; 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. if (data.m_bAuthorized) // Only execute if auth was successful.
{ {
@ -477,7 +482,7 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
} }
break; break;
} }
case cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG: case netcon::request_e::SERVERDATA_REQUEST_SEND_CONSOLE_LOG:
{ {
if (data.m_bAuthorized) 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) // Purpose: execute commands issued from netconsole (ignores all protection flags)
// Input : &request - // Input : &request -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Execute(const cl_rcon::request& request) const void CRConServer::Execute(const netcon::request& request) const
{ {
const string& commandString = request.requestmsg(); Cmd_ExecuteUnrestricted(request.requestmsg().c_str(), request.requestval().c_str());
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<ConVar*>(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);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -578,10 +533,10 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData& data)
if (m_BannedList.size() >= RCON_MAX_BANNEDLIST_SIZE) 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]) 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(); Shutdown();
return true; return true;
@ -590,9 +545,9 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData& data)
// Only allow whitelisted at this point. // Only allow whitelisted at this point.
if (!m_WhiteListAddress.CompareAdr(netAdr)) 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; return true;
@ -680,7 +635,7 @@ void CRConServer::CloseNonAuthConnection(void)
// Input : responseType - // Input : responseType -
// Output : true if it should send, false otherwise // 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()) if (!IsInitialized() || !m_Socket.GetAcceptedSocketCount())
{ {
@ -688,7 +643,7 @@ bool CRConServer::ShouldSend(const sv_rcon::response_t responseType) const
return false; 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()) if (!sv_rcon_sendlogs.GetBool() || !m_Socket.GetAuthorizedSocketCount())
{ {
@ -716,6 +671,29 @@ int CRConServer::GetAuthenticatedCount(void) const
return m_nAuthConnections; 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 // 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 (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName()))
{ {
if (strcmp(pOldString, pConVarRef->GetString()) == NULL) if (strcmp(pOldString, pConVarRef->GetString()) == NULL)
return; // Same password. return; // Same value.
if (RCONServer()->IsInitialized()) #ifndef CLIENT_DLL
RCONServer()->SetPassword(pConVarRef->GetString()); // Reboot the RCON server to switch address type.
else RCONServer()->Reboot();
RCONServer()->Init(); // Initialize first. #endif // !CLIENT_DLL
} }
} }

View File

@ -1,8 +1,7 @@
#pragma once #pragma once
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "engine/shared/base_rcon.h" #include "engine/shared/base_rcon.h"
#define RCON_MIN_PASSWORD_LEN 8 #define RCON_MIN_PASSWORD_LEN 8
@ -15,45 +14,48 @@ public:
CRConServer(void); CRConServer(void);
~CRConServer(void); ~CRConServer(void);
void Init(void); void Init(const char* pPassword, const char* pNetKey = nullptr);
void Shutdown(void); void Shutdown(void);
void Reboot(void);
bool SetPassword(const char* pszPassword); bool SetPassword(const char* pszPassword);
bool SetWhiteListAddress(const char* pszAddress); bool SetWhiteListAddress(const char* pszAddress);
void Think(void); void Think(void);
void RunFrame(void); void RunFrame(void);
bool SendEncode(const char* pResponseMsg, const char* pResponseVal, bool SendEncoded(const char* pResponseMsg, const char* pResponseVal,
const sv_rcon::response_t responseType, const netcon::response_e responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageId = static_cast<int>(eDLL_T::NETCON),
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const; const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
bool SendEncode(const SocketHandle_t hSocket, const char* pResponseMsg, bool SendEncoded(const SocketHandle_t hSocket, const char* pResponseMsg,
const char* pResponseVal, const sv_rcon::response_t responseType, const char* pResponseVal, const netcon::response_e responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageId = static_cast<int>(eDLL_T::NETCON),
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const; const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
bool SendToAll(const char* pMsgBuf, const int nMsgLen) const; bool SendToAll(const char* pMsgBuf, const int nMsgLen) const;
bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const sv_rcon::response_t responseType, bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const netcon::response_e responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const; const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(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; bool Comparator(const string& svPassword) const;
virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override; 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); bool CheckForBan(CConnectedNetConsoleData& data);
virtual void Disconnect(const char* szReason = nullptr) override; virtual void Disconnect(const char* szReason = nullptr) override;
void Disconnect(const int nIndex, const char* szReason = nullptr); void Disconnect(const int nIndex, const char* szReason = nullptr);
void CloseNonAuthConnection(void); void CloseNonAuthConnection(void);
bool ShouldSend(const sv_rcon::response_t responseType) const; bool ShouldSend(const netcon::response_e responseType) const;
bool IsInitialized(void) const; bool IsInitialized(void) const;
int GetAuthenticatedCount(void) const; int GetAuthenticatedCount(void) const;
void CloseAllSockets() { m_Socket.CloseAllAcceptedSockets(); }
private: private:
int m_nConnIndex; int m_nConnIndex;

View File

@ -4,9 +4,126 @@
// //
//===========================================================================// //===========================================================================//
#include "core/stdafx.h" #include "core/stdafx.h"
#include "tier2/cryptutils.h"
#include "base_rcon.h" #include "base_rcon.h"
#include "engine/net.h" #include "engine/net.h"
#include "shared_rcon.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<const unsigned char*>(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<unsigned char*>(&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<const unsigned char*>(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 // Purpose: connect to remote
@ -56,7 +173,7 @@ bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
data.m_nPayloadRead = 0; 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; data.m_RecvBuffer[data.m_nPayloadRead++] = *pRecvBuf;
@ -95,6 +212,39 @@ bool CNetConBase::ProcessBuffer(CConnectedNetConsoleData& data,
return bSuccess; 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<const unsigned char*>(pInBuf), nDataLen))
return Crypto_CTREncrypt(ctx, reinterpret_cast<const unsigned char*>(pInBuf),
reinterpret_cast<unsigned char*>(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<const unsigned char*>(pInBuf),
reinterpret_cast<unsigned char*>(pOutBuf), m_NetKey, nDataLen);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: encode message to buffer // Purpose: encode message to buffer
// Input : *pMsg - // Input : *pMsg -

View File

@ -2,14 +2,23 @@
#define BASE_RCON_H #define BASE_RCON_H
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "tier2/cryptutils.h"
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "protobuf/message_lite.h" #include "protobuf/message_lite.h"
// Max size of the payload in the envelope frame
#define RCON_MAX_PAYLOAD_SIZE 1024*1024
class CNetConBase class CNetConBase
{ {
public: public:
CNetConBase(void) 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 bool Connect(const char* pHostName, const int nHostPort = SOCKET_ERROR);
virtual void Disconnect(const char* szReason = nullptr) { NOTE_UNUSED(szReason); }; 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 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 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 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; virtual bool Decode(google::protobuf::MessageLite* pMsg, const char* pMsgBuf, const size_t nMsgLen) const;
@ -29,6 +41,8 @@ public:
protected: protected:
CSocketCreator m_Socket; CSocketCreator m_Socket;
netadr_t m_Address; netadr_t m_Address;
CryptoKey_t m_NetKey;
CUtlString m_Base64NetKey;
}; };
#endif // BASE_RCON_H #endif // BASE_RCON_H

View File

@ -6,6 +6,39 @@
#include "core/stdafx.h" #include "core/stdafx.h"
#include "base_rcon.h" #include "base_rcon.h"
#include "shared_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<char>& 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 // Purpose: serialize message to vector
@ -14,24 +47,22 @@
// *szReqBuf - // *szReqBuf -
// *szReqVal - // *szReqVal -
// *requestType - // *requestType -
// bEncrypt -
// bDebug -
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CL_NetConSerialize(const CNetConBase* pBase, vector<char>& vecBuf, const char* szReqBuf, bool CL_NetConSerialize(const CNetConBase* pBase, vector<char>& 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_messageid(-1);
request.set_requesttype(requestType); request.set_requesttype(requestType);
request.set_requestmsg(szReqBuf); request.set_requestmsg(szReqBuf);
request.set_requestval(szReqVal); request.set_requestval(szReqVal);
const size_t msgLen = request.ByteSizeLong(); if (!SH_NetConPackEnvelope(pBase, vecBuf, request.ByteSizeLong(), &request, bEncrypt, bDebug))
vecBuf.resize(msgLen);
if (!pBase->Encode(&request, &vecBuf[0], msgLen))
{ {
Error(eDLL_T::CLIENT, NO_ERROR, "Failed to encode RCON buffer\n");
return false; return false;
} }
@ -50,7 +81,7 @@ bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostP
string svLocalHost; string svLocalHost;
const bool bValidSocket = nHostPort != SOCKET_ERROR; const bool bValidSocket = nHostPort != SOCKET_ERROR;
if (bValidSocket && strcmp(pHostAdr, "localhost") == 0) if (bValidSocket && (strcmp(pHostAdr, "localhost") == 0))
{ {
char szHostName[512]; char szHostName[512];
if (!gethostname(szHostName, sizeof(szHostName))) if (!gethostname(szHostName, sizeof(szHostName)))
@ -83,6 +114,165 @@ bool CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostP
return true; 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<char>& outMsgBuf, const size_t nMsgLen,
google::protobuf::MessageLite* inMsg, const bool bEncrypt, const bool bDebug)
{
char* encodeBuf = new char[nMsgLen];
std::unique_ptr<char[]> 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<char[]> 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<char[]> 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 // Purpose: gets the netconsole data
// Input : *pBase - // Input : *pBase -
@ -119,3 +309,92 @@ SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, const int iSocket)
return pData->m_hSocket; 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

View File

@ -1,13 +1,31 @@
#ifndef SHARED_RCON_H #ifndef SHARED_RCON_H
#define SHARED_RCON_H #define SHARED_RCON_H
#include "base_rcon.h" #include "base_rcon.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.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<char>& 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<char>& vecBuf, const char* szReqBuf, bool CL_NetConSerialize(const CNetConBase* pBase, vector<char>& 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 CL_NetConConnect(CNetConBase* pBase, const char* pHostAdr, const int nHostPort);
bool SH_NetConPackEnvelope(const CNetConBase* pBase, vector<char>& 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); CConnectedNetConsoleData* SH_GetNetConData(CNetConBase* pBase, const int iSocket);
SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, const int iSocket); SocketHandle_t SH_GetNetConSocketHandle(CNetConBase* pBase, const int iSocket);

View File

@ -20,6 +20,7 @@
#include "engine/host_cmd.h" #include "engine/host_cmd.h"
#include "engine/enginetrace.h" #include "engine/enginetrace.h"
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
#include "engine/server/server.h"
#include "engine/server/sv_main.h" #include "engine/server/sv_main.h"
#include "server/vengineserver_impl.h" #include "server/vengineserver_impl.h"
#include "game/server/gameinterface.h" #include "game/server/gameinterface.h"

View File

@ -7,32 +7,56 @@ start_sources()
if( ${PROJECT_NAME} STREQUAL "game_shared_static" ) 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.cpp"
"shared/ai_utility_shared.h" "shared/ai_utility_shared.h"
"shared/animation.cpp" )
"shared/animation.h"
"shared/collisionproperty.cpp" add_sources( SOURCE_GROUP "Entity"
"shared/collisionproperty.h"
"shared/ehandle.h" "shared/ehandle.h"
"shared/entitylist_base.cpp" "shared/entitylist_base.cpp"
"shared/entitylist_base.h" "shared/entitylist_base.h"
"shared/imovehelper.h" )
"shared/playernet_vars.h"
add_sources( SOURCE_GROUP "Prediction"
"shared/predictioncopy.h" "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.cpp"
"shared/usercmd.h" "shared/usercmd.h"
"shared/usermessages.h" "shared/usermessages.h"
)
add_sources( SOURCE_GROUP "Utility"
"shared/imovehelper.h"
"shared/util_shared.cpp" "shared/util_shared.cpp"
"shared/util_shared.h" "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.cpp"
"shared/vscript_shared.h" "shared/vscript_shared.h"
) )
add_sources( SOURCE_GROUP "Shared/Weapon" add_sources( SOURCE_GROUP "Weapon"
"shared/r1/weapon_bolt.cpp" "shared/r1/weapon_bolt.cpp"
"shared/r1/weapon_bolt.h" "shared/r1/weapon_bolt.h"
) )
@ -73,6 +97,8 @@ add_sources( SOURCE_GROUP "Network"
add_sources( SOURCE_GROUP "Player" add_sources( SOURCE_GROUP "Player"
"server/player.cpp" "server/player.cpp"
"server/player.h" "server/player.h"
"server/player_command.cpp"
"server/player_command.h"
"server/playerlocaldata.h" "server/playerlocaldata.h"
) )
@ -114,22 +140,37 @@ endif()
if( ${PROJECT_NAME} STREQUAL "client_static" ) if( ${PROJECT_NAME} STREQUAL "client_static" )
add_sources( SOURCE_GROUP "Client" add_sources( SOURCE_GROUP "Entity"
"client/c_baseentity.cpp" "client/c_baseentity.cpp"
"client/c_baseentity.h" "client/c_baseentity.h"
"client/c_baseplayer.h"
"client/cliententitylist.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.cpp"
"client/input.h" "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/spritemodel.cpp"
"client/util_client.cpp"
"client/util_client.h"
"client/viewrender.cpp" "client/viewrender.cpp"
"client/viewrender.h" "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.cpp"
"client/vscript_client.h" "client/vscript_client.h"
) )

View File

@ -63,11 +63,13 @@ int CAI_Network::NumLinks(void) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: gets the number of zones // Purpose: gets the number of zones
// input : idx -
// Output : int // 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];
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -12,7 +12,7 @@ public:
static void DebugConnectMsg(int node1, int node2, const char* pszFormat, ...); static void DebugConnectMsg(int node1, int node2, const char* pszFormat, ...);
void* GetVTable(void) const; void* GetVTable(void) const;
int NumLinks(void) const; int NumLinks(void) const;
int NumZones(void) const; int NumZones(const int idx) const;
int NumHints(void) const; int NumHints(void) const;
int NumScriptNodes(void) const; int NumScriptNodes(void) const;
int NumPathNodes(void) const; int NumPathNodes(void) const;
@ -32,12 +32,7 @@ public:
int m_nUnk0; int m_nUnk0;
CAI_HullData m_HullData[MAX_HULLS]; CAI_HullData m_HullData[MAX_HULLS];
int m_iNumZones[MAX_HULLS]; // +0x0088
int m_iNumZones; // +0x0088
int m_iUnkCount0;
int m_iUnkCount1;
int m_iUnkCount2;
int m_iUnkCount4;
// unk8 on disk // unk8 on disk
int unk5; // +0x009C int unk5; // +0x009C

View File

@ -225,19 +225,18 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
// Dump the hull data blocks // Dump the hull data blocks
// ------------------------------- // -------------------------------
// Pointer to numZones counter, incremented up and until for (int i = 0; i < MAX_HULLS; i++)
// the last counter field for the hull data block.
int* countPtr = &pNetwork->m_iNumZones;
for (int i = 0; i < MAX_HULLS; i++, countPtr++)
{ {
const CAI_HullData& hullData = pNetwork->m_HullData[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); const unsigned short numHullBits = (unsigned short)hullData.m_bitVec.GetNumBits();
buf.PutShort(hullData.m_Count); const unsigned short numHullInts = (unsigned short)hullData.m_bitVec.GetNumDWords();
buf.PutShort(hullData.unk1);
buf.Put(hullData.pBuffer, bufferSize); buf.PutInt(numHullZones);
buf.PutUnsignedShort(numHullBits);
buf.PutUnsignedShort(numHullInts);
buf.Put(hullData.m_bitVec.Base(), numHullInts * sizeof(int));
} }
timer.End(); timer.End();

View File

@ -5,6 +5,7 @@
//=============================================================================// //=============================================================================//
#pragma once #pragma once
#include "mathlib/vector.h" #include "mathlib/vector.h"
#include "mathlib/bitvec.h"
constexpr int MAX_HULLS = 5; constexpr int MAX_HULLS = 5;
constexpr int NOT_CACHED = -2; // Returned if data not in cache 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 struct CAI_HullData
{ {
short m_Count; // Multiplied by 4; probably total buffer size. CVarBitVec m_bitVec;
short unk1;
int unk2; // Unknown, possible part of CVarBitVec ??? see [r5apex_ds + 1A52B0] if,
void* pBuffer; // Hull data buffer. // 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]; char unk3[8];
}; };

View File

@ -44,6 +44,10 @@ struct CTether
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class CBaseCombatCharacter : public CBaseAnimatingOverlay class CBaseCombatCharacter : public CBaseAnimatingOverlay
{ {
public:
inline const char* GetNetName() const { return m_szNetname; };
private:
bool m_bPreventWeaponPickup; bool m_bPreventWeaponPickup;
char gap_15b1[3]; char gap_15b1[3];
float m_phaseShiftTimeStart; float m_phaseShiftTimeStart;
@ -146,5 +150,4 @@ class CBaseCombatCharacter : public CBaseAnimatingOverlay
int m_headAttachment; int m_headAttachment;
int m_chestAttachment; int m_chestAttachment;
}; };
#endif // BASECOMBATCHARACTER_H #endif // BASECOMBATCHARACTER_H

View File

@ -56,6 +56,8 @@ public:
inline edict_t GetEdict(void) { return NetworkProp()->GetEdict(); } inline edict_t GetEdict(void) { return NetworkProp()->GetEdict(); }
inline string_t GetEntityName(void) const { return m_iName; } inline string_t GetEntityName(void) const { return m_iName; }
inline int GetFlags(void) const { return m_fFlags; }
protected: protected:
CBaseHandle m_RefEHandle; CBaseHandle m_RefEHandle;
char gap_c[4]; char gap_c[4];

View File

@ -18,14 +18,15 @@
#include "engine/server/server.h" #include "engine/server/server.h"
#include "game/shared/usercmd.h" #include "game/shared/usercmd.h"
#include "game/server/util_server.h" #include "game/server/util_server.h"
#include "pluginsystem/pluginsystem.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// This is called when a new game is started. (restart, map) // This is called when a new game is started. (restart, map)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CServerGameDLL::GameInit(void) bool CServerGameDLL::GameInit(void)
{ {
const static int index = 1; const static int index = 1;
CallVFunc<void>(index, this); return CallVFunc<bool>(index, this);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -77,8 +78,39 @@ ServerClass* CServerGameDLL::GetAllServerClasses(void)
return CallVFunc<ServerClass*>(index, this); return CallVFunc<ServerClass*>(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) 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<CPlayer*>(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 // 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 // this isn't a great way of doing it but it works so meh
CServerGameDLL__OnReceivedSayTextMessage(thisptr, senderId, text, false); CServerGameDLL__OnReceivedSayTextMessage(thisptr, senderId, text, false);

View File

@ -19,7 +19,7 @@ class ServerClass;
class CServerGameDLL class CServerGameDLL
{ {
public: public:
void GameInit(void); bool GameInit(void);
void PrecompileScriptsJob(void); void PrecompileScriptsJob(void);
void LevelShutdown(void); void LevelShutdown(void);
void GameShutdown(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 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, inline void(*CServerGameClients__ProcessUserCmds)(CServerGameClients* thisp, edict_t edict, bf_read* buf,
int numCmds, int totalCmds, int droppedPackets, bool ignore, bool paused); int numCmds, int totalCmds, int droppedPackets, bool ignore, bool paused);
inline void(*v_RunFrameServer)(double flFrameTime, bool bRunOverlays, bool bUniformUpdate); inline void(*v_RunFrameServer)(double flFrameTime, bool bRunOverlays, bool bUniformUpdate);
inline float* g_pflServerFrameTimeBase = nullptr;
extern CServerGameDLL* g_pServerGameDLL; extern CServerGameDLL* g_pServerGameDLL;
extern CServerGameClients* g_pServerGameClients; extern CServerGameClients* g_pServerGameClients;
extern CServerGameEnts* g_pServerGameEntities; extern CServerGameEnts* g_pServerGameEntities;
@ -65,8 +69,10 @@ class VServerGameDLL : public IDetour
virtual void GetAdr(void) const virtual void GetAdr(void) const
{ {
LogFunAdr("CServerGameDLL::OnReceivedSayTextMessage", CServerGameDLL__OnReceivedSayTextMessage); LogFunAdr("CServerGameDLL::OnReceivedSayTextMessage", CServerGameDLL__OnReceivedSayTextMessage);
LogFunAdr("CServerGameDLL::GameInit", CServerGameDLL__GameInit);
LogFunAdr("CServerGameClients::ProcessUserCmds", CServerGameClients__ProcessUserCmds); LogFunAdr("CServerGameClients::ProcessUserCmds", CServerGameClients__ProcessUserCmds);
LogFunAdr("RunFrameServer", v_RunFrameServer); LogFunAdr("RunFrameServer", v_RunFrameServer);
LogVarAdr("g_flServerFrameTimeBase", g_pflServerFrameTimeBase);
LogVarAdr("g_pServerGameDLL", g_pServerGameDLL); LogVarAdr("g_pServerGameDLL", g_pServerGameDLL);
LogVarAdr("g_pServerGameClients", g_pServerGameClients); LogVarAdr("g_pServerGameClients", g_pServerGameClients);
LogVarAdr("g_pServerGameEntities", g_pServerGameEntities); LogVarAdr("g_pServerGameEntities", g_pServerGameEntities);
@ -75,12 +81,14 @@ class VServerGameDLL : public IDetour
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
g_GameDll.FindPatternSIMD("85 D2 0F 8E ?? ?? ?? ?? 4C 8B DC").GetPtr(CServerGameDLL__OnReceivedSayTextMessage); 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 ?? 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); 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 virtual void GetVar(void) const
{ {
g_pGlobals = g_GameDll.FindPatternSIMD("4C 8B 0D ?? ?? ?? ?? 48 8B D1").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CGlobalVars**>(); g_pGlobals = g_GameDll.FindPatternSIMD("4C 8B 0D ?? ?? ?? ?? 48 8B D1").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CGlobalVars**>();
g_pflServerFrameTimeBase = CMemory(CServerGameDLL__GameInit).FindPatternSelf("F3 0F 11 0D").ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
} }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const; virtual void Detour(const bool bAttach) const;

View File

@ -13,6 +13,9 @@
#include "engine/server/server.h" #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 // Purpose: executes a null command for this player
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -57,37 +60,29 @@ QAngle* CPlayer::EyeAngles(QAngle* pAngles)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline void CPlayer::SetTimeBase(float flTimeBase) 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) const float flAttemptedTime = Max(flTimeBase - (m_lastUCmdSimulationRemainderTime * TICK_INTERVAL), 0.0f);
flTime = 0.0f; SetTotalExtraClientCmdTimeAttempted(flAttemptedTime);
SetLastUCmdSimulationRemainderTime(flTime);
float flSimulationTime = flTimeBase - m_lastUCmdSimulationRemainderTime * (*g_pGlobals)->m_flTickInterval;
if (flSimulationTime >= 0.0f)
{
flTime = flSimulationTime;
}
SetTotalExtraClientCmdTimeAttempted(flTime);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Purpose: sets the last user cmd simulation remainder time // 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) if (nEdict != FL_EDICT_INVALID)
{ {
_InterlockedOr16((SHORT*)(*g_pGlobals)->m_pEdicts + nEdict + 32, 0x200u); _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) if (m_totalExtraClientCmdTimeAttempted != flAttemptedTime)
{ {
edict_t nEdict = NetworkProp()->GetEdict(); const edict_t nEdict = NetworkProp()->GetEdict();
if (nEdict != FL_EDICT_INVALID) if (nEdict != FL_EDICT_INVALID)
{ {
_InterlockedOr16((SHORT*)(*g_pGlobals)->m_pEdicts + nEdict + 32, 0x200u); _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 // Purpose: processes user cmd's for this player
// Input : *cmds - // Input : *cmds -
@ -179,7 +116,7 @@ void CPlayer::ClampUnlag(CUserCmd* cmd)
// TODO: this code is experimental and has reported problems from players with // 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! // high latency, needs to be debugged or a different approach needs to be taken!
// Defaulted to OFF for now // 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, void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
int droppedPackets, bool paused) 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]; 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--) for (int i = totalCmds - 1; i >= 0; i--)
{ {
CUserCmd* cmd = &cmds[i]; CUserCmd* cmd = &cmds[i];
@ -203,8 +143,22 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS) if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
return; 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()) 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]; CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
queuedCmd->Copy(cmd); queuedCmd->Copy(cmd);
@ -241,6 +195,25 @@ void CPlayer::SetLastUserCommand(CUserCmd* pUserCmd)
m_LastCmd.Copy(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 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); 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);
}

View File

@ -241,25 +241,28 @@ struct SpeedChangeHistoryEntry
class CPlayer : public CBaseCombatCharacter class CPlayer : public CBaseCombatCharacter
{ {
friend class CPlayerMove;
public: public:
void RunNullCommand(void); void RunNullCommand(void);
QAngle* EyeAngles(QAngle* pAngles); QAngle* EyeAngles(QAngle* pAngles);
void SetTimeBase(float flTimeBase); void SetTimeBase(float flTimeBase);
void SetLastUCmdSimulationRemainderTime(float flRemainderTime); void SetLastUCmdSimulationRemainderTime(int nRemainderTime);
void SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime); void SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime);
void ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds, void ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
int droppedPackets, bool paused); int droppedPackets, bool paused);
void ClampUnlag(CUserCmd* cmd);
void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover); void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover);
void SetLastUserCommand(CUserCmd* pUserCmd); void SetLastUserCommand(CUserCmd* pUserCmd);
inline bool IsConnected() const { return m_iConnected != PlayerDisconnected; } inline bool IsConnected() const { return m_iConnected != PlayerDisconnected; }
inline bool IsDisconnecting() const { return m_iConnected == PlayerDisconnecting; } 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: private:
int m_StuckLast; int m_StuckLast;
char gap_5a8c[4]; char gap_5a8c[4];
@ -276,7 +279,7 @@ private:
char m_hardwareIcon[16]; char m_hardwareIcon[16];
bool m_happyHourActive; bool m_happyHourActive;
char gap_5ee6[2]; char gap_5ee6[2];
__int64 m_platformUserId; NucleusID_t m_platformUserId;
char m_hardware; char m_hardware;
char gap_5ef1[7]; char gap_5ef1[7];
__int64 m_classModsActive; __int64 m_classModsActive;
@ -571,7 +574,7 @@ private:
float m_totalFrameTime; float m_totalFrameTime;
float m_joinFrameTime; float m_joinFrameTime;
int m_lastUCmdSimulationTicks; int m_lastUCmdSimulationTicks;
float m_lastUCmdSimulationRemainderTime; int m_lastUCmdSimulationRemainderTime; // Originally float???
float m_totalExtraClientCmdTimeAttempted; float m_totalExtraClientCmdTimeAttempted;
int m_hPlayerViewEntity; int m_hPlayerViewEntity;
bool m_atLeastOneCommandRunThisServerFrame; bool m_atLeastOneCommandRunThisServerFrame;
@ -796,6 +799,7 @@ static_assert(sizeof(CPlayer) == 0x7EF0); // !TODO: backwards compatibility.
inline QAngle*(*CPlayer__EyeAngles)(CPlayer* pPlayer, QAngle* pAngles); inline QAngle*(*CPlayer__EyeAngles)(CPlayer* pPlayer, QAngle* pAngles);
inline void(*CPlayer__PlayerRunCommand)(CPlayer* pPlayer, CUserCmd* pUserCmd, IMoveHelper* pMover); inline void(*CPlayer__PlayerRunCommand)(CPlayer* pPlayer, CUserCmd* pUserCmd, IMoveHelper* pMover);
inline bool(*CPlayer__PhysicsSimulate)(CPlayer* pPlayer, int numPerIteration, bool adjustTimeBase);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class VPlayer : public IDetour class VPlayer : public IDetour
@ -804,15 +808,17 @@ class VPlayer : public IDetour
{ {
LogFunAdr("CPlayer::EyeAngles", CPlayer__EyeAngles); LogFunAdr("CPlayer::EyeAngles", CPlayer__EyeAngles);
LogFunAdr("CPlayer::PlayerRunCommand", CPlayer__PlayerRunCommand); LogFunAdr("CPlayer::PlayerRunCommand", CPlayer__PlayerRunCommand);
LogFunAdr("CPlayer::PhysicsSimulate", CPlayer__PhysicsSimulate);
} }
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 F2 0F 10 05 ?? ?? ?? ??").GetPtr(CPlayer__EyeAngles); 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 ?? ?? ?? ?? 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 GetVar(void) const { }
virtual void GetCon(void) const { } virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const { } virtual void Detour(const bool bAttach) const;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -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);
}

View File

@ -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

View File

@ -83,6 +83,7 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); SCRIPT_CHECK_AND_RETURN(v, SQ_OK);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: shuts the server down and disconnects all clients // Purpose: shuts the server down and disconnects all clients
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -94,6 +95,21 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); 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 // Purpose: kicks a player by given name
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -231,6 +247,15 @@ namespace VScriptCode
SCRIPT_CHECK_AND_RETURN(v, SQ_OK); 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 // 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, 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, 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", "");
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------

View File

@ -9,6 +9,8 @@ namespace VScriptCode
SQRESULT CreateServer(HSQUIRRELVM v); SQRESULT CreateServer(HSQUIRRELVM v);
SQRESULT DestroyServer(HSQUIRRELVM v); SQRESULT DestroyServer(HSQUIRRELVM v);
SQRESULT SetAutoReloadState(HSQUIRRELVM v);
SQRESULT KickPlayerByName(HSQUIRRELVM v); SQRESULT KickPlayerByName(HSQUIRRELVM v);
SQRESULT KickPlayerById(HSQUIRRELVM v); SQRESULT KickPlayerById(HSQUIRRELVM v);
SQRESULT BanPlayerByName(HSQUIRRELVM v); SQRESULT BanPlayerByName(HSQUIRRELVM v);
@ -18,6 +20,8 @@ namespace VScriptCode
SQRESULT GetNumHumanPlayers(HSQUIRRELVM v); SQRESULT GetNumHumanPlayers(HSQUIRRELVM v);
SQRESULT GetNumFakeClients(HSQUIRRELVM v); SQRESULT GetNumFakeClients(HSQUIRRELVM v);
SQRESULT GetServerID(HSQUIRRELVM v);
SQRESULT IsServerActive(HSQUIRRELVM v); SQRESULT IsServerActive(HSQUIRRELVM v);
SQRESULT IsDedicated(HSQUIRRELVM v); SQRESULT IsDedicated(HSQUIRRELVM v);
} }

View File

@ -27,8 +27,7 @@ int ReadUserCmd(bf_read* buf, CUserCmd* move, CUserCmd* from)
const int seed = v_ReadUserCmd(buf, move, from); const int seed = v_ReadUserCmd(buf, move, from);
// Initialize the camera position as <0,0,0>, this should at least avoid // 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 // crash and meme behaviors.
// patches performed below.
if (!move->camerapos.IsValid()) if (!move->camerapos.IsValid())
move->camerapos.Init(); move->camerapos.Init();

View File

@ -48,12 +48,15 @@ public:
int32_t command_number; int32_t command_number;
int32_t tick_count; int32_t tick_count;
float_t command_time; float_t command_time;
QAngle viewangles; QAngle viewangles;
QAngle pitchangles; // Pitch angles? See [r5apex_ds+705D80]. QAngle pitchangles; // Pitch angles? See [r5apex_ds+705D80].
float_t forwardmove; float_t forwardmove;
float_t sidemove; float_t sidemove;
float_t upmove; float_t upmove;
int32_t buttons; int32_t buttons;
byte impulse; byte impulse;
byte cycleslot; byte cycleslot;
byte weaponindex; byte weaponindex;
@ -64,12 +67,18 @@ public:
bool controllermode; bool controllermode;
bool fixangles; bool fixangles;
bool setlastcycleslot; bool setlastcycleslot;
char pad_0x0034[157]; char pad_0x0034[149];
QAngle renderangles; // IDK what this is used for.
QAngle renderangles_copy; // IDK what this is used for. // Zipline vars (see [r5apex_ds+8A6573] for read).
bool placedZiplineStation;
char unk[3];
int nUnkDC;
Vector3D beginStationOrigin;
Vector3D stationWorldRelative;
float fUnkF8; float fUnkF8;
QAngle another_renderangles_copy; // IDK what this is used for. Vector3D endStationOrigin;
QAngle yet_another_renderangles_copy; // IDK what this is used for. QAngle stationWorldAngles;
char pad_0x00114[112]; char pad_0x00114[112];
int32_t randomseed; int32_t randomseed;
byte bUnk188; byte bUnk188;

View File

@ -52,6 +52,7 @@ CBrowser::CBrowser(void)
{ {
m_surfaceLabel = "Server Browser"; m_surfaceLabel = "Server Browser";
memset(m_serverTokenTextBuf, '\0', sizeof(m_serverTokenTextBuf));
memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf)); memset(m_serverAddressTextBuf, '\0', sizeof(m_serverAddressTextBuf));
memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf)); memset(m_serverNetKeyTextBuf, '\0', sizeof(m_serverNetKeyTextBuf));
@ -71,7 +72,7 @@ CBrowser::~CBrowser(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CBrowser::Init(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<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize), bool ret = LoadTextureBuffer(reinterpret_cast<unsigned char*>(m_lockedIconDataResource.m_pData), int(m_lockedIconDataResource.m_nSize),
&m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight); &m_lockedIconShaderResource, &m_lockedIconDataResource.m_nWidth, &m_lockedIconDataResource.m_nHeight);
@ -343,10 +344,10 @@ void CBrowser::DrawBrowserPanel(void)
ImGui::PushItemWidth(itemWidth); 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::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(); ImGui::SameLine();
if (ImGui::Button("Connect", ImVec2(itemWidth, ImGui::GetFrameHeight()))) if (ImGui::Button("Connect", ImVec2(itemWidth, ImGui::GetFrameHeight())))
@ -437,8 +438,8 @@ void CBrowser::HiddenServersModal(void)
const ImVec2 contentRegionMax = ImGui::GetContentRegionAvail(); const ImVec2 contentRegionMax = ImGui::GetContentRegionAvail();
ImGui::PushItemWidth(contentRegionMax.x); // Override item width. ImGui::PushItemWidth(contentRegionMax.x); // Override item width.
string hiddenServerToken; const bool hitEnter = ImGui::InputTextWithHint("##HiddenServersConnectModal_TokenInput", "Token (required)",
ImGui::InputTextWithHint("##HiddenServersConnectModal_TokenInput", "Token (required)", &hiddenServerToken); m_serverTokenTextBuf, sizeof(m_serverTokenTextBuf), ImGuiInputTextFlags_EnterReturnsTrue);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -453,15 +454,15 @@ void CBrowser::HiddenServersModal(void)
ImGui::TextColored(m_hiddenServerMessageColor, "%s", m_hiddenServerRequestMessage.c_str()); ImGui::TextColored(m_hiddenServerMessageColor, "%s", m_hiddenServerRequestMessage.c_str());
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("Connect", ImVec2(contentRegionMax.x, 24))) if (ImGui::Button("Connect", ImVec2(contentRegionMax.x, 24)) || hitEnter)
{ {
m_hiddenServerRequestMessage.clear(); m_hiddenServerRequestMessage.clear();
m_reclaimFocusOnTokenField = true; m_reclaimFocusOnTokenField = true;
if (!hiddenServerToken.empty()) if (m_serverTokenTextBuf[0])
{ {
NetGameServer_t server; 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()) if (result && !server.name.empty())
{ {

View File

@ -47,8 +47,9 @@ private:
bool m_reclaimFocusOnTokenField; bool m_reclaimFocusOnTokenField;
bool m_queryNewListNonRecursive; // When set, refreshes the server list once the next frame. bool m_queryNewListNonRecursive; // When set, refreshes the server list once the next frame.
bool m_queryGlobalBanList; bool m_queryGlobalBanList;
char m_serverTokenTextBuf[128];
char m_serverAddressTextBuf[128]; char m_serverAddressTextBuf[128];
char m_serverNetKeyTextBuf[30]; char m_serverNetKeyTextBuf[45];
ID3D11ShaderResourceView* m_lockedIconShaderResource; ID3D11ShaderResourceView* m_lockedIconShaderResource;
MODULERESOURCE m_lockedIconDataResource; MODULERESOURCE m_lockedIconDataResource;

View File

@ -255,6 +255,7 @@ bool CConsole::DrawSurface(void)
ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavInputs |
ImGuiWindowFlags_OverlayHorizontalScrollbar; ImGuiWindowFlags_OverlayHorizontalScrollbar;
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_fadeAlpha); numLoggerStyleVars++;
ImGui::BeginChild(m_loggerLabel, ImVec2(0, -footerHeightReserve), loggerFlags, colorLoggerWindowFlags); ImGui::BeginChild(m_loggerLabel, ImVec2(0, -footerHeightReserve), loggerFlags, colorLoggerWindowFlags);
// NOTE: scoped so the mutex releases after we have rendered. // 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 maxWindowWidth = con_autocomplete_window_width.GetFloat();
const float flWindowWidth = maxWindowWidth > 0 const float flWindowWidth = maxWindowWidth > 0
? ImMin(con_autocomplete_window_width.GetFloat(), lastItemRectSize.x) ? ImMin(maxWindowWidth, lastItemRectSize.x)
: lastItemRectSize.x; : lastItemRectSize.x;
// NOTE: minimum vertical size of the window, going below this will // NOTE: minimum vertical size of the window, going below this will

View File

@ -32,13 +32,7 @@ bool Localize_LoadLocalizationFileLists(CLocalize* thisptr)
bool Localize_IsLanguageSupported(const char* pLocaleName) bool Localize_IsLanguageSupported(const char* pLocaleName)
{ {
for (int i = 0; i < SDK_ARRAYSIZE(g_LanguageNames); ++i) return V_LocaleNameExists(pLocaleName);
{
if (strcmp(pLocaleName, g_LanguageNames[i]) == NULL)
return true;
}
return false;
} }
void VLocalize::Detour(const bool bAttach) const void VLocalize::Detour(const bool bAttach) const

View File

@ -1,5 +1,5 @@
cmake_minimum_required( VERSION 3.16 ) cmake_minimum_required( VERSION 3.16 )
add_module( "exe" "naveditor" "" ${FOLDER_CONTEXT} TRUE TRUE ) add_module( "exe" "recast" "" ${FOLDER_CONTEXT} TRUE TRUE )
start_sources() start_sources()

View File

@ -1,5 +1,5 @@
cmake_minimum_required( VERSION 3.16 ) 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() start_sources()
@ -31,11 +31,8 @@ add_sources( SOURCE_GROUP "Windows"
end_sources( "${BUILD_OUTPUT_DIR}/bin/" ) end_sources( "${BUILD_OUTPUT_DIR}/bin/" )
set_target_properties( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME
"netcon32"
)
set_target_properties( ${PROJECT_NAME} PROPERTIES set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND "netcon32.exe" VS_DEBUGGER_COMMAND "${PROJECT_NAME}.exe"
VS_DEBUGGER_COMMAND_ARGUMENTS "-ansicolor" VS_DEBUGGER_COMMAND_ARGUMENTS "-ansicolor"
VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/bin/" VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/bin/"
) )
@ -48,8 +45,15 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
"tier2" "tier2"
"libprotobuf" "libprotobuf"
"libspdlog" "libspdlog"
"SV_RCon_Pb" "libmbedcrypto"
"CL_RCon_Pb" "libmbedtls"
"libmbedx509"
"NetCon_Pb"
"Rpcrt4.lib" "Rpcrt4.lib"
"ws2_32.lib" "ws2_32.lib"
"bcrypt.lib"
"crypt32.lib"
)
target_include_directories( ${PROJECT_NAME} PRIVATE
"${THIRDPARTY_SOURCE_DIR}/mbedtls/include"
) )

View File

@ -12,8 +12,7 @@
#include "tier1/NetAdr.h" #include "tier1/NetAdr.h"
#include "tier2/socketcreator.h" #include "tier2/socketcreator.h"
#include "windows/console.h" #include "windows/console.h"
#include "protoc/sv_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/cl_rcon.pb.h"
#include "engine/net.h" #include "engine/net.h"
#include "engine/shared/shared_rcon.h" #include "engine/shared/shared_rcon.h"
#include "netconsole/netconsole.h" #include "netconsole/netconsole.h"
@ -25,6 +24,7 @@ CNetCon::CNetCon(void)
: m_bInitialized(false) : m_bInitialized(false)
, m_bQuitting(false) , m_bQuitting(false)
, m_bPromptConnect(true) , m_bPromptConnect(true)
, m_bEncryptFrames(false)
, m_flTickInterval(0.05f) , m_flTickInterval(0.05f)
{ {
// Empty character set used for ip addresses if we still need to initiate a // 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 // Purpose: WSA and NETCON systems init
// Output : true on success, false otherwise // 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<std::mutex> l(m_Mutex); std::lock_guard<std::mutex> l(m_Mutex);
g_CoreMsgVCallback = &EngineLoggerSink; g_CoreMsgVCallback = &EngineLoggerSink;
TermSetup(bAnsiColor); TermSetup(bAnsiColor);
Msg(eDLL_T::NONE, "R5 TCP net console [Version %s]\n", NETCON_VERSION);
WSAData wsaData; WSAData wsaData;
const int nError = ::WSAStartup(MAKEWORD(2, 2), &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; return false;
} }
// Try to connect from given parameters, these are passed in from the // Install the encryption key and enable encryption if this has been passed
// command line. If we fail, return out as this allows the user to // in by the user.
// quickly retry again. if (pKey)
if (pHostName && nPort != SOCKET_ERROR)
{ {
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; return false;
} }
} }
m_bInitialized = true; m_bInitialized = true;
Msg(eDLL_T::NONE, "R5 TCP net console [Version %s]\n", NETCON_VERSION);
static std::thread frame([this]() static std::thread frame([this]()
{ {
@ -176,6 +185,24 @@ void CNetCon::TermSetup(const bool bAnsiColor)
SpdLog_InstallSupplementalLogger("supplemental_logger_mt", "netconsole.log"); 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 // 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. if (V_strcmp(cmd.Arg(0), "PASS") == 0) // Auth with RCON server.
{ {
bSend = Serialize(vecMsg, cmd.Arg(1), "", bSend = Serialize(vecMsg, cmd.Arg(1), "",
cl_rcon::request_t::SERVERDATA_REQUEST_AUTH); netcon::request_e::SERVERDATA_REQUEST_AUTH);
} }
else // Execute command query. else // Execute command query.
{ {
bSend = Serialize(vecMsg, cmd.Arg(0), cmd.GetCommandString(), 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. 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. if (bSend) // Only send if serialization process was successful.
@ -244,25 +271,31 @@ void CNetCon::RunInput(const string& lineInput)
if (cmd.ArgC() > 1) if (cmd.ArgC() > 1)
{ {
const char* inAddr = cmd.Arg(0); const char* inAdr = cmd.Arg(0);
const char* inPort = cmd.Arg(1); 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); SetPrompting(true);
return; return;
} }
if (!Connect(inAddr, atoi(inPort))) TrySetKey(inKey);
m_bEncryptFrames = true;
if (!Connect(inAdr))
{ {
SetPrompting(true); SetPrompting(true);
return; return;
} }
} }
else else // No encryption
{ {
if (!Connect(cmd.GetCommandString())) const char* inAdr = cmd.GetCommandString();
m_bEncryptFrames = false;
if (!Connect(inAdr))
{ {
SetPrompting(true); SetPrompting(true);
return; return;
@ -287,7 +320,7 @@ bool CNetCon::RunFrame(void)
} }
else if (GetPrompting()) else if (GetPrompting())
{ {
Msg(eDLL_T::NONE, "Enter [<IP>]:<PORT> or <IP> <PORT>: "); Msg(eDLL_T::NONE, "Enter [<address>]:<port> and <key>: ");
SetPrompting(false); SetPrompting(false);
} }
} }
@ -332,6 +365,28 @@ void CNetCon::SetPrompting(const bool bPrompt)
m_bPromptConnect = 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 // Purpose: disconnect from current session
// Input : *szReason - // Input : *szReason -
@ -360,18 +415,17 @@ void CNetCon::Disconnect(const char* szReason)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen) bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
{ {
sv_rcon::response response; netcon::response response;
bool bSuccess = Decode(&response, pMsgBuf, nMsgLen);
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; return false;
} }
switch (response.responsetype()) switch (response.responsetype())
{ {
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH: case netcon::response_e::SERVERDATA_RESPONSE_AUTH:
{ {
if (!response.responseval().empty()) 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. if (!i) // Means we are marked 'input only' on the rcon server.
{ {
vector<char> vecMsg; vector<char> 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()))) 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()); Msg(eDLL_T::NETCON, "%s", response.responsemsg().c_str());
break; break;
} }
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG: case netcon::response_e::SERVERDATA_RESPONSE_CONSOLE_LOG:
{ {
NetMsg(static_cast<LogType_t>(response.messagetype()), NetMsg(static_cast<LogType_t>(response.messagetype()),
static_cast<eDLL_T>(response.messageid()), static_cast<eDLL_T>(response.messageid()),
@ -416,9 +470,9 @@ bool CNetCon::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
// Output : true on success, false otherwise // Output : true on success, false otherwise
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CNetCon::Serialize(vector<char>& vecBuf, const char* szReqBuf, bool CNetCon::Serialize(vector<char>& 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[]) int main(int argc, char* argv[])
{ {
CheckCPUforSSE2(); CheckSystemCPUForSSE2();
bool bEnableColor = false; bool bEnableColor = false;
@ -466,16 +520,21 @@ int main(int argc, char* argv[])
} }
} }
const char* pHostName = nullptr; // The address and key from command line if passed in.
int nPort = SOCKET_ERROR; const char* pAdr = nullptr;
const char* pKey = nullptr;
if (argc >= 3) // Get IP and Port from command line. if (argc >= 2)
{ {
pHostName = argv[1]; pAdr = argv[1];
nPort = atoi(argv[2]);
} }
if (!NetConsole()->Init(bEnableColor, pHostName, nPort)) if (argc >= 3)
{
pKey = argv[2];
}
if (!NetConsole()->Init(bEnableColor, pAdr, pKey))
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -5,8 +5,7 @@
//===========================================================================// //===========================================================================//
#pragma once #pragma once
#include "tier1/cmd.h" #include "tier1/cmd.h"
#include "protoc/cl_rcon.pb.h" #include "protoc/netcon.pb.h"
#include "protoc/sv_rcon.pb.h"
#include "engine/shared/base_rcon.h" #include "engine/shared/base_rcon.h"
constexpr const char* NETCON_VERSION = "2.0.0.1"; constexpr const char* NETCON_VERSION = "2.0.0.1";
@ -17,7 +16,7 @@ public:
CNetCon(void); CNetCon(void);
~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); bool Shutdown(void);
void TermSetup(const bool bAnsiColor); void TermSetup(const bool bAnsiColor);
@ -33,11 +32,14 @@ public:
inline float GetTickInterval() const { return m_flTickInterval; } inline float GetTickInterval() const { return m_flTickInterval; }
static BOOL WINAPI CloseHandler(DWORD eventCode); 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; virtual bool ProcessMessage(const char* pMsgBuf, const int nMsgLen) override;
void TrySetKey(const char* const pKey);
bool Serialize(vector<char>& vecBuf, const char* szReqBuf, bool Serialize(vector<char>& 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); SocketHandle_t GetSocket(void);
bool IsInitialized(void) const; bool IsInitialized(void) const;
@ -47,6 +49,7 @@ private:
bool m_bInitialized; bool m_bInitialized;
bool m_bQuitting; bool m_bQuitting;
bool m_bPromptConnect; bool m_bPromptConnect;
bool m_bEncryptFrames;
float m_flTickInterval; float m_flTickInterval;
characterset_t m_CharacterSet; characterset_t m_CharacterSet;

View File

@ -23,8 +23,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
"libspdlog" "libspdlog"
"SigCache_Pb" "SigCache_Pb"
"SV_RCon_Pb" "NetCon_Pb"
"CL_RCon_Pb"
"Rpcrt4.lib" "Rpcrt4.lib"
) )

View File

@ -13,8 +13,12 @@ struct PluginHelpWithAnything_t
enum class ePluginCallback : int16_t enum class ePluginCallback : int16_t
{ {
// !! - WARNING: if any existing values are changed, you must increment INTERFACEVERSION_PLUGINSYSTEM - !!
CModAppSystemGroup_Create = 0, CModAppSystemGroup_Create = 0,
CServer_ConnectClient CServer_ConnectClient = 1,
SV_RegisterScriptFunctions = 2,
OnReceivedChatMessage = 3,
}; };
ePluginHelp m_nHelpID; ePluginHelp m_nHelpID;

View File

@ -131,7 +131,16 @@ CUtlVector<CPluginSystem::PluginInstance_t>& CPluginSystem::GetInstances()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help) void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help)
{ {
#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast<fn>(function) #define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast<fn>(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) switch (help->m_nCallbackID)
{ {
@ -145,6 +154,11 @@ void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help)
ADD_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction); ADD_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction);
break; break;
} }
case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage:
{
ADD_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction);
break;
}
default: default:
break; break;
} }
@ -160,6 +174,9 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help)
{ {
#define REMOVE_PLUGIN_CALLBACK(fn, callback, function) callback -= reinterpret_cast<fn>(function) #define REMOVE_PLUGIN_CALLBACK(fn, callback, function) callback -= reinterpret_cast<fn>(function)
if (!help->m_pFunction)
return;
switch (help->m_nCallbackID) switch (help->m_nCallbackID)
{ {
case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create: case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create:
@ -172,6 +189,11 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help)
REMOVE_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction); REMOVE_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction);
break; break;
} }
case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage:
{
REMOVE_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction);
break;
}
default: default:
break; break;
} }

View File

@ -6,6 +6,7 @@
class CModAppSystemGroup; class CModAppSystemGroup;
class CServer; class CServer;
class CClient; class CClient;
class CPlayer;
struct user_creds_s; struct user_creds_s;
template<typename T> template<typename T>
@ -82,6 +83,32 @@ private:
CUtlVector<T> m_vCallbacks; CUtlVector<T> m_vCallbacks;
}; };
template<typename T>
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 class CPluginSystem : IPluginSystem
{ {
public: public:
@ -120,10 +147,11 @@ public:
virtual void* HelpWithAnything(PluginHelpWithAnything_t* help); virtual void* HelpWithAnything(PluginHelpWithAnything_t* help);
#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList<typeName>& funcName() { return varName; } private: CPluginCallbackList<typeName> varName; #define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList<CPluginCallback<typeName>>& funcName() { return varName; } private: CPluginCallbackList<CPluginCallback<typeName>> varName;
CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks); CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks);
CREATE_PLUGIN_CALLBACK(ConnectClientFn, bool(*)(CServer*, CClient*, user_creds_s*), GetConnectClientCallbacks, connectClientCallbacks); 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 #undef CREATE_PLUGIN_CALLBACK
@ -140,4 +168,4 @@ FORCEINLINE CPluginSystem* PluginSystem()
// Monitor this and performance profile this if fps drops are detected. // Monitor this and performance profile this if fps drops are detected.
#define CALL_PLUGIN_CALLBACKS(callback, ...) \ #define CALL_PLUGIN_CALLBACKS(callback, ...) \
for (auto& cb : !callback) \ for (auto& cb : !callback) \
cb(__VA_ARGS__) cb.Function()(__VA_ARGS__)

View File

@ -23,25 +23,13 @@ add_sources( SOURCE_GROUP "Runtime"
end_sources() end_sources()
thirdparty_suppress_warnings() 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() start_sources()
add_sources( SOURCE_GROUP "Runtime" add_sources( SOURCE_GROUP "Runtime"
"sv_rcon.pb.cc" "netcon.pb.cc"
"sv_rcon.pb.h" "netcon.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"
) )
end_sources() end_sources()

View File

@ -1,489 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: cl_rcon.proto
#include "cl_rcon.pb.h"
#include <algorithm>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/extension_set.h>
#include <thirdparty/protobuf/wire_format_lite.h>
#include <thirdparty/protobuf/io/zero_copy_stream_impl_lite.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
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<std::string> 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<request_t>(int_value);
}
return success;
}
// ===================================================================
class request::_Internal {
public:
using HasBits = decltype(std::declval<request>()._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<std::string>(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<size_t>(reinterpret_cast<char*>(&_impl_.requesttype_) -
reinterpret_cast<char*>(&_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<std::string>()) {
(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<size_t>(
reinterpret_cast<char*>(&_impl_.requesttype_) -
reinterpret_cast<char*>(&_impl_.messageid_)) + sizeof(_impl_.requesttype_));
}
_impl_._has_bits_.Clear();
_internal_metadata_.Clear<std::string>();
}
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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<std::string>(),
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<int>(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<int>(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<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::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<std::string>(::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<const request*>(
&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<std::string>(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<char*>(&_impl_.messageid_),
reinterpret_cast<char*>(&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 <thirdparty/protobuf/port_undef.inc>

View File

@ -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 <limits>
#include <string>
#include <thirdparty/protobuf/port_def.inc>
#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 <thirdparty/protobuf/port_undef.inc>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/arena.h>
#include <thirdparty/protobuf/arenastring.h>
#include <thirdparty/protobuf/generated_message_util.h>
#include <thirdparty/protobuf/metadata_lite.h>
#include <thirdparty/protobuf/message_lite.h>
#include <thirdparty/protobuf/repeated_field.h> // IWYU pragma: export
#include <thirdparty/protobuf/extension_set.h> // IWYU pragma: export
#include <thirdparty/protobuf/generated_enum_util.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
#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<int32_t>::min(),
request_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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<typename T>
inline const std::string& request_t_Name(T enum_t_value) {
static_assert(::std::is_same<T, request_t>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function request_t_Name.");
return request_t_Name(static_cast<request_t>(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<const request*>(
&_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<request>(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 <typename ArgT0 = const std::string&, typename... ArgT>
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 <typename ArgT0 = const std::string&, typename... ArgT>
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 <typename T> 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 <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void request::set_requestmsg(ArgT0&& arg0, ArgT... args) {
_impl_._has_bits_[0] |= 0x00000001u;
_impl_.requestmsg_.Set(static_cast<ArgT0 &&>(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 <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void request::set_requestval(ArgT0&& arg0, ArgT... args) {
_impl_._has_bits_[0] |= 0x00000002u;
_impl_.requestval_.Set(static_cast<ArgT0 &&>(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 <thirdparty/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_cl_5frcon_2eproto

1235
r5dev/protoc/netcon.pb.cc Normal file

File diff suppressed because it is too large Load Diff

1279
r5dev/protoc/netcon.pb.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,485 +0,0 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: sv_rcon.proto
#include "sv_rcon.pb.h"
#include <algorithm>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/extension_set.h>
#include <thirdparty/protobuf/wire_format_lite.h>
#include <thirdparty/protobuf/io/zero_copy_stream_impl_lite.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
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<std::string> 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<response_t>(int_value);
}
return success;
}
// ===================================================================
class response::_Internal {
public:
using HasBits = decltype(std::declval<response>()._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<std::string>(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<size_t>(reinterpret_cast<char*>(&_impl_.responsetype_) -
reinterpret_cast<char*>(&_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<std::string>()) {
(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<size_t>(
reinterpret_cast<char*>(&_impl_.responsetype_) -
reinterpret_cast<char*>(&_impl_.messageid_)) + sizeof(_impl_.responsetype_));
}
_impl_._has_bits_.Clear();
_internal_metadata_.Clear<std::string>();
}
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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<std::string>(),
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<int>(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<int>(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<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::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<std::string>(::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<const response*>(
&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<std::string>(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<char*>(&_impl_.messageid_),
reinterpret_cast<char*>(&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 <thirdparty/protobuf/port_undef.inc>

View File

@ -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 <limits>
#include <string>
#include <thirdparty/protobuf/port_def.inc>
#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 <thirdparty/protobuf/port_undef.inc>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/arena.h>
#include <thirdparty/protobuf/arenastring.h>
#include <thirdparty/protobuf/generated_message_util.h>
#include <thirdparty/protobuf/metadata_lite.h>
#include <thirdparty/protobuf/message_lite.h>
#include <thirdparty/protobuf/repeated_field.h> // IWYU pragma: export
#include <thirdparty/protobuf/extension_set.h> // IWYU pragma: export
#include <thirdparty/protobuf/generated_enum_util.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
#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<int32_t>::min(),
response_t_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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<typename T>
inline const std::string& response_t_Name(T enum_t_value) {
static_assert(::std::is_same<T, response_t>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function response_t_Name.");
return response_t_Name(static_cast<response_t>(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<const response*>(
&_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<response>(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 <typename ArgT0 = const std::string&, typename... ArgT>
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 <typename ArgT0 = const std::string&, typename... ArgT>
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 <typename T> 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 <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void response::set_responsemsg(ArgT0&& arg0, ArgT... args) {
_impl_._has_bits_[0] |= 0x00000001u;
_impl_.responsemsg_.Set(static_cast<ArgT0 &&>(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 <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void response::set_responseval(ArgT0&& arg0, ArgT... args) {
_impl_._has_bits_[0] |= 0x00000002u;
_impl_.responseval_.Set(static_cast<ArgT0 &&>(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 <thirdparty/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_sv_5frcon_2eproto

View File

@ -26,6 +26,8 @@
#define FIXANGLE_ABSOLUTE 1 #define FIXANGLE_ABSOLUTE 1
#define FIXANGLE_RELATIVE 2 #define FIXANGLE_RELATIVE 2
#define FL_FAKECLIENT (1<<7) // Fake client, simulated server side; don't send network messages to them
enum RenderMode_t enum RenderMode_t
{ {
kRenderNormal = 0, // src kRenderNormal = 0, // src
@ -64,4 +66,22 @@ enum MoveType_t
MOVETYPE_ZEROG // ? 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 #endif // CONST_H

View File

@ -2,7 +2,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: // Purpose:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum GameMode_t enum class GameMode_t
{ {
NO_MODE = 0, NO_MODE = 0,
MP_MODE, MP_MODE,

View File

@ -65,6 +65,7 @@ inline const char* const g_LanguageNames[] = {
"italian", "italian",
"korean", "korean",
"spanish", "spanish",
"mspanish",
"schinese", "schinese",
"tchinese", "tchinese",
"russian", "russian",
@ -73,4 +74,46 @@ inline const char* const g_LanguageNames[] = {
"polish", "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 #endif // LOCALIZE_H

View File

@ -25,20 +25,20 @@ public:
__int64 requestedClass; __int64 requestedClass;
__int64 onDeathClass; __int64 onDeathClass;
__int64 oldClass; __int64 oldClass;
__int64 netname; string_t netname;
int fixangle; int fixangle;
Vector3D anglechange; QAngle anglechange;
int index; int index;
Vector3D forceWorldViewAngle; QAngle forceWorldViewAngle;
int forceWorldViewAngleUntilTick; int forceWorldViewAngleUntilTick;
bool replay; bool replay;
char gap_5d[3]; char gap_5d[3];
int lastPlayerView_tickcount; int lastPlayerView_tickcount;
Vector3D lastPlayerView_origin; Vector3D lastPlayerView_origin;
Vector3D lastPlayerView_angle; QAngle lastPlayerView_angle;
bool deadflag; bool deadflag;
char gap_7d[3]; char gap_7d[3];
Vector3D m_localViewAngles; QAngle m_localViewAngles;
}; };
#endif // PLAYERSTATE_H #endif // PLAYERSTATE_H

View File

@ -1,3 +1,8 @@
//=============================================================================//
//
// Purpose: pak file constants and types
//
//=============================================================================//
#ifndef RTECH_IPACKFILE_H #ifndef RTECH_IPACKFILE_H
#define RTECH_IPACKFILE_H #define RTECH_IPACKFILE_H
#include "tier0/jobthread.h" #include "tier0/jobthread.h"
@ -12,7 +17,7 @@
// pak header flags // pak header flags
#define PAK_HEADER_FLAGS_HAS_MODULE (1<<0) #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) #define PAK_HEADER_FLAGS_COMPRESSED (1<<8)
@ -20,15 +25,15 @@
#define PAK_HEADER_FLAGS_ZSTREAM_ENCODED (1<<9) #define PAK_HEADER_FLAGS_ZSTREAM_ENCODED (1<<9)
// max amount of types at runtime in which assets will be tracked // max amount of types at runtime in which assets will be tracked
#define PAK_MAX_TYPES 64 #define PAK_MAX_TRACKED_TYPES 64
#define PAK_MAX_TYPES_MASK (PAK_MAX_TYPES-1) #define PAK_MAX_TRACKED_TYPES_MASK (PAK_MAX_TRACKED_TYPES-1)
// max amount of global pak assets at runtime // max amount of global pak assets at runtime
#define PAK_MAX_ASSETS 0x40000 // TODO: rename to PAK_MAX_LOADED_ASSETS #define PAK_MAX_LOADED_ASSETS 0x40000
#define PAK_MAX_ASSETS_MASK (PAK_MAX_ASSETS-1) #define PAK_MAX_LOADED_ASSETS_MASK (PAK_MAX_LOADED_ASSETS-1)
// max amount of global pak assets tracked at runtime // 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) #define PAK_MAX_TRACKED_ASSETS_MASK (PAK_MAX_TRACKED_ASSETS-1)
// max amount of segments a pak file could have // max amount of segments a pak file could have
@ -42,8 +47,8 @@
#define PAK_MAX_STREAMING_FILE_HANDLES_PER_SET 4 #define PAK_MAX_STREAMING_FILE_HANDLES_PER_SET 4
// max amount of paks that could be loaded at runtime // 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_LOADED_PAKS 512
#define PAK_MAX_HANDLES_MASK (PAK_MAX_HANDLES-1) #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 // 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 // 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 // base pak directory containing paks sorted in platform specific subdirectories
#define PAK_BASE_PATH "paks\\" #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 // pak override directory; the system will looks for pak files in this directory
// first before falling back to PLATFORM_PAK_PATH // first before falling back to PAK_PLATFORM_PATH
#define PLATFORM_PAK_OVERRIDE_PATH PAK_BASE_PATH"Win64_override\\" #define PAK_PLATFORM_OVERRIDE_PATH PAK_BASE_PATH"Win64_override\\"
// the handle that should be returned when a pak failed to load or process // 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_MAX_DISPATCH_LOAD_JOBS 4
#define PAK_DEFAULT_JOB_GROUP_ID 0x3000 #define PAK_DEFAULT_JOB_GROUP_ID 0x3000
@ -90,7 +95,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Forward declarations // Forward declarations
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct PakFile_t; struct PakFile_s;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Handle types // Handle types
@ -101,7 +106,7 @@ typedef uint64_t PakGuid_t;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Page handle types // Page handle types
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct PakPageHeader_t struct PakPageHeader_s
{ {
uint32_t segmentIdx; uint32_t segmentIdx;
uint32_t pageAlignment; 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 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") #define ASSERT_PAKPTR_VALID(pak, ptr) Assert(IS_PAKPTR_VALID(pak, ptr), "Invalid pak page pointer")
union PakPage_t union PakPage_u
{ {
struct struct
{ {
@ -128,7 +133,7 @@ union PakPage_t
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Enumerations // Enumerations
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum EPakDecodeMode : int32_t enum PakDecodeMode_e
{ {
MODE_DISABLED = -1, MODE_DISABLED = -1,
@ -137,7 +142,7 @@ enum EPakDecodeMode : int32_t
MODE_ZSTD MODE_ZSTD
}; };
enum EPakStreamSet enum PakStreamSet_e
{ {
STREAMING_SET_MANDATORY = 0, STREAMING_SET_MANDATORY = 0,
STREAMING_SET_OPTIONAL, STREAMING_SET_OPTIONAL,
@ -146,7 +151,7 @@ enum EPakStreamSet
STREAMING_SET_COUNT STREAMING_SET_COUNT
}; };
enum EPakStatus : int32_t enum PakStatus_e
{ {
PAK_STATUS_FREED = 0, PAK_STATUS_FREED = 0,
PAK_STATUS_LOAD_PENDING = 1, PAK_STATUS_LOAD_PENDING = 1,
@ -166,7 +171,7 @@ enum EPakStatus : int32_t
PAK_STATUS_BUSY = 15 PAK_STATUS_BUSY = 15
}; };
struct PakAssetBinding_t struct PakAssetBinding_s
{ {
enum EType enum EType
{ {
@ -205,15 +210,15 @@ struct PakAssetBinding_t
// [ PIXIE ]: Should be the full size across Season 0-3. // [ 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 // the guid of this asset, which will be used to index into, and retrieve
// this asset from the hash table // this asset from the hash table
PakGuid_t guid; PakGuid_t guid;
uint64_t padding; // Unknown. uint64_t padding; // Unknown.
PakPage_t headPtr; PakPage_u headPtr;
PakPage_t dataPtr; PakPage_u dataPtr;
// offset to the streaming data in the streaming set // offset to the streaming data in the streaming set
uint64_t streamingDataFileOffset[STREAMING_SET_COUNT]; uint64_t streamingDataFileOffset[STREAMING_SET_COUNT];
@ -235,11 +240,11 @@ struct PakAsset_t
FORCEINLINE uint8_t HashTableIndexForAssetType() const 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; PakGuid_t guid;
uint32_t trackerIndex; uint32_t trackerIndex;
@ -264,11 +269,11 @@ struct PakTracker_s
int unk_4; int unk_4;
int unk_8; int unk_8;
char gap_C[644100]; char gap_C[644100];
int loadedAssetIndices[PAK_MAX_HANDLES]; int loadedAssetIndices[PAK_MAX_LOADED_PAKS];
char gap_9DC04[522240]; char gap_9DC04[522240];
}; };
class PakLoadedInfo_t class PakLoadedInfo_s
{ {
public: public:
struct StreamingInfo_t struct StreamingInfo_t
@ -292,7 +297,7 @@ public:
}; };
PakHandle_t handle; PakHandle_t handle;
EPakStatus status; PakStatus_e status;
JobID_t loadJobId; JobID_t loadJobId;
uint32_t padding_maybe; uint32_t padding_maybe;
@ -307,7 +312,7 @@ public:
void* segmentBuffers[PAK_SEGMENT_BUFFER_TYPES]; void* segmentBuffers[PAK_SEGMENT_BUFFER_TYPES];
_QWORD qword50; _QWORD qword50;
FILETIME fileTime; FILETIME fileTime;
PakFile_t* pakFile; PakFile_s* pakFile;
StreamingInfo_t streamInfo[STREAMING_SET_COUNT]; StreamingInfo_t streamInfo[STREAMING_SET_COUNT];
uint32_t fileHandle; uint32_t fileHandle;
uint8_t m_nUnk5; uint8_t m_nUnk5;
@ -315,11 +320,11 @@ public:
}; //Size: 0x00B8/0x00E8 }; //Size: 0x00B8/0x00E8
struct PakGlobals_s struct PakGlobalState_s
{ {
// [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet. // [ PIXIE ]: Max possible registered assets on Season 3, 0-2 I did not check yet.
PakAssetBinding_t assetBindings[PAK_MAX_TYPES]; PakAssetBinding_s assetBindings[PAK_MAX_TRACKED_TYPES];
PakAssetShort_t loadedAssets[PAK_MAX_ASSETS]; PakAssetShort_s loadedAssets[PAK_MAX_LOADED_ASSETS];
// assets that are tracked across all asset types // assets that are tracked across all asset types
PakAssetTracker_s trackedAssets[PAK_MAX_TRACKED_ASSETS]; PakAssetTracker_s trackedAssets[PAK_MAX_TRACKED_ASSETS];
@ -328,11 +333,11 @@ struct PakGlobals_s
RHashMap loadedPakMap; // links to 'loadedPaks' RHashMap loadedPakMap; // links to 'loadedPaks'
// all currently loaded pak handles // 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' RMultiHashMap unkMap2; // links to 'unkIntArray' and 'unkIntArray2'
int unkIntArray[PAK_MAX_TRACKED_ASSETS]; int unkIntArray[PAK_MAX_TRACKED_ASSETS];
int unkIntArray2[PAK_MAX_ASSETS]; int unkIntArray2[PAK_MAX_LOADED_ASSETS];
// whether asset streaming (mandatory & optional) is enabled // whether asset streaming (mandatory & optional) is enabled
b64 useStreamingSystem; b64 useStreamingSystem;
@ -365,10 +370,10 @@ struct PakGlobals_s
int16_t loadedPakCount; int16_t loadedPakCount;
int16_t requestedPakCount; int16_t requestedPakCount;
PakHandle_t loadedPakHandles[PAK_MAX_HANDLES]; PakHandle_t loadedPakHandles[PAK_MAX_LOADED_PAKS];
JobTypeID_t assetBindJobTypes[PAK_MAX_TYPES]; JobTypeID_t assetBindJobTypes[PAK_MAX_TRACKED_TYPES];
JobTypeID_t jobTypeSlots_Unused[PAK_MAX_TYPES]; JobTypeID_t jobTypeSlots_Unused[PAK_MAX_TRACKED_TYPES];
JobTypeID_t dispatchLoadJobTypes[PAK_MAX_DISPATCH_LOAD_JOBS]; JobTypeID_t dispatchLoadJobTypes[PAK_MAX_DISPATCH_LOAD_JOBS];
uint8_t dispathLoadJobPriorities[PAK_MAX_DISPATCH_LOAD_JOBS]; // promoted to JobPriority_e uint8_t dispathLoadJobPriorities[PAK_MAX_DISPATCH_LOAD_JOBS]; // promoted to JobPriority_e
@ -390,19 +395,19 @@ struct PakGlobals_s
uint8_t* patchNumbers; uint8_t* patchNumbers;
}; };
struct PakPatchFileHeader_t struct PakPatchFileHeader_s
{ {
uint64_t compressedSize; uint64_t compressedSize;
uint64_t decompressedSize; uint64_t decompressedSize;
}; };
struct PakPatchDataHeader_t struct PakPatchDataHeader_s
{ {
uint32_t editStreamSize; uint32_t editStreamSize;
uint32_t pageCount; uint32_t pageCount;
}; };
struct PakFileHeader_t struct PakFileHeader_s
{ {
inline uint32_t GetTotalStreamingNamesBufferSize() const inline uint32_t GetTotalStreamingNamesBufferSize() const
{ {
@ -420,30 +425,30 @@ struct PakFileHeader_t
inline uint64_t GetTotalHeaderSize() const 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 we have patches, we should include the patch header as well
if (patchIndex > 0) if (patchIndex > 0)
headerSize += sizeof(PakPatchDataHeader_t); headerSize += sizeof(PakPatchDataHeader_s);
// the streaming file paths belong to the header as well // the streaming file paths belong to the header as well
headerSize += GetTotalStreamingNamesBufferSize(); headerSize += GetTotalStreamingNamesBufferSize();
return headerSize; return headerSize;
} }
inline EPakDecodeMode GetCompressionMode() const inline PakDecodeMode_e GetCompressionMode() const
{ {
if (flags & PAK_HEADER_FLAGS_ZSTREAM_ENCODED) 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 // NOTE: this should be the first check once we rebuilt function
// 14043F300 and alloc ring buffer for the flags individually instead // 14043F300 and alloc ring buffer for the flags individually instead
// instead of having to define the main compress flag (which really // instead of having to define the main compress flag (which really
// just means that the pak is using the RTech decoder) // just means that the pak is using the RTech decoder)
else if (flags & PAK_HEADER_FLAGS_COMPRESSED) 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 // file versions
@ -496,7 +501,7 @@ struct PakFileHeader_t
uint32_t memPageOffset; uint32_t memPageOffset;
uint8_t unk3[0x8]; uint8_t unk3[0x8];
}; static_assert(sizeof(PakFileHeader_t) == 0x80); }; static_assert(sizeof(PakFileHeader_s) == 0x80);
// segment flags // segment flags
#define SF_HEAD (0) #define SF_HEAD (0)
@ -504,23 +509,23 @@ struct PakFileHeader_t
#define SF_CPU (1 << 1) // 0x2 #define SF_CPU (1 << 1) // 0x2
#define SF_DEV (1 << 8) // 0x80 #define SF_DEV (1 << 8) // 0x80
struct PakSegmentHeader_t struct PakSegmentHeader_s
{ {
int typeFlags; int typeFlags;
int dataAlignment; int dataAlignment;
size_t dataSize; 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]; int64_t segmentSizes[PAK_MAX_SEGMENTS];
size_t segmentSizeForType[PAK_SEGMENT_BUFFER_TYPES]; size_t segmentSizeForType[PAK_SEGMENT_BUFFER_TYPES];
int segmentAlignmentForType[PAK_SEGMENT_BUFFER_TYPES]; int segmentAlignmentForType[PAK_SEGMENT_BUFFER_TYPES];
}; };
struct PakDecoder_t struct PakDecoder_s
{ {
const uint8_t* inputBuf; const uint8_t* inputBuf;
uint8_t* outputBuf; uint8_t* outputBuf;
@ -537,7 +542,7 @@ struct PakDecoder_t
uint32_t headerOffset; uint32_t headerOffset;
// this field was unused, it now contains the decoder mode // 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 // NOTE: unless you are in the RTech decoder, use the getter if you need to
// get the current pos!!! // get the current pos!!!
@ -574,13 +579,13 @@ struct PakDecoder_t
}; };
}; };
struct PakRingBufferFrame_t struct PakRingBufferFrame_s
{ {
size_t bufIndex; size_t bufIndex;
size_t frameLen; size_t frameLen;
}; };
struct PakFileStream_t struct PakFileStream_s
{ {
struct Descriptor struct Descriptor
{ {
@ -590,7 +595,7 @@ struct PakFileStream_t
// NOTE: if this is set, the game sets 'PakMemoryData_t::processedPatchedDataSize' // NOTE: if this is set, the game sets 'PakMemoryData_t::processedPatchedDataSize'
// to 'dataOffset'; else its getting set to 'sizeof(PakFileHeader_t)'. // to 'dataOffset'; else its getting set to 'sizeof(PakFileHeader_t)'.
EPakDecodeMode compressionMode; PakDecodeMode_e compressionMode;
}; };
_QWORD qword0; _QWORD qword0;
@ -610,11 +615,11 @@ struct PakFileStream_t
_QWORD bytesStreamed; _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_CMD0,
PATCH_CMD1, PATCH_CMD1,
@ -636,9 +641,9 @@ typedef struct PakPatchFuncs_s
PatchFunc_t patchFuncs[PATCH_CMD_COUNT]; PatchFunc_t patchFuncs[PATCH_CMD_COUNT];
} PakPatchFuncs_t; };
struct PakMemoryData_t struct PakMemoryData_s
{ {
uint64_t processedPatchedDataSize; uint64_t processedPatchedDataSize;
char* patchData; // pointer to patch stream data char* patchData; // pointer to patch stream data
@ -670,37 +675,37 @@ struct PakMemoryData_t
int* loadedAssetIndices; int* loadedAssetIndices;
uint8_t** memPageBuffers; uint8_t** memPageBuffers;
PakPatchFileHeader_t* patchHeaders; PakPatchFileHeader_s* patchHeaders;
unsigned short* patchIndices; unsigned short* patchIndices;
char* streamingFilePaths[STREAMING_SET_COUNT]; char* streamingFilePaths[STREAMING_SET_COUNT];
PakSegmentHeader_t* segmentHeaders; PakSegmentHeader_s* segmentHeaders;
PakPageHeader_t* pageHeaders; PakPageHeader_s* pageHeaders;
PakPage_t* virtualPointers; PakPage_u* virtualPointers;
PakAsset_t* assetEntries; PakAsset_s* assetEntries;
PakPage_t* guidDescriptors; PakPage_u* guidDescriptors;
uint32_t* fileRelations; uint32_t* fileRelations;
char gap5E0[32]; char gap5E0[32];
PakPatchDataHeader_t* patchDataHeader; PakPatchDataHeader_s* patchDataHeader;
PakAsset_t** ppAssetEntries; PakAsset_s** ppAssetEntries;
int someAssetCount; int someAssetCount;
int numShiftedPointers; int numShiftedPointers;
// array of sizes/offsets in the SF_HEAD segment buffer // array of sizes/offsets in the SF_HEAD segment buffer
__int64 unkAssetTypeBindingSizes[PAK_MAX_TYPES]; __int64 unkAssetTypeBindingSizes[PAK_MAX_TRACKED_TYPES];
const char* fileName; const char* fileName;
PakFileHeader_t pakHeader; PakFileHeader_s pakHeader;
PakPatchFileHeader_t patchHeader; PakPatchFileHeader_s patchHeader;
}; };
struct PakFile_t struct PakFile_s
{ {
int numProcessedPointers; int numProcessedPointers;
uint32_t processedAssetCount; uint32_t processedAssetCount;
@ -710,26 +715,26 @@ struct PakFile_t
uint32_t patchCount; uint32_t patchCount;
uint32_t dword14; uint32_t dword14;
PakFileStream_t fileStream; PakFileStream_s fileStream;
uint64_t inputBytePos; uint64_t inputBytePos;
uint8_t byte1F8; uint8_t byte1F8;
char gap1F9[4]; char gap1F9[4];
uint8_t byte1FD; uint8_t byte1FD;
bool isOffsetted_MAYBE; bool isOffsetted_MAYBE;
bool isCompressed; bool isCompressed;
PakDecoder_t pakDecoder; PakDecoder_s pakDecoder;
uint8_t* decompBuffer; uint8_t* decompBuffer;
size_t maxCopySize; size_t maxCopySize;
uint64_t qword298; uint64_t qword298;
PakMemoryData_t memoryData; PakMemoryData_s memoryData;
inline const char* GetName() const inline const char* GetName() const
{ {
return memoryData.fileName; return memoryData.fileName;
} }
inline const PakFileHeader_t& GetHeader() const inline const PakFileHeader_s& GetHeader() const
{ {
return memoryData.pakHeader; return memoryData.pakHeader;
} }
@ -766,7 +771,7 @@ struct PakFile_t
return true; 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()); assert(i != UINT32_MAX && i < GetPageCount());
@ -786,14 +791,14 @@ struct PakFile_t
return memoryData.memPageBuffers[index] + offset; 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)); assert(IsPageOffsetValid(ptr.index, ptr.offset));
return memoryData.memPageBuffers[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)); assert(IsPageOffsetValid(ptr->index, ptr->offset));
@ -806,7 +811,7 @@ struct PakFile_t
return GetHeader().virtualSegmentCount; 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()); assert(i < GetSegmentCount());
@ -816,11 +821,11 @@ struct PakFile_t
static_assert(sizeof(PakTracker_s) == 0x11D410); static_assert(sizeof(PakTracker_s) == 0x11D410);
static_assert(sizeof(PakFile_t) == 2224); // S3+ static_assert(sizeof(PakFile_s) == 2224); // S3+
static_assert(sizeof(PakLoadedInfo_t) == 184); static_assert(sizeof(PakLoadedInfo_s) == 184);
static_assert(sizeof(PakDecoder_t) == 136); static_assert(sizeof(PakDecoder_s) == 136);
static_assert(sizeof(PakPatchFileHeader_t) == 16); static_assert(sizeof(PakPatchFileHeader_s) == 16);
static_assert(sizeof(PakPatchDataHeader_t) == 8); static_assert(sizeof(PakPatchDataHeader_s) == 8);
static_assert(sizeof(PakGlobals_s) == 0xC98A48); static_assert(sizeof(PakGlobalState_s) == 0xC98A48);
#endif // RTECH_IPACKFILE_H #endif // RTECH_IPACKFILE_H

View File

@ -4,8 +4,8 @@
#include "public/iframetask.h" #include "public/iframetask.h"
//=============================================================================// //=============================================================================//
// This class is set up to run before each frame (main thread). // This class is set up to run before each frame, committed tasks are scheduled
// Committed tasks are scheduled to execute after 'i' frames. // to execute after 'i' frames.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// A use case for scheduling tasks in the main thread would be (for example) // 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 // performing a web request in a separate thread, and apply the results (such as

View File

@ -7,7 +7,7 @@
#define SIGDB_DICT_SIZE 20 #define SIGDB_DICT_SIZE 20
#define SIGDB_MAJOR_VERSION 0x2 // Increment when library changes are made. #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 class CSigCache
{ {

View File

@ -212,6 +212,24 @@ public:
int64 ReadSignedVarInt64() { return bitbuf::ZigZagDecode64(ReadVarInt64()); } int64 ReadSignedVarInt64() { return bitbuf::ZigZagDecode64(ReadVarInt64()); }
void ReadBits(void* pOutData, int nBits); 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 <typename T, int N>
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); bool ReadBytes(void* pOut, int nBytes);
@ -362,7 +380,7 @@ public:
: CBitRead(pData, nBytes, nBits) {} : CBitRead(pData, nBytes, nBits) {}
bf_read(const char* pDebugName, void* pData, int nBytes, int nMaxBits = -1) 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() bf_read(void) : CBitRead()
{} {}
@ -423,7 +441,9 @@ FORCEINLINE void CBitRead::GrabNextDWord(bool bOverFlowImmediately)
{ {
if (m_pDataIn > m_pBufferEnd) if (m_pDataIn > m_pBufferEnd)
{ {
if (!IsOverflowed())
SetOverflowFlag(); SetOverflowFlag();
m_nInBufWord = 0; m_nInBufWord = 0;
} }
else else

View File

@ -183,7 +183,7 @@ public:
inputBuffer = outputBuffer; 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 (!m_bSwapBytes || (sizeof(T) == 1))
{ {
// If we were just going to swap in place then return. // If we were just going to swap in place then return.

View File

@ -7,6 +7,7 @@
#define INCORRECT_PATH_SEPARATOR_S "/" #define INCORRECT_PATH_SEPARATOR_S "/"
#define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES ":/\\" #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES ":/\\"
#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/') #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
#define PATHSEPARATORW(c) ((c) == L'\\' || (c) == L'/')
#elif POSIX || defined( _PS3 ) #elif POSIX || defined( _PS3 )
#define CORRECT_PATH_SEPARATOR '/' #define CORRECT_PATH_SEPARATOR '/'
#define CORRECT_PATH_SEPARATOR_S "/" #define CORRECT_PATH_SEPARATOR_S "/"
@ -14,6 +15,7 @@
#define INCORRECT_PATH_SEPARATOR_S "\\" #define INCORRECT_PATH_SEPARATOR_S "\\"
#define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES "/" #define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES "/"
#define PATHSEPARATOR(c) ((c) == '/') #define PATHSEPARATOR(c) ((c) == '/')
#define PATHSEPARATORW(c) ((c) == L'/')
#endif #endif
#define COPY_ALL_CHARACTERS -1 #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); size_t V_StripLastDir(char* dirName, size_t maxLen);
// Returns a pointer to the unqualified file name (no path) of a file name // Returns a pointer to the unqualified file name (no path) of a file name
const char* V_UnqualifiedFileName(const char* in); 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 // 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); void V_ComposeFileName(const char* path, const char* filename, char* dest, size_t destSize);

View File

@ -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

View File

@ -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 <map>
#include <vector>
#include <unordered_map>
#include <utility>
#include <fstream>
#include <memory>
#include <unordered_set>
#include <algorithm>
#include <iterator>
#include <functional>
#include <system_error>
#include <exception>
//for wstring support
#include <locale>
#include <string>
// internal
#include <stack>
//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 <typename T>
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<wchar_t>
{
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<type>::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 <class Facet>
struct deletable_facet : Facet
{
template <class... Args>
deletable_facet(Args &&... args) : Facet(std::forward<Args>(args)...) {}
~deletable_facet() {}
};
inline std::string string_converter(const std::wstring& w) //todo: use us-locale
{
std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>> conv1;
return conv1.to_bytes(w);
}
///////////////////////////////////////////////////////////////////////////
// Writer helper functions
///////////////////////////////////////////////////////////////////////////
template <typename charT>
class tabs
{
const size_t t;
public:
explicit CONSTEXPR tabs(size_t i) NOEXCEPT : t(i) {}
std::basic_string<charT> print() const { return std::basic_string<charT>(t, TYTI_L(charT, '\t')); }
inline CONSTEXPR tabs operator+(size_t i) const NOEXCEPT
{
return tabs(t + i);
}
};
template <typename oStreamT>
oStreamT& operator<<(oStreamT& s, const tabs<typename oStreamT::char_type> 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 <typename CharT>
struct basic_object
{
typedef CharT char_type;
std::basic_string<char_type> name;
std::unordered_map<std::basic_string<char_type>, std::basic_string<char_type>> attribs;
std::unordered_map<std::basic_string<char_type>, std::shared_ptr<basic_object<char_type>>> childs;
void add_attribute(std::basic_string<char_type> key, std::basic_string<char_type> value)
{
attribs.emplace(std::move(key), std::move(value));
}
void add_child(std::unique_ptr<basic_object<char_type>> child)
{
std::shared_ptr<basic_object<char_type>> obj{ child.release() };
childs.emplace(obj->name, obj);
}
void set_name(std::basic_string<char_type> n)
{
name = std::move(n);
}
};
template <typename CharT>
struct basic_multikey_object
{
typedef CharT char_type;
std::basic_string<char_type> name;
std::unordered_multimap<std::basic_string<char_type>, std::basic_string<char_type>> attribs;
std::unordered_multimap<std::basic_string<char_type>, std::shared_ptr<basic_multikey_object<char_type>>> childs;
void add_attribute(std::basic_string<char_type> key, std::basic_string<char_type> value)
{
attribs.emplace(std::move(key), std::move(value));
}
void add_child(std::unique_ptr<basic_multikey_object<char_type>> child)
{
std::shared_ptr<basic_multikey_object<char_type>> obj{ child.release() };
childs.emplace(obj->name, obj);
}
void set_name(std::basic_string<char_type> n)
{
name = std::move(n);
}
};
typedef basic_object<char> object;
typedef basic_object<wchar_t> wobject;
typedef basic_multikey_object<char> multikey_object;
typedef basic_multikey_object<wchar_t> 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 <typename OutputT, typename iStreamT>
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 <typename oStreamT, typename T>
void write(oStreamT& s, const T& r,
const detail::tabs<typename oStreamT::char_type> tab = detail::tabs<typename oStreamT::char_type>(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 <typename iStreamT>
std::basic_string<typename iStreamT::char_type> read_file(iStreamT& inStream)
{
// cache the file
typedef typename iStreamT::char_type charT;
std::basic_string<charT> str;
inStream.seekg(0, std::ios::end);
str.resize(static_cast<size_t>(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 <typename OutputT, typename IterT>
std::vector<std::unique_ptr<OutputT>> read_internal(IterT first, const IterT last,
std::unordered_set<std::basic_string<typename std::iterator_traits<IterT>::value_type>>& exclude_files,
const Options& opt)
{
static_assert(std::is_default_constructible<OutputT>::value,
"Output Type must be default constructible (provide constructor without arguments)");
static_assert(std::is_move_constructible<OutputT>::value,
"Output Type must be move constructible");
typedef typename std::iterator_traits<IterT>::value_type charT;
const std::basic_string<charT> comment_end_str = TYTI_L(charT, "*/");
const std::basic_string<charT> whitespaces = TYTI_L(charT, " \n\v\f\r\t");
#ifdef WIN32
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$WINDOWS");
};
#elif __APPLE__
// WIN32 stands for pc in general
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& 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<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$LINUX");
};
#else
std::function<bool(const std::basic_string<charT>&)> is_platform_str = [](const std::basic_string<charT>& in) {
return false;
};
#endif
if (opt.ignore_all_platform_conditionals)
is_platform_str = [](const std::basic_string<charT>&) {
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<void(std::basic_string<charT>&)> strip_escape_symbols = [](std::basic_string<charT>& 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<charT>&) {};
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<charT>(iter, end);
const bool is_platform = is_platform_str(conditional);
iter = end + 1;
return static_cast<bool>(is_platform ^ negate);
}
return true;
};
//read header
// first, quoted name
std::unique_ptr<OutputT> curObj = nullptr;
std::vector<std::unique_ptr<OutputT>> roots;
std::stack<std::unique_ptr<OutputT>> 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<charT> 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<charT>(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<charT> i(detail::string_converter(value));
auto str = read_file(i);
auto file_objs = read_internal<OutputT>(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<OutputT>();
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<OutputT> 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 <typename OutputT, typename IterT>
OutputT read(IterT first, const IterT last, const Options& opt = Options{})
{
auto exclude_files = std::unordered_set<std::basic_string<typename std::iterator_traits<IterT>::value_type>>{};
auto roots = detail::read_internal<OutputT>(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 <typename OutputT, typename IterT>
OutputT read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT
{
ec.clear();
OutputT r{};
try
{
r = read<OutputT>(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 <typename OutputT, typename IterT>
OutputT read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT
{
std::error_code ec;
auto r = read<OutputT>(first, last, ec, opt);
if (ok)
*ok = !ec;
return r;
}
template <typename IterT>
inline auto read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT -> basic_object<typename std::iterator_traits<IterT>::value_type>
{
return read<basic_object<typename std::iterator_traits<IterT>::value_type>>(first, last, ok, opt);
}
template <typename IterT>
inline auto read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT
-> basic_object<typename std::iterator_traits<IterT>::value_type>
{
return read<basic_object<typename std::iterator_traits<IterT>::value_type>>(first, last, ec, opt);
}
template <typename IterT>
inline auto read(IterT first, const IterT last, const Options& opt = Options{})
-> basic_object<typename std::iterator_traits<IterT>::value_type>
{
return read<basic_object<typename std::iterator_traits<IterT>::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 <typename OutputT, typename iStreamT>
OutputT read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{})
{
// cache the file
typedef typename iStreamT::char_type charT;
std::basic_string<charT> str = detail::read_file(inStream);
// parse it
return read<OutputT>(str.begin(), str.end(), ec, opt);
}
template <typename iStreamT>
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{})
{
return read<basic_object<typename iStreamT::char_type>>(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 <typename OutputT, typename iStreamT>
OutputT read(iStreamT& inStream, bool* ok, const Options& opt = Options{})
{
std::error_code ec;
const auto r = read<OutputT>(inStream, ec, opt);
if (ok)
*ok = !ec;
return r;
}
template <typename iStreamT>
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, bool* ok, const Options& opt = Options{})
{
return read<basic_object<typename iStreamT::char_type>>(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 <typename OutputT, typename iStreamT>
OutputT read(iStreamT& inStream, const Options& opt)
{
// cache the file
typedef typename iStreamT::char_type charT;
std::basic_string<charT> str = detail::read_file(inStream);
// parse it
return read<OutputT>(str.begin(), str.end(), opt);
}
template <typename iStreamT>
inline basic_object<typename iStreamT::char_type> read(iStreamT& inStream, const Options& opt = Options{})
{
return read<basic_object<typename iStreamT::char_type>>(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__

View File

@ -17,6 +17,15 @@ typedef void* ScriptFunctionBindingStorageType_t;
//--------------------------------------------------------- //---------------------------------------------------------
enum ScriptStatus_t
{
SCRIPT_ERROR = -1,
SCRIPT_DONE,
SCRIPT_RUNNING,
};
//---------------------------------------------------------
enum ExtendedFieldType enum ExtendedFieldType
{ {
FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT, FIELD_TYPEUNKNOWN = FIELD_TYPECOUNT,

View File

@ -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). 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\log"
rd /S /Q "%~dp0..\platform\logs" 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. REM Remove old NavMesh files which where included as an attempt to debug/suppress warnings.
rd /S /Q "%~dp0..\maps" rd /S /Q "%~dp0..\maps"
rd /S /Q "%~dp0..\platform\maps\graphs" rd /S /Q "%~dp0..\platform\maps\graphs"
@ -15,6 +16,12 @@ del /Q "%~dp0..\r5reloaded.exe"
del /Q "%~dp0..\r5apexsdkd64.dll" del /Q "%~dp0..\r5apexsdkd64.dll"
del /Q "%~dp0..\r5detours.dll" del /Q "%~dp0..\r5detours.dll"
del /Q "%~dp0..\r5dev.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). REM Remove deprecated pak files (these are no longer used).
del /Q "%~dp0..\paks\Win32\common_empty.rpak" del /Q "%~dp0..\paks\Win32\common_empty.rpak"
del /Q "%~dp0..\paks\Win32\common_sdk2.rpak" del /Q "%~dp0..\paks\Win32\common_sdk2.rpak"

View File

@ -1,16 +1,16 @@
REM Build NavMesh for all levels. REM Build NavMesh for all levels.
naveditor -console levels\mp_lobby.obj 1 recast -console levels\mp_lobby.obj 1
naveditor -console levels\mp_rr_aqueduct.obj 1 recast -console levels\mp_rr_aqueduct.obj 1
naveditor -console levels\mp_rr_arena_composite.obj 1 recast -console levels\mp_rr_arena_composite.obj 1
naveditor -console levels\mp_rr_arena_skygarden.obj 1 recast -console levels\mp_rr_arena_skygarden.obj 1
naveditor -console levels\mp_rr_ashs_redemption.obj 1 recast -console levels\mp_rr_ashs_redemption.obj 1
naveditor -console levels\mp_rr_canyonlands_64k_x_64k.obj 1 recast -console levels\mp_rr_canyonlands_64k_x_64k.obj 1
naveditor -console levels\mp_rr_canyonlands_mu1.obj 1 recast -console levels\mp_rr_canyonlands_mu1.obj 1
naveditor -console levels\mp_rr_canyonlands_mu1_night.obj 1 recast -console levels\mp_rr_canyonlands_mu1_night.obj 1
naveditor -console levels\mp_rr_canyonlands_staging.obj 1 recast -console levels\mp_rr_canyonlands_staging.obj 1
naveditor -console levels\mp_rr_desertlands_64k_x_64k.obj 1 recast -console levels\mp_rr_desertlands_64k_x_64k.obj 1
naveditor -console levels\mp_rr_desertlands_64k_x_64k_tt.obj 1 recast -console levels\mp_rr_desertlands_64k_x_64k_tt.obj 1
naveditor -console levels\mp_rr_party_crasher.obj 1 recast -console levels\mp_rr_party_crasher.obj 1
REM Copy NavMesh for identical levels. 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 copy /y /v %~dp0..\maps\navmesh\mp_rr_aqueduct_small.nm %~dp0..\maps\navmesh\mp_rr_aqueduct_night_small.nm

Some files were not shown because too many files have changed in this diff Show More