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();
}
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();
int GetSendPropOffset(SendProp *prop);
ICommandLine *GetValveCommandLine();
const char *GetEntityClassname(edict_t *pEdict);
const char *GetEntityClassname(CBaseEntity *pEntity);
public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
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]);
}
const char *cls = pEdict->GetClassName();
const char *cls = g_HL2.GetEntityClassname(pEdict);
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) \
{ \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \
params[1], \
class_name); \
((class_name) ? class_name : "")); \
}
#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)) \
{ \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \
params[1], \
class_name); \
((class_name) ? class_name : "")); \
} \
\
offset = info.actual_offset; \
@ -1082,7 +1084,6 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params
{
CBaseEntity *pEntity;
char *prop;
const char *class_name;
edict_t *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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
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))
{
const char *class_name = g_HL2.GetEntityClassname(pEntity);
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
prop,
params[1],
class_name);
((class_name) ? class_name : ""));
}
if (info.prop->GetType() != DPT_DataTable)
@ -1152,7 +1149,6 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity;
char *prop;
int offset;
const char *class_name;
edict_t *pEdict;
int bit_count;
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]);
}
/* 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);
switch (params[2])
@ -1251,7 +1241,6 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity;
char *prop;
int offset;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1339,7 +1323,6 @@ static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1404,7 +1382,6 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1474,7 +1446,6 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1538,7 +1504,6 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1623,7 +1583,6 @@ static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1695,7 +1649,6 @@ static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
char *prop;
int offset;
int bit_count;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
switch (params[2])
@ -1771,7 +1719,6 @@ static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
CBaseEntity *pEntity;
char *prop;
int offset;
const char *class_name;
edict_t *pEdict;
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]);
}
if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
{
class_name = "";
}
pContext->LocalToString(params[3], &prop);
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))
{
const char *class_name = g_HL2.GetEntityClassname(pEntity);
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
prop,
params[1],
class_name);
((class_name) ? class_name : ""));
}
offset = info.actual_offset;

View File

@ -40,7 +40,7 @@
*/
#define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers"
#define SMINTERFACE_GAMEHELPERS_VERSION 8
#define SMINTERFACE_GAMEHELPERS_VERSION 9
class CBaseEntity;
class CBaseHandle;
@ -292,6 +292,22 @@ namespace SourceMod
* @return ICommandLine ptr or NULL if not found.
*/
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;
};
}