diff --git a/gradle.properties b/gradle.properties index abe9c92..e05d574 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ majorVersion=3 -minorVersion=0 +minorVersion=3 maintenanceVersion=0 diff --git a/rehlds/build.gradle b/rehlds/build.gradle index 4a4cc16..4098d5d 100644 --- a/rehlds/build.gradle +++ b/rehlds/build.gradle @@ -125,7 +125,7 @@ void setupToolchain(NativeBinarySpec b) { } b.lib LazyNativeDepSet.create(dep_bzip2, 'bzip2', b.buildType.name, true) - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'SWDS', 'REHLDS_SELF', 'REHLDS_OPT_PEDANTIC', 'REHLDS_FLIGHT_REC' + cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'DEDICATED', 'SWDS', 'REHLDS_SELF', 'REHLDS_OPT_PEDANTIC', 'REHLDS_FLIGHT_REC', 'REHLDS_API' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( diff --git a/rehlds/common/cvardef.h b/rehlds/common/cvardef.h index d1bf88b..aea0f9e 100644 --- a/rehlds/common/cvardef.h +++ b/rehlds/common/cvardef.h @@ -1,9 +1,9 @@ /*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting @@ -36,4 +36,15 @@ typedef struct cvar_s struct cvar_s *next; } cvar_t; +using cvar_callback_t = void (*)(const char *pszNewValue); + +struct cvar_listener_t +{ + cvar_listener_t(const char *var_name, cvar_callback_t handler) : + func(handler), name(var_name) {} + + cvar_callback_t func; + const char *name; +}; + #endif // CVARDEF_H diff --git a/rehlds/engine/cvar.cpp b/rehlds/engine/cvar.cpp index 2792db0..37d18ed 100644 --- a/rehlds/engine/cvar.cpp +++ b/rehlds/engine/cvar.cpp @@ -174,6 +174,15 @@ NOXREF const char *Cvar_CompleteVariable(const char *search, int forward) return NULL; } +void Cvar_FireListeners(const char *var_name, const char *value) +{ + for (auto var : g_CvarsListeners) { + if (Q_strcmp(var->name, var_name) == 0) { + var->func(value); + } + } +} + void EXT_FUNC Cvar_DirectSet_internal(struct cvar_s *var, const char *value) { if (!var || !value) @@ -239,7 +248,6 @@ void EXT_FUNC Cvar_DirectSet_internal(struct cvar_s *var, const char *value) } qboolean changed = Q_strcmp(var->string, pszValue); - if (var->flags & FCVAR_USERINFO) { if (g_pcls.state == ca_dedicated) @@ -296,6 +304,12 @@ void EXT_FUNC Cvar_DirectSet_internal(struct cvar_s *var, const char *value) var->string = (char *)Z_Malloc(Q_strlen(pszValue) + 1); Q_strcpy(var->string, pszValue); var->value = (float)Q_atof(var->string); + +#ifdef REHLDS_API + if (changed) { + Cvar_FireListeners(var->name, pszValue); + } +#endif } void Cvar_DirectSet(struct cvar_s *var, const char *value) diff --git a/rehlds/engine/pr_cmds.cpp b/rehlds/engine/pr_cmds.cpp index 2620f25..b32a7df 100644 --- a/rehlds/engine/pr_cmds.cpp +++ b/rehlds/engine/pr_cmds.cpp @@ -1549,7 +1549,7 @@ int EXT_FUNC PF_IsMapValid_I(const char *mapname) if (!mapname || Q_strlen(mapname) == 0) #endif return 0; - + Q_snprintf(cBuf, sizeof(cBuf), "maps/%.32s.bsp", mapname); return FS_FileExists(cBuf); } @@ -1943,7 +1943,12 @@ void EXT_FUNC PF_crosshairangle_I(const edict_t *clientent, float pitch, float y } } -edict_t* EXT_FUNC PF_CreateFakeClient_I(const char *netname) +edict_t *EXT_FUNC PF_CreateFakeClient_I(const char *netname) +{ + return g_RehldsHookchains.m_CreateFakeClient.callChain(CreateFakeClient_internal, netname); +} + +edict_t *EXT_FUNC CreateFakeClient_internal(const char *netname) { client_t *fakeclient; edict_t *ent; diff --git a/rehlds/engine/pr_cmds.h b/rehlds/engine/pr_cmds.h index bbd670a..1f62fcc 100644 --- a/rehlds/engine/pr_cmds.h +++ b/rehlds/engine/pr_cmds.h @@ -172,6 +172,7 @@ void PF_changepitch_I(edict_t *ent); void PF_setview_I(const edict_t *clientent, const edict_t *viewent); void PF_crosshairangle_I(const edict_t *clientent, float pitch, float yaw); edict_t *PF_CreateFakeClient_I(const char *netname); +edict_t *CreateFakeClient_internal(const char *netname); void PF_RunPlayerMove_I(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, unsigned char impulse, unsigned char msec); sizebuf_t *WriteDest_Parm(int dest); void PF_MessageBegin_I(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index eb54699..085ad3f 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -4344,7 +4344,7 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e else newindex = 9999; } - + #ifdef REHLDS_FIXES if (oldnum < oldmax && from) #else diff --git a/rehlds/engine/sys_dll.cpp b/rehlds/engine/sys_dll.cpp index 1e3c38a..73504ff 100644 --- a/rehlds/engine/sys_dll.cpp +++ b/rehlds/engine/sys_dll.cpp @@ -59,7 +59,7 @@ int giStateInfo; DLL_FUNCTIONS gEntityInterface; NEW_DLL_FUNCTIONS gNewDLLFunctions; -extensiondll_t g_rgextdll[50]; +extensiondll_t g_rgextdll[MAX_EXTENSION_DLL]; int g_iextdllMac; modinfo_t gmodinfo; @@ -789,7 +789,7 @@ const char* EXT_FUNC NameForFunction(uint32 function) return NULL; } -ENTITYINIT GetEntityInit(char *pClassName) +ENTITYINIT EXT_FUNC GetEntityInit(char *pClassName) { return (ENTITYINIT)GetDispatch(pClassName); } @@ -1089,7 +1089,7 @@ void LoadThisDll(const char *szDllFilename) } pfnGiveFnptrsToDll(&g_engfuncsExportedToDlls, &gGlobalVariables); - if (g_iextdllMac == 50) + if (g_iextdllMac == MAX_EXTENSION_DLL) { Con_Printf("Too many DLLs, ignoring remainder\n"); goto IgnoreThisDLL; diff --git a/rehlds/msvc/ReHLDS.vcxproj b/rehlds/msvc/ReHLDS.vcxproj index d0d7359..4d5147d 100644 --- a/rehlds/msvc/ReHLDS.vcxproj +++ b/rehlds/msvc/ReHLDS.vcxproj @@ -441,7 +441,6 @@ - @@ -512,6 +511,7 @@ + @@ -767,7 +767,7 @@ Level3 Disabled true - REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_FIXES;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_FIXES;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -805,7 +805,7 @@ Level3 Disabled true - REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_FIXES;REHLDS_SELF;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_FIXES;REHLDS_SELF;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -953,7 +953,7 @@ Level3 Disabled true - REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;HAVE_OPT_STRTOOLS;REHLDS_SELF;REHLDS_UNIT_TESTS;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;HAVE_OPT_STRTOOLS;REHLDS_SELF;REHLDS_UNIT_TESTS;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug Use precompiled.h @@ -989,7 +989,7 @@ Level3 Disabled true - REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_FIXES;HAVE_OPT_STRTOOLS;REHLDS_SELF;REHLDS_UNIT_TESTS;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_FLIGHT_REC;REHLDS_OPT_PEDANTIC;REHLDS_FIXES;HAVE_OPT_STRTOOLS;REHLDS_SELF;REHLDS_UNIT_TESTS;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug Use precompiled.h @@ -1026,7 +1026,7 @@ true true true - REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded /arch:IA32 %(AdditionalOptions) Use @@ -1149,7 +1149,7 @@ true true true - REHLDS_FLIGHT_REC;REHLDS_FIXES;REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + REHLDS_API;REHLDS_FLIGHT_REC;REHLDS_FIXES;REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_CHECKS;HAVE_OPT_STRTOOLS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded /arch:IA32 %(AdditionalOptions) Use diff --git a/rehlds/msvc/ReHLDS.vcxproj.filters b/rehlds/msvc/ReHLDS.vcxproj.filters index 1f6d429..e143343 100644 --- a/rehlds/msvc/ReHLDS.vcxproj.filters +++ b/rehlds/msvc/ReHLDS.vcxproj.filters @@ -577,9 +577,6 @@ engine\server - - engine\common - engine\server @@ -844,6 +841,9 @@ public\rehlds + + public\rehlds + rehlds diff --git a/rehlds/engine/pr_dlls.h b/rehlds/public/rehlds/pr_dlls.h similarity index 97% rename from rehlds/engine/pr_dlls.h rename to rehlds/public/rehlds/pr_dlls.h index 8f3ae16..d7b72c1 100644 --- a/rehlds/engine/pr_dlls.h +++ b/rehlds/public/rehlds/pr_dlls.h @@ -1,49 +1,51 @@ -/* -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at -* your option) any later version. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* In addition, as a special exception, the author gives permission to -* link the code of this program with the Half-Life Game Engine ("HL -* Engine") and Modified Game Libraries ("MODs") developed by Valve, -* L.L.C ("Valve"). You must obey the GNU General Public License in all -* respects for all of the code used other than the HL Engine and MODs -* from Valve. If you modify this file, you may extend this exception -* to your version of the file, but you are not obligated to do so. If -* you do not wish to do so, delete this exception statement from your -* version. -* -*/ - -#pragma once - -#include "maintypes.h" -#include "eiface.h" - -typedef struct functiontable_s -{ - uint32 pFunction; - char *pFunctionName; -} functiontable_t; - -typedef struct extensiondll_s -{ - void *lDLLHandle; - functiontable_t *functionTable; - int functionCount; -} extensiondll_t; - -typedef void(*ENTITYINIT)(struct entvars_s *); -typedef void(*DISPATCHFUNCTION)(struct entvars_s *, void *); -typedef void(*FIELDIOFUNCTION)(SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int); +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +#include "maintypes.h" +#include "eiface.h" + +const int MAX_EXTENSION_DLL = 50; + +typedef struct functiontable_s +{ + uint32 pFunction; + char *pFunctionName; +} functiontable_t; + +typedef struct extensiondll_s +{ + void *lDLLHandle; + functiontable_t *functionTable; + int functionCount; +} extensiondll_t; + +typedef void(*ENTITYINIT)(struct entvars_s *); +typedef void(*DISPATCHFUNCTION)(struct entvars_s *, void *); +typedef void(*FIELDIOFUNCTION)(SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int); diff --git a/rehlds/public/rehlds/rehlds_api.h b/rehlds/public/rehlds/rehlds_api.h index 245d9cb..938bd0c 100644 --- a/rehlds/public/rehlds/rehlds_api.h +++ b/rehlds/public/rehlds/rehlds_api.h @@ -34,9 +34,10 @@ #include "interface.h" #include "model.h" #include "ObjectList.h" +#include "pr_dlls.h" #define REHLDS_API_VERSION_MAJOR 3 -#define REHLDS_API_VERSION_MINOR 2 +#define REHLDS_API_VERSION_MINOR 3 //Steam_NotifyClientConnect hook typedef IHookChain IRehldsHook_Steam_NotifyClientConnect; @@ -190,6 +191,10 @@ typedef IHookChainRegistry IRehldsHook_SV_EmitSound2; typedef IHookChainRegistry IRehldsHookRegistry_SV_EmitSound2; +//CreateFakeClient hook +typedef IHookChain IRehldsHook_CreateFakeClient; +typedef IHookChainRegistry IRehldsHookRegistry_CreateFakeClient; + class IRehldsHookchains { public: virtual ~IRehldsHookchains() { } @@ -232,6 +237,7 @@ public: virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f() = 0; virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities() = 0; virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2() = 0; + virtual IRehldsHookRegistry_CreateFakeClient* CreateFakeClient() = 0; }; struct RehldsFuncs_t { @@ -285,6 +291,11 @@ struct RehldsFuncs_t { bool(*StripUnprintableAndSpace)(char *pch); void(*Cmd_RemoveCmd)(const char *cmd_name); void(*GetCommandMatches)(const char *string, ObjectList *pMatchList); + bool(*AddExtDll)(void *hModule); + void(*AddCvarListener)(const char *var_name, cvar_callback_t func); + void(*RemoveExtDll)(void *hModule); + void(*RemoveCvarListener)(const char *var_name, cvar_callback_t func); + ENTITYINIT(*GetEntityInit)(char *pszClassName); }; class IRehldsApi { diff --git a/rehlds/rehlds/rehlds_api_impl.cpp b/rehlds/rehlds/rehlds_api_impl.cpp index ee32549..a4235d1 100644 --- a/rehlds/rehlds/rehlds_api_impl.cpp +++ b/rehlds/rehlds/rehlds_api_impl.cpp @@ -34,6 +34,7 @@ struct plugin_api_t }; std::vector g_PluginApis; +std::vector g_CvarsListeners; plugin_api_t* FindPluginApiByName(const char *name) { for (auto pl : g_PluginApis) { @@ -181,10 +182,84 @@ void EXT_FUNC GetCommandMatches_api(const char *string, ObjectList *pMatchList) } } +bool EXT_FUNC AddExtDll_api(void *hModule) +{ + if (!hModule) { + return false; + } + + if (g_iextdllMac >= MAX_EXTENSION_DLL) { + Con_Printf("Too many DLLs, ignoring remainder\n"); + return false; + } + + auto pextdll = &g_rgextdll[g_iextdllMac++]; + Q_memset(pextdll, 0, sizeof(*pextdll)); + pextdll->lDLLHandle = hModule; + return true; +} + +void EXT_FUNC RemoveExtDll_api(void *hModule) +{ + if (!hModule) { + return; + } + + for (auto i = 0; i < g_iextdllMac; i++) + { + if (g_rgextdll[i].lDLLHandle == hModule) + { + g_iextdllMac--; + if (g_iextdllMac != i) + { + Q_memmove(&g_rgextdll[i], &g_rgextdll[i + 1], (g_iextdllMac - i) * sizeof(g_rgextdll[0])); + i = g_iextdllMac; + } + + Q_memset(&g_rgextdll[i], 0, sizeof(g_rgextdll[0])); + break; + } + } +} + +void EXT_FUNC AddCvarListener_api(const char *var_name, cvar_callback_t func) +{ + cvar_t *var = Cvar_FindVar(var_name); + if (!var) { + return; + } + + for (auto cvars : g_CvarsListeners) { + if (!Q_strcmp(cvars->name, var_name)) { + if (cvars->func == func) { + return; + } + } + } + + cvar_listener_t *list = new cvar_listener_t(var_name, func); + g_CvarsListeners.push_back(list); +} + +void EXT_FUNC RemoveCvarListener_api(const char *var_name, cvar_callback_t func) +{ + auto iter = g_CvarsListeners.begin(); + while (iter != g_CvarsListeners.end()) + { + if (Q_strcmp((*iter)->name, var_name) != 0 || (*iter)->func != func) { + iter++; + continue; + } + + delete (*iter); + iter = g_CvarsListeners.erase(iter); + } +} + CRehldsServerStatic g_RehldsServerStatic; CRehldsServerData g_RehldsServerData; CRehldsHookchains g_RehldsHookchains; -RehldsFuncs_t g_RehldsApiFuncs = +RehldsFuncs_t g_RehldsApiFuncs = { &SV_DropClient_api, &SV_RejectConnection, @@ -235,7 +310,12 @@ RehldsFuncs_t g_RehldsApiFuncs = &SV_UpdateUserInfo_api, &StripUnprintableAndSpace_api, &Cmd_RemoveCmd, - &GetCommandMatches_api + &GetCommandMatches_api, + &AddExtDll_api, + &AddCvarListener_api, + &RemoveExtDll_api, + &RemoveCvarListener_api, + &GetEntityInit }; bool EXT_FUNC SV_EmitSound2_internal(edict_t *entity, IGameClient *pReceiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin) @@ -486,6 +566,10 @@ IRehldsHookRegistry_SV_EmitSound2* CRehldsHookchains::SV_EmitSound2() { return &m_SV_EmitSound2; } +IRehldsHookRegistry_CreateFakeClient* CRehldsHookchains::CreateFakeClient() { + return &m_CreateFakeClient; +} + int EXT_FUNC CRehldsApi::GetMajorVersion() { return REHLDS_API_VERSION_MAJOR; diff --git a/rehlds/rehlds/rehlds_api_impl.h b/rehlds/rehlds/rehlds_api_impl.h index 93124e4..436ff19 100644 --- a/rehlds/rehlds/rehlds_api_impl.h +++ b/rehlds/rehlds/rehlds_api_impl.h @@ -183,6 +183,10 @@ typedef IHookChainRegistryImpl CRehldsHook_SV_EmitSound2; typedef IHookChainRegistryImpl CRehldsHookRegistry_SV_EmitSound2; +//CreateFakeClient hook +typedef IHookChainImpl CRehldsHook_CreateFakeClient; +typedef IHookChainRegistryImpl CRehldsHookRegistry_CreateFakeClient; + class CRehldsHookchains : public IRehldsHookchains { public: CRehldsHookRegistry_Steam_NotifyClientConnect m_Steam_NotifyClientConnect; @@ -223,6 +227,7 @@ public: CRehldsHookRegistry_SV_Spawn_f m_SV_Spawn_f; CRehldsHookRegistry_SV_CreatePacketEntities m_SV_CreatePacketEntities; CRehldsHookRegistry_SV_EmitSound2 m_SV_EmitSound2; + CRehldsHookRegistry_CreateFakeClient m_CreateFakeClient; public: virtual IRehldsHookRegistry_Steam_NotifyClientConnect* Steam_NotifyClientConnect(); @@ -263,6 +268,7 @@ public: virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f(); virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities(); virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2(); + virtual IRehldsHookRegistry_CreateFakeClient* CreateFakeClient(); }; extern CRehldsHookchains g_RehldsHookchains; @@ -285,5 +291,6 @@ public: extern sizebuf_t* GetNetMessage_api(); extern IGameClient* GetHostClient_api(); extern int* GetMsgReadCount_api(); +extern std::vector g_CvarsListeners; bool SV_EmitSound2_api(edict_t *entity, IGameClient *receiver, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch, int emitFlags, const float *pOrigin);