diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index 05a8bb7e..ae3f1f38 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -342,6 +342,8 @@ bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char co { m_bAnyLevelInited = true; + UpdateValveGlobals(); + const char *name; char key[32]; int count, n = 1; diff --git a/extensions/sdktools/vglobals.cpp b/extensions/sdktools/vglobals.cpp index 1526dc12..2c581130 100644 --- a/extensions/sdktools/vglobals.cpp +++ b/extensions/sdktools/vglobals.cpp @@ -32,13 +32,14 @@ #include "extension.h" #include "vhelpers.h" +static void *s_pGameRules = nullptr; static void **g_ppGameRules = nullptr; void *g_EntList = nullptr; CBaseHandle g_ResourceEntity; void *GameRules() { - return g_ppGameRules ? *g_ppGameRules : g_ppGameRules; + return g_ppGameRules ? *g_ppGameRules : s_pGameRules; } void InitializeValveGlobals() @@ -69,6 +70,81 @@ void InitializeValveGlobals() } } +static bool UTIL_FindDataTable(SendTable *pTable, + const char *name, + sm_sendprop_info_t *info, + unsigned int offset = 0) +{ + const char *pname; + int props = pTable->GetNumProps(); + SendProp *prop; + SendTable *table; + + for (int i = 0; iGetProp(i); + + if ((table = prop->GetDataTable()) != NULL) + { + pname = prop->GetName(); + if (pname && strcmp(name, pname) == 0) + { + info->prop = prop; + info->actual_offset = offset + info->prop->GetOffset(); + return true; + } + + if (UTIL_FindDataTable(table, + name, + info, + offset + prop->GetOffset()) + ) + { + return true; + } + } + } + + return false; +} + +static ServerClass *UTIL_FindServerClass(const char *classname) +{ + ServerClass *sc = gamedll->GetAllServerClasses(); + while (sc) + { + if (strcmp(classname, sc->GetName()) == 0) + { + return sc; + } + sc = sc->m_pNext; + } + + return NULL; +} + +void UpdateValveGlobals() +{ + s_pGameRules = nullptr; + + const char *pszNetClass = g_pGameConf->GetKeyValue("GameRulesProxy"); + const char *pszDTName = g_pGameConf->GetKeyValue("GameRulesDataTable"); + if (pszNetClass && pszDTName) + { + ServerClass *sc = UTIL_FindServerClass(pszNetClass); + sm_sendprop_info_t info; + if (UTIL_FindDataTable(sc->m_pTable, pszDTName, &info)) + { + auto proxyFn = info.prop->GetDataTableProxyFn(); + if (proxyFn) + { + CSendProxyRecipients recp; + s_pGameRules = proxyFn(nullptr, nullptr, nullptr, &recp, 0); + } + } + } +} + size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength) { size_t real_bytes = 0; diff --git a/extensions/sdktools/vglobals.h b/extensions/sdktools/vglobals.h index 773e9d80..1b6e045f 100644 --- a/extensions/sdktools/vglobals.h +++ b/extensions/sdktools/vglobals.h @@ -37,6 +37,7 @@ extern void *g_EntList; extern CBaseHandle g_ResourceEntity; void InitializeValveGlobals(); +void UpdateValveGlobals(); void GetIServer(); void *GameRules(); diff --git a/gamedata/sdktools.games/game.tf.txt b/gamedata/sdktools.games/game.tf.txt index 62fd79f1..bba489f8 100644 --- a/gamedata/sdktools.games/game.tf.txt +++ b/gamedata/sdktools.games/game.tf.txt @@ -111,6 +111,7 @@ "Keys" { "GameRulesProxy" "CTFGameRulesProxy" + "GameRulesDataTable" "tf_gamerules_data" } } }