core/logic/smn_players.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Wed Aug 14 14:20:57 2013 -0400 (2013-08-14)
changeset 4008 490b01aa0683
parent 3872 4c93f74cae51
permissions -rw-r--r--
Updated some CS:GO gamedata.
dvander@2996
     1
/**
dvander@2996
     2
 * vim: set ts=4 sw=4 tw=99 noet :
dvander@2996
     3
 * =============================================================================
dvander@2996
     4
 * SourceMod
dvander@2996
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
dvander@2996
     6
 * =============================================================================
dvander@2996
     7
 *
dvander@2996
     8
 * This program is free software; you can redistribute it and/or modify it under
dvander@2996
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
dvander@2996
    10
 * Free Software Foundation.
dvander@2996
    11
 * 
dvander@2996
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@2996
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@2996
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
dvander@2996
    15
 * details.
dvander@2996
    16
 *
dvander@2996
    17
 * You should have received a copy of the GNU General Public License along with
dvander@2996
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@2996
    19
 *
dvander@2996
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
dvander@2996
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
dvander@2996
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@2996
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
dvander@2996
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
dvander@2996
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
dvander@2996
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@2996
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@2996
    28
 *
dvander@2996
    29
 * Version: $Id$
dvander@2996
    30
 */
dvander@2996
    31
dvander@2996
    32
#include "common_logic.h"
dvander@2996
    33
#include <IPluginSys.h>
dvander@2996
    34
#include <IPlayerHelpers.h>
dvander@2996
    35
#include <sh_string.h>
dvander@2996
    36
#include <sh_list.h>
dvander@3872
    37
#include "CellArray.h"
dvander@2996
    38
#include "AutoHandleRooter.h"
dvander@2996
    39
dvander@2996
    40
using namespace SourceHook;
dvander@2996
    41
using namespace SourceMod;
dvander@2996
    42
dvander@2996
    43
class PlayerLogicHelpers : 
dvander@2996
    44
	public SMGlobalClass,
dvander@2996
    45
	public IPluginsListener,
dvander@2996
    46
	public ICommandTargetProcessor
dvander@2996
    47
{
dvander@2996
    48
	struct SimpleMultiTargetFilter
dvander@2996
    49
	{
dvander@2996
    50
		IPlugin *plugin;
dvander@2996
    51
		SourceHook::String pattern;
dvander@2996
    52
		IPluginFunction *fun;
dvander@2996
    53
		SourceHook::String phrase;
dvander@2996
    54
		bool phraseIsML;
dvander@2996
    55
dvander@2996
    56
		SimpleMultiTargetFilter(IPlugin *plugin, const char *pattern, IPluginFunction *fun,
dvander@2996
    57
		                        const char *phrase, bool phraseIsML)
dvander@2996
    58
		  : plugin(plugin), pattern(pattern), fun(fun), phrase(phrase), phraseIsML(phraseIsML)
dvander@2996
    59
		{
dvander@2996
    60
		}
dvander@2996
    61
	};
dvander@2996
    62
dvander@2996
    63
	List<SimpleMultiTargetFilter *> simpleMultis;
dvander@2996
    64
	bool filterEnabled;
dvander@2996
    65
dvander@2996
    66
public:
dvander@2996
    67
	void AddMultiTargetFilter(IPlugin *plugin, const char *pattern, IPluginFunction *fun,
dvander@2996
    68
	                          const char *phrase, bool phraseIsML)
dvander@2996
    69
	{
dvander@2996
    70
		SimpleMultiTargetFilter *smtf = new SimpleMultiTargetFilter(plugin, pattern, fun, phrase,
dvander@2996
    71
		                                                            phraseIsML);
dvander@2996
    72
dvander@2996
    73
		simpleMultis.push_back(smtf);
dvander@2996
    74
dvander@2996
    75
		if (!filterEnabled) {
dvander@2996
    76
			playerhelpers->RegisterCommandTargetProcessor(this);
dvander@2996
    77
			filterEnabled = true;
dvander@2996
    78
		}
dvander@2996
    79
	}
dvander@2996
    80
dvander@2996
    81
	void RemoveMultiTargetFilter(const char *pattern, IPluginFunction *fun)
dvander@2996
    82
	{
dvander@2996
    83
		List<SimpleMultiTargetFilter *>::iterator iter = simpleMultis.begin();
dvander@2996
    84
dvander@2996
    85
		while (iter != simpleMultis.end()) {
dvander@2996
    86
			if ((*iter)->fun == fun && strcmp((*iter)->pattern.c_str(), pattern) == 0) {
dvander@2996
    87
				delete (*iter);
dvander@2996
    88
				iter = simpleMultis.erase(iter);
dvander@2996
    89
				break;
dvander@2996
    90
			}
dvander@2996
    91
			iter++;
dvander@2996
    92
		}
dvander@2996
    93
	}
dvander@2996
    94
dvander@2996
    95
	PlayerLogicHelpers()
dvander@2996
    96
	 : filterEnabled(false)
dvander@2996
    97
	{
dvander@2996
    98
	}
dvander@2996
    99
dvander@2996
   100
public: //ICommandTargetProcessor
dvander@2996
   101
	bool ProcessCommandTarget(cmd_target_info_t *info)
dvander@2996
   102
	{
dvander@2996
   103
		List<SimpleMultiTargetFilter *>::iterator iter;
dvander@2996
   104
dvander@2996
   105
		for (iter = simpleMultis.begin(); iter != simpleMultis.end(); iter++) {
dvander@2996
   106
			SimpleMultiTargetFilter *smtf = (*iter);
dvander@2996
   107
			if (strcmp(smtf->pattern.c_str(), info->pattern) == 0) {
dvander@2996
   108
				CellArray *array = new CellArray(1);
dvander@2996
   109
				HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
dvander@2996
   110
				Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
dvander@2996
   111
				AutoHandleCloner ahc(hndl, sec);
dvander@2996
   112
				if (ahc.getClone() == BAD_HANDLE) {
dvander@2996
   113
					smcore.LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
dvander@2996
   114
					delete array;
dvander@2996
   115
					return false;
dvander@2996
   116
				}
dvander@2996
   117
dvander@2996
   118
				smtf->fun->PushString(info->pattern);
dvander@2996
   119
				smtf->fun->PushCell(ahc.getClone());
dvander@2996
   120
				cell_t result = 0;
dvander@2996
   121
				if (smtf->fun->Execute(&result) != SP_ERROR_NONE || !result)
dvander@2996
   122
					return false;
dvander@2996
   123
dvander@2996
   124
				IGamePlayer *pAdmin = info->admin
dvander@2996
   125
				                      ? playerhelpers->GetGamePlayer(info->admin)
dvander@2996
   126
				                      : NULL;
dvander@2996
   127
dvander@2996
   128
				info->num_targets = 0;
dvander@2996
   129
				for (size_t i = 0; i < array->size(); i++) {
dvander@2996
   130
					cell_t client = *array->at(i);
dvander@2996
   131
					IGamePlayer *pClient = playerhelpers->GetGamePlayer(client);
dvander@2996
   132
					if (pClient == NULL || !pClient->IsConnected())
dvander@2996
   133
						continue;
dvander@2996
   134
					if (playerhelpers->FilterCommandTarget(pAdmin, pClient, info->flags) ==
dvander@2996
   135
					    COMMAND_TARGET_VALID)
dvander@2996
   136
					{
dvander@2996
   137
						info->targets[info->num_targets++] = client;
dvander@2996
   138
						if (info->num_targets >= unsigned(info->max_targets))
dvander@2996
   139
							break;
dvander@2996
   140
					}
dvander@2996
   141
				}
dvander@2996
   142
dvander@2996
   143
				info->reason = info->num_targets > 0
dvander@2996
   144
				               ? COMMAND_TARGET_VALID
dvander@2996
   145
				               : COMMAND_TARGET_EMPTY_FILTER;
dvander@2996
   146
				if (info->num_targets) {
dvander@2996
   147
					smcore.strncopy(info->target_name, smtf->phrase.c_str(), info->target_name_maxlength);
dvander@2996
   148
					info->target_name_style = smtf->phraseIsML
dvander@2996
   149
					                          ? COMMAND_TARGETNAME_ML
dvander@2996
   150
					                          : COMMAND_TARGETNAME_RAW;
dvander@2996
   151
				}
dvander@2996
   152
dvander@2996
   153
				return true;
dvander@2996
   154
			}
dvander@2996
   155
		}
dvander@2996
   156
dvander@2996
   157
		return false;
dvander@2996
   158
	}
dvander@2996
   159
dvander@2996
   160
public: //SMGlobalClass
dvander@2996
   161
	void OnSourceModAllInitialized()
dvander@2996
   162
	{
dvander@2996
   163
		pluginsys->AddPluginsListener(this);
dvander@2996
   164
	}
dvander@2996
   165
dvander@2996
   166
	void OnSourceModShutdown()
dvander@2996
   167
	{
dvander@2996
   168
		pluginsys->RemovePluginsListener(this);
dvander@2996
   169
		if (filterEnabled) {
dvander@2996
   170
			playerhelpers->UnregisterCommandTargetProcessor(this);
dvander@2996
   171
			filterEnabled = false;
dvander@2996
   172
		}
dvander@2996
   173
	}
dvander@2996
   174
dvander@2996
   175
public: //IPluginsListener
dvander@2996
   176
dvander@2996
   177
	void OnPluginDestroyed(IPlugin *plugin)
dvander@2996
   178
	{
dvander@2996
   179
		List<SimpleMultiTargetFilter *>::iterator iter = simpleMultis.begin();
dvander@2996
   180
dvander@2996
   181
		while (iter != simpleMultis.end()) {
dvander@2996
   182
			if ((*iter)->plugin != plugin) {
dvander@2996
   183
				iter++;
dvander@2996
   184
			} else {
dvander@2996
   185
				delete (*iter);
dvander@2996
   186
				iter = simpleMultis.erase(iter);
dvander@2996
   187
			}
dvander@2996
   188
		}
dvander@2996
   189
	}
dvander@2996
   190
} s_PlayerLogicHelpers;
dvander@2996
   191
dvander@2996
   192
static cell_t
dvander@2996
   193
AddMultiTargetFilter(IPluginContext *ctx, const cell_t *params)
dvander@2996
   194
{
dvander@2996
   195
	IPluginFunction *fun = ctx->GetFunctionById(funcid_t(params[2]));
dvander@2996
   196
	if (fun == NULL)
dvander@2996
   197
		return ctx->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@2996
   198
dvander@2996
   199
	char *pattern;
dvander@2996
   200
	char *phrase;
dvander@2996
   201
dvander@2996
   202
	ctx->LocalToString(params[1], &pattern);
dvander@2996
   203
	ctx->LocalToString(params[3], &phrase);
dvander@2996
   204
dvander@2996
   205
	bool phraseIsML = !!params[4];
dvander@2996
   206
	IPlugin *plugin = pluginsys->FindPluginByContext(ctx->GetContext());
dvander@2996
   207
dvander@2996
   208
	s_PlayerLogicHelpers.AddMultiTargetFilter(plugin, pattern, fun, phrase, phraseIsML);
dvander@2996
   209
dvander@2996
   210
	return 1;
dvander@2996
   211
}
dvander@2996
   212
dvander@2996
   213
static cell_t
dvander@2996
   214
RemoveMultiTargetFilter(IPluginContext *ctx, const cell_t *params)
dvander@2996
   215
{
dvander@2996
   216
	IPluginFunction *fun = ctx->GetFunctionById(funcid_t(params[2]));
dvander@2996
   217
	if (fun == NULL)
dvander@2996
   218
		return ctx->ThrowNativeError("Invalid function id (%X)", params[2]);
dvander@2996
   219
dvander@2996
   220
	char *pattern;
dvander@2996
   221
dvander@2996
   222
	ctx->LocalToString(params[1], &pattern);
dvander@2996
   223
dvander@2996
   224
	s_PlayerLogicHelpers.RemoveMultiTargetFilter(pattern, fun);
dvander@2996
   225
dvander@2996
   226
	return 1;
dvander@2996
   227
}
dvander@2996
   228
dvander@2996
   229
REGISTER_NATIVES(playernatives)
dvander@2996
   230
{
dvander@2996
   231
	{"AddMultiTargetFilter",	AddMultiTargetFilter},
dvander@2996
   232
	{"RemoveMultiTargetFilter",	RemoveMultiTargetFilter},
dvander@2996
   233
	{NULL,						NULL}
dvander@2996
   234
};
dvander@2996
   235