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