Fixed crash in EntProp natives (bug 5297, r=psychonic).
This commit is contained in:
parent
4f800fbd00
commit
e8058912b8
@ -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);
|
||||||
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user