2007-02-16 19:47:16 +01:00
|
|
|
/**
|
2007-03-12 01:07:54 +01:00
|
|
|
* vim: set ts=4 :
|
|
|
|
* ===============================================================
|
|
|
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
|
|
|
* ===============================================================
|
|
|
|
*
|
|
|
|
* This file is not open source and may not be copied without explicit
|
|
|
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
|
|
|
* in whole or significant part.
|
|
|
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
|
|
|
*
|
|
|
|
* Version: $Id$
|
|
|
|
*/
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
#include "HandleSys.h"
|
2007-03-01 23:49:08 +01:00
|
|
|
#include "PluginSys.h"
|
2007-03-10 22:26:04 +01:00
|
|
|
#include "UserMessages.h"
|
2007-03-10 22:12:40 +01:00
|
|
|
#include "smn_usermsgs.h"
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
HandleType_t g_WrBitBufType;
|
2007-03-11 22:09:05 +01:00
|
|
|
HandleType_t g_RdBitBufType;
|
2007-02-16 19:47:16 +01:00
|
|
|
Handle_t g_CurMsgHandle;
|
2007-03-11 22:09:05 +01:00
|
|
|
Handle_t g_ReadBufHandle;
|
|
|
|
bf_read g_ReadBitBuf;
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
int g_MsgPlayers[256];
|
2007-02-16 19:47:16 +01:00
|
|
|
bool g_IsMsgInExec = false;
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
typedef List<MsgListenerWrapper *> MsgWrapperList;
|
|
|
|
typedef List<MsgListenerWrapper *>::iterator MsgWrapperIter;
|
|
|
|
|
2007-02-16 19:47:16 +01:00
|
|
|
class UsrMessageNatives :
|
|
|
|
public SMGlobalClass,
|
2007-03-01 23:49:08 +01:00
|
|
|
public IHandleTypeDispatch,
|
|
|
|
public IPluginsListener
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
2007-03-17 01:55:46 +01:00
|
|
|
public:
|
|
|
|
~UsrMessageNatives();
|
2007-03-01 23:49:08 +01:00
|
|
|
public: //SMGlobalClass, IHandleTypeDispatch, IPluginListener
|
|
|
|
void OnSourceModAllInitialized();
|
|
|
|
void OnSourceModShutdown();
|
|
|
|
void OnHandleDestroy(HandleType_t type, void *object);
|
|
|
|
void OnPluginUnloaded(IPlugin *plugin);
|
2007-02-16 19:47:16 +01:00
|
|
|
public:
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgListenerWrapper *CreateListener(IPluginContext *pCtx);
|
|
|
|
MsgWrapperIter FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept);
|
|
|
|
bool DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter);
|
2007-03-01 23:49:08 +01:00
|
|
|
private:
|
|
|
|
CStack<MsgListenerWrapper *> m_FreeListeners;
|
|
|
|
};
|
|
|
|
|
2007-03-17 01:55:46 +01:00
|
|
|
UsrMessageNatives::~UsrMessageNatives()
|
|
|
|
{
|
|
|
|
CStack<MsgListenerWrapper *>::iterator iter;
|
|
|
|
for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
|
|
|
|
{
|
|
|
|
delete (*iter);
|
|
|
|
}
|
|
|
|
m_FreeListeners.popall();
|
|
|
|
}
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
void UsrMessageNatives::OnSourceModAllInitialized()
|
|
|
|
{
|
2007-03-11 22:09:05 +01:00
|
|
|
HandleAccess sec;
|
|
|
|
sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
2007-03-11 22:09:05 +01:00
|
|
|
g_RdBitBufType = g_HandleSys.CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
|
|
|
|
|
|
|
g_ReadBufHandle = g_HandleSys.CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL);
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
g_PluginSys.AddPluginsListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UsrMessageNatives::OnSourceModShutdown()
|
|
|
|
{
|
2007-03-11 22:09:05 +01:00
|
|
|
HandleSecurity sec;
|
|
|
|
sec.pIdentity = g_pCoreIdent;
|
|
|
|
|
|
|
|
g_HandleSys.FreeHandle(g_ReadBufHandle, &sec);
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent);
|
2007-03-11 22:09:05 +01:00
|
|
|
g_HandleSys.RemoveType(g_RdBitBufType, g_pCoreIdent);
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
g_WrBitBufType = 0;
|
2007-03-11 22:09:05 +01:00
|
|
|
g_RdBitBufType = 0;
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
2007-03-02 00:44:27 +01:00
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
void UsrMessageNatives::OnHandleDestroy(HandleType_t type, void *object)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void UsrMessageNatives::OnPluginUnloaded(IPlugin *plugin)
|
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperList *pList;
|
2007-03-01 23:49:08 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
if (plugin->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList), true))
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperIter iter;
|
|
|
|
MsgListenerWrapper *pListener;
|
2007-03-01 23:49:08 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
for (iter=pList->begin(); iter!=pList->end(); iter++)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = (*iter);
|
|
|
|
if (g_UserMsgs.UnhookUserMessage(pListener->GetMessageId(), pListener, pListener->IsInterceptHook()))
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
m_FreeListeners.push(pListener);
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
delete pList;
|
2007-02-16 19:47:16 +01:00
|
|
|
}
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgListenerWrapper *UsrMessageNatives::CreateListener(IPluginContext *pCtx)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperList *pList;
|
|
|
|
MsgListenerWrapper *pListener;
|
|
|
|
IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
|
2007-03-01 23:49:08 +01:00
|
|
|
|
|
|
|
if (m_FreeListeners.empty())
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = new MsgListenerWrapper;
|
2007-03-01 23:49:08 +01:00
|
|
|
} else {
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = m_FreeListeners.front();
|
2007-03-01 23:49:08 +01:00
|
|
|
m_FreeListeners.pop();
|
2007-02-16 19:47:16 +01:00
|
|
|
}
|
2007-03-01 23:49:08 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
pList = new List<MsgListenerWrapper *>;
|
|
|
|
pl->SetProperty("MsgListeners", pList);
|
2007-02-16 19:47:16 +01:00
|
|
|
}
|
2007-03-01 23:49:08 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
pList->push_back(pListener);
|
2007-03-01 23:49:08 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
return pListener;
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperIter UsrMessageNatives::FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperList *pList;
|
|
|
|
MsgWrapperIter iter;
|
|
|
|
MsgListenerWrapper *pListener;
|
2007-03-01 23:49:08 +01:00
|
|
|
IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
for (iter=pList->begin(); iter!=pList->end(); iter++)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = (*iter);
|
|
|
|
if ((msgid == pListener->GetMessageId())
|
|
|
|
&& (intercept == pListener->IsInterceptHook())
|
|
|
|
&& (pHook == pListener->GetHookedFunction()))
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
return iter;
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
return NULL;
|
2007-03-01 23:49:08 +01:00
|
|
|
}
|
2007-03-02 00:44:27 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
bool UsrMessageNatives::DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgWrapperList *pList;
|
|
|
|
MsgListenerWrapper *pListener;
|
2007-03-01 23:49:08 +01:00
|
|
|
IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = (*iter);
|
|
|
|
pList->erase(iter);
|
|
|
|
m_FreeListeners.push(pListener);
|
2007-03-01 23:49:08 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-03-10 22:12:40 +01:00
|
|
|
/***************************************
|
|
|
|
* *
|
|
|
|
* USER MESSAGE WRAPPER IMPLEMENTATION *
|
|
|
|
* *
|
|
|
|
***************************************/
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
void MsgListenerWrapper::Initialize(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept)
|
|
|
|
{
|
|
|
|
if (intercept)
|
|
|
|
{
|
|
|
|
m_Intercept = hook;
|
|
|
|
m_Hook = NULL;
|
|
|
|
} else {
|
|
|
|
m_Hook = hook;
|
|
|
|
m_Intercept = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (notify)
|
|
|
|
{
|
|
|
|
m_Notify = notify;
|
|
|
|
} else {
|
|
|
|
m_Notify = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_MsgId = msgid;
|
|
|
|
m_IsInterceptHook = intercept;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t MsgListenerWrapper::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
|
2007-03-10 22:12:40 +01:00
|
|
|
{
|
|
|
|
size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
|
|
|
|
|
|
|
|
for (size_t i=0; i<size; i++)
|
|
|
|
{
|
|
|
|
pl_array[i] = pFilter->GetRecipientIndex(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MsgListenerWrapper::IsInterceptHook() const
|
|
|
|
{
|
|
|
|
return m_IsInterceptHook;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MsgListenerWrapper::GetMessageId() const
|
|
|
|
{
|
|
|
|
return m_MsgId;
|
|
|
|
}
|
|
|
|
|
|
|
|
IPluginFunction *MsgListenerWrapper::GetHookedFunction() const
|
|
|
|
{
|
|
|
|
if (m_Hook)
|
|
|
|
{
|
|
|
|
return m_Hook;
|
|
|
|
} else {
|
|
|
|
return m_Intercept;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IPluginFunction *MsgListenerWrapper::GetNotifyFunction() const
|
|
|
|
{
|
|
|
|
return m_Notify;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MsgListenerWrapper::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
|
|
|
|
{
|
|
|
|
cell_t res;
|
2007-03-11 04:04:39 +01:00
|
|
|
size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
|
2007-03-10 22:12:40 +01:00
|
|
|
|
2007-03-11 22:09:05 +01:00
|
|
|
g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
|
|
|
|
|
2007-03-10 22:12:40 +01:00
|
|
|
m_Hook->PushCell(msg_id);
|
2007-03-11 22:09:05 +01:00
|
|
|
m_Hook->PushCell(g_ReadBufHandle);
|
2007-03-10 22:12:40 +01:00
|
|
|
m_Hook->PushArray(g_MsgPlayers, size);
|
|
|
|
m_Hook->PushCell(size);
|
|
|
|
m_Hook->PushCell(pFilter->IsReliable());
|
|
|
|
m_Hook->PushCell(pFilter->IsInitMessage());
|
|
|
|
m_Hook->Execute(&res);
|
|
|
|
}
|
|
|
|
|
|
|
|
ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
|
|
|
|
{
|
|
|
|
cell_t res = static_cast<cell_t>(Pl_Continue);
|
2007-03-11 04:04:39 +01:00
|
|
|
size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
|
2007-03-10 22:12:40 +01:00
|
|
|
|
2007-03-11 22:09:05 +01:00
|
|
|
g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
|
|
|
|
|
2007-03-10 22:12:40 +01:00
|
|
|
m_Intercept->PushCell(msg_id);
|
2007-03-11 22:09:05 +01:00
|
|
|
m_Intercept->PushCell(g_ReadBufHandle);
|
2007-03-10 22:12:40 +01:00
|
|
|
m_Intercept->PushArray(g_MsgPlayers, size);
|
|
|
|
m_Intercept->PushCell(size);
|
|
|
|
m_Intercept->PushCell(pFilter->IsReliable());
|
|
|
|
m_Intercept->PushCell(pFilter->IsInitMessage());
|
|
|
|
m_Intercept->Execute(&res);
|
|
|
|
|
|
|
|
return static_cast<ResultType>(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MsgListenerWrapper::OnUserMessageSent(int msg_id)
|
|
|
|
{
|
|
|
|
if (!m_Notify)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
cell_t res;
|
2007-03-10 22:12:40 +01:00
|
|
|
m_Notify->PushCell(msg_id);
|
|
|
|
m_Notify->Execute(&res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************
|
|
|
|
* *
|
|
|
|
* USER MESSAGE NATIVE IMPLEMENTATIONS *
|
|
|
|
* *
|
|
|
|
***************************************/
|
2007-03-01 23:49:08 +01:00
|
|
|
|
|
|
|
static UsrMessageNatives s_UsrMessageNatives;
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
static cell_t smn_GetUserMessageId(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
char *msgname;
|
2007-04-15 07:43:43 +02:00
|
|
|
pCtx->LocalToString(params[1], &msgname);
|
2007-02-16 19:47:16 +01:00
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
return g_UserMsgs.GetMessageIndex(msgname);
|
2007-02-16 19:47:16 +01:00
|
|
|
}
|
|
|
|
|
2007-03-02 00:44:27 +01:00
|
|
|
static cell_t smn_GetUserMessageName(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
2007-04-15 07:43:43 +02:00
|
|
|
const char *msgname = g_SMAPI->GetUserMessage(params[1]);
|
2007-03-02 00:44:27 +01:00
|
|
|
|
2007-04-15 07:43:43 +02:00
|
|
|
if (msgname == NULL)
|
2007-03-02 00:44:27 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-04-15 07:43:43 +02:00
|
|
|
pCtx->StringToLocalUTF8(params[2], params[3], msgname, NULL);
|
|
|
|
|
2007-03-02 00:44:27 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-02-16 19:47:16 +01:00
|
|
|
static cell_t smn_StartMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
char *msgname;
|
|
|
|
cell_t *cl_array;
|
2007-04-15 07:43:43 +02:00
|
|
|
int msgid;
|
2007-02-16 19:47:16 +01:00
|
|
|
bf_write *pBitBuf;
|
|
|
|
|
|
|
|
if (g_IsMsgInExec)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
|
|
|
|
}
|
|
|
|
|
2007-04-15 07:43:43 +02:00
|
|
|
pCtx->LocalToString(params[1], &msgname);
|
2007-02-16 19:47:16 +01:00
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
if ((msgid=g_UserMsgs.GetMessageIndex(msgname)) == INVALID_MESSAGE_ID)
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid message name: \"%s\"", msgname);
|
|
|
|
}
|
|
|
|
|
|
|
|
pCtx->LocalToPhysAddr(params[2], &cl_array);
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
|
2007-03-11 04:04:39 +01:00
|
|
|
if (!pBitBuf)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
|
|
|
|
}
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
|
|
|
|
g_IsMsgInExec = true;
|
|
|
|
|
|
|
|
return g_CurMsgHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_StartMessageEx(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
cell_t *cl_array;
|
|
|
|
bf_write *pBitBuf;
|
|
|
|
int msgid = params[1];
|
|
|
|
|
|
|
|
if (g_IsMsgInExec)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
|
|
|
|
}
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
if (msgid < 0 || msgid >= 255)
|
2007-02-16 19:47:16 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
pCtx->LocalToPhysAddr(params[2], &cl_array);
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
|
2007-03-11 04:04:39 +01:00
|
|
|
if (!pBitBuf)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
|
|
|
|
}
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
|
|
|
|
g_IsMsgInExec = true;
|
|
|
|
|
|
|
|
return g_CurMsgHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_EndMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
HandleSecurity sec;
|
|
|
|
|
|
|
|
if (!g_IsMsgInExec)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to end message, no message is in progress");
|
|
|
|
}
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
g_UserMsgs.EndMessage();
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
sec.pOwner = pCtx->GetIdentity();
|
|
|
|
sec.pIdentity = g_pCoreIdent;
|
|
|
|
g_HandleSys.FreeHandle(g_CurMsgHandle, &sec);
|
|
|
|
|
|
|
|
g_IsMsgInExec = false;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-03-01 23:49:08 +01:00
|
|
|
static cell_t smn_HookUserMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
IPluginFunction *pHook, *pNotify;
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgListenerWrapper *pListener;
|
2007-03-01 23:49:08 +01:00
|
|
|
bool intercept;
|
|
|
|
int msgid = params[1];
|
|
|
|
|
|
|
|
if (msgid < 0 || msgid >= 255)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
pHook = pCtx->GetFunctionById(params[2]);
|
|
|
|
if (!pHook)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
|
|
|
|
}
|
|
|
|
pNotify = pCtx->GetFunctionById(params[4]);
|
|
|
|
intercept = (params[3]) ? true : false;
|
2007-03-02 00:44:27 +01:00
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = s_UsrMessageNatives.CreateListener(pCtx);
|
|
|
|
pListener->Initialize(msgid, pHook, pNotify, intercept);
|
|
|
|
|
|
|
|
g_UserMsgs.HookUserMessage(msgid, pListener, intercept);
|
2007-03-01 23:49:08 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-03-16 18:29:05 +01:00
|
|
|
static cell_t smn_UnhookUserMessage(IPluginContext *pCtx, const cell_t *params)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
|
|
|
IPluginFunction *pFunc;
|
2007-03-11 04:04:39 +01:00
|
|
|
MsgListenerWrapper *pListener;
|
|
|
|
MsgWrapperIter iter;
|
2007-03-01 23:49:08 +01:00
|
|
|
bool intercept;
|
|
|
|
int msgid = params[1];
|
|
|
|
|
|
|
|
if (msgid < 0 || msgid >= 255)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
pFunc = pCtx->GetFunctionById(params[2]);
|
|
|
|
if (!pFunc)
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
|
|
|
|
}
|
|
|
|
intercept = (params[3]) ? true : false;
|
2007-03-11 04:04:39 +01:00
|
|
|
|
|
|
|
iter = s_UsrMessageNatives.FindListener(msgid, pCtx, pFunc, intercept);
|
|
|
|
if (iter == NULL)
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to unhook the current user message");
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
pListener = (*iter);
|
|
|
|
if (!g_UserMsgs.UnhookUserMessage(msgid, pListener, intercept))
|
2007-03-01 23:49:08 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Unable to unhook the current user message");
|
|
|
|
}
|
|
|
|
|
2007-03-11 04:04:39 +01:00
|
|
|
s_UsrMessageNatives.DeleteListener(pCtx, iter);
|
2007-03-01 23:49:08 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2007-02-16 19:47:16 +01:00
|
|
|
|
|
|
|
REGISTER_NATIVES(usrmsgnatives)
|
|
|
|
{
|
|
|
|
{"GetUserMessageId", smn_GetUserMessageId},
|
2007-03-02 00:44:27 +01:00
|
|
|
{"GetUserMessageName", smn_GetUserMessageName},
|
2007-02-16 19:47:16 +01:00
|
|
|
{"StartMessage", smn_StartMessage},
|
|
|
|
{"StartMessageEx", smn_StartMessageEx},
|
|
|
|
{"EndMessage", smn_EndMessage},
|
2007-03-01 23:49:08 +01:00
|
|
|
{"HookUserMessage", smn_HookUserMessage},
|
2007-03-16 18:29:05 +01:00
|
|
|
{"UnhookUserMessage", smn_UnhookUserMessage},
|
2007-02-16 19:47:16 +01:00
|
|
|
{NULL, NULL}
|
|
|
|
};
|