1.1 --- a/core/smn_entities.cpp Fri Apr 13 17:18:41 2007 +0000
1.2 +++ b/core/smn_entities.cpp Sat Apr 14 02:24:23 2007 +0000
1.3 @@ -19,6 +19,13 @@
1.4 #include "PlayerManager.h"
1.5 #include "HalfLife2.h"
1.6 #include "GameConfigs.h"
1.7 +#include "sm_stringutil.h"
1.8 +
1.9 +enum PropType
1.10 +{
1.11 + Prop_Send = 0,
1.12 + Prop_Data
1.13 +};
1.14
1.15 inline edict_t *GetEdict(cell_t num)
1.16 {
1.17 @@ -557,6 +564,207 @@
1.18 return td->fieldOffset[TD_OFFSET_NORMAL];
1.19 }
1.20
1.21 +static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
1.22 +{
1.23 + CBaseEntity *pEntity;
1.24 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.25 +
1.26 + if (!pEdict || !pEntity)
1.27 + {
1.28 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.29 + }
1.30 +
1.31 + int offset = params[2];
1.32 + if (offset < 0 || offset > 32768)
1.33 + {
1.34 + return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.35 + }
1.36 +
1.37 + size_t len;
1.38 + char *src = (char *)((uint8_t *)pEntity + offset);
1.39 + pContext->StringToLocalUTF8(params[3], params[4], src, &len);
1.40 +
1.41 + return len;
1.42 +}
1.43 +
1.44 +static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
1.45 +{
1.46 + CBaseEntity *pEntity;
1.47 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.48 +
1.49 + if (!pEdict || !pEntity)
1.50 + {
1.51 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.52 + }
1.53 +
1.54 + int offset = params[2];
1.55 + if (offset < 0 || offset > 32768)
1.56 + {
1.57 + return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.58 + }
1.59 +
1.60 + char *src;
1.61 + char *dest = (char *)((uint8_t *)pEntity + offset);
1.62 +
1.63 + pContext->LocalToString(params[3], &src);
1.64 + size_t len = strncopy(dest, src, params[4]);
1.65 +
1.66 + if (params[5])
1.67 + {
1.68 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.69 + }
1.70 +
1.71 + return len;
1.72 +}
1.73 +
1.74 +static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
1.75 +{
1.76 + CBaseEntity *pEntity;
1.77 + char *prop;
1.78 + int offset;
1.79 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.80 +
1.81 + if (!pEdict || !pEntity)
1.82 + {
1.83 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.84 + }
1.85 +
1.86 + switch (params[2])
1.87 + {
1.88 + case Prop_Data:
1.89 + {
1.90 + datamap_t *pMap;
1.91 + typedescription_t *td;
1.92 + if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.93 + {
1.94 + return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.95 + }
1.96 + pContext->LocalToString(params[3], &prop);
1.97 + if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.98 + {
1.99 + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.100 + }
1.101 + if (td->fieldType != FIELD_CHARACTER)
1.102 + {
1.103 + return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.104 + }
1.105 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.106 + break;
1.107 + }
1.108 + case Prop_Send:
1.109 + {
1.110 + char *prop;
1.111 + IServerNetworkable *pNet = pEdict->GetNetworkable();
1.112 + if (!pNet)
1.113 + {
1.114 + return pContext->ThrowNativeError("The edict is not networkable");
1.115 + }
1.116 + pContext->LocalToString(params[3], &prop);
1.117 + SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
1.118 + if (!pSend)
1.119 + {
1.120 + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.121 + }
1.122 + if (pSend->GetType() != DPT_String)
1.123 + {
1.124 + return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.125 + }
1.126 + offset = pSend->GetOffset();
1.127 + break;
1.128 + }
1.129 + default:
1.130 + {
1.131 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.132 + }
1.133 + }
1.134 +
1.135 + size_t len;
1.136 + char *src = (char *)((uint8_t *)pEntity + offset);
1.137 + pContext->StringToLocalUTF8(params[4], params[5], src, &len);
1.138 +
1.139 + return len;
1.140 +}
1.141 +
1.142 +static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
1.143 +{
1.144 + CBaseEntity *pEntity;
1.145 + char *prop;
1.146 + int offset;
1.147 + int maxlen;
1.148 + bool is_sendprop = false;
1.149 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.150 +
1.151 + if (!pEdict || !pEntity)
1.152 + {
1.153 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.154 + }
1.155 +
1.156 + switch (params[2])
1.157 + {
1.158 + case Prop_Data:
1.159 + {
1.160 + datamap_t *pMap;
1.161 + typedescription_t *td;
1.162 + if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.163 + {
1.164 + return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.165 + }
1.166 + pContext->LocalToString(params[3], &prop);
1.167 + if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.168 + {
1.169 + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.170 + }
1.171 + if (td->fieldType != FIELD_CHARACTER)
1.172 + {
1.173 + return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.174 + }
1.175 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.176 + maxlen = td->fieldSize;
1.177 + break;
1.178 + }
1.179 + case Prop_Send:
1.180 + {
1.181 + char *prop;
1.182 + IServerNetworkable *pNet = pEdict->GetNetworkable();
1.183 + if (!pNet)
1.184 + {
1.185 + return pContext->ThrowNativeError("The edict is not networkable");
1.186 + }
1.187 + pContext->LocalToString(params[3], &prop);
1.188 + SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
1.189 + if (!pSend)
1.190 + {
1.191 + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.192 + }
1.193 + if (pSend->GetType() != DPT_String)
1.194 + {
1.195 + return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.196 + }
1.197 + offset = pSend->GetOffset();
1.198 + maxlen = DT_MAX_STRING_BUFFERSIZE;
1.199 + is_sendprop = true;
1.200 + break;
1.201 + }
1.202 + default:
1.203 + {
1.204 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.205 + }
1.206 + }
1.207 +
1.208 + char *src;
1.209 + char *dest = (char *)((uint8_t *)pEntity + offset);
1.210 +
1.211 + pContext->LocalToString(params[4], &src);
1.212 + size_t len = strncopy(dest, src, maxlen);
1.213 +
1.214 + if (is_sendprop)
1.215 + {
1.216 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.217 + }
1.218 +
1.219 + return len;
1.220 +}
1.221 +
1.222 REGISTER_NATIVES(entityNatives)
1.223 {
1.224 {"ChangeEdictState", ChangeEdictState},
1.225 @@ -581,5 +789,9 @@
1.226 {"SetEntDataFloat", SetEntDataFloat},
1.227 {"SetEntDataVector", SetEntDataVector},
1.228 {"FindDataMapOffs", FindDataMapOffs},
1.229 + {"GetEntDataString", GetEntDataString},
1.230 + {"SetEntDataString", SetEntDataString},
1.231 + {"GetEntPropString", GetEntPropString},
1.232 + {"SetEntPropString", SetEntPropString},
1.233 {NULL, NULL}
1.234 };