Merge pull request #220 from alliedmodders/gamerules-no-gamedata

Fixup SDKTools to not require byte sig or symbol to get g_pGameRules (r=VoiDeD).
This commit is contained in:
Nicholas Hastings 2014-12-14 15:29:14 -05:00
commit ed87e048b4
7 changed files with 135 additions and 47 deletions

View File

@ -340,6 +340,10 @@ bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar)
bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background) bool SDKTools::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background)
{ {
m_bAnyLevelInited = true;
UpdateValveGlobals();
const char *name; const char *name;
char key[32]; char key[32];
int count, n = 1; int count, n = 1;
@ -472,10 +476,7 @@ public:
virtual void *GetGameRules() virtual void *GetGameRules()
{ {
if (!g_pGameRules) return GameRules();
return NULL;
return *g_pGameRules;
} }
} g_SDKTools_API; } g_SDKTools_API;

View File

@ -107,6 +107,11 @@ public: //ICommandTargetProcessor
public: public:
bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); bool LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax); void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
public:
bool HasAnyLevelInited() { return m_bAnyLevelInited; }
private:
bool m_bAnyLevelInited = false;
}; };
extern SDKTools g_SdkTools; extern SDKTools g_SdkTools;

View File

@ -163,7 +163,9 @@ static cell_t GameRules_GetProp(IPluginContext *pContext, const cell_t *params)
int bit_count; int bit_count;
bool is_unsigned; bool is_unsigned;
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) void *pGameRules = GameRules();
if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
@ -185,8 +187,6 @@ static cell_t GameRules_GetProp(IPluginContext *pContext, const cell_t *params)
bit_count = params[2] * 8; bit_count = params[2] * 8;
} }
void *pGameRules = *g_pGameRules;
if (bit_count >= 17) if (bit_count >= 17)
{ {
return *(int32_t *)((intptr_t)pGameRules + offset); return *(int32_t *)((intptr_t)pGameRules + offset);
@ -232,11 +232,13 @@ static cell_t GameRules_SetProp(IPluginContext *pContext, const cell_t *params)
if (params[5] == 0) if (params[5] == 0)
sendChange = false; sendChange = false;
void *pGameRules = GameRules();
CBaseEntity *pProxy = NULL; CBaseEntity *pProxy = NULL;
if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL)) if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
return pContext->ThrowNativeError("Couldn't find gamerules proxy entity"); return pContext->ThrowNativeError("Couldn't find gamerules proxy entity");
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed"); return pContext->ThrowNativeError("Gamerules lookup failed");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
@ -250,8 +252,6 @@ static cell_t GameRules_SetProp(IPluginContext *pContext, const cell_t *params)
} }
#endif #endif
void *pGameRules = *g_pGameRules;
if (bit_count < 1) if (bit_count < 1)
{ {
bit_count = params[3] * 8; bit_count = params[3] * 8;
@ -304,15 +304,15 @@ static cell_t GameRules_GetPropFloat(IPluginContext *pContext, const cell_t *par
int offset; int offset;
int bit_count; int bit_count;
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) void *pGameRules = GameRules();
if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Float, "float"); FIND_PROP_SEND(DPT_Float, "float");
void *pGameRules = *g_pGameRules;
float val = *(float *)((intptr_t)pGameRules + offset); float val = *(float *)((intptr_t)pGameRules + offset);
return sp_ftoc(val); return sp_ftoc(val);
@ -329,18 +329,19 @@ static cell_t GameRules_SetPropFloat(IPluginContext *pContext, const cell_t *par
if (params[4] == 0) if (params[4] == 0)
sendChange = false; sendChange = false;
void *pGameRules = GameRules();
CBaseEntity *pProxy = NULL; CBaseEntity *pProxy = NULL;
if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL)) if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
return pContext->ThrowNativeError("Couldn't find gamerules proxy entity."); return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Float, "float"); FIND_PROP_SEND(DPT_Float, "float");
void *pGameRules = *g_pGameRules;
float newVal = sp_ctof(params[2]); float newVal = sp_ctof(params[2]);
*(float *)((intptr_t)pGameRules + offset) = newVal; *(float *)((intptr_t)pGameRules + offset) = newVal;
@ -361,15 +362,15 @@ static cell_t GameRules_GetPropEnt(IPluginContext *pContext, const cell_t *param
int offset; int offset;
int bit_count; int bit_count;
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) void *pGameRules = GameRules();
if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Int, "Integer"); FIND_PROP_SEND(DPT_Int, "Integer");
void *pGameRules = *g_pGameRules;
CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset); CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset);
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(hndl.GetEntryIndex()); CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(hndl.GetEntryIndex());
@ -392,19 +393,19 @@ static cell_t GameRules_SetPropEnt(IPluginContext *pContext, const cell_t *param
if (params[4] == 0) if (params[4] == 0)
sendChange = false; sendChange = false;
void *pGameRules = GameRules();
CBaseEntity *pProxy = NULL; CBaseEntity *pProxy = NULL;
if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL)) if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
return pContext->ThrowNativeError("Couldn't find gamerules proxy entity."); return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Int, "integer"); FIND_PROP_SEND(DPT_Int, "integer");
void *pGameRules = *g_pGameRules;
CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset); CBaseHandle &hndl = *(CBaseHandle *)((intptr_t)pGameRules + offset);
CBaseEntity *pOther; CBaseEntity *pOther;
@ -451,15 +452,15 @@ static cell_t GameRules_GetPropVector(IPluginContext *pContext, const cell_t *pa
int offset; int offset;
int bit_count; int bit_count;
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) void *pGameRules = GameRules();
if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Vector, "vector"); FIND_PROP_SEND(DPT_Vector, "vector");
void *pGameRules = *g_pGameRules;
Vector *v = (Vector *)((intptr_t)pGameRules + offset); Vector *v = (Vector *)((intptr_t)pGameRules + offset);
cell_t *vec; cell_t *vec;
@ -483,19 +484,19 @@ static cell_t GameRules_SetPropVector(IPluginContext *pContext, const cell_t *pa
if (params[4] == 0) if (params[4] == 0)
sendChange = false; sendChange = false;
void *pGameRules = GameRules();
CBaseEntity *pProxy = NULL; CBaseEntity *pProxy = NULL;
if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL)) if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
return pContext->ThrowNativeError("Couldn't find gamerules proxy entity."); return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
FIND_PROP_SEND(DPT_Vector, "vector"); FIND_PROP_SEND(DPT_Vector, "vector");
void *pGameRules = *g_pGameRules;
Vector *v = (Vector *)((intptr_t)pGameRules + offset); Vector *v = (Vector *)((intptr_t)pGameRules + offset);
cell_t *vec; cell_t *vec;
@ -523,7 +524,9 @@ static cell_t GameRules_GetPropString(IPluginContext *pContext, const cell_t *pa
char *prop; char *prop;
int offset; int offset;
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) void *pGameRules = GameRules();
if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
@ -544,8 +547,6 @@ static cell_t GameRules_GetPropString(IPluginContext *pContext, const cell_t *pa
DPT_String); DPT_String);
} }
void *pGameRules = *g_pGameRules;
size_t len; size_t len;
const char *src; const char *src;
@ -585,11 +586,13 @@ static cell_t GameRules_SetPropString(IPluginContext *pContext, const cell_t *pa
if (params[3] == 0) if (params[3] == 0)
sendChange = false; sendChange = false;
void *pGameRules = GameRules();
CBaseEntity *pProxy = NULL; CBaseEntity *pProxy = NULL;
if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL)) if (sendChange && ((pProxy = GetGameRulesProxyEnt()) == NULL))
return pContext->ThrowNativeError("Couldn't find gamerules proxy entity."); return pContext->ThrowNativeError("Couldn't find gamerules proxy entity.");
if (!g_pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, "")) if (!pGameRules || !g_szGameRulesProxy || !strcmp(g_szGameRulesProxy, ""))
return pContext->ThrowNativeError("Gamerules lookup failed."); return pContext->ThrowNativeError("Gamerules lookup failed.");
pContext->LocalToString(params[1], &prop); pContext->LocalToString(params[1], &prop);
@ -610,7 +613,6 @@ static cell_t GameRules_SetPropString(IPluginContext *pContext, const cell_t *pa
DPT_String); DPT_String);
} }
void *pGameRules = *g_pGameRules;
maxlen = DT_MAX_STRING_BUFFERSIZE; maxlen = DT_MAX_STRING_BUFFERSIZE;
char *src; char *src;

View File

@ -320,20 +320,17 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
break; break;
case ValveCall_GameRules: case ValveCall_GameRules:
{ {
if (g_pGameRules == NULL) void *pGameRules = GameRules();
if (pGameRules == NULL)
{ {
vc->stk_put(ptr); vc->stk_put(ptr);
return pContext->ThrowNativeError("GameRules unsupported or not available; file a bug report");
}
void *gamerules = *g_pGameRules; if (g_SdkTools.HasAnyLevelInited())
return pContext->ThrowNativeError("GameRules unsupported or not available; file a bug report");
if (gamerules == NULL) else
{ return pContext->ThrowNativeError("GameRules not available before map is loaded");
vc->stk_put(ptr);
return pContext->ThrowNativeError("GameRules not available before map is loaded");
} }
*(void **)ptr = gamerules; *(void **)ptr = pGameRules;
} }
break; break;
case ValveCall_EntityList: case ValveCall_EntityList:

View File

@ -32,10 +32,15 @@
#include "extension.h" #include "extension.h"
#include "vhelpers.h" #include "vhelpers.h"
void **g_pGameRules = NULL; static void *s_pGameRules = nullptr;
void *g_EntList = NULL; static void **g_ppGameRules = nullptr;
void *g_EntList = nullptr;
CBaseHandle g_ResourceEntity; CBaseHandle g_ResourceEntity;
void *GameRules()
{
return g_ppGameRules ? *g_ppGameRules : s_pGameRules;
}
void InitializeValveGlobals() void InitializeValveGlobals()
{ {
@ -52,7 +57,7 @@ void InitializeValveGlobals()
char *addr; char *addr;
if (g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) && addr) if (g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) && addr)
{ {
g_pGameRules = reinterpret_cast<void **>(addr); g_ppGameRules = reinterpret_cast<void **>(addr);
} }
else if (g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) && addr) else if (g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) && addr)
{ {
@ -61,7 +66,83 @@ void InitializeValveGlobals()
{ {
return; return;
} }
g_pGameRules = *reinterpret_cast<void ***>(addr + offset); g_ppGameRules = *reinterpret_cast<void ***>(addr + offset);
}
}
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; i<props; i++)
{
prop = pTable->GetProp(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 nullptr;
}
void UpdateValveGlobals()
{
s_pGameRules = nullptr;
const char *pszNetClass = g_pGameConf->GetKeyValue("GameRulesProxy");
const char *pszDTName = g_pGameConf->GetKeyValue("GameRulesDataTable");
if (pszNetClass && pszDTName)
{
sm_sendprop_info_t info;
ServerClass *sc = UTIL_FindServerClass(pszNetClass);
if (sc && UTIL_FindDataTable(sc->m_pTable, pszDTName, &info))
{
auto proxyFn = info.prop->GetDataTableProxyFn();
if (proxyFn)
{
CSendProxyRecipients recp;
s_pGameRules = proxyFn(nullptr, nullptr, nullptr, &recp, 0);
}
}
} }
} }

View File

@ -32,13 +32,14 @@
#ifndef _INCLUDE_SDKTOOLS_VGLOBALS_H_ #ifndef _INCLUDE_SDKTOOLS_VGLOBALS_H_
#define _INCLUDE_SDKTOOLS_VGLOBALS_H_ #define _INCLUDE_SDKTOOLS_VGLOBALS_H_
extern void **g_pGameRules;
extern void *g_EntList; extern void *g_EntList;
extern CBaseHandle g_ResourceEntity; extern CBaseHandle g_ResourceEntity;
void InitializeValveGlobals(); void InitializeValveGlobals();
void UpdateValveGlobals();
void GetIServer(); void GetIServer();
void *GameRules();
void GetResourceEntity(); void GetResourceEntity();

View File

@ -111,6 +111,7 @@
"Keys" "Keys"
{ {
"GameRulesProxy" "CTFGameRulesProxy" "GameRulesProxy" "CTFGameRulesProxy"
"GameRulesDataTable" "tf_gamerules_data"
} }
} }
} }