Fixed crash in EntProp natives (bug 5297, r=psychonic).
authorKyle Sanderson <kyle.leet@gmail.com>
Tue Aug 28 16:20:15 2012 -0400 (2012-08-28)
changeset 363813ea64fe5237
parent 3637 868db34cf3e6
child 3639 93afd6413ce1
child 3640 d11a9edd1cb5
Fixed crash in EntProp natives (bug 5297, r=psychonic).
core/HalfLife2.cpp
core/HalfLife2.h
core/smn_entities.cpp
public/IGameHelpers.h
     1.1 --- a/core/HalfLife2.cpp	Mon Aug 27 19:31:38 2012 -0400
     1.2 +++ b/core/HalfLife2.cpp	Tue Aug 28 16:20:15 2012 -0400
     1.3 @@ -1009,3 +1009,38 @@
     1.4  	return prop->GetOffset();
     1.5  }
     1.6  
     1.7 +const char *CHalfLife2::GetEntityClassname(edict_t * pEdict)
     1.8 +{
     1.9 +	if (pEdict == NULL || pEdict->IsFree())
    1.10 +	{
    1.11 +		return NULL;
    1.12 +	}
    1.13 +	
    1.14 +	IServerUnknown *pUnk = pEdict->GetUnknown();
    1.15 +	if (pUnk == NULL)
    1.16 +	{
    1.17 +		return NULL;
    1.18 +	}
    1.19 +	
    1.20 +	CBaseEntity * pEntity = pUnk->GetBaseEntity();
    1.21 +	
    1.22 +	if (pEntity == NULL)
    1.23 +	{
    1.24 +		return NULL;
    1.25 +	}
    1.26 +	
    1.27 +	return GetEntityClassname(pEntity);
    1.28 +}
    1.29 +
    1.30 +const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
    1.31 +{
    1.32 +	static int offset = -1;
    1.33 +	if (offset == -1)
    1.34 +	{
    1.35 +		datamap_t *pMap = GetDataMap(pEntity);
    1.36 +		typedescription_t *pDesc = FindInDataMap(pMap, "m_iClassname");
    1.37 +		offset = GetTypeDescOffs(pDesc);
    1.38 +	}
    1.39 +
    1.40 +	return *(const char **)(((unsigned char *)pEntity) + offset);
    1.41 +}
     2.1 --- a/core/HalfLife2.h	Mon Aug 27 19:31:38 2012 -0400
     2.2 +++ b/core/HalfLife2.h	Tue Aug 28 16:20:15 2012 -0400
     2.3 @@ -146,6 +146,8 @@
     2.4  	void *GetGlobalEntityList();
     2.5  	int GetSendPropOffset(SendProp *prop);
     2.6  	ICommandLine *GetValveCommandLine();
     2.7 +	const char *GetEntityClassname(edict_t *pEdict);
     2.8 +	const char *GetEntityClassname(CBaseEntity *pEntity);
     2.9  public:
    2.10  	void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
    2.11  	void ProcessFakeCliCmdQueue();
     3.1 --- a/core/smn_entities.cpp	Mon Aug 27 19:31:38 2012 -0400
     3.2 +++ b/core/smn_entities.cpp	Tue Aug 28 16:20:15 2012 -0400
     3.3 @@ -325,7 +325,7 @@
     3.4  		return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
     3.5  	}
     3.6  
     3.7 -	const char *cls = pEdict->GetClassName();
     3.8 +	const char *cls = g_HL2.GetEntityClassname(pEdict);
     3.9  
    3.10  	if (!cls || cls[0] == '\0')
    3.11  	{
    3.12 @@ -961,10 +961,11 @@
    3.13  	} \
    3.14  	if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \
    3.15  	{ \
    3.16 +		const char *class_name = g_HL2.GetEntityClassname(pEntity); \
    3.17  		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
    3.18  			prop, \
    3.19  			params[1], \
    3.20 -			class_name); \
    3.21 +			((class_name) ? class_name : "")); \
    3.22  	}
    3.23  
    3.24  #define CHECK_SET_PROP_DATA_OFFSET() \
    3.25 @@ -988,10 +989,11 @@
    3.26  	} \
    3.27  	if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \
    3.28  	{ \
    3.29 +		const char *class_name = g_HL2.GetEntityClassname(pEntity); \
    3.30  		return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
    3.31  			prop, \
    3.32  			params[1], \
    3.33 -			class_name); \
    3.34 +			((class_name) ? class_name : "")); \
    3.35  	} \
    3.36  	\
    3.37  	offset = info.actual_offset; \
    3.38 @@ -1082,7 +1084,6 @@
    3.39  {
    3.40  	CBaseEntity *pEntity;
    3.41  	char *prop;
    3.42 -	const char *class_name;
    3.43  	edict_t *pEdict;
    3.44  
    3.45  	if (!IndexToAThings(params[1], &pEntity, &pEdict))
    3.46 @@ -1090,11 +1091,6 @@
    3.47  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
    3.48  	}
    3.49  
    3.50 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
    3.51 -	{
    3.52 -		class_name = "";
    3.53 -	}
    3.54 -
    3.55  	pContext->LocalToString(params[3], &prop);
    3.56  
    3.57  	switch (params[2])
    3.58 @@ -1119,10 +1115,11 @@
    3.59  			}
    3.60  			if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
    3.61  			{
    3.62 +				const char *class_name = g_HL2.GetEntityClassname(pEntity);
    3.63  				return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
    3.64  					prop,
    3.65  					params[1],
    3.66 -					class_name);
    3.67 +					((class_name) ? class_name : ""));
    3.68  			}
    3.69  
    3.70  			if (info.prop->GetType() != DPT_DataTable)
    3.71 @@ -1152,7 +1149,6 @@
    3.72  	CBaseEntity *pEntity;
    3.73  	char *prop;
    3.74  	int offset;
    3.75 -	const char *class_name;
    3.76  	edict_t *pEdict;
    3.77  	int bit_count;
    3.78  	bool is_unsigned = false;
    3.79 @@ -1168,12 +1164,6 @@
    3.80  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
    3.81  	}
    3.82  
    3.83 -	/* TODO: Find a way to lookup classname without having an edict - Is this a guaranteed prop? */
    3.84 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
    3.85 -	{
    3.86 -		class_name = "";
    3.87 -	}
    3.88 -
    3.89  	pContext->LocalToString(params[3], &prop);
    3.90  
    3.91  	switch (params[2])
    3.92 @@ -1251,7 +1241,6 @@
    3.93  	CBaseEntity *pEntity;
    3.94  	char *prop;
    3.95  	int offset;
    3.96 -	const char *class_name;
    3.97  	edict_t *pEdict;
    3.98  	int bit_count;
    3.99  
   3.100 @@ -1266,11 +1255,6 @@
   3.101  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.102  	}
   3.103  
   3.104 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.105 -	{
   3.106 -		class_name = "";
   3.107 -	}
   3.108 -
   3.109  	pContext->LocalToString(params[3], &prop);
   3.110  
   3.111  	switch (params[2])
   3.112 @@ -1339,7 +1323,6 @@
   3.113  	char *prop;
   3.114  	int offset;
   3.115  	int bit_count;
   3.116 -	const char *class_name;
   3.117  	edict_t *pEdict;
   3.118  
   3.119  	int element = 0;
   3.120 @@ -1353,11 +1336,6 @@
   3.121  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.122  	}
   3.123  
   3.124 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.125 -	{
   3.126 -		class_name = "";
   3.127 -	}
   3.128 -
   3.129  	pContext->LocalToString(params[3], &prop);
   3.130  
   3.131  	switch (params[2])
   3.132 @@ -1404,7 +1382,6 @@
   3.133  	char *prop;
   3.134  	int offset;
   3.135  	int bit_count;
   3.136 -	const char *class_name;
   3.137  	edict_t *pEdict;
   3.138  
   3.139  	int element = 0;
   3.140 @@ -1418,11 +1395,6 @@
   3.141  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.142  	}
   3.143  
   3.144 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.145 -	{
   3.146 -		class_name = "";
   3.147 -	}
   3.148 -
   3.149  	pContext->LocalToString(params[3], &prop);
   3.150  
   3.151  	switch (params[2])
   3.152 @@ -1474,7 +1446,6 @@
   3.153  	char *prop;
   3.154  	int offset;
   3.155  	int bit_count;
   3.156 -	const char *class_name;
   3.157  	edict_t *pEdict;
   3.158  
   3.159  	int element = 0;
   3.160 @@ -1488,11 +1459,6 @@
   3.161  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.162  	}
   3.163  
   3.164 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.165 -	{
   3.166 -		class_name = "";
   3.167 -	}
   3.168 -
   3.169  	pContext->LocalToString(params[3], &prop);
   3.170  
   3.171  	switch (params[2])
   3.172 @@ -1538,7 +1504,6 @@
   3.173  	char *prop;
   3.174  	int offset;
   3.175  	int bit_count;
   3.176 -	const char *class_name;
   3.177  	edict_t *pEdict;
   3.178  
   3.179  	int element = 0;
   3.180 @@ -1552,11 +1517,6 @@
   3.181  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.182  	}
   3.183  
   3.184 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.185 -	{
   3.186 -		class_name = "";
   3.187 -	}
   3.188 -
   3.189  	pContext->LocalToString(params[3], &prop);
   3.190  
   3.191  	switch (params[2])
   3.192 @@ -1623,7 +1583,6 @@
   3.193  	char *prop;
   3.194  	int offset;
   3.195  	int bit_count;
   3.196 -	const char *class_name;
   3.197  	edict_t *pEdict;
   3.198  
   3.199  	int element = 0;
   3.200 @@ -1637,11 +1596,6 @@
   3.201  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.202  	}
   3.203  
   3.204 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.205 -	{
   3.206 -		class_name = "";
   3.207 -	}
   3.208 -
   3.209  	pContext->LocalToString(params[3], &prop);
   3.210  
   3.211  	switch (params[2])
   3.212 @@ -1695,7 +1649,6 @@
   3.213  	char *prop;
   3.214  	int offset;
   3.215  	int bit_count;
   3.216 -	const char *class_name;
   3.217  	edict_t *pEdict;
   3.218  
   3.219  	int element = 0;
   3.220 @@ -1709,11 +1662,6 @@
   3.221  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.222  	}
   3.223  
   3.224 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.225 -	{
   3.226 -		class_name = "";
   3.227 -	}
   3.228 -
   3.229  	pContext->LocalToString(params[3], &prop);
   3.230  
   3.231  	switch (params[2])
   3.232 @@ -1771,7 +1719,6 @@
   3.233  	CBaseEntity *pEntity;
   3.234  	char *prop;
   3.235  	int offset;
   3.236 -	const char *class_name;
   3.237  	edict_t *pEdict;
   3.238  	bool bIsStringIndex;
   3.239  
   3.240 @@ -1786,11 +1733,6 @@
   3.241  		return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
   3.242  	}
   3.243  
   3.244 -	if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
   3.245 -	{
   3.246 -		class_name = "";
   3.247 -	}
   3.248 -
   3.249  	pContext->LocalToString(params[3], &prop);
   3.250  
   3.251  	bIsStringIndex = false;
   3.252 @@ -1849,10 +1791,11 @@
   3.253  			}
   3.254  			if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
   3.255  			{
   3.256 +				const char *class_name = g_HL2.GetEntityClassname(pEntity);
   3.257  				return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
   3.258  					prop,
   3.259  					params[1],
   3.260 -					class_name);
   3.261 +					((class_name) ? class_name : ""));
   3.262  			}
   3.263  
   3.264  			offset = info.actual_offset;
     4.1 --- a/public/IGameHelpers.h	Mon Aug 27 19:31:38 2012 -0400
     4.2 +++ b/public/IGameHelpers.h	Tue Aug 28 16:20:15 2012 -0400
     4.3 @@ -40,7 +40,7 @@
     4.4   */
     4.5  
     4.6  #define SMINTERFACE_GAMEHELPERS_NAME		"IGameHelpers"
     4.7 -#define SMINTERFACE_GAMEHELPERS_VERSION		8
     4.8 +#define SMINTERFACE_GAMEHELPERS_VERSION		9
     4.9  
    4.10  class CBaseEntity;
    4.11  class CBaseHandle;
    4.12 @@ -292,6 +292,22 @@
    4.13  		 * @return				ICommandLine ptr or NULL if not found.
    4.14  		 */
    4.15  		virtual ICommandLine *GetValveCommandLine() =0;
    4.16 +
    4.17 +		/**
    4.18 +		 * @brief Gets a Classname from an edict_t pointer.
    4.19 +		 *
    4.20 +		 * @param pEdict		edict_t pointer.
    4.21 +		 * @return				Pointer to the string, or NULL if bad pointer.
    4.22 +		 */
    4.23 +		virtual const char *GetEntityClassname(edict_t *pEdict) =0;
    4.24 +
    4.25 +		/**
    4.26 +		 * @brief Gets a Classname from an CBaseEntity pointer.
    4.27 +		 *
    4.28 +		 * @param pEntity		CBaseEntity pointer.
    4.29 +		 * @return				Pointer to the string, or NULL if bad pointer.
    4.30 +		 */
    4.31 +		virtual const char *GetEntityClassname(CBaseEntity *pEntity) =0;
    4.32  	};
    4.33  }
    4.34