Fixed crash in EntProp natives (bug 5297, r=psychonic).
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