1.1 --- a/core/CellRecipientFilter.h Sat Mar 10 21:26:04 2007 +0000
1.2 +++ b/core/CellRecipientFilter.h Sun Mar 11 03:04:39 2007 +0000
1.3 @@ -21,7 +21,7 @@
1.4 class CellRecipientFilter : public IRecipientFilter
1.5 {
1.6 public:
1.7 - CellRecipientFilter() : m_Reliable(false), m_InitMessage(false), m_Size(0) {}
1.8 + CellRecipientFilter() : m_IsReliable(false), m_IsInitMessage(false), m_Size(0) {}
1.9 ~CellRecipientFilter() {}
1.10 public: //IRecipientFilter
1.11 bool IsReliable() const;
1.12 @@ -29,32 +29,32 @@
1.13 int GetRecipientCount() const;
1.14 int GetRecipientIndex(int slot) const;
1.15 public:
1.16 - void SetRecipientPtr(cell_t *ptr, size_t count);
1.17 - void SetReliable(bool isreliable);
1.18 - void SetInitMessage(bool isinitmsg);
1.19 - void ResetFilter();
1.20 + void Initialize(cell_t *ptr, size_t count);
1.21 + void SetToReliable(bool isreliable);
1.22 + void SetToInit(bool isinitmsg);
1.23 + void Reset();
1.24 private:
1.25 - cell_t m_CellRecipients[255];
1.26 - bool m_Reliable;
1.27 - bool m_InitMessage;
1.28 + cell_t m_Players[255];
1.29 + bool m_IsReliable;
1.30 + bool m_IsInitMessage;
1.31 size_t m_Size;
1.32 };
1.33
1.34 -inline void CellRecipientFilter::ResetFilter()
1.35 +inline void CellRecipientFilter::Reset()
1.36 {
1.37 - m_Reliable = false;
1.38 - m_InitMessage = false;
1.39 + m_IsReliable = false;
1.40 + m_IsInitMessage = false;
1.41 m_Size = 0;
1.42 }
1.43
1.44 inline bool CellRecipientFilter::IsReliable() const
1.45 {
1.46 - return m_Reliable;
1.47 + return m_IsReliable;
1.48 }
1.49
1.50 inline bool CellRecipientFilter::IsInitMessage() const
1.51 {
1.52 - return m_InitMessage;
1.53 + return m_IsInitMessage;
1.54 }
1.55
1.56 inline int CellRecipientFilter::GetRecipientCount() const
1.57 @@ -68,22 +68,22 @@
1.58 {
1.59 return -1;
1.60 }
1.61 - return static_cast<int>(m_CellRecipients[slot]);
1.62 + return static_cast<int>(m_Players[slot]);
1.63 }
1.64
1.65 -inline void CellRecipientFilter::SetInitMessage(bool isinitmsg)
1.66 +inline void CellRecipientFilter::SetToInit(bool isinitmsg)
1.67 {
1.68 - m_InitMessage = isinitmsg;
1.69 + m_IsInitMessage = isinitmsg;
1.70 }
1.71
1.72 -inline void CellRecipientFilter::SetReliable(bool isreliable)
1.73 +inline void CellRecipientFilter::SetToReliable(bool isreliable)
1.74 {
1.75 - m_Reliable = isreliable;
1.76 + m_IsReliable = isreliable;
1.77 }
1.78
1.79 -inline void CellRecipientFilter::SetRecipientPtr(cell_t *ptr, size_t count)
1.80 +inline void CellRecipientFilter::Initialize(cell_t *ptr, size_t count)
1.81 {
1.82 - memcpy(m_CellRecipients, ptr, count * sizeof(cell_t));
1.83 + memcpy(m_Players, ptr, count * sizeof(cell_t));
1.84 m_Size = count;
1.85 }
1.86
2.1 --- a/core/UserMessages.cpp Sat Mar 10 21:26:04 2007 +0000
2.2 +++ b/core/UserMessages.cpp Sun Mar 11 03:04:39 2007 +0000
2.3 @@ -88,8 +88,8 @@
2.4 bf_write *CUserMessages::StartMessage(int msg_id, cell_t players[], unsigned int playersNum, int flags)
2.5 {
2.6 bf_write *buffer;
2.7 -
2.8 - if (m_InExec)
2.9 +
2.10 + if (m_InExec || m_InHook)
2.11 {
2.12 return NULL;
2.13 }
2.14 @@ -98,16 +98,16 @@
2.15 return NULL;
2.16 }
2.17
2.18 - m_CellRecFilter.SetRecipientPtr(players, playersNum);
2.19 + m_CellRecFilter.Initialize(players, playersNum);
2.20
2.21 m_CurFlags = flags;
2.22 if (m_CurFlags & USERMSG_INITMSG)
2.23 {
2.24 - m_CellRecFilter.SetInitMessage(true);
2.25 + m_CellRecFilter.SetToInit(true);
2.26 }
2.27 if (m_CurFlags & USERMSG_RELIABLE)
2.28 {
2.29 - m_CellRecFilter.SetReliable(true);
2.30 + m_CellRecFilter.SetToReliable(true);
2.31 }
2.32
2.33 m_InExec = true;
2.34 @@ -138,7 +138,7 @@
2.35
2.36 m_InExec = false;
2.37 m_CurFlags = 0;
2.38 - m_CellRecFilter.ResetFilter();
2.39 + m_CellRecFilter.Reset();
2.40
2.41 return true;
2.42 }
2.43 @@ -150,6 +150,19 @@
2.44 return false;
2.45 }
2.46
2.47 + ListenerInfo *pInfo;
2.48 + if (m_FreeListeners.empty())
2.49 + {
2.50 + pInfo = new ListenerInfo;
2.51 + } else {
2.52 + pInfo = m_FreeListeners.front();
2.53 + m_FreeListeners.pop();
2.54 + }
2.55 +
2.56 + pInfo->Callback = pListener;
2.57 + pInfo->IsHooked = false;
2.58 + pInfo->KillMe = false;
2.59 +
2.60 if (!m_HookCount++)
2.61 {
2.62 SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &CUserMessages::OnStartMessage_Pre, false);
2.63 @@ -160,20 +173,19 @@
2.64
2.65 if (intercept)
2.66 {
2.67 - m_msgIntercepts[msg_id].push_back(pListener);
2.68 + m_msgIntercepts[msg_id].push_back(pInfo);
2.69 } else {
2.70 - m_msgHooks[msg_id].push_back(pListener);
2.71 + m_msgHooks[msg_id].push_back(pInfo);
2.72 }
2.73
2.74 return true;
2.75 }
2.76
2.77 bool CUserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
2.78 -{
2.79 - //:TODO: restrict user from unhooking stuff during a message hook to avoid iterator mess
2.80 - List<IUserMessageListener *> *lst;
2.81 - IUserMessageListener *listener;
2.82 +{
2.83 + MsgList *pList;
2.84 MsgIter iter;
2.85 + ListenerInfo *pInfo;
2.86 bool deleted = false;
2.87
2.88 if (msg_id < 0 || msg_id >= 255)
2.89 @@ -181,27 +193,40 @@
2.90 return false;
2.91 }
2.92
2.93 - lst = (intercept) ? &m_msgIntercepts[msg_id] : &m_msgHooks[msg_id];
2.94 - for (iter=lst->begin(); iter!=lst->end(); iter++)
2.95 + pList = (intercept) ? &m_msgIntercepts[msg_id] : &m_msgHooks[msg_id];
2.96 + for (iter=pList->begin(); iter!=pList->end(); iter++)
2.97 {
2.98 - listener = (*iter);
2.99 - if (listener == pListener)
2.100 + pInfo = (*iter);
2.101 + if (pInfo->Callback == pListener)
2.102 {
2.103 - lst->erase(iter);
2.104 + if (pInfo->IsHooked)
2.105 + {
2.106 + pInfo->KillMe = true;
2.107 + return true;
2.108 + }
2.109 + pList->erase(iter);
2.110 deleted = true;
2.111 break;
2.112 }
2.113 }
2.114
2.115 - if (deleted && !(--m_HookCount))
2.116 + if (deleted)
2.117 + {
2.118 + _DecRefCounter();
2.119 + }
2.120 +
2.121 + return deleted;
2.122 +}
2.123 +
2.124 +void CUserMessages::_DecRefCounter()
2.125 +{
2.126 + if (--m_HookCount == 0)
2.127 {
2.128 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &CUserMessages::OnStartMessage_Pre, false);
2.129 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &CUserMessages::OnStartMessage_Post, true);
2.130 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &CUserMessages::OnMessageEnd_Pre, false);
2.131 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &CUserMessages::OnMessageEnd_Post, true);
2.132 }
2.133 -
2.134 - return (deleted) ? true : false;
2.135 }
2.136
2.137 bf_write *CUserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type)
2.138 @@ -209,13 +234,8 @@
2.139 bool is_intercept_empty = m_msgIntercepts[msg_type].empty();
2.140 bool is_hook_empty = m_msgHooks[msg_type].empty();
2.141
2.142 - if (is_intercept_empty && is_hook_empty)
2.143 - {
2.144 - m_InHook = false;
2.145 - RETURN_META_VALUE(MRES_IGNORED, NULL);
2.146 - }
2.147 -
2.148 - if ((m_InExec) && !(m_CurFlags & USERMSG_PASSTHRU_ALL))
2.149 + if ((is_intercept_empty && is_hook_empty)
2.150 + || (m_InExec && !(m_CurFlags & USERMSG_PASSTHRU_ALL)))
2.151 {
2.152 m_InHook = false;
2.153 RETURN_META_VALUE(MRES_IGNORED, NULL);
2.154 @@ -223,11 +243,11 @@
2.155
2.156 m_CurId = msg_type;
2.157 m_CurRecFilter = filter;
2.158 - m_InterceptBuffer.Reset();
2.159 m_InHook = true;
2.160
2.161 if (!is_intercept_empty)
2.162 {
2.163 + m_InterceptBuffer.Reset();
2.164 RETURN_META_VALUE(MRES_SUPERCEDE, &m_InterceptBuffer);
2.165 }
2.166
2.167 @@ -253,23 +273,48 @@
2.168 RETURN_META(MRES_IGNORED);
2.169 }
2.170
2.171 - List<IUserMessageListener *> *lst;
2.172 - IUserMessageListener *listener;
2.173 + MsgList *pList;
2.174 MsgIter iter;
2.175 + ListenerInfo *pInfo;
2.176 +
2.177 + pList = &m_msgIntercepts[m_CurId];
2.178 + for (iter=pList->begin(); iter!=pList->end(); )
2.179 + {
2.180 + pInfo = (*iter);
2.181 + pInfo->IsHooked = true;
2.182 + pInfo->Callback->OnUserMessageSent(m_CurId);
2.183
2.184 - lst = &m_msgIntercepts[m_CurId];
2.185 - for (iter=lst->begin(); iter!=lst->end(); iter++)
2.186 - {
2.187 - listener = (*iter);
2.188 - listener->OnUserMessageSent(m_CurId);
2.189 + if (pInfo->KillMe)
2.190 + {
2.191 + iter = pList->erase(iter);
2.192 + m_FreeListeners.push(pInfo);
2.193 + _DecRefCounter();
2.194 + continue;
2.195 + }
2.196 +
2.197 + pInfo->IsHooked = false;
2.198 + iter++;
2.199 }
2.200
2.201 - lst = &m_msgHooks[m_CurId];
2.202 - for (iter=lst->begin(); iter!=lst->end(); iter++)
2.203 + pList = &m_msgHooks[m_CurId];
2.204 + for (iter=pList->begin(); iter!=pList->end(); iter++)
2.205 {
2.206 - listener = (*iter);
2.207 - listener->OnUserMessageSent(m_CurId);
2.208 + pInfo = (*iter);
2.209 + pInfo->Callback->OnUserMessageSent(m_CurId);
2.210 +
2.211 + if (pInfo->KillMe)
2.212 + {
2.213 + iter = pList->erase(iter);
2.214 + m_FreeListeners.push(pInfo);
2.215 + _DecRefCounter();
2.216 + continue;
2.217 + }
2.218 +
2.219 + pInfo->IsHooked = false;
2.220 + iter++;
2.221 }
2.222 +
2.223 + m_InHook = false;
2.224 }
2.225
2.226 void CUserMessages::OnMessageEnd_Pre()
2.227 @@ -279,26 +324,61 @@
2.228 RETURN_META(MRES_IGNORED);
2.229 }
2.230
2.231 - List<IUserMessageListener *> *lst;
2.232 - IUserMessageListener *listener;
2.233 - bf_write *engine_bfw;
2.234 + MsgList *pList;
2.235 MsgIter iter;
2.236 + ListenerInfo *pInfo;
2.237 +
2.238 ResultType res;
2.239 bool intercepted = false;
2.240 bool handled = false;
2.241
2.242 - lst = &m_msgIntercepts[m_CurId];
2.243 - for (iter=lst->begin(); iter!=lst->end(); iter++)
2.244 + pList = &m_msgIntercepts[m_CurId];
2.245 + for (iter=pList->begin(); iter!=pList->end(); )
2.246 {
2.247 - listener = (*iter);
2.248 - res = listener->InterceptUserMessage(m_CurId, &m_InterceptBuffer, m_CurRecFilter);
2.249 - if (res == Pl_Stop)
2.250 + pInfo = (*iter);
2.251 + pInfo->IsHooked = true;
2.252 + res = pInfo->Callback->InterceptUserMessage(m_CurId, &m_InterceptBuffer, m_CurRecFilter);
2.253 +
2.254 + switch (res)
2.255 {
2.256 - goto supercede;
2.257 - } else if (res == Pl_Handled) {
2.258 - handled = true;
2.259 + case Pl_Stop:
2.260 + {
2.261 + if (pInfo->KillMe)
2.262 + {
2.263 + pList->erase(iter);
2.264 + m_FreeListeners.push(pInfo);
2.265 + _DecRefCounter();
2.266 + goto supercede;
2.267 + }
2.268 + pInfo->IsHooked = false;
2.269 + goto supercede;
2.270 + }
2.271 + case Pl_Handled:
2.272 + {
2.273 + handled = true;
2.274 + if (pInfo->KillMe)
2.275 + {
2.276 + iter = pList->erase(iter);
2.277 + m_FreeListeners.push(pInfo);
2.278 + _DecRefCounter();
2.279 + continue;
2.280 + }
2.281 + break;
2.282 + }
2.283 + default:
2.284 + {
2.285 + if (pInfo->KillMe)
2.286 + {
2.287 + iter = pList->erase(iter);
2.288 + m_FreeListeners.push(pInfo);
2.289 + _DecRefCounter();
2.290 + continue;
2.291 + }
2.292 + }
2.293 }
2.294 + pInfo->IsHooked = false;
2.295 intercepted = true;
2.296 + iter++;
2.297 }
2.298
2.299 if (handled)
2.300 @@ -308,21 +388,36 @@
2.301
2.302 if (intercepted)
2.303 {
2.304 + bf_write *engine_bfw;
2.305 +
2.306 engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId);
2.307 m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
2.308 engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
2.309 ENGINE_CALL(MessageEnd)();
2.310 +
2.311 goto supercede;
2.312 }
2.313
2.314 - lst = &m_msgHooks[m_CurId];
2.315 - for (iter=lst->begin(); iter!=lst->end(); iter++)
2.316 + pList = &m_msgHooks[m_CurId];
2.317 + for (iter=pList->begin(); iter!=pList->end(); )
2.318 {
2.319 - listener = (*iter);
2.320 - listener->OnUserMessage(m_CurId, m_OrigBuffer, m_CurRecFilter);
2.321 + pInfo = (*iter);
2.322 + pInfo->IsHooked = true;
2.323 + pInfo->Callback->OnUserMessage(m_CurId, m_OrigBuffer, m_CurRecFilter);
2.324 +
2.325 + if (pInfo->KillMe)
2.326 + {
2.327 + iter = pList->erase(iter);
2.328 + m_FreeListeners.push(pInfo);
2.329 + _DecRefCounter();
2.330 + continue;
2.331 + }
2.332 +
2.333 + iter++;
2.334 }
2.335
2.336 RETURN_META(MRES_IGNORED);
2.337 supercede:
2.338 + m_InHook = false;
2.339 RETURN_META(MRES_SUPERCEDE);
2.340 }
3.1 --- a/core/UserMessages.h Sat Mar 10 21:26:04 2007 +0000
3.2 +++ b/core/UserMessages.h Sun Mar 11 03:04:39 2007 +0000
3.3 @@ -26,7 +26,15 @@
3.4
3.5 #define INVALID_MESSAGE_ID -1
3.6
3.7 -typedef List<IUserMessageListener *>::iterator MsgIter;
3.8 +struct ListenerInfo
3.9 +{
3.10 + IUserMessageListener *Callback;
3.11 + bool IsHooked;
3.12 + bool KillMe;
3.13 +};
3.14 +
3.15 +typedef List<ListenerInfo *> MsgList;
3.16 +typedef List<ListenerInfo *>::iterator MsgIter;
3.17
3.18 class CUserMessages :
3.19 public IUserMessages,
3.20 @@ -51,8 +59,11 @@
3.21 void OnMessageEnd_Pre();
3.22 void OnMessageEnd_Post();
3.23 private:
3.24 - List<IUserMessageListener *> m_msgHooks[255];
3.25 - List<IUserMessageListener *> m_msgIntercepts[255];
3.26 + void _DecRefCounter();
3.27 +private:
3.28 + List<ListenerInfo *> m_msgHooks[255];
3.29 + List<ListenerInfo *> m_msgIntercepts[255];
3.30 + CStack<ListenerInfo *> m_FreeListeners;
3.31 unsigned char m_pBase[2500];
3.32 IRecipientFilter *m_CurRecFilter;
3.33 bf_write m_InterceptBuffer;
4.1 --- a/core/msvc8/sourcemod_mm.vcproj Sat Mar 10 21:26:04 2007 +0000
4.2 +++ b/core/msvc8/sourcemod_mm.vcproj Sun Mar 11 03:04:39 2007 +0000
4.3 @@ -1,7 +1,7 @@
4.4 <?xml version="1.0" encoding="Windows-1252"?>
4.5 <VisualStudioProject
4.6 ProjectType="Visual C++"
4.7 - Version="8.00"
4.8 + Version="8,00"
4.9 Name="sourcemod_mm"
4.10 ProjectGUID="{E39527CD-7CAB-4420-97CC-DA1B93B260BC}"
4.11 RootNamespace="sourcemod_mm"
5.1 --- a/core/smn_usermsgs.cpp Sat Mar 10 21:26:04 2007 +0000
5.2 +++ b/core/smn_usermsgs.cpp Sun Mar 11 03:04:39 2007 +0000
5.3 @@ -22,6 +22,9 @@
5.4 int g_MsgPlayers[256];
5.5 bool g_IsMsgInExec = false;
5.6
5.7 +typedef List<MsgListenerWrapper *> MsgWrapperList;
5.8 +typedef List<MsgListenerWrapper *>::iterator MsgWrapperIter;
5.9 +
5.10 class UsrMessageNatives :
5.11 public SMGlobalClass,
5.12 public IHandleTypeDispatch,
5.13 @@ -33,9 +36,9 @@
5.14 void OnHandleDestroy(HandleType_t type, void *object);
5.15 void OnPluginUnloaded(IPlugin *plugin);
5.16 public:
5.17 - MsgListenerWrapper *GetNewListener(IPluginContext *pCtx);
5.18 - MsgListenerWrapper *FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept);
5.19 - bool RemoveListener(IPluginContext *pCtx, MsgListenerWrapper *listener, bool intercept);
5.20 + MsgListenerWrapper *CreateListener(IPluginContext *pCtx);
5.21 + MsgWrapperIter FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept);
5.22 + bool DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter);
5.23 private:
5.24 CStack<MsgListenerWrapper *> m_FreeListeners;
5.25 };
5.26 @@ -59,92 +62,91 @@
5.27
5.28 void UsrMessageNatives::OnPluginUnloaded(IPlugin *plugin)
5.29 {
5.30 - List<MsgListenerWrapper *> *wrapper_list;
5.31 + MsgWrapperList *pList;
5.32
5.33 - if (plugin->GetProperty("MsgListeners", reinterpret_cast<void **>(&wrapper_list), true))
5.34 + if (plugin->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList), true))
5.35 {
5.36 - List<MsgListenerWrapper *>::iterator iter;
5.37 - MsgListenerWrapper *listener;
5.38 + MsgWrapperIter iter;
5.39 + MsgListenerWrapper *pListener;
5.40
5.41 - for (iter=wrapper_list->begin(); iter!=wrapper_list->end(); iter++)
5.42 + for (iter=pList->begin(); iter!=pList->end(); iter++)
5.43 {
5.44 - listener = (*iter);
5.45 - if (g_UserMsgs.UnhookUserMessage(listener->GetMessageId(), listener, listener->IsInterceptHook()))
5.46 + pListener = (*iter);
5.47 + if (g_UserMsgs.UnhookUserMessage(pListener->GetMessageId(), pListener, pListener->IsInterceptHook()))
5.48 {
5.49 - m_FreeListeners.push(listener);
5.50 + m_FreeListeners.push(pListener);
5.51 }
5.52 }
5.53
5.54 - delete wrapper_list;
5.55 + delete pList;
5.56 }
5.57 }
5.58
5.59 -MsgListenerWrapper *UsrMessageNatives::GetNewListener(IPluginContext *pCtx)
5.60 +MsgListenerWrapper *UsrMessageNatives::CreateListener(IPluginContext *pCtx)
5.61 {
5.62 - MsgListenerWrapper *listener_wrapper;
5.63 + MsgWrapperList *pList;
5.64 + MsgListenerWrapper *pListener;
5.65 + IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
5.66
5.67 if (m_FreeListeners.empty())
5.68 {
5.69 - listener_wrapper = new MsgListenerWrapper;
5.70 + pListener = new MsgListenerWrapper;
5.71 } else {
5.72 - listener_wrapper = m_FreeListeners.front();
5.73 + pListener = m_FreeListeners.front();
5.74 m_FreeListeners.pop();
5.75 }
5.76
5.77 - List<MsgListenerWrapper *> *wrapper_list;
5.78 - IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
5.79 -
5.80 - if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&wrapper_list)))
5.81 + if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
5.82 {
5.83 - wrapper_list = new List<MsgListenerWrapper *>;
5.84 - pl->SetProperty("MsgListeners", wrapper_list);
5.85 + pList = new List<MsgListenerWrapper *>;
5.86 + pl->SetProperty("MsgListeners", pList);
5.87 }
5.88
5.89 - wrapper_list->push_back(listener_wrapper);
5.90 + pList->push_back(pListener);
5.91
5.92 - return listener_wrapper;
5.93 + return pListener;
5.94 }
5.95
5.96 -MsgListenerWrapper *UsrMessageNatives::FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept)
5.97 +MsgWrapperIter UsrMessageNatives::FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept)
5.98 {
5.99 - MsgListenerWrapper *listener;
5.100 - List<MsgListenerWrapper *> *wrapper_list;
5.101 - List<MsgListenerWrapper *>::iterator iter;
5.102 + MsgWrapperList *pList;
5.103 + MsgWrapperIter iter;
5.104 + MsgListenerWrapper *pListener;
5.105 IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
5.106 - bool found = false;
5.107
5.108 - if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&wrapper_list)))
5.109 + if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
5.110 {
5.111 return NULL;
5.112 }
5.113
5.114 - for (iter=wrapper_list->begin(); iter!=wrapper_list->end(); iter++)
5.115 + for (iter=pList->begin(); iter!=pList->end(); iter++)
5.116 {
5.117 - listener = (*iter);
5.118 - if ((msgid == listener->GetMessageId())
5.119 - && (intercept == listener->IsInterceptHook())
5.120 - && (pHook == listener->GetHookedFunction()))
5.121 + pListener = (*iter);
5.122 + if ((msgid == pListener->GetMessageId())
5.123 + && (intercept == pListener->IsInterceptHook())
5.124 + && (pHook == pListener->GetHookedFunction()))
5.125 {
5.126 - found = true;
5.127 - break;
5.128 + return iter;
5.129 }
5.130 }
5.131
5.132 - return (found) ? listener : NULL;
5.133 + return NULL;
5.134 }
5.135
5.136 -bool UsrMessageNatives::RemoveListener(IPluginContext *pCtx, MsgListenerWrapper *listener, bool intercept)
5.137 +bool UsrMessageNatives::DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter)
5.138 {
5.139 - List<MsgListenerWrapper *> *wrapper_list;
5.140 + MsgWrapperList *pList;
5.141 + MsgListenerWrapper *pListener;
5.142 IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
5.143
5.144 - if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&wrapper_list)))
5.145 + if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
5.146 {
5.147 return false;
5.148 }
5.149
5.150 - wrapper_list->remove(listener);
5.151 - m_FreeListeners.push(listener);
5.152 + pListener = (*iter);
5.153 + pList->erase(iter);
5.154 + m_FreeListeners.push(pListener);
5.155
5.156 return true;
5.157 }
5.158 @@ -155,7 +157,29 @@
5.159 * *
5.160 ***************************************/
5.161
5.162 -size_t MsgListenerWrapper::PreparePlArray(int *pl_array, IRecipientFilter *pFilter)
5.163 +void MsgListenerWrapper::Initialize(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept)
5.164 +{
5.165 + if (intercept)
5.166 + {
5.167 + m_Intercept = hook;
5.168 + m_Hook = NULL;
5.169 + } else {
5.170 + m_Hook = hook;
5.171 + m_Intercept = NULL;
5.172 + }
5.173 +
5.174 + if (notify)
5.175 + {
5.176 + m_Notify = notify;
5.177 + } else {
5.178 + m_Notify = NULL;
5.179 + }
5.180 +
5.181 + m_MsgId = msgid;
5.182 + m_IsInterceptHook = intercept;
5.183 +}
5.184 +
5.185 +size_t MsgListenerWrapper::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
5.186 {
5.187 size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
5.188
5.189 @@ -192,32 +216,10 @@
5.190 return m_Notify;
5.191 }
5.192
5.193 -void MsgListenerWrapper::InitListener(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept)
5.194 -{
5.195 - if (intercept)
5.196 - {
5.197 - m_Intercept = hook;
5.198 - m_Hook = NULL;
5.199 - } else {
5.200 - m_Hook = hook;
5.201 - m_Intercept = NULL;
5.202 - }
5.203 -
5.204 - if (notify)
5.205 - {
5.206 - m_Notify = notify;
5.207 - } else {
5.208 - m_Notify = NULL;
5.209 - }
5.210 -
5.211 - m_MsgId = msgid;
5.212 - m_IsInterceptHook = intercept;
5.213 -}
5.214 -
5.215 void MsgListenerWrapper::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
5.216 {
5.217 cell_t res;
5.218 - size_t size = PreparePlArray(g_MsgPlayers, pFilter);
5.219 + size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
5.220
5.221 m_Hook->PushCell(msg_id);
5.222 m_Hook->PushCell(0); //:TODO: push handle!
5.223 @@ -231,7 +233,7 @@
5.224 ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
5.225 {
5.226 cell_t res = static_cast<cell_t>(Pl_Continue);
5.227 - size_t size = PreparePlArray(g_MsgPlayers, pFilter);
5.228 + size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
5.229
5.230 m_Intercept->PushCell(msg_id);
5.231 m_Intercept->PushCell(0); //:TODO: push handle!
5.232 @@ -246,13 +248,12 @@
5.233
5.234 void MsgListenerWrapper::OnUserMessageSent(int msg_id)
5.235 {
5.236 - cell_t res;
5.237 -
5.238 if (!m_Notify)
5.239 {
5.240 return;
5.241 }
5.242
5.243 + cell_t res;
5.244 m_Notify->PushCell(msg_id);
5.245 m_Notify->Execute(&res);
5.246 }
5.247 @@ -319,6 +320,10 @@
5.248 pCtx->LocalToPhysAddr(params[2], &cl_array);
5.249
5.250 pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
5.251 + if (!pBitBuf)
5.252 + {
5.253 + return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
5.254 + }
5.255
5.256 g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
5.257 g_IsMsgInExec = true;
5.258 @@ -345,6 +350,10 @@
5.259 pCtx->LocalToPhysAddr(params[2], &cl_array);
5.260
5.261 pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
5.262 + if (!pBitBuf)
5.263 + {
5.264 + return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
5.265 + }
5.266
5.267 g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
5.268 g_IsMsgInExec = true;
5.269 @@ -375,7 +384,7 @@
5.270 static cell_t smn_HookUserMessage(IPluginContext *pCtx, const cell_t *params)
5.271 {
5.272 IPluginFunction *pHook, *pNotify;
5.273 - MsgListenerWrapper *listener;
5.274 + MsgListenerWrapper *pListener;
5.275 bool intercept;
5.276 int msgid = params[1];
5.277
5.278 @@ -390,12 +399,12 @@
5.279 return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
5.280 }
5.281 pNotify = pCtx->GetFunctionById(params[4]);
5.282 + intercept = (params[3]) ? true : false;
5.283
5.284 - intercept = (params[3]) ? true : false;
5.285 - listener = s_UsrMessageNatives.GetNewListener(pCtx);
5.286 - listener->InitListener(msgid, pHook, pNotify, intercept);
5.287 + pListener = s_UsrMessageNatives.CreateListener(pCtx);
5.288 + pListener->Initialize(msgid, pHook, pNotify, intercept);
5.289
5.290 - g_UserMsgs.HookUserMessage(msgid, listener, intercept);
5.291 + g_UserMsgs.HookUserMessage(msgid, pListener, intercept);
5.292
5.293 return 1;
5.294 }
5.295 @@ -403,7 +412,8 @@
5.296 static cell_t smn_UnHookUserMessage(IPluginContext *pCtx, const cell_t *params)
5.297 {
5.298 IPluginFunction *pFunc;
5.299 - MsgListenerWrapper *listener;
5.300 + MsgListenerWrapper *pListener;
5.301 + MsgWrapperIter iter;
5.302 bool intercept;
5.303 int msgid = params[1];
5.304
5.305 @@ -417,20 +427,21 @@
5.306 {
5.307 return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
5.308 }
5.309 + intercept = (params[3]) ? true : false;
5.310
5.311 - intercept = (params[3]) ? true : false;
5.312 - listener = s_UsrMessageNatives.FindListener(msgid, pCtx, pFunc, intercept);
5.313 - if (!listener)
5.314 + iter = s_UsrMessageNatives.FindListener(msgid, pCtx, pFunc, intercept);
5.315 + if (iter == NULL)
5.316 {
5.317 return pCtx->ThrowNativeError("Unable to unhook the current user message");
5.318 }
5.319
5.320 - if (!g_UserMsgs.UnhookUserMessage(msgid, listener, intercept))
5.321 + pListener = (*iter);
5.322 + if (!g_UserMsgs.UnhookUserMessage(msgid, pListener, intercept))
5.323 {
5.324 return pCtx->ThrowNativeError("Unable to unhook the current user message");
5.325 }
5.326
5.327 - s_UsrMessageNatives.RemoveListener(pCtx, listener, intercept);
5.328 + s_UsrMessageNatives.DeleteListener(pCtx, iter);
5.329
5.330 return 1;
5.331 }
6.1 --- a/core/smn_usermsgs.h Sat Mar 10 21:26:04 2007 +0000
6.2 +++ b/core/smn_usermsgs.h Sun Mar 11 03:04:39 2007 +0000
6.3 @@ -20,7 +20,7 @@
6.4 class MsgListenerWrapper : public IUserMessageListener
6.5 {
6.6 public:
6.7 - void InitListener(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept);
6.8 + void Initialize(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept);
6.9 bool IsInterceptHook() const;
6.10 int GetMessageId() const;
6.11 IPluginFunction *GetHookedFunction() const;
6.12 @@ -30,7 +30,7 @@
6.13 ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
6.14 void OnUserMessageSent(int msg_id);
6.15 private:
6.16 - size_t PreparePlArray(int *pl_array, IRecipientFilter *pFilter);
6.17 + size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
6.18 private:
6.19 IPluginFunction *m_Hook;
6.20 IPluginFunction *m_Intercept;
7.1 --- a/core/sourcemod.cpp Sat Mar 10 21:26:04 2007 +0000
7.2 +++ b/core/sourcemod.cpp Sun Mar 11 03:04:39 2007 +0000
7.3 @@ -26,7 +26,7 @@
7.4 #include "PlayerManager.h"
7.5 #include "Translator.h"
7.6 #include "ForwardSys.h"
7.7 -#include "CTimerSys.h"
7.8 +#include "TimerSys.h"
7.9
7.10 SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
7.11 SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false);