core/smn_usermsgs.cpp
author David Anderson <dvander@alliedmods.net>
Sat Feb 17 19:03:18 2007 +0000 (2007-02-17)
changeset 520 7676d61cde2d
parent 505 9fb8a1ccd4ec
child 552 e58968c96860
permissions -rw-r--r--
added helper a core translation helper to the translator
regadmincmd is now officially done and tested, as are overrides
printtoplayers now prints to the server on id==0 as a convenience
fixed a crash bug in the admin system
fixed up console.inc a bit
faluco@505
     1
/**
faluco@505
     2
* vim: set ts=4 :
faluco@505
     3
* ===============================================================
faluco@505
     4
* SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
faluco@505
     5
* ===============================================================
faluco@505
     6
*
faluco@505
     7
* This file is not open source and may not be copied without explicit
faluco@505
     8
* written permission of AlliedModders LLC.  This file may not be redistributed 
faluco@505
     9
* in whole or significant part.
faluco@505
    10
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
faluco@505
    11
*
faluco@505
    12
* Version: $Id$
faluco@505
    13
*/
faluco@505
    14
faluco@505
    15
#include "HandleSys.h"
faluco@505
    16
#include "CellRecipientFilter.h"
faluco@505
    17
#include "CMsgIdPool.h"
faluco@505
    18
faluco@505
    19
#define USERMSG_PASSTHRU			(1<<0)
faluco@505
    20
#define USERMSG_PASSTHRU_ALL		(1<<1)
faluco@505
    21
#define USERMSG_RELIABLE			(1<<2)
faluco@505
    22
#define USERMSG_INITMSG				(1<<3)
faluco@505
    23
faluco@505
    24
CMessageIdPool g_MessageIds;
faluco@505
    25
CellRecipientFilter g_MsgRecFilter;
faluco@505
    26
HandleType_t g_WrBitBufType;
faluco@505
    27
Handle_t g_CurMsgHandle;
faluco@505
    28
bool g_IsMsgInExec = false;
faluco@505
    29
int g_CurMsgFlags = 0;
faluco@505
    30
faluco@505
    31
class UsrMessageNatives :
faluco@505
    32
	public SMGlobalClass,
faluco@505
    33
	public IHandleTypeDispatch
faluco@505
    34
{
faluco@505
    35
public:
faluco@505
    36
	void OnSourceModAllInitialized()
faluco@505
    37
	{
faluco@505
    38
		g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
faluco@505
    39
	}
faluco@505
    40
	void OnSourceModShutdown()
faluco@505
    41
	{
faluco@505
    42
		g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent);
faluco@505
    43
		g_WrBitBufType = 0;
faluco@505
    44
	}
faluco@505
    45
	void OnHandleDestroy(HandleType_t type, void *object)
faluco@505
    46
	{
faluco@505
    47
	}
faluco@505
    48
};
faluco@505
    49
faluco@505
    50
static cell_t smn_GetUserMessageId(IPluginContext *pCtx, const cell_t *params)
faluco@505
    51
{
faluco@505
    52
	char *msgname;
faluco@505
    53
	int err;
faluco@505
    54
	if ((err=pCtx->LocalToString(params[1], &msgname)) != SP_ERROR_NONE)
faluco@505
    55
	{
faluco@505
    56
		pCtx->ThrowNativeErrorEx(err, NULL);
faluco@505
    57
		return 0;
faluco@505
    58
	}
faluco@505
    59
faluco@505
    60
	return g_MessageIds.GetMessageId(msgname);
faluco@505
    61
}
faluco@505
    62
faluco@505
    63
static cell_t smn_StartMessage(IPluginContext *pCtx, const cell_t *params)
faluco@505
    64
{
faluco@505
    65
	char *msgname;
faluco@505
    66
	cell_t *cl_array;
faluco@505
    67
	int msgid, err;
faluco@505
    68
	bf_write *pBitBuf;
faluco@505
    69
faluco@505
    70
	if (g_IsMsgInExec)
faluco@505
    71
	{
faluco@505
    72
		return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
faluco@505
    73
	}
faluco@505
    74
faluco@505
    75
	if ((err=pCtx->LocalToString(params[1], &msgname)) != SP_ERROR_NONE)
faluco@505
    76
	{
faluco@505
    77
		pCtx->ThrowNativeErrorEx(err, NULL);
faluco@505
    78
		return 0;
faluco@505
    79
	}
faluco@505
    80
faluco@505
    81
	if ((msgid=g_MessageIds.GetMessageId(msgname)) == INVALID_MESSAGE_ID)
faluco@505
    82
	{
faluco@505
    83
		return pCtx->ThrowNativeError("Invalid message name: \"%s\"", msgname);
faluco@505
    84
	}
faluco@505
    85
faluco@505
    86
	pCtx->LocalToPhysAddr(params[2], &cl_array);
faluco@505
    87
	g_CurMsgFlags = params[4];
faluco@505
    88
faluco@505
    89
	g_MsgRecFilter.SetRecipientPtr(cl_array, params[3]);
faluco@505
    90
	if (g_CurMsgFlags & USERMSG_INITMSG)
faluco@505
    91
	{
faluco@505
    92
		g_MsgRecFilter.SetInitMessage(true);
faluco@505
    93
	}
faluco@505
    94
	if (g_CurMsgFlags & USERMSG_RELIABLE)
faluco@505
    95
	{
faluco@505
    96
		g_MsgRecFilter.SetReliable(true);
faluco@505
    97
	}
faluco@505
    98
faluco@505
    99
	if (g_CurMsgFlags & (USERMSG_PASSTHRU_ALL|USERMSG_PASSTHRU)) //:TODO: change this when we can hook messages
faluco@505
   100
	{
faluco@505
   101
		pBitBuf = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&g_MsgRecFilter), msgid);
faluco@505
   102
	} else {
faluco@505
   103
		pBitBuf = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&g_MsgRecFilter), msgid);
faluco@505
   104
	}
faluco@505
   105
faluco@505
   106
	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@505
   107
	g_IsMsgInExec = true;
faluco@505
   108
faluco@505
   109
	return g_CurMsgHandle;
faluco@505
   110
}
faluco@505
   111
faluco@505
   112
static cell_t smn_StartMessageEx(IPluginContext *pCtx, const cell_t *params)
faluco@505
   113
{
faluco@505
   114
	cell_t *cl_array;
faluco@505
   115
	bf_write *pBitBuf;
faluco@505
   116
	int msgid = params[1];
faluco@505
   117
faluco@505
   118
	if (g_IsMsgInExec)
faluco@505
   119
	{
faluco@505
   120
		return pCtx->ThrowNativeError("Unable to execute a new message, there is already one in progress");
faluco@505
   121
	}
faluco@505
   122
faluco@505
   123
	if (msgid < 0 || msgid > 255)
faluco@505
   124
	{
faluco@505
   125
		return pCtx->ThrowNativeError("Invalid message id supplied (%d)", msgid);
faluco@505
   126
	}
faluco@505
   127
faluco@505
   128
	pCtx->LocalToPhysAddr(params[2], &cl_array);
faluco@505
   129
	g_CurMsgFlags = params[4];
faluco@505
   130
faluco@505
   131
	g_MsgRecFilter.SetRecipientPtr(cl_array, params[3]);
faluco@505
   132
	if (g_CurMsgFlags & USERMSG_INITMSG)
faluco@505
   133
	{
faluco@505
   134
		g_MsgRecFilter.SetInitMessage(true);
faluco@505
   135
	}
faluco@505
   136
	if (g_CurMsgFlags & USERMSG_RELIABLE)
faluco@505
   137
	{
faluco@505
   138
		g_MsgRecFilter.SetReliable(true);
faluco@505
   139
	}
faluco@505
   140
faluco@505
   141
	if (g_CurMsgFlags & (USERMSG_PASSTHRU_ALL|USERMSG_PASSTHRU)) //:TODO: change this when we can hook messages
faluco@505
   142
	{
faluco@505
   143
		pBitBuf = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&g_MsgRecFilter), msgid);
faluco@505
   144
	} else {
faluco@505
   145
		pBitBuf = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&g_MsgRecFilter), msgid);
faluco@505
   146
	}
faluco@505
   147
faluco@505
   148
	g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@505
   149
	g_IsMsgInExec = true;
faluco@505
   150
faluco@505
   151
	return g_CurMsgHandle;
faluco@505
   152
}
faluco@505
   153
faluco@505
   154
static cell_t smn_EndMessage(IPluginContext *pCtx, const cell_t *params)
faluco@505
   155
{
faluco@505
   156
	HandleSecurity sec;
faluco@505
   157
faluco@505
   158
	if (!g_IsMsgInExec)
faluco@505
   159
	{
faluco@505
   160
		return pCtx->ThrowNativeError("Unable to end message, no message is in progress");
faluco@505
   161
	}
faluco@505
   162
faluco@505
   163
	if (g_CurMsgFlags & (USERMSG_PASSTHRU_ALL|USERMSG_PASSTHRU))
faluco@505
   164
	{
faluco@505
   165
		engine->MessageEnd();
faluco@505
   166
	} else {
faluco@505
   167
		ENGINE_CALL(MessageEnd)();
faluco@505
   168
	}
faluco@505
   169
faluco@505
   170
	sec.pOwner = pCtx->GetIdentity();
faluco@505
   171
	sec.pIdentity = g_pCoreIdent;
faluco@505
   172
	g_HandleSys.FreeHandle(g_CurMsgHandle, &sec);
faluco@505
   173
faluco@505
   174
	g_IsMsgInExec = false;
faluco@505
   175
	g_CurMsgFlags = 0;
faluco@505
   176
	g_MsgRecFilter.ResetFilter();
faluco@505
   177
faluco@505
   178
	return 1;
faluco@505
   179
}
faluco@505
   180
faluco@505
   181
static UsrMessageNatives s_UsrMessageNatives;
faluco@505
   182
faluco@505
   183
REGISTER_NATIVES(usrmsgnatives)
faluco@505
   184
{
faluco@505
   185
	{"GetUserMessageId",			smn_GetUserMessageId},
faluco@505
   186
	{"StartMessage",				smn_StartMessage},
faluco@505
   187
	{"StartMessageEx",				smn_StartMessageEx},
faluco@505
   188
	{"EndMessage",					smn_EndMessage},
faluco@505
   189
	{NULL,							NULL}
faluco@505
   190
};