Fixed crash in EntProp natives (bug 5297, r=psychonic).

This commit is contained in:
Kyle Sanderson 2012-08-28 16:20:15 -04:00
parent 4f800fbd00
commit e8058912b8
4 changed files with 63 additions and 67 deletions

View File

@ -1009,3 +1009,38 @@ int CHalfLife2::GetSendPropOffset(SendProp *prop)
return prop->GetOffset(); return prop->GetOffset();
} }
const char *CHalfLife2::GetEntityClassname(edict_t * pEdict)
{
if (pEdict == NULL || pEdict->IsFree())
{
return NULL;
}
IServerUnknown *pUnk = pEdict->GetUnknown();
if (pUnk == NULL)
{
return NULL;
}
CBaseEntity * pEntity = pUnk->GetBaseEntity();
if (pEntity == NULL)
{
return NULL;
}
return GetEntityClassname(pEntity);
}
const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
{
static int offset = -1;
if (offset == -1)
{
datamap_t *pMap = GetDataMap(pEntity);
typedescription_t *pDesc = FindInDataMap(pMap, "m_iClassname");
offset = GetTypeDescOffs(pDesc);
}
return *(const char **)(((unsigned char *)pEntity) + offset);
}

View File

@ -146,6 +146,8 @@ public: //IGameHelpers
void *GetGlobalEntityList(); void *GetGlobalEntityList();
int GetSendPropOffset(SendProp *prop); int GetSendPropOffset(SendProp *prop);
ICommandLine *GetValveCommandLine(); ICommandLine *GetValveCommandLine();
const char *GetEntityClassname(edict_t *pEdict);
const char *GetEntityClassname(CBaseEntity *pEntity);
public: public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd); void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
void ProcessFakeCliCmdQueue(); void ProcessFakeCliCmdQueue();

View File

@ -325,7 +325,7 @@ static cell_t GetEdictClassname(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
const char *cls = pEdict->GetClassName(); const char *cls = g_HL2.GetEntityClassname(pEdict);
if (!cls || cls[0] == '\0') if (!cls || cls[0] == '\0')
{ {
@ -961,10 +961,11 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
} \ } \
if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \ if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \
{ \ { \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \ return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \ prop, \
params[1], \ params[1], \
class_name); \ ((class_name) ? class_name : "")); \
} }
#define CHECK_SET_PROP_DATA_OFFSET() \ #define CHECK_SET_PROP_DATA_OFFSET() \
@ -988,10 +989,11 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
} \ } \
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \ if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \
{ \ { \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \ return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \ prop, \
params[1], \ params[1], \
class_name); \ ((class_name) ? class_name : "")); \
} \ } \
\ \
offset = info.actual_offset; \ offset = info.actual_offset; \
@ -1082,7 +1084,6 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params
{ {
CBaseEntity *pEntity; CBaseEntity *pEntity;
char *prop; char *prop;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
if (!IndexToAThings(params[1], &pEntity, &pEdict)) if (!IndexToAThings(params[1], &pEntity, &pEdict))
@ -1090,11 +1091,6 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1119,10 +1115,11 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params
} }
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
{ {
const char *class_name = g_HL2.GetEntityClassname(pEntity);
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
prop, prop,
params[1], params[1],
class_name); ((class_name) ? class_name : ""));
} }
if (info.prop->GetType() != DPT_DataTable) if (info.prop->GetType() != DPT_DataTable)
@ -1152,7 +1149,6 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity; CBaseEntity *pEntity;
char *prop; char *prop;
int offset; int offset;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int bit_count; int bit_count;
bool is_unsigned = false; bool is_unsigned = false;
@ -1168,12 +1164,6 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
/* TODO: Find a way to lookup classname without having an edict - Is this a guaranteed prop? */
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1251,7 +1241,6 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity; CBaseEntity *pEntity;
char *prop; char *prop;
int offset; int offset;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int bit_count; int bit_count;
@ -1266,11 +1255,6 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1339,7 +1323,6 @@ static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1353,11 +1336,6 @@ static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1404,7 +1382,6 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1418,11 +1395,6 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1474,7 +1446,6 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1488,11 +1459,6 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1538,7 +1504,6 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1552,11 +1517,6 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1623,7 +1583,6 @@ static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1637,11 +1596,6 @@ static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1695,7 +1649,6 @@ static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
char *prop; char *prop;
int offset; int offset;
int bit_count; int bit_count;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
int element = 0; int element = 0;
@ -1709,11 +1662,6 @@ static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
switch (params[2]) switch (params[2])
@ -1771,7 +1719,6 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity; CBaseEntity *pEntity;
char *prop; char *prop;
int offset; int offset;
const char *class_name;
edict_t *pEdict; edict_t *pEdict;
bool bIsStringIndex; bool bIsStringIndex;
@ -1786,11 +1733,6 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]); return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
} }
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop); pContext->LocalToString(params[3], &prop);
bIsStringIndex = false; bIsStringIndex = false;
@ -1849,10 +1791,11 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
} }
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
{ {
const char *class_name = g_HL2.GetEntityClassname(pEntity);
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
prop, prop,
params[1], params[1],
class_name); ((class_name) ? class_name : ""));
} }
offset = info.actual_offset; offset = info.actual_offset;

View File

@ -40,7 +40,7 @@
*/ */
#define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers" #define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers"
#define SMINTERFACE_GAMEHELPERS_VERSION 8 #define SMINTERFACE_GAMEHELPERS_VERSION 9
class CBaseEntity; class CBaseEntity;
class CBaseHandle; class CBaseHandle;
@ -292,6 +292,22 @@ namespace SourceMod
* @return ICommandLine ptr or NULL if not found. * @return ICommandLine ptr or NULL if not found.
*/ */
virtual ICommandLine *GetValveCommandLine() =0; virtual ICommandLine *GetValveCommandLine() =0;
/**
* @brief Gets a Classname from an edict_t pointer.
*
* @param pEdict edict_t pointer.
* @return Pointer to the string, or NULL if bad pointer.
*/
virtual const char *GetEntityClassname(edict_t *pEdict) =0;
/**
* @brief Gets a Classname from an CBaseEntity pointer.
*
* @param pEntity CBaseEntity pointer.
* @return Pointer to the string, or NULL if bad pointer.
*/
virtual const char *GetEntityClassname(CBaseEntity *pEntity) =0;
}; };
} }