added amb719, added TE hooks and read prop natives to read props before transmission
1.1 --- a/extensions/sdktools/extension.cpp Thu Aug 02 23:11:07 2007 +0000
1.2 +++ b/extensions/sdktools/extension.cpp Fri Aug 03 01:53:00 2007 +0000
1.3 @@ -119,6 +119,7 @@
1.4 ShutdownHelpers();
1.5
1.6 g_TEManager.Shutdown();
1.7 + s_TempEntHooks.Shutdown();
1.8
1.9 gameconfs->CloseGameConfigFile(g_pGameConf);
1.10 playerhelpers->RemoveClientListener(&g_SdkTools);
1.11 @@ -143,6 +144,7 @@
1.12 SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
1.13
1.14 g_TEManager.Initialize();
1.15 + s_TempEntHooks.Initialize();
1.16 InitializeValveGlobals();
1.17 }
1.18
1.19 @@ -176,6 +178,7 @@
1.20 ShutdownHelpers();
1.21
1.22 g_TEManager.Shutdown();
1.23 + s_TempEntHooks.Shutdown();
1.24 }
1.25
1.26 bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar)
2.1 --- a/extensions/sdktools/tempents.cpp Thu Aug 02 23:11:07 2007 +0000
2.2 +++ b/extensions/sdktools/tempents.cpp Fri Aug 03 01:53:00 2007 +0000
2.3 @@ -143,6 +143,31 @@
2.4 return true;
2.5 }
2.6
2.7 +bool TempEntityInfo::TE_GetEntData(const char *name, int *value)
2.8 +{
2.9 + /* Search for our offset */
2.10 + int size;
2.11 + int offset = _FindOffset(name, &size);
2.12 +
2.13 + if (offset < 0)
2.14 + {
2.15 + return false;
2.16 + }
2.17 +
2.18 + if (size <= 8)
2.19 + {
2.20 + *value = *((uint8_t *)m_Me + offset);
2.21 + } else if (size <= 16) {
2.22 + *value = *(short *)((uint8_t *)m_Me + offset);
2.23 + } else if (size <= 32) {
2.24 + *value = *(int *)((uint8_t *)m_Me + offset);
2.25 + } else {
2.26 + return false;
2.27 + }
2.28 +
2.29 + return true;
2.30 +}
2.31 +
2.32 bool TempEntityInfo::TE_SetEntDataFloat(const char *name, float value)
2.33 {
2.34 /* Search for our offset */
2.35 @@ -158,6 +183,21 @@
2.36 return true;
2.37 }
2.38
2.39 +bool TempEntityInfo::TE_GetEntDataFloat(const char *name, float *value)
2.40 +{
2.41 + /* Search for our offset */
2.42 + int offset = _FindOffset(name);
2.43 +
2.44 + if (offset < 0)
2.45 + {
2.46 + return false;
2.47 + }
2.48 +
2.49 + *value = *(float *)((uint8_t *)m_Me + offset);
2.50 +
2.51 + return true;
2.52 +}
2.53 +
2.54 bool TempEntityInfo::TE_SetEntDataVector(const char *name, float vector[3])
2.55 {
2.56 /* Search for our offset */
2.57 @@ -176,6 +216,24 @@
2.58 return true;
2.59 }
2.60
2.61 +bool TempEntityInfo::TE_GetEntDataVector(const char *name, float vector[3])
2.62 +{
2.63 + /* Search for our offset */
2.64 + int offset = _FindOffset(name);
2.65 +
2.66 + if (offset < 0)
2.67 + {
2.68 + return false;
2.69 + }
2.70 +
2.71 + Vector *v = (Vector *)((uint8_t *)m_Me + offset);
2.72 + vector[0] = v->x;
2.73 + vector[1] = v->y;
2.74 + vector[2] = v->z;
2.75 +
2.76 + return true;
2.77 +}
2.78 +
2.79 bool TempEntityInfo::TE_SetEntDataFloatArray(const char *name, cell_t *array, int size)
2.80 {
2.81 /* Search for our offset */
2.82 @@ -314,6 +372,11 @@
2.83 return te;
2.84 }
2.85
2.86 +const char *TempEntityManager::GetNameFromThisPtr(void *me)
2.87 +{
2.88 + return *(const char **)((unsigned char *)me + m_NameOffs);
2.89 +}
2.90 +
2.91 void TempEntityManager::DumpList()
2.92 {
2.93 unsigned int index = 0;
3.1 --- a/extensions/sdktools/tempents.h Thu Aug 02 23:11:07 2007 +0000
3.2 +++ b/extensions/sdktools/tempents.h Fri Aug 03 01:53:00 2007 +0000
3.3 @@ -53,6 +53,9 @@
3.4 bool TE_SetEntDataFloat(const char *name, float value);
3.5 bool TE_SetEntDataVector(const char *name, float vector[3]);
3.6 bool TE_SetEntDataFloatArray(const char *name, cell_t *array, int size);
3.7 + bool TE_GetEntData(const char *name, int *value);
3.8 + bool TE_GetEntDataFloat(const char *name, float *value);
3.9 + bool TE_GetEntDataVector(const char *name, float vector[3]);
3.10 void Send(IRecipientFilter &filter, float delay);
3.11 private:
3.12 int _FindOffset(const char *name, int *size=NULL);
3.13 @@ -72,6 +75,7 @@
3.14 void Shutdown();
3.15 public:
3.16 TempEntityInfo *GetTempEntityInfo(const char *name);
3.17 + const char *GetNameFromThisPtr(void *me);
3.18 public:
3.19 void DumpList();
3.20 void DumpProps(FILE *fp);
3.21 @@ -85,6 +89,31 @@
3.22 bool m_Loaded;
3.23 };
3.24
3.25 +struct TEHookInfo
3.26 +{
3.27 + TempEntityInfo *te;
3.28 + List<IPluginFunction *> lst;
3.29 +};
3.30 +
3.31 +class TempEntHooks
3.32 +{
3.33 +public:
3.34 + void Initialize();
3.35 + void Shutdown();
3.36 + bool AddHook(const char *name, IPluginFunction *pFunc);
3.37 + bool RemoveHook(const char *name, IPluginFunction *pFunc);
3.38 + void OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID);
3.39 +private:
3.40 + void _IncRefCounter();
3.41 + void _DecRefCounter();
3.42 + size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
3.43 +private:
3.44 + IBasicTrie *m_TEHooks;
3.45 + List<TEHookInfo *> m_HookInfo;
3.46 + size_t m_HookCount;
3.47 +};
3.48 +
3.49 extern TempEntityManager g_TEManager;
3.50 +extern TempEntHooks s_TempEntHooks;
3.51
3.52 #endif //_INCLUDE_SOURCEMOD_TEMPENTS_H_
4.1 --- a/extensions/sdktools/tenatives.cpp Thu Aug 02 23:11:07 2007 +0000
4.2 +++ b/extensions/sdktools/tenatives.cpp Fri Aug 03 01:53:00 2007 +0000
4.3 @@ -32,9 +32,166 @@
4.4
4.5 #include "tempents.h"
4.6 #include "CellRecipientFilter.h"
4.7 +#include <IForwardSys.h>
4.8 +
4.9 +SH_DECL_HOOK5_void(IVEngineServer, PlaybackTempEntity, SH_NOATTRIB, 0, IRecipientFilter &, float, const void *, const SendTable *, int);
4.10
4.11 CellRecipientFilter g_TERecFilter;
4.12 TempEntityInfo *g_CurrentTE = NULL;
4.13 +int g_TEPlayers[256];
4.14 +
4.15 +/*************************
4.16 +* *
4.17 +* Temp Entity Hook Class *
4.18 +* *
4.19 +**************************/
4.20 +
4.21 +void TempEntHooks::Initialize()
4.22 +{
4.23 + m_TEHooks = adtfactory->CreateBasicTrie();
4.24 +}
4.25 +
4.26 +void TempEntHooks::Shutdown()
4.27 +{
4.28 + List<TEHookInfo *>::iterator iter;
4.29 + for (iter=m_HookInfo.begin(); iter!=m_HookInfo.end(); iter++)
4.30 + {
4.31 + delete (*iter);
4.32 + }
4.33 + if (m_HookCount)
4.34 + {
4.35 + m_HookCount = 1;
4.36 + _DecRefCounter();
4.37 + }
4.38 + m_TEHooks->Destroy();
4.39 +}
4.40 +
4.41 +void TempEntHooks::_IncRefCounter()
4.42 +{
4.43 + if (m_HookCount++ == 0)
4.44 + {
4.45 + SH_ADD_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false);
4.46 + }
4.47 +}
4.48 +
4.49 +void TempEntHooks::_DecRefCounter()
4.50 +{
4.51 + if (--m_HookCount == 0)
4.52 + {
4.53 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, PlaybackTempEntity, engine, this, &TempEntHooks::OnPlaybackTempEntity, false);
4.54 + }
4.55 +}
4.56 +
4.57 +size_t TempEntHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
4.58 +{
4.59 + size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
4.60 +
4.61 + for (size_t i=0; i<size; i++)
4.62 + {
4.63 + pl_array[i] = pFilter->GetRecipientIndex(i);
4.64 + }
4.65 +
4.66 + return size;
4.67 +}
4.68 +
4.69 +bool TempEntHooks::AddHook(const char *name, IPluginFunction *pFunc)
4.70 +{
4.71 + TEHookInfo *pInfo;
4.72 +
4.73 + if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
4.74 + {
4.75 + pInfo->lst.push_back(pFunc);
4.76 + } else {
4.77 + TempEntityInfo *te;
4.78 + if (!(te=g_TEManager.GetTempEntityInfo(name)))
4.79 + {
4.80 + return false;
4.81 + }
4.82 +
4.83 + pInfo = new TEHookInfo;
4.84 + pInfo->te = te;
4.85 + pInfo->lst.push_back(pFunc);
4.86 +
4.87 + m_TEHooks->Insert(name, reinterpret_cast<void *>(pInfo));
4.88 + m_HookInfo.push_back(pInfo);
4.89 + }
4.90 +
4.91 + _IncRefCounter();
4.92 +
4.93 + return true;
4.94 +}
4.95 +
4.96 +bool TempEntHooks::RemoveHook(const char *name, IPluginFunction *pFunc)
4.97 +{
4.98 + TEHookInfo *pInfo;
4.99 +
4.100 + if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
4.101 + {
4.102 + List<IPluginFunction *>::iterator iter;
4.103 + if ((iter=pInfo->lst.find(pFunc)) != pInfo->lst.end())
4.104 + {
4.105 + pInfo->lst.erase(iter);
4.106 + if (pInfo->lst.empty())
4.107 + {
4.108 + m_HookInfo.remove(pInfo);
4.109 + m_TEHooks->Delete(name);
4.110 + delete pInfo;
4.111 + }
4.112 + _DecRefCounter();
4.113 + } else {
4.114 + return false;
4.115 + }
4.116 + } else {
4.117 + return false;
4.118 + }
4.119 +
4.120 + return true;
4.121 +}
4.122 +
4.123 +void TempEntHooks::OnPlaybackTempEntity(IRecipientFilter &filter, float delay, const void *pSender, const SendTable *pST, int classID)
4.124 +{
4.125 + TEHookInfo *pInfo;
4.126 + const char *name = g_TEManager.GetNameFromThisPtr(const_cast<void *>(pSender));
4.127 +
4.128 + if (m_TEHooks->Retrieve(name, reinterpret_cast<void **>(&pInfo)))
4.129 + {
4.130 + List<IPluginFunction *>::iterator iter;
4.131 + IPluginFunction *pFunc;
4.132 + size_t size;
4.133 + cell_t res = static_cast<ResultType>(Pl_Continue);
4.134 +
4.135 + TempEntityInfo *oldinfo = g_CurrentTE;
4.136 + g_CurrentTE = pInfo->te;
4.137 + size = _FillInPlayers(g_TEPlayers, &filter);
4.138 +
4.139 + for (iter=pInfo->lst.begin(); iter!=pInfo->lst.end(); iter++)
4.140 + {
4.141 + pFunc = (*iter);
4.142 + pFunc->PushString(name);
4.143 + pFunc->PushArray(g_TEPlayers, size);
4.144 + pFunc->PushCell(size);
4.145 + pFunc->PushFloat(delay);
4.146 + pFunc->Execute(&res);
4.147 +
4.148 + if (res != Pl_Continue)
4.149 + {
4.150 + g_CurrentTE = oldinfo;
4.151 + RETURN_META(MRES_SUPERCEDE);
4.152 + }
4.153 + }
4.154 +
4.155 + g_CurrentTE = oldinfo;
4.156 + RETURN_META(MRES_IGNORED);
4.157 + }
4.158 +}
4.159 +
4.160 +/**********************
4.161 +* *
4.162 +* Temp Entity Natives *
4.163 +* *
4.164 +***********************/
4.165 +
4.166 +TempEntHooks s_TempEntHooks;
4.167
4.168 static cell_t smn_TEStart(IPluginContext *pContext, const cell_t *params)
4.169 {
4.170 @@ -77,6 +234,29 @@
4.171 return 1;
4.172 }
4.173
4.174 +static cell_t smn_TEReadNum(IPluginContext *pContext, const cell_t *params)
4.175 +{
4.176 + if (!g_TEManager.IsAvailable())
4.177 + {
4.178 + return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
4.179 + }
4.180 + if (!g_CurrentTE)
4.181 + {
4.182 + return pContext->ThrowNativeError("No TempEntity call is in progress");
4.183 + }
4.184 +
4.185 + char *prop;
4.186 + int val;
4.187 + pContext->LocalToString(params[1], &prop);
4.188 +
4.189 + if (!g_CurrentTE->TE_GetEntData(prop, &val))
4.190 + {
4.191 + return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
4.192 + }
4.193 +
4.194 + return val;
4.195 +}
4.196 +
4.197 static cell_t smn_TE_WriteFloat(IPluginContext *pContext, const cell_t *params)
4.198 {
4.199 if (!g_TEManager.IsAvailable())
4.200 @@ -99,6 +279,29 @@
4.201 return 1;
4.202 }
4.203
4.204 +static cell_t smn_TE_ReadFloat(IPluginContext *pContext, const cell_t *params)
4.205 +{
4.206 + if (!g_TEManager.IsAvailable())
4.207 + {
4.208 + return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
4.209 + }
4.210 + if (!g_CurrentTE)
4.211 + {
4.212 + return pContext->ThrowNativeError("No TempEntity call is in progress");
4.213 + }
4.214 +
4.215 + char *prop;
4.216 + float val;
4.217 + pContext->LocalToString(params[1], &prop);
4.218 +
4.219 + if (!g_CurrentTE->TE_GetEntDataFloat(prop, &val))
4.220 + {
4.221 + return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
4.222 + }
4.223 +
4.224 + return sp_ftoc(val);
4.225 +}
4.226 +
4.227 static cell_t smn_TEWriteVector(IPluginContext *pContext, const cell_t *params)
4.228 {
4.229 if (!g_TEManager.IsAvailable())
4.230 @@ -125,6 +328,36 @@
4.231 return 1;
4.232 }
4.233
4.234 +static cell_t smn_TEReadVector(IPluginContext *pContext, const cell_t *params)
4.235 +{
4.236 + if (!g_TEManager.IsAvailable())
4.237 + {
4.238 + return pContext->ThrowNativeError("TempEntity System unsupported or not available, file a bug report");
4.239 + }
4.240 + if (!g_CurrentTE)
4.241 + {
4.242 + return pContext->ThrowNativeError("No TempEntity call is in progress");
4.243 + }
4.244 +
4.245 + char *prop;
4.246 + pContext->LocalToString(params[1], &prop);
4.247 +
4.248 + cell_t *addr;
4.249 + float vec[3];
4.250 + pContext->LocalToPhysAddr(params[2], &addr);
4.251 +
4.252 + if (!g_CurrentTE->TE_GetEntDataVector(prop, vec))
4.253 + {
4.254 + return pContext->ThrowNativeError("Temp entity property \"%s\" not found", prop);
4.255 + }
4.256 +
4.257 + addr[0] = sp_ftoc(vec[0]);
4.258 + addr[1] = sp_ftoc(vec[1]);
4.259 + addr[2] = sp_ftoc(vec[2]);
4.260 +
4.261 + return 1;
4.262 +}
4.263 +
4.264 static cell_t smn_TEWriteFloatArray(IPluginContext *pContext, const cell_t *params)
4.265 {
4.266 if (!g_TEManager.IsAvailable())
4.267 @@ -190,15 +423,60 @@
4.268 return g_CurrentTE->IsValidProp(prop) ? 1 : 0;
4.269 }
4.270
4.271 +static cell_t smn_AddTempEntHook(IPluginContext *pContext, const cell_t *params)
4.272 +{
4.273 + char *name;
4.274 + IPluginFunction *pFunc;
4.275 +
4.276 + pContext->LocalToString(params[1], &name);
4.277 + pFunc = pContext->GetFunctionById(params[2]);
4.278 + if (!pFunc)
4.279 + {
4.280 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
4.281 + }
4.282 +
4.283 + if (!s_TempEntHooks.AddHook(name, pFunc))
4.284 + {
4.285 + return pContext->ThrowNativeError("Invalid TempEntity name: \"%s\"", name);
4.286 + }
4.287 +
4.288 + return 1;
4.289 +}
4.290 +
4.291 +static cell_t smn_RemoveTempEntHook(IPluginContext *pContext, const cell_t *params)
4.292 +{
4.293 + char *name;
4.294 + IPluginFunction *pFunc;
4.295 +
4.296 + pContext->LocalToString(params[1], &name);
4.297 + pFunc = pContext->GetFunctionById(params[2]);
4.298 + if (!pFunc)
4.299 + {
4.300 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
4.301 + }
4.302 +
4.303 + if (!s_TempEntHooks.RemoveHook(name, pFunc))
4.304 + {
4.305 + return pContext->ThrowNativeError("Invalid hooked TempEntity name or function");
4.306 + }
4.307 +
4.308 + return 1;
4.309 +}
4.310 +
4.311 sp_nativeinfo_t g_TENatives[] =
4.312 {
4.313 {"TE_Start", smn_TEStart},
4.314 {"TE_WriteNum", smn_TEWriteNum},
4.315 + {"TE_ReadNum", smn_TEReadNum},
4.316 {"TE_WriteFloat", smn_TE_WriteFloat},
4.317 + {"TE_ReadFloat", smn_TE_ReadFloat},
4.318 {"TE_WriteVector", smn_TEWriteVector},
4.319 + {"TE_ReadVector", smn_TEReadVector},
4.320 {"TE_WriteAngles", smn_TEWriteVector},
4.321 {"TE_Send", smn_TESend},
4.322 {"TE_IsValidProp", smn_TEIsValidProp},
4.323 {"TE_WriteFloatArray", smn_TEWriteFloatArray},
4.324 + {"AddTempEntHook", smn_AddTempEntHook},
4.325 + {"RemoveTempEntHook", smn_RemoveTempEntHook},
4.326 {NULL, NULL}
4.327 };
5.1 --- a/plugins/include/sdktools_tempents.inc Thu Aug 02 23:11:07 2007 +0000
5.2 +++ b/plugins/include/sdktools_tempents.inc Fri Aug 03 01:53:00 2007 +0000
5.3 @@ -19,6 +19,37 @@
5.4 #define _sdktools_tempents_included
5.5
5.6 /**
5.7 + * Called when a temp entity is going to be sent.
5.8 + *
5.9 + * @param te_name TE name.
5.10 + * @param Players Array containing target player indexes.
5.11 + * @param numClients Number of players in the array.
5.12 + * @param delay Delay in seconds to send the TE.
5.13 + * @return Plugin_Continue to allow the transmission of the TE, Plugin_Stop to block it.
5.14 + */
5.15 +functag TEHook Action:public(const String:te_name[], const Players[], numClients, Float:delay);
5.16 +
5.17 +/**
5.18 + * Hooks a temp entity.
5.19 + *
5.20 + * @param te_name TE name to hook.
5.21 + * @param hook Function to use as a hook.
5.22 + * @noreturn
5.23 + * @error Temp Entity name not available or invalid function hook.
5.24 + */
5.25 +native AddTempEntHook(const String:te_name[], TEHook:hook);
5.26 +
5.27 +/**
5.28 + * Removes a temp entity.
5.29 + *
5.30 + * @param te_name TE name to unhook.
5.31 + * @param hook Function used for the hook.
5.32 + * @noreturn
5.33 + * @error Temp Entity name not available or invalid function hook.
5.34 + */
5.35 +native RemoveTempEntHook(const String:te_name[], TEHook:hook);
5.36 +
5.37 +/**
5.38 * Starts a temp entity transmission.
5.39 *
5.40 * @param te_name TE name.
5.41 @@ -46,6 +77,16 @@
5.42 native TE_WriteNum(const String:prop[], value);
5.43
5.44 /**
5.45 + * Reads an integer value in the current temp entity.
5.46 + *
5.47 + * @param prop Property to use.
5.48 + * @param value Integer value to read.
5.49 + * @return Property value.
5.50 + * @error Property not found.
5.51 + */
5.52 +native TE_ReadNum(const String:prop[]);
5.53 +
5.54 +/**
5.55 * Sets a floating point number in the current temp entity.
5.56 *
5.57 * @param prop Property to use.
5.58 @@ -56,6 +97,16 @@
5.59 native TE_WriteFloat(const String:prop[], Float:value);
5.60
5.61 /**
5.62 + * Reads a floating point number in the current temp entity.
5.63 + *
5.64 + * @param prop Property to use.
5.65 + * @param value Floating point number to read.
5.66 + * @noreturn Property value.
5.67 + * @error Property not found.
5.68 + */
5.69 +native Float:TE_ReadFloat(const String:prop[]);
5.70 +
5.71 +/**
5.72 * Sets a vector in the current temp entity.
5.73 *
5.74 * @param prop Property to use.
5.75 @@ -66,6 +117,16 @@
5.76 native TE_WriteVector(const String:prop[], const Float:vector[3]);
5.77
5.78 /**
5.79 + * Reads a vector in the current temp entity.
5.80 + *
5.81 + * @param prop Property to use.
5.82 + * @param vector Vector to read.
5.83 + * @noreturn
5.84 + * @error Property not found.
5.85 + */
5.86 +native TE_ReadVector(const String:prop[], Float:vector[3]);
5.87 +
5.88 +/**
5.89 * Sets a QAngle in the current temp entity.
5.90 *
5.91 * @param prop Property to use.