core/smn_usermsgs.cpp
author David Anderson <dvander@alliedmods.net>
Mon Mar 19 01:44:09 2007 +0000 (2007-03-19)
changeset 647 1e29dcc9ca97
parent 641 ce1f369ba889
child 698 8c68fc683dba
permissions -rw-r--r--
fixed a potential bug with kicking players during authorization
faluco@505
     1
/**
dvander@600
     2
 * vim: set ts=4 :
dvander@600
     3
 * ===============================================================
dvander@600
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@600
     5
 * ===============================================================
dvander@600
     6
 *
dvander@600
     7
 * This file is not open source and may not be copied without explicit
dvander@600
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@600
     9
 * in whole or significant part.
dvander@600
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@600
    11
 *
dvander@600
    12
 * Version: $Id$
dvander@600
    13
 */
faluco@505
    14
faluco@505
    15
#include "HandleSys.h"
faluco@552
    16
#include "PluginSys.h"
dvander@592
    17
#include "UserMessages.h"
dvander@590
    18
#include "smn_usermsgs.h"
faluco@505
    19
faluco@505
    20
HandleType_t g_WrBitBufType;
faluco@598
    21
HandleType_t g_RdBitBufType;
faluco@505
    22
Handle_t g_CurMsgHandle;
faluco@598
    23
Handle_t g_ReadBufHandle;
faluco@598
    24
bf_read g_ReadBitBuf;
faluco@598
    25
faluco@552
    26
int g_MsgPlayers[256];
faluco@505
    27
bool g_IsMsgInExec = false;
faluco@505
    28
faluco@593
    29
typedef List<MsgListenerWrapper *> MsgWrapperList;
faluco@593
    30
typedef List<MsgListenerWrapper *>::iterator MsgWrapperIter;
faluco@593
    31
faluco@505
    32
class UsrMessageNatives :
faluco@505
    33
	public SMGlobalClass,
faluco@552
    34
	public IHandleTypeDispatch,
faluco@552
    35
	public IPluginsListener
faluco@505
    36
{
faluco@641
    37
public:
faluco@641
    38
	~UsrMessageNatives();
faluco@552
    39
public: //SMGlobalClass, IHandleTypeDispatch, IPluginListener
faluco@552
    40
	void OnSourceModAllInitialized();
faluco@552
    41
	void OnSourceModShutdown();
faluco@552
    42
	void OnHandleDestroy(HandleType_t type, void *object);
faluco@552
    43
	void OnPluginUnloaded(IPlugin *plugin);
faluco@505
    44
public:
faluco@593
    45
	MsgListenerWrapper *CreateListener(IPluginContext *pCtx);
faluco@593
    46
	MsgWrapperIter FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept);
faluco@593
    47
	bool DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter);
faluco@552
    48
private:
faluco@552
    49
	CStack<MsgListenerWrapper *> m_FreeListeners;
faluco@552
    50
};
faluco@552
    51
faluco@641
    52
UsrMessageNatives::~UsrMessageNatives()
faluco@641
    53
{
faluco@641
    54
	CStack<MsgListenerWrapper *>::iterator iter;
faluco@641
    55
	for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
faluco@641
    56
	{
faluco@641
    57
		delete (*iter);
faluco@641
    58
	}
faluco@641
    59
	m_FreeListeners.popall();
faluco@641
    60
}
faluco@641
    61
faluco@552
    62
void UsrMessageNatives::OnSourceModAllInitialized()
faluco@552
    63
{
faluco@598
    64
	HandleAccess sec;
faluco@598
    65
	sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;
faluco@598
    66
faluco@552
    67
	g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
faluco@598
    68
	g_RdBitBufType = g_HandleSys.CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL);
faluco@598
    69
faluco@598
    70
	g_ReadBufHandle = g_HandleSys.CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL);
faluco@598
    71
faluco@552
    72
	g_PluginSys.AddPluginsListener(this);
faluco@552
    73
}
faluco@552
    74
faluco@552
    75
void UsrMessageNatives::OnSourceModShutdown()
faluco@552
    76
{
faluco@598
    77
	HandleSecurity sec;
faluco@598
    78
	sec.pIdentity = g_pCoreIdent;
faluco@598
    79
faluco@598
    80
	g_HandleSys.FreeHandle(g_ReadBufHandle, &sec);
faluco@598
    81
faluco@552
    82
	g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent);
faluco@598
    83
	g_HandleSys.RemoveType(g_RdBitBufType, g_pCoreIdent);
faluco@598
    84
faluco@552
    85
	g_WrBitBufType = 0;
faluco@598
    86
	g_RdBitBufType = 0;
faluco@552
    87
}
faluco@553
    88
faluco@552
    89
void UsrMessageNatives::OnHandleDestroy(HandleType_t type, void *object)
faluco@552
    90
{
faluco@552
    91
}
faluco@552
    92
faluco@552
    93
void UsrMessageNatives::OnPluginUnloaded(IPlugin *plugin)
faluco@552
    94
{
faluco@593
    95
	MsgWrapperList *pList;
faluco@552
    96
faluco@593
    97
	if (plugin->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList), true))
faluco@505
    98
	{
faluco@593
    99
		MsgWrapperIter iter;
faluco@593
   100
		MsgListenerWrapper *pListener;
faluco@552
   101
faluco@593
   102
		for (iter=pList->begin(); iter!=pList->end(); iter++)
faluco@552
   103
		{
faluco@593
   104
			pListener = (*iter);
faluco@593
   105
			if (g_UserMsgs.UnhookUserMessage(pListener->GetMessageId(), pListener, pListener->IsInterceptHook()))
faluco@552
   106
			{
faluco@593
   107
				m_FreeListeners.push(pListener);
faluco@552
   108
			}
faluco@552
   109
		}
faluco@552
   110
faluco@593
   111
		delete pList;
faluco@552
   112
	}
faluco@552
   113
}
faluco@552
   114
faluco@593
   115
MsgListenerWrapper *UsrMessageNatives::CreateListener(IPluginContext *pCtx)
faluco@552
   116
{
faluco@593
   117
	MsgWrapperList *pList;
faluco@593
   118
	MsgListenerWrapper *pListener;
faluco@593
   119
	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
faluco@552
   120
faluco@552
   121
	if (m_FreeListeners.empty())
faluco@552
   122
	{
faluco@593
   123
		pListener = new MsgListenerWrapper;
faluco@552
   124
	} else {
faluco@593
   125
		pListener = m_FreeListeners.front();
faluco@552
   126
		m_FreeListeners.pop();
faluco@505
   127
	}
faluco@552
   128
faluco@593
   129
	if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
faluco@505
   130
	{
faluco@593
   131
		pList = new List<MsgListenerWrapper *>;
faluco@593
   132
		pl->SetProperty("MsgListeners", pList);
faluco@552
   133
	}
faluco@552
   134
faluco@593
   135
	pList->push_back(pListener);
faluco@552
   136
faluco@593
   137
	return pListener;
faluco@552
   138
}
faluco@552
   139
faluco@593
   140
MsgWrapperIter UsrMessageNatives::FindListener(int msgid, IPluginContext *pCtx, IPluginFunction *pHook, bool intercept)
faluco@552
   141
{
faluco@593
   142
	MsgWrapperList *pList;
faluco@593
   143
	MsgWrapperIter iter;
faluco@593
   144
	MsgListenerWrapper *pListener;
faluco@552
   145
	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
faluco@552
   146
faluco@593
   147
	if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
faluco@552
   148
	{
faluco@552
   149
		return NULL;
faluco@505
   150
	}
faluco@552
   151
faluco@593
   152
	for (iter=pList->begin(); iter!=pList->end(); iter++)
faluco@505
   153
	{
faluco@593
   154
		pListener = (*iter);
faluco@593
   155
		if ((msgid == pListener->GetMessageId()) 
faluco@593
   156
			&& (intercept == pListener->IsInterceptHook()) 
faluco@593
   157
			&& (pHook == pListener->GetHookedFunction()))
faluco@552
   158
		{
faluco@593
   159
			return iter;
faluco@552
   160
		}
faluco@505
   161
	}
faluco@552
   162
faluco@593
   163
	return NULL;
faluco@552
   164
}
faluco@553
   165
faluco@593
   166
bool UsrMessageNatives::DeleteListener(IPluginContext *pCtx, MsgWrapperIter iter)
faluco@552
   167
{
faluco@593
   168
	MsgWrapperList *pList;
faluco@593
   169
	MsgListenerWrapper *pListener;
faluco@552
   170
	IPlugin *pl = g_PluginSys.FindPluginByContext(pCtx->GetContext());
faluco@552
   171
faluco@593
   172
	if (!pl->GetProperty("MsgListeners", reinterpret_cast<void **>(&pList)))
faluco@552
   173
	{
faluco@552
   174
		return false;
faluco@552
   175
	}
faluco@552
   176
faluco@593
   177
	pListener = (*iter);
faluco@593
   178
	pList->erase(iter);
faluco@593
   179
	m_FreeListeners.push(pListener);
faluco@552
   180
faluco@552
   181
	return true;
faluco@552
   182
}
faluco@552
   183
dvander@590
   184
/***************************************
dvander@590
   185
 *                                     *
dvander@590
   186
 * USER MESSAGE WRAPPER IMPLEMENTATION *
dvander@590
   187
 *                                     *
dvander@590
   188
 ***************************************/
dvander@590
   189
faluco@593
   190
void MsgListenerWrapper::Initialize(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept)
faluco@593
   191
{
faluco@593
   192
	if (intercept)
faluco@593
   193
	{
faluco@593
   194
		m_Intercept = hook;
faluco@593
   195
		m_Hook = NULL;
faluco@593
   196
	} else {
faluco@593
   197
		m_Hook = hook;
faluco@593
   198
		m_Intercept = NULL;
faluco@593
   199
	}
faluco@593
   200
faluco@593
   201
	if (notify)
faluco@593
   202
	{
faluco@593
   203
		m_Notify = notify;
faluco@593
   204
	} else {
faluco@593
   205
		m_Notify = NULL;
faluco@593
   206
	}
faluco@593
   207
faluco@593
   208
	m_MsgId = msgid;
faluco@593
   209
	m_IsInterceptHook = intercept;
faluco@593
   210
}
faluco@593
   211
faluco@593
   212
size_t MsgListenerWrapper::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
dvander@590
   213
{
dvander@590
   214
	size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
dvander@590
   215
dvander@590
   216
	for (size_t i=0; i<size; i++)
dvander@590
   217
	{
dvander@590
   218
		pl_array[i] = pFilter->GetRecipientIndex(i);
dvander@590
   219
	}
dvander@590
   220
dvander@590
   221
	return size;
dvander@590
   222
}
dvander@590
   223
dvander@590
   224
bool MsgListenerWrapper::IsInterceptHook() const
dvander@590
   225
{
dvander@590
   226
	return m_IsInterceptHook;
dvander@590
   227
}
dvander@590
   228
dvander@590
   229
int MsgListenerWrapper::GetMessageId() const
dvander@590
   230
{
dvander@590
   231
	return m_MsgId;
dvander@590
   232
}
dvander@590
   233
dvander@590
   234
IPluginFunction *MsgListenerWrapper::GetHookedFunction() const
dvander@590
   235
{
dvander@590
   236
	if (m_Hook)
dvander@590
   237
	{
dvander@590
   238
		return m_Hook;
dvander@590
   239
	} else {
dvander@590
   240
		return m_Intercept;
dvander@590
   241
	}
dvander@590
   242
}
dvander@590
   243
dvander@590
   244
IPluginFunction *MsgListenerWrapper::GetNotifyFunction() const
dvander@590
   245
{
dvander@590
   246
	return m_Notify;
dvander@590
   247
}
dvander@590
   248
dvander@590
   249
void MsgListenerWrapper::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
dvander@590
   250
{
dvander@590
   251
	cell_t res;
faluco@593
   252
	size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
dvander@590
   253
faluco@598
   254
	g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
faluco@598
   255
dvander@590
   256
	m_Hook->PushCell(msg_id);
faluco@598
   257
	m_Hook->PushCell(g_ReadBufHandle);
dvander@590
   258
	m_Hook->PushArray(g_MsgPlayers, size);
dvander@590
   259
	m_Hook->PushCell(size);
dvander@590
   260
	m_Hook->PushCell(pFilter->IsReliable());
dvander@590
   261
	m_Hook->PushCell(pFilter->IsInitMessage());
dvander@590
   262
	m_Hook->Execute(&res);
dvander@590
   263
}
dvander@590
   264
dvander@590
   265
ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
dvander@590
   266
{
dvander@590
   267
	cell_t res = static_cast<cell_t>(Pl_Continue);
faluco@593
   268
	size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
dvander@590
   269
faluco@598
   270
	g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
faluco@598
   271
dvander@590
   272
	m_Intercept->PushCell(msg_id);
faluco@598
   273
	m_Intercept->PushCell(g_ReadBufHandle);
dvander@590
   274
	m_Intercept->PushArray(g_MsgPlayers, size);
dvander@590
   275
	m_Intercept->PushCell(size);
dvander@590
   276
	m_Intercept->PushCell(pFilter->IsReliable());
dvander@590
   277
	m_Intercept->PushCell(pFilter->IsInitMessage());
dvander@590
   278
	m_Intercept->Execute(&res);
dvander@590
   279
dvander@590
   280
	return static_cast<ResultType>(res);
dvander@590
   281
}
dvander@590
   282
dvander@590
   283
void MsgListenerWrapper::OnUserMessageSent(int msg_id)
dvander@590
   284
{
dvander@590
   285
	if (!m_Notify)
dvander@590
   286
	{
dvander@590
   287
		return;
dvander@590
   288
	}
dvander@590
   289
faluco@593
   290
	cell_t res;
dvander@590
   291
	m_Notify->PushCell(msg_id);
dvander@590
   292
	m_Notify->Execute(&res);
dvander@590
   293
}
dvander@590
   294
dvander@590
   295
/***************************************
dvander@590
   296
 *                                     *
dvander@590
   297
 * USER MESSAGE NATIVE IMPLEMENTATIONS *
dvander@590
   298
 *                                     *
dvander@590
   299
 ***************************************/
faluco@552
   300
faluco@552
   301
static UsrMessageNatives s_UsrMessageNatives;
faluco@505
   302
faluco@505
   303
static cell_t smn_GetUserMessageId(IPluginContext *pCtx, const cell_t *params)
faluco@505
   304
{
faluco@505
   305
	char *msgname;
faluco@505
   306
	int err;
faluco@505
   307
	if ((err=pCtx->LocalToString(params[1], &msgname)) != SP_ERROR_NONE)
faluco@505
   308
	{
faluco@505
   309
		pCtx->ThrowNativeErrorEx(err, NULL);
faluco@505
   310
		return 0;
faluco@505
   311
	}
faluco@505
   312
faluco@552
   313
	return g_UserMsgs.GetMessageIndex(msgname);
faluco@505
   314
}
faluco@505
   315
faluco@553
   316
static cell_t smn_GetUserMessageName(IPluginContext *pCtx, const cell_t *params)
faluco@553
   317
{
faluco@553
   318
	char *msgname;
faluco@553
   319
faluco@553
   320
	pCtx->LocalToPhysAddr(params[2], (cell_t **)&msgname);
faluco@553
   321
faluco@553
   322
	if (!g_UserMsgs.GetMessageName(params[1], msgname, params[3]))
faluco@553
   323
	{
faluco@553
   324
		msgname = "";
faluco@553
   325
		return 0;
faluco@553
   326
	}
faluco@553
   327
faluco@553
   328
	return 1;
faluco@553
   329
}
faluco@553
   330
faluco@505
   331
static cell_t smn_StartMessage(IPluginContext *pCtx, const cell_t *params)
faluco@505
   332
{
faluco@505
   333
	char *msgname;
faluco@505
   334
	cell_t *cl_array;
faluco@505
   335
	int msgid, err;
faluco@505
   336
	bf_write *pBitBuf;
faluco@505
   337
faluco@505
   338
	if (g_IsMsgInExec)
faluco@505
   339
	{
faluco@505
   340
		return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
faluco@505
   341
	}
faluco@505
   342
faluco@505
   343
	if ((err=pCtx->LocalToString(params[1], &msgname)) != SP_ERROR_NONE)
faluco@505
   344
	{
faluco@505
   345
		pCtx->ThrowNativeErrorEx(err, NULL);
faluco@505
   346
		return 0;
faluco@505
   347
	}
faluco@505
   348
faluco@552
   349
	if ((msgid=g_UserMsgs.GetMessageIndex(msgname)) == INVALID_MESSAGE_ID)
faluco@505
   350
	{
faluco@505
   351
		return pCtx->ThrowNativeError("Invalid message name: \"%s\"", msgname);
faluco@505
   352
	}
faluco@505
   353
faluco@505
   354
	pCtx->LocalToPhysAddr(params[2], &cl_array);
faluco@505
   355
faluco@552
   356
	pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
faluco@593
   357
	if (!pBitBuf)
faluco@593
   358
	{
faluco@593
   359
		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
faluco@593
   360
	}
faluco@505
   361
faluco@505
   362
	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@505
   363
	g_IsMsgInExec = true;
faluco@505
   364
faluco@505
   365
	return g_CurMsgHandle;
faluco@505
   366
}
faluco@505
   367
faluco@505
   368
static cell_t smn_StartMessageEx(IPluginContext *pCtx, const cell_t *params)
faluco@505
   369
{
faluco@505
   370
	cell_t *cl_array;
faluco@505
   371
	bf_write *pBitBuf;
faluco@505
   372
	int msgid = params[1];
faluco@505
   373
faluco@505
   374
	if (g_IsMsgInExec)
faluco@505
   375
	{
faluco@505
   376
		return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
faluco@505
   377
	}
faluco@505
   378
faluco@552
   379
	if (msgid < 0 || msgid >= 255)
faluco@505
   380
	{
faluco@505
   381
		return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
faluco@505
   382
	}
faluco@505
   383
faluco@505
   384
	pCtx->LocalToPhysAddr(params[2], &cl_array);
faluco@505
   385
faluco@552
   386
	pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
faluco@593
   387
	if (!pBitBuf)
faluco@593
   388
	{
faluco@593
   389
		return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
faluco@593
   390
	}
faluco@505
   391
faluco@505
   392
	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@505
   393
	g_IsMsgInExec = true;
faluco@505
   394
faluco@505
   395
	return g_CurMsgHandle;
faluco@505
   396
}
faluco@505
   397
faluco@505
   398
static cell_t smn_EndMessage(IPluginContext *pCtx, const cell_t *params)
faluco@505
   399
{
faluco@505
   400
	HandleSecurity sec;
faluco@505
   401
faluco@505
   402
	if (!g_IsMsgInExec)
faluco@505
   403
	{
faluco@505
   404
		return pCtx->ThrowNativeError("Unable to end message, no message is in progress");
faluco@505
   405
	}
faluco@505
   406
faluco@552
   407
	g_UserMsgs.EndMessage();
faluco@505
   408
faluco@505
   409
	sec.pOwner = pCtx->GetIdentity();
faluco@505
   410
	sec.pIdentity = g_pCoreIdent;
faluco@505
   411
	g_HandleSys.FreeHandle(g_CurMsgHandle, &sec);
faluco@505
   412
faluco@505
   413
	g_IsMsgInExec = false;
faluco@552
   414
faluco@552
   415
	return 1;
faluco@552
   416
}
faluco@552
   417
faluco@552
   418
static cell_t smn_HookUserMessage(IPluginContext *pCtx, const cell_t *params)
faluco@552
   419
{
faluco@552
   420
	IPluginFunction *pHook, *pNotify;
faluco@593
   421
	MsgListenerWrapper *pListener;
faluco@552
   422
	bool intercept;
faluco@552
   423
	int msgid = params[1];
faluco@552
   424
faluco@552
   425
	if (msgid < 0 || msgid >= 255)
faluco@552
   426
	{
faluco@552
   427
		return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
faluco@552
   428
	}
faluco@552
   429
faluco@552
   430
	pHook = pCtx->GetFunctionById(params[2]);
faluco@552
   431
	if (!pHook)
faluco@552
   432
	{
faluco@552
   433
		return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
faluco@552
   434
	}
faluco@552
   435
	pNotify = pCtx->GetFunctionById(params[4]);
faluco@593
   436
	intercept = (params[3]) ? true : false;
faluco@552
   437
faluco@593
   438
	pListener = s_UsrMessageNatives.CreateListener(pCtx);
faluco@593
   439
	pListener->Initialize(msgid, pHook, pNotify, intercept);
faluco@553
   440
faluco@593
   441
	g_UserMsgs.HookUserMessage(msgid, pListener, intercept);
faluco@505
   442
faluco@505
   443
	return 1;
faluco@505
   444
}
faluco@505
   445
ds@626
   446
static cell_t smn_UnhookUserMessage(IPluginContext *pCtx, const cell_t *params)
faluco@552
   447
{
faluco@552
   448
	IPluginFunction *pFunc;
faluco@593
   449
	MsgListenerWrapper *pListener;
faluco@593
   450
	MsgWrapperIter iter;
faluco@552
   451
	bool intercept;
faluco@552
   452
	int msgid = params[1];
faluco@552
   453
faluco@552
   454
	if (msgid < 0 || msgid >= 255)
faluco@552
   455
	{
faluco@552
   456
		return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
faluco@552
   457
	}
faluco@552
   458
faluco@552
   459
	pFunc = pCtx->GetFunctionById(params[2]);
faluco@552
   460
	if (!pFunc)
faluco@552
   461
	{
faluco@552
   462
		return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
faluco@552
   463
	}
faluco@593
   464
	intercept = (params[3]) ? true : false;
faluco@552
   465
faluco@593
   466
	iter = s_UsrMessageNatives.FindListener(msgid, pCtx, pFunc, intercept);
faluco@593
   467
	if (iter == NULL)
faluco@552
   468
	{
faluco@552
   469
		return pCtx->ThrowNativeError("Unable to unhook the current user message");
faluco@552
   470
	}
faluco@552
   471
faluco@593
   472
	pListener = (*iter);
faluco@593
   473
	if (!g_UserMsgs.UnhookUserMessage(msgid, pListener, intercept))
faluco@552
   474
	{
faluco@552
   475
		return pCtx->ThrowNativeError("Unable to unhook the current user message");
faluco@552
   476
	}
faluco@552
   477
faluco@593
   478
	s_UsrMessageNatives.DeleteListener(pCtx, iter);
faluco@552
   479
faluco@552
   480
	return 1;
faluco@552
   481
}
faluco@505
   482
faluco@505
   483
REGISTER_NATIVES(usrmsgnatives)
faluco@505
   484
{
faluco@505
   485
	{"GetUserMessageId",			smn_GetUserMessageId},
faluco@553
   486
	{"GetUserMessageName",			smn_GetUserMessageName},
faluco@505
   487
	{"StartMessage",				smn_StartMessage},
faluco@505
   488
	{"StartMessageEx",				smn_StartMessageEx},
faluco@505
   489
	{"EndMessage",					smn_EndMessage},
faluco@552
   490
	{"HookUserMessage",				smn_HookUserMessage},
ds@626
   491
	{"UnhookUserMessage",			smn_UnhookUserMessage},
faluco@505
   492
	{NULL,							NULL}
faluco@505
   493
};