core/PlayerManager.cpp
branchrefac-jit
changeset 2284 026da5437111
parent 2192 7602d7fb60d9
child 2288 15c77b21589a
     1.1 --- a/core/PlayerManager.cpp	Fri Jul 11 06:51:21 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1579 +0,0 @@
     1.4 -/**
     1.5 - * vim: set ts=4 :
     1.6 - * =============================================================================
     1.7 - * SourceMod
     1.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     1.9 - * =============================================================================
    1.10 - *
    1.11 - * This program is free software; you can redistribute it and/or modify it under
    1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
    1.13 - * Free Software Foundation.
    1.14 - * 
    1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
    1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    1.18 - * details.
    1.19 - *
    1.20 - * You should have received a copy of the GNU General Public License along with
    1.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
    1.22 - *
    1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
    1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
    1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    1.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
    1.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
    1.28 - * this exception to all derivative works.  AlliedModders LLC defines further
    1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    1.30 - * or <http://www.sourcemod.net/license.php>.
    1.31 - *
    1.32 - * Version: $Id$
    1.33 - */
    1.34 -
    1.35 -#include "PlayerManager.h"
    1.36 -#include "ForwardSys.h"
    1.37 -#include "ShareSys.h"
    1.38 -#include "AdminCache.h"
    1.39 -#include "ConCmdManager.h"
    1.40 -#include "MenuStyle_Valve.h"
    1.41 -#include "MenuStyle_Radio.h"
    1.42 -#include "sm_stringutil.h"
    1.43 -#include "CoreConfig.h"
    1.44 -#include "TimerSys.h"
    1.45 -#include "Translator.h"
    1.46 -#include "Logger.h"
    1.47 -#include "ChatTriggers.h"
    1.48 -#include "HalfLife2.h"
    1.49 -#include <inetchannel.h>
    1.50 -#include <iclient.h>
    1.51 -#include "GameConfigs.h"
    1.52 -#include "systems/ExtensionSys.h"
    1.53 -
    1.54 -PlayerManager g_Players;
    1.55 -bool g_OnMapStarted = false;
    1.56 -IForward *PreAdminCheck = NULL;
    1.57 -IForward *PostAdminCheck = NULL;
    1.58 -IForward *PostAdminFilter = NULL;
    1.59 -const unsigned int *g_NumPlayersToAuth = NULL;
    1.60 -int lifestate_offset = -1;
    1.61 -List<ICommandTargetProcessor *> target_processors;
    1.62 -
    1.63 -SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
    1.64 -SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
    1.65 -SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
    1.66 -#if defined ORANGEBOX_BUILD
    1.67 -SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
    1.68 -#else
    1.69 -SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
    1.70 -#endif
    1.71 -SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
    1.72 -SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
    1.73 -
    1.74 -class KickPlayerTimer : public ITimedEvent
    1.75 -{
    1.76 -public:
    1.77 -	ResultType OnTimer(ITimer *pTimer, void *pData)
    1.78 -	{
    1.79 -		int userid = (int)pData;
    1.80 -		int client = g_Players.GetClientOfUserId(userid);
    1.81 -		if (client)
    1.82 -		{
    1.83 -			CPlayer *player = g_Players.GetPlayerByIndex(client);
    1.84 -			player->Kick("Your name is reserved by SourceMod; set your password to use it.");
    1.85 -		}
    1.86 -		return Pl_Stop;
    1.87 -	}
    1.88 -	void OnTimerEnd(ITimer *pTimer, void *pData)
    1.89 -	{
    1.90 -	}
    1.91 -} s_KickPlayerTimer;
    1.92 -
    1.93 -PlayerManager::PlayerManager()
    1.94 -{
    1.95 -	m_AuthQueue = NULL;
    1.96 -	m_FirstPass = false;
    1.97 -	m_maxClients = 0;
    1.98 -
    1.99 -	m_UserIdLookUp = new int[USHRT_MAX+1];
   1.100 -	memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
   1.101 -}
   1.102 -
   1.103 -PlayerManager::~PlayerManager()
   1.104 -{
   1.105 -	g_NumPlayersToAuth = NULL;
   1.106 -
   1.107 -	delete [] m_AuthQueue;
   1.108 -	delete [] m_UserIdLookUp;
   1.109 -}
   1.110 -
   1.111 -void PlayerManager::OnSourceModAllInitialized()
   1.112 -{
   1.113 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
   1.114 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect_Post, true);
   1.115 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
   1.116 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
   1.117 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
   1.118 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
   1.119 -	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
   1.120 -	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
   1.121 -
   1.122 -	g_ShareSys.AddInterface(NULL, this);
   1.123 -
   1.124 -	ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
   1.125 -	ParamType p2[] = {Param_Cell};
   1.126 -
   1.127 -	m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
   1.128 -	m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
   1.129 -	m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
   1.130 -	m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
   1.131 -	m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 2, NULL, Param_Cell, Param_Cell);
   1.132 -	m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
   1.133 -	m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
   1.134 -	m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL);
   1.135 -	m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL);
   1.136 -
   1.137 -	PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1);
   1.138 -	PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1);
   1.139 -	PostAdminFilter = g_Forwards.CreateForward("OnClientPostAdminFilter", ET_Ignore, 1, p1);
   1.140 -
   1.141 -	m_bIsListenServer = !engine->IsDedicatedServer();
   1.142 -	m_ListenClient = 0;
   1.143 -}
   1.144 -
   1.145 -void PlayerManager::OnSourceModShutdown()
   1.146 -{
   1.147 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
   1.148 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
   1.149 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
   1.150 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
   1.151 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
   1.152 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
   1.153 -	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
   1.154 -
   1.155 -	/* Release forwards */
   1.156 -	g_Forwards.ReleaseForward(m_clconnect);
   1.157 -	g_Forwards.ReleaseForward(m_clputinserver);
   1.158 -	g_Forwards.ReleaseForward(m_cldisconnect);
   1.159 -	g_Forwards.ReleaseForward(m_cldisconnect_post);
   1.160 -	g_Forwards.ReleaseForward(m_clcommand);
   1.161 -	g_Forwards.ReleaseForward(m_clinfochanged);
   1.162 -	g_Forwards.ReleaseForward(m_clauth);
   1.163 -	g_Forwards.ReleaseForward(m_onActivate);
   1.164 -	g_Forwards.ReleaseForward(m_onActivate2);
   1.165 -
   1.166 -	g_Forwards.ReleaseForward(PreAdminCheck);
   1.167 -	g_Forwards.ReleaseForward(PostAdminCheck);
   1.168 -	g_Forwards.ReleaseForward(PostAdminFilter);
   1.169 -
   1.170 -	delete [] m_Players;
   1.171 -}
   1.172 -
   1.173 -ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key, 
   1.174 -												 const char *value, 
   1.175 -												 ConfigSource source, 
   1.176 -												 char *error, 
   1.177 -												 size_t maxlength)
   1.178 -{
   1.179 -	if (strcmp(key, "PassInfoVar") == 0)
   1.180 -	{
   1.181 -		if (strcmp(value, "_password") != 0)
   1.182 -		{
   1.183 -			m_PassInfoVar.assign(value);
   1.184 -		}
   1.185 -		return ConfigResult_Accept;
   1.186 -	} else if (strcmp(key, "AllowClLanguageVar") == 0) {
   1.187 -		if (strcasecmp(value, "on") == 0)
   1.188 -		{
   1.189 -			m_QueryLang = true;
   1.190 -		} else if (strcasecmp(value, "off") == 0) {
   1.191 -			m_QueryLang = false;
   1.192 -		} else {
   1.193 -			UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
   1.194 -			return ConfigResult_Reject;
   1.195 -		}
   1.196 -		return ConfigResult_Accept;
   1.197 -	}
   1.198 -	return ConfigResult_Ignore;
   1.199 -}
   1.200 -
   1.201 -void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
   1.202 -{
   1.203 -	if (!m_FirstPass)
   1.204 -	{
   1.205 -		/* Initialize all players */
   1.206 -		m_maxClients = clientMax;
   1.207 -		m_PlayerCount = 0;
   1.208 -		m_Players = new CPlayer[m_maxClients + 1];
   1.209 -		m_AuthQueue = new unsigned int[m_maxClients + 1];
   1.210 -		m_FirstPass = true;
   1.211 -
   1.212 -		memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
   1.213 -
   1.214 -		g_NumPlayersToAuth = &m_AuthQueue[0];
   1.215 -	}
   1.216 -	g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, clientMax);
   1.217 -	m_onActivate->Execute(NULL);
   1.218 -	m_onActivate2->Execute(NULL);
   1.219 -
   1.220 -	List<IClientListener *>::iterator iter;
   1.221 -	for (iter = m_hooks.begin(); iter != m_hooks.end(); iter++)
   1.222 -	{
   1.223 -		if ((*iter)->GetClientListenerVersion() >= 5)
   1.224 -		{
   1.225 -			(*iter)->OnServerActivated(clientMax);
   1.226 -		}
   1.227 -	}
   1.228 -
   1.229 -	g_OnMapStarted = true;
   1.230 -
   1.231 -	SM_ExecuteAllConfigs();
   1.232 -}
   1.233 -
   1.234 -bool PlayerManager::IsServerActivated()
   1.235 -{
   1.236 -	return m_FirstPass;
   1.237 -}
   1.238 -
   1.239 -bool PlayerManager::CheckSetAdmin(int index, CPlayer *pPlayer, AdminId id)
   1.240 -{
   1.241 -	const char *password = g_Admins.GetAdminPassword(id);
   1.242 -	if (password != NULL)
   1.243 -	{
   1.244 -		if (m_PassInfoVar.size() < 1)
   1.245 -		{
   1.246 -			return false;
   1.247 -		}
   1.248 -
   1.249 -		/* Whoa... the user needs a password! */
   1.250 -		const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
   1.251 -		if (!given || strcmp(given, password) != 0)
   1.252 -		{
   1.253 -			return false;
   1.254 -		}
   1.255 -	}
   1.256 -
   1.257 -	pPlayer->SetAdminId(id, false);
   1.258 -
   1.259 -	return true;
   1.260 -}
   1.261 -
   1.262 -bool PlayerManager::CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id)
   1.263 -{
   1.264 -	const char *password = g_Admins.GetAdminPassword(id);
   1.265 -	if (password == NULL)
   1.266 -	{
   1.267 -		return false;
   1.268 -	}
   1.269 -
   1.270 -	if (m_PassInfoVar.size() < 1)
   1.271 -	{
   1.272 -		return false;
   1.273 -	}
   1.274 -
   1.275 -	/* Whoa... the user needs a password! */
   1.276 -	const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
   1.277 -	if (!given || strcmp(given, password) != 0)
   1.278 -	{
   1.279 -		return false;
   1.280 -	}
   1.281 -
   1.282 -	pPlayer->SetAdminId(id, false);
   1.283 -
   1.284 -	return true;
   1.285 -}
   1.286 -
   1.287 -void PlayerManager::RunAuthChecks()
   1.288 -{
   1.289 -	CPlayer *pPlayer;
   1.290 -	const char *authstr;
   1.291 -	unsigned int removed = 0;
   1.292 -	for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
   1.293 -	{
   1.294 -		pPlayer = GetPlayerByIndex(m_AuthQueue[i]);
   1.295 -		authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
   1.296 -		if (authstr && authstr[0] != '\0'
   1.297 -			&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
   1.298 -		{
   1.299 -			/* Set authorization */
   1.300 -			pPlayer->Authorize(authstr);
   1.301 -
   1.302 -			/* Mark as removed from queue */
   1.303 -			unsigned int client = m_AuthQueue[i];
   1.304 -			m_AuthQueue[i] = 0;
   1.305 -			removed++;
   1.306 -
   1.307 -			/* Send to extensions */
   1.308 -			List<IClientListener *>::iterator iter;
   1.309 -			IClientListener *pListener;
   1.310 -			for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.311 -			{
   1.312 -				pListener = (*iter);
   1.313 -				pListener->OnClientAuthorized(client, authstr);
   1.314 -				if (!pPlayer->IsConnected())
   1.315 -				{
   1.316 -					break;
   1.317 -				}
   1.318 -			}
   1.319 -
   1.320 -			/* Send to plugins if player is still connected */
   1.321 -			if (pPlayer->IsConnected() && m_clauth->GetFunctionCount())
   1.322 -			{
   1.323 -				/* :TODO: handle the case of a player disconnecting in the middle */
   1.324 -				m_clauth->PushCell(client);
   1.325 -				m_clauth->PushString(authstr);
   1.326 -				m_clauth->Execute(NULL);
   1.327 -			}
   1.328 -
   1.329 -			if (pPlayer->IsConnected())
   1.330 -			{
   1.331 -				pPlayer->Authorize_Post();
   1.332 -			}
   1.333 -		}
   1.334 -	}
   1.335 -
   1.336 -	/* Clean up the queue */
   1.337 -	if (removed)
   1.338 -	{
   1.339 -		/* We don't have to compact the list if it's empty */
   1.340 -		if (removed != m_AuthQueue[0])
   1.341 -		{
   1.342 -			unsigned int diff = 0;
   1.343 -			for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
   1.344 -			{
   1.345 -				/* If this member is removed... */
   1.346 -				if (m_AuthQueue[i] == 0)
   1.347 -				{
   1.348 -					/* Increase the differential */
   1.349 -					diff++;
   1.350 -				} else {
   1.351 -					/* diff cannot increase faster than i+1 */
   1.352 -					assert(i > diff);
   1.353 -					assert(i - diff >= 1);
   1.354 -					/* move this index down */
   1.355 -					m_AuthQueue[i - diff] = m_AuthQueue[i];
   1.356 -				}
   1.357 -			}
   1.358 -			m_AuthQueue[0] -= removed;
   1.359 -		} else {
   1.360 -			m_AuthQueue[0] = 0;
   1.361 -		}
   1.362 -	}
   1.363 -}
   1.364 -
   1.365 -bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
   1.366 -{
   1.367 -	int client = engine->IndexOfEdict(pEntity);
   1.368 -
   1.369 -	List<IClientListener *>::iterator iter;
   1.370 -	IClientListener *pListener = NULL;
   1.371 -	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.372 -	{
   1.373 -		pListener = (*iter);
   1.374 -		if (!pListener->InterceptClientConnect(client, reject, maxrejectlen))
   1.375 -		{
   1.376 -			return false;
   1.377 -		}
   1.378 -	}
   1.379 -
   1.380 -	cell_t res = 1;
   1.381 -
   1.382 -	m_Players[client].Initialize(pszName, pszAddress, pEntity);
   1.383 -	m_clconnect->PushCell(client);
   1.384 -	m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
   1.385 -	m_clconnect->PushCell(maxrejectlen);
   1.386 -	m_clconnect->Execute(&res, NULL);
   1.387 -
   1.388 -	if (res)
   1.389 -	{
   1.390 -		if (!m_Players[client].IsAuthorized())
   1.391 -		{
   1.392 -			m_AuthQueue[++m_AuthQueue[0]] = client;
   1.393 -		}
   1.394 -	}
   1.395 -	else
   1.396 -	{
   1.397 -		RETURN_META_VALUE(MRES_SUPERCEDE, false);
   1.398 -	}
   1.399 -
   1.400 -	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = client;
   1.401 -
   1.402 -	return true;
   1.403 -}
   1.404 -
   1.405 -bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
   1.406 -{
   1.407 -	int client = engine->IndexOfEdict(pEntity);
   1.408 -	bool orig_value = META_RESULT_ORIG_RET(bool);
   1.409 -	CPlayer *pPlayer = GetPlayerByIndex(client);
   1.410 -
   1.411 -	if (orig_value)
   1.412 -	{
   1.413 -		List<IClientListener *>::iterator iter;
   1.414 -		IClientListener *pListener = NULL;
   1.415 -		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.416 -		{
   1.417 -			pListener = (*iter);
   1.418 -			pListener->OnClientConnected(client);
   1.419 -			if (!pPlayer->IsConnected())
   1.420 -			{
   1.421 -				break;
   1.422 -			}
   1.423 -		}
   1.424 -	}
   1.425 -
   1.426 -	if (!pPlayer->IsFakeClient() 
   1.427 -		&& m_bIsListenServer
   1.428 -		&& strncmp(pszAddress, "127.0.0.1", 9) == 0)
   1.429 -	{
   1.430 -		m_ListenClient = client;
   1.431 -	}
   1.432 -
   1.433 -	return true;
   1.434 -}
   1.435 -
   1.436 -void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
   1.437 -{
   1.438 -	cell_t res;
   1.439 -	int client = engine->IndexOfEdict(pEntity);
   1.440 -
   1.441 -	CPlayer *pPlayer = GetPlayerByIndex(client);
   1.442 -	/* If they're not connected, they're a bot */
   1.443 -	if (!pPlayer->IsConnected())
   1.444 -	{
   1.445 -		/* Run manual connection routines */
   1.446 -		char error[255];
   1.447 -		const char *authid = engine->GetPlayerNetworkIDString(pEntity);
   1.448 -		pPlayer->Authorize(authid);
   1.449 -		if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
   1.450 -		{
   1.451 -			/* :TODO: kick the bot if it's rejected */
   1.452 -			return;
   1.453 -		}
   1.454 -		List<IClientListener *>::iterator iter;
   1.455 -		IClientListener *pListener = NULL;
   1.456 -		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.457 -		{
   1.458 -			pListener = (*iter);
   1.459 -			pListener->OnClientConnected(client);
   1.460 -			/* See if bot was kicked */
   1.461 -			if (!pPlayer->IsConnected())
   1.462 -			{
   1.463 -				return;
   1.464 -			}
   1.465 -		}
   1.466 -		/* Now do authorization */
   1.467 -		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.468 -		{
   1.469 -			pListener = (*iter);
   1.470 -			pListener->OnClientAuthorized(client, authid);
   1.471 -		}
   1.472 -		/* Finally, tell plugins */
   1.473 -		if (m_clauth->GetFunctionCount())
   1.474 -		{
   1.475 -			m_clauth->PushCell(client);
   1.476 -			m_clauth->PushString(authid);
   1.477 -			m_clauth->Execute(NULL);
   1.478 -		}
   1.479 -		pPlayer->Authorize_Post();
   1.480 -	}
   1.481 -
   1.482 -	if (playerinfo)
   1.483 -	{
   1.484 -		pPlayer->m_Info = playerinfo->GetPlayerInfo(pEntity);
   1.485 -	}
   1.486 -
   1.487 -	/* Get the client's language */
   1.488 -	if (m_QueryLang)
   1.489 -	{
   1.490 -		const char *name;
   1.491 -		if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
   1.492 -		{
   1.493 -			unsigned int langid;
   1.494 -			pPlayer->m_LangId = (g_Translator.GetLanguageByName(name, &langid)) ? langid : g_Translator.GetServerLanguage();
   1.495 -		} else {
   1.496 -			pPlayer->m_LangId = g_Translator.GetServerLanguage();
   1.497 -		}
   1.498 -	}
   1.499 -
   1.500 -	m_Players[client].Connect();
   1.501 -	m_PlayerCount++;
   1.502 -
   1.503 -	List<IClientListener *>::iterator iter;
   1.504 -	IClientListener *pListener = NULL;
   1.505 -	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.506 -	{
   1.507 -		pListener = (*iter);
   1.508 -		pListener->OnClientPutInServer(client);
   1.509 -	}
   1.510 -
   1.511 -	m_clputinserver->PushCell(client);
   1.512 -	m_clputinserver->Execute(&res, NULL);
   1.513 -
   1.514 -	if (m_Players[client].IsAuthorized())
   1.515 -	{
   1.516 -		m_Players[client].DoPostConnectAuthorization();
   1.517 -	}
   1.518 -}
   1.519 -
   1.520 -void PlayerManager::OnSourceModLevelEnd()
   1.521 -{
   1.522 -	/* Disconnect all bots still in game */
   1.523 -	for (int i=1; i<=m_maxClients; i++)
   1.524 -	{
   1.525 -		if (m_Players[i].IsConnected())
   1.526 -		{
   1.527 -			OnClientDisconnect(m_Players[i].GetEdict());
   1.528 -		}
   1.529 -	}
   1.530 -	m_PlayerCount = 0;
   1.531 -}
   1.532 -
   1.533 -void PlayerManager::OnClientDisconnect(edict_t *pEntity)
   1.534 -{
   1.535 -	cell_t res;
   1.536 -	int client = engine->IndexOfEdict(pEntity);
   1.537 -
   1.538 -	if (m_Players[client].IsConnected())
   1.539 -	{
   1.540 -		m_cldisconnect->PushCell(client);
   1.541 -		m_cldisconnect->Execute(&res, NULL);
   1.542 -	}
   1.543 -	else
   1.544 -	{
   1.545 -		/* We don't care, prevent a double call */
   1.546 -		return;
   1.547 -	}
   1.548 -
   1.549 -	if (m_Players[client].WasCountedAsInGame())
   1.550 -	{
   1.551 -		m_PlayerCount--;
   1.552 -	}
   1.553 -
   1.554 -	List<IClientListener *>::iterator iter;
   1.555 -	IClientListener *pListener = NULL;
   1.556 -	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.557 -	{
   1.558 -		pListener = (*iter);
   1.559 -		pListener->OnClientDisconnecting(client);
   1.560 -	}
   1.561 -
   1.562 -	/**
   1.563 -	 * Remove client from auth queue if necessary
   1.564 -	 */
   1.565 -	if (!m_Players[client].IsAuthorized())
   1.566 -	{
   1.567 -		for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
   1.568 -		{
   1.569 -			if (m_AuthQueue[i] == (unsigned)client)
   1.570 -			{
   1.571 -				/* Move everything ahead of us back by one */
   1.572 -				for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
   1.573 -				{
   1.574 -					m_AuthQueue[j-1] = m_AuthQueue[j];
   1.575 -				}
   1.576 -				/* Remove us and break */
   1.577 -				m_AuthQueue[0]--;
   1.578 -				break;
   1.579 -			}
   1.580 -		}
   1.581 -	}
   1.582 -
   1.583 -	m_Players[client].Disconnect();
   1.584 -	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = 0;
   1.585 -
   1.586 -	if (m_ListenClient == client)
   1.587 -	{
   1.588 -		m_ListenClient = 0;
   1.589 -	}
   1.590 -}
   1.591 -
   1.592 -void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
   1.593 -{
   1.594 -	cell_t res;
   1.595 -	int client = engine->IndexOfEdict(pEntity);
   1.596 -
   1.597 -	m_cldisconnect_post->PushCell(client);
   1.598 -	m_cldisconnect_post->Execute(&res, NULL);
   1.599 -
   1.600 -	List<IClientListener *>::iterator iter;
   1.601 -	IClientListener *pListener = NULL;
   1.602 -	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
   1.603 -	{
   1.604 -		pListener = (*iter);
   1.605 -		pListener->OnClientDisconnected(client);
   1.606 -	}
   1.607 -}
   1.608 -
   1.609 -#if defined ORANGEBOX_BUILD
   1.610 -void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args)
   1.611 -{
   1.612 -#else
   1.613 -void PlayerManager::OnClientCommand(edict_t *pEntity)
   1.614 -{
   1.615 -	CCommand args;
   1.616 -#endif
   1.617 -	int client = engine->IndexOfEdict(pEntity);
   1.618 -	cell_t res = Pl_Continue;
   1.619 -
   1.620 -	CPlayer *pPlayer = GetPlayerByIndex(client);
   1.621 -	if (!pPlayer || !pPlayer->IsConnected())
   1.622 -	{
   1.623 -		return;
   1.624 -	}
   1.625 -
   1.626 -	g_HL2.PushCommandStack(&args);
   1.627 -
   1.628 -	int argcount = args.ArgC() - 1;
   1.629 -	const char *cmd = g_HL2.CurrentCommandName();
   1.630 -
   1.631 -	bool result = g_ValveMenuStyle.OnClientCommand(client, cmd, args);
   1.632 -	if (result)
   1.633 -	{
   1.634 -		res = Pl_Handled;
   1.635 -	} else {
   1.636 -		result = g_RadioMenuStyle.OnClientCommand(client, cmd, args);
   1.637 -		if (result)
   1.638 -		{
   1.639 -			res = Pl_Handled;
   1.640 -		}
   1.641 -	}
   1.642 -
   1.643 -	cell_t res2 = Pl_Continue;
   1.644 -	m_clcommand->PushCell(client);
   1.645 -	m_clcommand->PushCell(argcount);
   1.646 -	m_clcommand->Execute(&res2, NULL);
   1.647 -
   1.648 -	if (res2 > res)
   1.649 -	{
   1.650 -		res = res2;
   1.651 -	}
   1.652 -
   1.653 -	if (res >= Pl_Stop)
   1.654 -	{
   1.655 -		g_HL2.PopCommandStack();
   1.656 -		RETURN_META(MRES_SUPERCEDE);
   1.657 -	}
   1.658 -
   1.659 -	res = g_ConCmds.DispatchClientCommand(client, cmd, argcount, (ResultType)res);
   1.660 -
   1.661 -	g_HL2.PopCommandStack();
   1.662 -
   1.663 -	if (res >= Pl_Handled)
   1.664 -	{
   1.665 -		RETURN_META(MRES_SUPERCEDE);
   1.666 -	}
   1.667 -}
   1.668 -
   1.669 -void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
   1.670 -{
   1.671 -	cell_t res;
   1.672 -	int client = engine->IndexOfEdict(pEntity);
   1.673 -
   1.674 -	if (!m_Players[client].IsConnected())
   1.675 -	{
   1.676 -		return;
   1.677 -	}
   1.678 -
   1.679 -	m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
   1.680 -	m_clinfochanged->Execute(&res, NULL);
   1.681 -
   1.682 -	IPlayerInfo *info = m_Players[client].GetPlayerInfo();
   1.683 -	const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
   1.684 -	const char *old_name = m_Players[client].m_Name.c_str();
   1.685 -
   1.686 -	if (strcmp(old_name, new_name) != 0)
   1.687 -	{
   1.688 -		AdminId id = g_Admins.FindAdminByIdentity("name", new_name);
   1.689 -		if (id != INVALID_ADMIN_ID && m_Players[client].GetAdminId() != id)
   1.690 -		{
   1.691 -			if (!CheckSetAdminName(client, &m_Players[client], id))
   1.692 -			{
   1.693 -				m_Players[client].Kick("Your name is reserved by SourceMod; set your password to use it.");
   1.694 -				RETURN_META(MRES_IGNORED);
   1.695 -			}
   1.696 -		} else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
   1.697 -			if (id == m_Players[client].GetAdminId())
   1.698 -			{
   1.699 -				/* This player is changing their name; force them to drop admin privileges! */
   1.700 -				m_Players[client].SetAdminId(INVALID_ADMIN_ID, false);
   1.701 -			}
   1.702 -		}
   1.703 -		m_Players[client].SetName(new_name);
   1.704 -	}
   1.705 -	
   1.706 -	if (m_PassInfoVar.size() > 0)
   1.707 -	{
   1.708 -		/* Try for a password change */
   1.709 -		const char *old_pass = m_Players[client].m_LastPassword.c_str();
   1.710 -		const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str());
   1.711 -		if (strcmp(old_pass, new_pass) != 0)
   1.712 -		{
   1.713 -			m_Players[client].m_LastPassword.assign(new_pass);
   1.714 -			if (m_Players[client].IsInGame() && m_Players[client].IsAuthorized())
   1.715 -			{
   1.716 -				/* If there is already an admin id assigned, this will just bail out. */
   1.717 -				m_Players[client].DoBasicAdminChecks();
   1.718 -			}
   1.719 -		}
   1.720 -	}
   1.721 -}
   1.722 -
   1.723 -int PlayerManager::GetMaxClients()
   1.724 -{
   1.725 -	return m_maxClients;
   1.726 -}
   1.727 -
   1.728 -CPlayer *PlayerManager::GetPlayerByIndex(int client) const
   1.729 -{
   1.730 -	if (client > m_maxClients || client < 1)
   1.731 -	{
   1.732 -		return NULL;
   1.733 -	}
   1.734 -	return &m_Players[client];
   1.735 -}
   1.736 -
   1.737 -int PlayerManager::GetNumPlayers()
   1.738 -{
   1.739 -	return m_PlayerCount;
   1.740 -}
   1.741 -
   1.742 -int PlayerManager::GetClientOfUserId(int userid)
   1.743 -{
   1.744 -	if (userid < 0 || userid > USHRT_MAX)
   1.745 -	{
   1.746 -		return 0;
   1.747 -	}
   1.748 -	
   1.749 -	int client = m_UserIdLookUp[userid];
   1.750 -
   1.751 -	/* Verify the userid.  The cache can get messed up with older
   1.752 -	 * Valve engines.  :TODO: If this gets fixed, do an old engine 
   1.753 -	 * check before invoking this backwards compat code.
   1.754 -	 */
   1.755 -	if (client)
   1.756 -	{
   1.757 -		CPlayer *player = GetPlayerByIndex(client);
   1.758 -		if (player && player->IsConnected())
   1.759 -		{
   1.760 -			int realUserId = engine->GetPlayerUserId(player->GetEdict());
   1.761 -			if (realUserId == userid)
   1.762 -			{
   1.763 -				return client;
   1.764 -			}
   1.765 -		}
   1.766 -	}
   1.767 -
   1.768 -	/* If we can't verify the userid, we have to do a manual loop */
   1.769 -	CPlayer *player;
   1.770 -	for (int i = 1; i <= m_maxClients; i++)
   1.771 -	{
   1.772 -		player = GetPlayerByIndex(i);
   1.773 -		if (!player || !player->IsConnected())
   1.774 -		{
   1.775 -			continue;
   1.776 -		}
   1.777 -		if (engine->GetPlayerUserId(player->GetEdict()) == userid)
   1.778 -		{
   1.779 -			m_UserIdLookUp[userid] = i;
   1.780 -			return i;
   1.781 -		}
   1.782 -	}
   1.783 -
   1.784 -	return 0;
   1.785 -}
   1.786 -
   1.787 -void PlayerManager::AddClientListener(IClientListener *listener)
   1.788 -{
   1.789 -	m_hooks.push_back(listener);
   1.790 -}
   1.791 -
   1.792 -void PlayerManager::RemoveClientListener(IClientListener *listener)
   1.793 -{
   1.794 -	m_hooks.remove(listener);
   1.795 -}
   1.796 -
   1.797 -IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict)
   1.798 -{
   1.799 -	int index = engine->IndexOfEdict(pEdict);
   1.800 -	return GetGamePlayer(index);
   1.801 -}
   1.802 -
   1.803 -IGamePlayer *PlayerManager::GetGamePlayer(int client)
   1.804 -{
   1.805 -	return GetPlayerByIndex(client);
   1.806 -}
   1.807 -
   1.808 -void PlayerManager::ClearAdminId(AdminId id)
   1.809 -{
   1.810 -	for (int i=1; i<=m_maxClients; i++)
   1.811 -	{
   1.812 -		if (m_Players[i].m_Admin == id)
   1.813 -		{
   1.814 -			m_Players[i].DumpAdmin(true);
   1.815 -		}
   1.816 -	}
   1.817 -}
   1.818 -
   1.819 -void PlayerManager::ClearAllAdmins()
   1.820 -{
   1.821 -	for (int i=1; i<=m_maxClients; i++)
   1.822 -	{
   1.823 -		m_Players[i].DumpAdmin(true);
   1.824 -	}
   1.825 -}
   1.826 -
   1.827 -const char *PlayerManager::GetPassInfoVar()
   1.828 -{
   1.829 -	return m_PassInfoVar.c_str();
   1.830 -}
   1.831 -
   1.832 -void PlayerManager::RecheckAnyAdmins()
   1.833 -{
   1.834 -	for (int i=1; i<=m_maxClients; i++)
   1.835 -	{
   1.836 -		if (m_Players[i].IsInGame() && m_Players[i].IsAuthorized())
   1.837 -		{
   1.838 -			m_Players[i].DoBasicAdminChecks();
   1.839 -		}
   1.840 -	}
   1.841 -}
   1.842 -
   1.843 -unsigned int PlayerManager::GetReplyTo()
   1.844 -{
   1.845 -	return g_ChatTriggers.GetReplyTo();
   1.846 -}
   1.847 -
   1.848 -unsigned int PlayerManager::SetReplyTo(unsigned int reply)
   1.849 -{
   1.850 -	return g_ChatTriggers.SetReplyTo(reply);
   1.851 -}
   1.852 -
   1.853 -int PlayerManager::FilterCommandTarget(IGamePlayer *pAdmin, IGamePlayer *pTarget, int flags)
   1.854 -{
   1.855 -	return InternalFilterCommandTarget((CPlayer *)pAdmin, (CPlayer *)pTarget, flags);
   1.856 -}
   1.857 -
   1.858 -void PlayerManager::RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler)
   1.859 -{
   1.860 -	target_processors.push_back(pHandler);
   1.861 -}
   1.862 -
   1.863 -void PlayerManager::UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler)
   1.864 -{
   1.865 -	target_processors.remove(pHandler);
   1.866 -}
   1.867 -
   1.868 -int PlayerManager::InternalFilterCommandTarget(CPlayer *pAdmin, CPlayer *pTarget, int flags)
   1.869 -{
   1.870 -	if ((flags & COMMAND_FILTER_CONNECTED) == COMMAND_FILTER_CONNECTED
   1.871 -		&& !pTarget->IsConnected())
   1.872 -	{
   1.873 -		return COMMAND_TARGET_NONE;
   1.874 -	}
   1.875 -	else if ((flags & COMMAND_FILTER_CONNECTED) != COMMAND_FILTER_CONNECTED && 
   1.876 -		!pTarget->IsInGame())
   1.877 -	{
   1.878 -		return COMMAND_TARGET_NOT_IN_GAME;
   1.879 -	}
   1.880 -
   1.881 -	if ((flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS
   1.882 -		&& pTarget->IsFakeClient())
   1.883 -	{
   1.884 -		return COMMAND_TARGET_NOT_HUMAN;
   1.885 -	}
   1.886 -
   1.887 -	if (pAdmin != NULL)
   1.888 -	{
   1.889 -		if ((flags & COMMAND_FILTER_NO_IMMUNITY) != COMMAND_FILTER_NO_IMMUNITY
   1.890 -			&& !g_Admins.CanAdminTarget(pAdmin->GetAdminId(), pTarget->GetAdminId()))
   1.891 -		{
   1.892 -			return COMMAND_TARGET_IMMUNE;
   1.893 -		}
   1.894 -	}
   1.895 -
   1.896 -	if ((flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE 
   1.897 -		&& pTarget->GetLifeState() != PLAYER_LIFE_ALIVE)
   1.898 -	{
   1.899 -		return COMMAND_TARGET_NOT_ALIVE;
   1.900 -	}
   1.901 -
   1.902 -	if ((flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD
   1.903 -		&& pTarget->GetLifeState() != PLAYER_LIFE_DEAD)
   1.904 -	{
   1.905 -		return COMMAND_TARGET_NOT_DEAD;
   1.906 -	}
   1.907 -
   1.908 -	return COMMAND_TARGET_VALID;
   1.909 -}
   1.910 -
   1.911 -void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
   1.912 -{
   1.913 -	CPlayer *pTarget, *pAdmin;
   1.914 -	int max_clients, total = 0;
   1.915 -
   1.916 -	max_clients = GetMaxClients();
   1.917 -
   1.918 -	if (info->max_targets < 1)
   1.919 -	{
   1.920 -		info->reason = COMMAND_TARGET_NONE;
   1.921 -		info->num_targets = 0;
   1.922 -	}
   1.923 -
   1.924 -	if (info->admin == 0)
   1.925 -	{
   1.926 -		pAdmin = NULL;
   1.927 -	}
   1.928 -	else
   1.929 -	{
   1.930 -		pAdmin = GetPlayerByIndex(info->admin);
   1.931 -	}
   1.932 -
   1.933 -	if (info->pattern[0] == '#')
   1.934 -	{
   1.935 -		int userid = atoi(&info->pattern[1]);
   1.936 -		int client = GetClientOfUserId(userid);
   1.937 -
   1.938 -		/* See if a valid userid matched */
   1.939 -		if (client > 0)
   1.940 -		{
   1.941 -			IGamePlayer *pTarget = GetPlayerByIndex(client);
   1.942 -			if (pTarget != NULL)
   1.943 -			{
   1.944 -				if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags)) == COMMAND_TARGET_VALID)
   1.945 -				{
   1.946 -					info->targets[0] = client;
   1.947 -					info->num_targets = 1;
   1.948 -					strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
   1.949 -					info->target_name_style = COMMAND_TARGETNAME_RAW;
   1.950 -				}
   1.951 -				else
   1.952 -				{
   1.953 -					info->num_targets = 0;
   1.954 -				}
   1.955 -				return;
   1.956 -			}
   1.957 -		}
   1.958 -
   1.959 -		/* Do we need to look for a steam id? */
   1.960 -		if (strncmp(&info->pattern[1], "STEAM_", 6) == 0)
   1.961 -		{
   1.962 -			size_t p, len;
   1.963 -			char new_pattern[256];
   1.964 -
   1.965 -			strcpy(new_pattern, "STEAM_");
   1.966 -			len = strlen(&info->pattern[7]);
   1.967 -			for (p = 0; p < len; p++)
   1.968 -			{
   1.969 -				new_pattern[6 + p] = info->pattern[7 + p];
   1.970 -				if (new_pattern[6 + p] == '_')
   1.971 -				{
   1.972 -					new_pattern[6 + p] = ':';
   1.973 -				}
   1.974 -			}
   1.975 -			new_pattern[6 + p] = '\0';
   1.976 -
   1.977 -			for (int i = 1; i <= max_clients; i++)
   1.978 -			{
   1.979 -				if ((pTarget = GetPlayerByIndex(i)) == NULL)
   1.980 -				{
   1.981 -					continue;
   1.982 -				}
   1.983 -				if (!pTarget->IsConnected() || !pTarget->IsAuthorized())
   1.984 -				{
   1.985 -					continue;
   1.986 -				}
   1.987 -				if (strcmp(pTarget->GetAuthString(), new_pattern) == 0)
   1.988 -				{
   1.989 -					if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
   1.990 -						== COMMAND_TARGET_VALID)
   1.991 -					{
   1.992 -						info->targets[0] = i;
   1.993 -						info->num_targets = 1;
   1.994 -						strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
   1.995 -						info->target_name_style = COMMAND_TARGETNAME_RAW;
   1.996 -					}
   1.997 -					else
   1.998 -					{
   1.999 -						info->num_targets = 0;
  1.1000 -					}
  1.1001 -					return;
  1.1002 -				}
  1.1003 -			}
  1.1004 -		}
  1.1005 -
  1.1006 -		/* See if an exact name matches */
  1.1007 -		for (int i = 1; i <= max_clients; i++)
  1.1008 -		{
  1.1009 -			if ((pTarget = GetPlayerByIndex(i)) == NULL)
  1.1010 -			{
  1.1011 -				continue;
  1.1012 -			}
  1.1013 -			if  (!pTarget->IsConnected())
  1.1014 -			{
  1.1015 -				continue;
  1.1016 -			}
  1.1017 -			if (strcmp(pTarget->GetName(), &info->pattern[1]) == 0)
  1.1018 -			{
  1.1019 -				if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
  1.1020 -					== COMMAND_TARGET_VALID)
  1.1021 -				{
  1.1022 -					info->targets[0] = i;
  1.1023 -					info->num_targets = 1;
  1.1024 -					strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
  1.1025 -					info->target_name_style = COMMAND_TARGETNAME_RAW;
  1.1026 -				}
  1.1027 -				else
  1.1028 -				{
  1.1029 -					info->num_targets = 0;
  1.1030 -				}
  1.1031 -				return;
  1.1032 -			}
  1.1033 -		}
  1.1034 -	}
  1.1035 -
  1.1036 -	if (strcmp(info->pattern, "@me") == 0 && info->admin != 0)
  1.1037 -	{
  1.1038 -		info->targets[0] = info->admin;
  1.1039 -		info->num_targets = 1;
  1.1040 -		strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
  1.1041 -		info->target_name_style = COMMAND_TARGETNAME_RAW;
  1.1042 -		return;
  1.1043 -	}
  1.1044 -
  1.1045 -	if ((info->flags & COMMAND_FILTER_NO_MULTI) != COMMAND_FILTER_NO_MULTI)
  1.1046 -	{
  1.1047 -		bool is_multi = false;
  1.1048 -		bool bots_only = false;
  1.1049 -		int skip_client = -1;
  1.1050 -
  1.1051 -		if (strcmp(info->pattern, "@all") == 0)
  1.1052 -		{
  1.1053 -			is_multi = true;
  1.1054 -			strncopy(info->target_name, "all players", info->target_name_maxlength);
  1.1055 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1056 -		}
  1.1057 -		else if (strcmp(info->pattern, "@dead") == 0)
  1.1058 -		{
  1.1059 -			is_multi = true;
  1.1060 -			if ((info->flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE)
  1.1061 -			{
  1.1062 -				info->num_targets = 0;
  1.1063 -				info->reason = COMMAND_TARGET_NOT_ALIVE;
  1.1064 -				return;
  1.1065 -			}
  1.1066 -			info->flags |= COMMAND_FILTER_DEAD;
  1.1067 -			strncopy(info->target_name, "all dead players", info->target_name_maxlength);
  1.1068 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1069 -		}
  1.1070 -		else if (strcmp(info->pattern, "@alive") == 0)
  1.1071 -		{
  1.1072 -			is_multi = true;
  1.1073 -			if ((info->flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD)
  1.1074 -			{
  1.1075 -				info->num_targets = 0;
  1.1076 -				info->reason = COMMAND_TARGET_NOT_DEAD;
  1.1077 -				return;
  1.1078 -			}
  1.1079 -			strncopy(info->target_name, "all alive players", info->target_name_maxlength);
  1.1080 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1081 -			info->flags |= COMMAND_FILTER_ALIVE;
  1.1082 -		}
  1.1083 -		else if (strcmp(info->pattern, "@bots") == 0)
  1.1084 -		{
  1.1085 -			is_multi = true;
  1.1086 -			if ((info->flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS)
  1.1087 -			{
  1.1088 -				info->num_targets = 0;
  1.1089 -				info->reason = COMMAND_FILTER_NO_BOTS;
  1.1090 -				return;
  1.1091 -			}
  1.1092 -			strncopy(info->target_name, "all bots", info->target_name_maxlength);
  1.1093 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1094 -			bots_only = true;
  1.1095 -		}
  1.1096 -		else if (strcmp(info->pattern, "@humans") == 0)
  1.1097 -		{
  1.1098 -			is_multi = true;
  1.1099 -			strncopy(info->target_name, "all humans", info->target_name_maxlength);
  1.1100 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1101 -			info->flags |= COMMAND_FILTER_NO_BOTS;
  1.1102 -		}
  1.1103 -		else if (strcmp(info->pattern, "@!me") == 0)
  1.1104 -		{
  1.1105 -			is_multi = true;
  1.1106 -			strncopy(info->target_name, "all players", info->target_name_maxlength);
  1.1107 -			info->target_name_style = COMMAND_TARGETNAME_ML;
  1.1108 -			skip_client = info->admin;
  1.1109 -		}
  1.1110 -
  1.1111 -		if (is_multi)
  1.1112 -		{
  1.1113 -			for (int i = 1; i <= max_clients && total < info->max_targets; i++)
  1.1114 -			{
  1.1115 -				if ((pTarget = GetPlayerByIndex(i)) == NULL)
  1.1116 -				{
  1.1117 -					continue;
  1.1118 -				}
  1.1119 -				if (FilterCommandTarget(pAdmin, pTarget, info->flags) > 0)
  1.1120 -				{
  1.1121 -					if ((!bots_only || pTarget->IsFakeClient())
  1.1122 -						&& skip_client != i)
  1.1123 -					{
  1.1124 -						info->targets[total++] = i;
  1.1125 -					}
  1.1126 -				}
  1.1127 -			}
  1.1128 -
  1.1129 -			info->num_targets = total;
  1.1130 -			info->reason = (info->num_targets) ? COMMAND_TARGET_VALID : COMMAND_TARGET_EMPTY_FILTER;
  1.1131 -			return;
  1.1132 -		}
  1.1133 -	}
  1.1134 -
  1.1135 -	List<ICommandTargetProcessor *>::iterator iter;
  1.1136 -	for (iter = target_processors.begin(); iter != target_processors.end(); iter++)
  1.1137 -	{
  1.1138 -		ICommandTargetProcessor *pProcessor = (*iter);
  1.1139 -		if (pProcessor->ProcessCommandTarget(info))
  1.1140 -		{
  1.1141 -			return;
  1.1142 -		}
  1.1143 -	}
  1.1144 -
  1.1145 -	/* Check partial names */
  1.1146 -	int found_client = 0;
  1.1147 -	CPlayer *pFoundClient = NULL;
  1.1148 -	for (int i = 1; i <= max_clients; i++)
  1.1149 -	{
  1.1150 -		if ((pTarget = GetPlayerByIndex(i)) == NULL)
  1.1151 -		{
  1.1152 -			continue;
  1.1153 -		}
  1.1154 -
  1.1155 -		if (stristr(pTarget->GetName(), info->pattern) != NULL)
  1.1156 -		{
  1.1157 -			if (found_client)
  1.1158 -			{
  1.1159 -				info->num_targets = 0;
  1.1160 -				info->reason = COMMAND_TARGET_AMBIGUOUS;
  1.1161 -				return;
  1.1162 -			}
  1.1163 -			else
  1.1164 -			{
  1.1165 -				found_client = i;
  1.1166 -				pFoundClient = pTarget;
  1.1167 -			}
  1.1168 -		}
  1.1169 -	}
  1.1170 -
  1.1171 -	if (found_client)
  1.1172 -	{
  1.1173 -		if ((info->reason = FilterCommandTarget(pAdmin, pFoundClient, info->flags)) 
  1.1174 -			== COMMAND_TARGET_VALID)
  1.1175 -		{
  1.1176 -			info->targets[0] = found_client;
  1.1177 -			info->num_targets = 1;
  1.1178 -			strncopy(info->target_name, pFoundClient->GetName(), info->target_name_maxlength);
  1.1179 -			info->target_name_style = COMMAND_TARGETNAME_RAW;
  1.1180 -		}
  1.1181 -		else
  1.1182 -		{
  1.1183 -			info->num_targets = 0;
  1.1184 -		}
  1.1185 -	}
  1.1186 -	else
  1.1187 -	{
  1.1188 -		info->num_targets = 0;
  1.1189 -		info->reason = COMMAND_TARGET_NONE;
  1.1190 -	}
  1.1191 -}
  1.1192 -
  1.1193 -/*******************
  1.1194 - *** PLAYER CODE ***
  1.1195 - *******************/
  1.1196 -
  1.1197 -CPlayer::CPlayer()
  1.1198 -{
  1.1199 -	m_IsConnected = false;
  1.1200 -	m_IsInGame = false;
  1.1201 -	m_IsAuthorized = false;
  1.1202 -	m_pEdict = NULL;
  1.1203 -	m_Admin = INVALID_ADMIN_ID;
  1.1204 -	m_TempAdmin = false;
  1.1205 -	m_Info = NULL;
  1.1206 -	m_bAdminCheckSignalled = false;
  1.1207 -	m_bIsInKickQueue = false;
  1.1208 -	m_LastPassword.clear();
  1.1209 -	m_LangId = SOURCEMOD_LANGUAGE_ENGLISH;
  1.1210 -}
  1.1211 -
  1.1212 -void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
  1.1213 -{
  1.1214 -	m_IsConnected = true;
  1.1215 -	m_Name.assign(name);
  1.1216 -	m_Ip.assign(ip);
  1.1217 -	m_pEdict = pEntity;
  1.1218 -	m_iIndex = engine->IndexOfEdict(pEntity);
  1.1219 -	m_LangId = g_Translator.GetServerLanguage();
  1.1220 -
  1.1221 -	char ip2[24], *ptr;
  1.1222 -	strncopy(ip2, ip, sizeof(ip2));
  1.1223 -	if ((ptr = strchr(ip2, ':')) != NULL)
  1.1224 -	{
  1.1225 -		*ptr = '\0';
  1.1226 -	}
  1.1227 -	m_IpNoPort.assign(ip2);
  1.1228 -}
  1.1229 -
  1.1230 -void CPlayer::Connect()
  1.1231 -{
  1.1232 -	if (m_IsInGame)
  1.1233 -	{
  1.1234 -		return;
  1.1235 -	}
  1.1236 -
  1.1237 -	m_IsInGame = true;
  1.1238 -
  1.1239 -	const char *var = g_Players.GetPassInfoVar();
  1.1240 -	int client = engine->IndexOfEdict(m_pEdict);
  1.1241 -	if (var[0] != '\0')
  1.1242 -	{
  1.1243 -		const char *pass = engine->GetClientConVarValue(client, var);
  1.1244 -		m_LastPassword.assign(pass ? pass : "");
  1.1245 -	}
  1.1246 -	else
  1.1247 -	{
  1.1248 -		m_LastPassword.assign("");
  1.1249 -	}
  1.1250 -}
  1.1251 -
  1.1252 -void CPlayer::Authorize(const char *steamid)
  1.1253 -{
  1.1254 -	if (m_IsAuthorized)
  1.1255 -	{
  1.1256 -		return;
  1.1257 -	}
  1.1258 -
  1.1259 -	m_IsAuthorized = true;
  1.1260 -	m_AuthID.assign(steamid);
  1.1261 -}
  1.1262 -
  1.1263 -void CPlayer::Disconnect()
  1.1264 -{
  1.1265 -	DumpAdmin(false);
  1.1266 -	m_IsConnected = false;
  1.1267 -	m_IsInGame = false;
  1.1268 -	m_IsAuthorized = false;
  1.1269 -	m_Name.clear();
  1.1270 -	m_Ip.clear();
  1.1271 -	m_AuthID.clear();
  1.1272 -	m_pEdict = NULL;
  1.1273 -	m_Info = NULL;
  1.1274 -	m_bAdminCheckSignalled = false;
  1.1275 -	m_UserId = -1;
  1.1276 -	m_bIsInKickQueue = false;
  1.1277 -}
  1.1278 -
  1.1279 -void CPlayer::SetName(const char *name)
  1.1280 -{
  1.1281 -	m_Name.assign(name);
  1.1282 -}
  1.1283 -
  1.1284 -const char *CPlayer::GetName()
  1.1285 -{
  1.1286 -	if (m_Info && m_pEdict->GetUnknown())
  1.1287 -	{
  1.1288 -		return m_Info->GetName();
  1.1289 -	}
  1.1290 -	
  1.1291 -	return m_Name.c_str();
  1.1292 -}
  1.1293 -
  1.1294 -const char *CPlayer::GetIPAddress()
  1.1295 -{
  1.1296 -	return m_Ip.c_str();
  1.1297 -}
  1.1298 -
  1.1299 -const char *CPlayer::GetAuthString()
  1.1300 -{
  1.1301 -	return m_AuthID.c_str();
  1.1302 -}
  1.1303 -
  1.1304 -edict_t *CPlayer::GetEdict()
  1.1305 -{
  1.1306 -	return m_pEdict;
  1.1307 -}
  1.1308 -
  1.1309 -bool CPlayer::IsInGame()
  1.1310 -{
  1.1311 -	return m_IsInGame && (m_pEdict->GetUnknown() != NULL);
  1.1312 -}
  1.1313 -
  1.1314 -bool CPlayer::WasCountedAsInGame()
  1.1315 -{
  1.1316 -	return m_IsInGame;
  1.1317 -}
  1.1318 -
  1.1319 -bool CPlayer::IsConnected()
  1.1320 -{
  1.1321 -	return m_IsConnected;
  1.1322 -}
  1.1323 -
  1.1324 -bool CPlayer::IsAuthorized()
  1.1325 -{
  1.1326 -	return m_IsAuthorized;
  1.1327 -}
  1.1328 -
  1.1329 -IPlayerInfo *CPlayer::GetPlayerInfo()
  1.1330 -{
  1.1331 -	if (m_pEdict->GetUnknown())
  1.1332 -	{
  1.1333 -		return m_Info;
  1.1334 -	}
  1.1335 -
  1.1336 -	return NULL;
  1.1337 -}
  1.1338 -
  1.1339 -bool CPlayer::IsFakeClient()
  1.1340 -{
  1.1341 -	return (strncasecmp(m_AuthID.c_str(), "BOT", 3) == 0);
  1.1342 -}
  1.1343 -
  1.1344 -void CPlayer::SetAdminId(AdminId id, bool temporary)
  1.1345 -{
  1.1346 -	if (!m_IsConnected)
  1.1347 -	{
  1.1348 -		return;
  1.1349 -	}
  1.1350 -
  1.1351 -	DumpAdmin(false);
  1.1352 -
  1.1353 -	m_Admin = id;
  1.1354 -	m_TempAdmin = temporary;
  1.1355 -}
  1.1356 -
  1.1357 -AdminId CPlayer::GetAdminId()
  1.1358 -{
  1.1359 -	return m_Admin;
  1.1360 -}
  1.1361 -
  1.1362 -void CPlayer::DumpAdmin(bool deleting)
  1.1363 -{
  1.1364 -	if (m_Admin != INVALID_ADMIN_ID)
  1.1365 -	{
  1.1366 -		if (m_TempAdmin && !deleting)
  1.1367 -		{
  1.1368 -			g_Admins.InvalidateAdmin(m_Admin);
  1.1369 -		}
  1.1370 -		m_Admin = INVALID_ADMIN_ID;
  1.1371 -		m_TempAdmin = false;
  1.1372 -	}
  1.1373 -}
  1.1374 -
  1.1375 -void CPlayer::Kick(const char *str)
  1.1376 -{
  1.1377 -	MarkAsBeingKicked();
  1.1378 -	INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex));
  1.1379 -	IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
  1.1380 -	pClient->Disconnect("%s", str);
  1.1381 -}
  1.1382 -
  1.1383 -void CPlayer::Authorize_Post()
  1.1384 -{
  1.1385 -	if (m_IsInGame)
  1.1386 -	{
  1.1387 -		DoPostConnectAuthorization();
  1.1388 -	}
  1.1389 -}
  1.1390 -
  1.1391 -void CPlayer::DoPostConnectAuthorization()
  1.1392 -{
  1.1393 -	bool delay = false;
  1.1394 -
  1.1395 -	List<IClientListener *>::iterator iter;
  1.1396 -	for (iter = g_Players.m_hooks.begin();
  1.1397 -		 iter != g_Players.m_hooks.end();
  1.1398 -		 iter++)
  1.1399 -	{
  1.1400 -		IClientListener *pListener = (*iter);
  1.1401 -#if defined MIN_API_FOR_ADMINCALLS
  1.1402 -		if (pListener->GetClientListenerVersion() < MIN_API_FOR_ADMINCALLS)
  1.1403 -		{
  1.1404 -			continue;
  1.1405 -		}
  1.1406 -#endif
  1.1407 -		if (!pListener->OnClientPreAdminCheck(m_iIndex))
  1.1408 -		{
  1.1409 -			delay = true;
  1.1410 -		}
  1.1411 -	}
  1.1412 -	
  1.1413 -	cell_t result = 0;
  1.1414 -	PreAdminCheck->PushCell(m_iIndex);
  1.1415 -	PreAdminCheck->Execute(&result);
  1.1416 -
  1.1417 -	/* Defer, for better or worse */
  1.1418 -	if (delay || (ResultType)result >= Pl_Handled)
  1.1419 -	{
  1.1420 -		return;
  1.1421 -	}
  1.1422 -
  1.1423 -	/* Sanity check */
  1.1424 -	if (!IsConnected())
  1.1425 -	{
  1.1426 -		return;
  1.1427 -	}
  1.1428 -
  1.1429 -	/* Otherwise, go ahead and do admin checks */
  1.1430 -	DoBasicAdminChecks();
  1.1431 -
  1.1432 -	/* Send the notification out */
  1.1433 -	NotifyPostAdminChecks();
  1.1434 -}
  1.1435 -
  1.1436 -bool CPlayer::RunAdminCacheChecks()
  1.1437 -{
  1.1438 -	AdminId old_id = GetAdminId();
  1.1439 -
  1.1440 -	DoBasicAdminChecks();
  1.1441 -
  1.1442 -	return (GetAdminId() != old_id);
  1.1443 -}
  1.1444 -
  1.1445 -void CPlayer::NotifyPostAdminChecks()
  1.1446 -{
  1.1447 -	if (m_bAdminCheckSignalled)
  1.1448 -	{
  1.1449 -		return;
  1.1450 -	}
  1.1451 -
  1.1452 -	/* Block beforehand so they can't double-call */
  1.1453 -	m_bAdminCheckSignalled = true;
  1.1454 -
  1.1455 -	List<IClientListener *>::iterator iter;
  1.1456 -	for (iter = g_Players.m_hooks.begin();
  1.1457 -		iter != g_Players.m_hooks.end();
  1.1458 -		iter++)
  1.1459 -	{
  1.1460 -		IClientListener *pListener = (*iter);
  1.1461 -#if defined MIN_API_FOR_ADMINCALLS
  1.1462 -		if (pListener->GetClientListenerVersion() < MIN_API_FOR_ADMINCALLS)
  1.1463 -		{
  1.1464 -			continue;
  1.1465 -		}
  1.1466 -#endif
  1.1467 -		pListener->OnClientPostAdminCheck(m_iIndex);
  1.1468 -	}
  1.1469 -
  1.1470 -	PostAdminFilter->PushCell(m_iIndex);
  1.1471 -	PostAdminFilter->Execute(NULL);
  1.1472 -
  1.1473 -	PostAdminCheck->PushCell(m_iIndex);
  1.1474 -	PostAdminCheck->Execute(NULL);
  1.1475 -}
  1.1476 -
  1.1477 -void CPlayer::DoBasicAdminChecks()
  1.1478 -{
  1.1479 -	if (GetAdminId() != INVALID_ADMIN_ID)
  1.1480 -	{
  1.1481 -		return;
  1.1482 -	}
  1.1483 -
  1.1484 -	/* First check the name */
  1.1485 -	AdminId id;
  1.1486 -	int client = engine->IndexOfEdict(m_pEdict);
  1.1487 -
  1.1488 -	if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
  1.1489 -	{
  1.1490 -		if (!g_Players.CheckSetAdminName(client, this, id))
  1.1491 -		{
  1.1492 -			int userid = engine->GetPlayerUserId(m_pEdict);
  1.1493 -			g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
  1.1494 -		}
  1.1495 -		return;
  1.1496 -	}
  1.1497 -	
  1.1498 -	/* Check IP */
  1.1499 -	if ((id = g_Admins.FindAdminByIdentity("ip", m_IpNoPort.c_str())) != INVALID_ADMIN_ID)
  1.1500 -	{
  1.1501 -		if (g_Players.CheckSetAdmin(client, this, id))
  1.1502 -		{
  1.1503 -			return;
  1.1504 -		}
  1.1505 -	}
  1.1506 -
  1.1507 -	/* Check IP address */
  1.1508 -	if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
  1.1509 -	{
  1.1510 -		if (g_Players.CheckSetAdmin(client, this, id))
  1.1511 -		{
  1.1512 -			return;
  1.1513 -		}
  1.1514 -	}
  1.1515 -}
  1.1516 -
  1.1517 -unsigned int CPlayer::GetLanguageId()
  1.1518 -{
  1.1519 -	return m_LangId;
  1.1520 -}
  1.1521 -
  1.1522 -int CPlayer::GetUserId()
  1.1523 -{
  1.1524 -	if (m_UserId == -1)
  1.1525 -	{
  1.1526 -		m_UserId = engine->GetPlayerUserId(GetEdict());
  1.1527 -	}
  1.1528 -
  1.1529 -	return m_UserId;
  1.1530 -}
  1.1531 -
  1.1532 -bool CPlayer::IsInKickQueue()
  1.1533 -{
  1.1534 -	return m_bIsInKickQueue;
  1.1535 -}
  1.1536 -
  1.1537 -void CPlayer::MarkAsBeingKicked()
  1.1538 -{
  1.1539 -	m_bIsInKickQueue = true;
  1.1540 -}
  1.1541 -
  1.1542 -int CPlayer::GetLifeState()
  1.1543 -{
  1.1544 -	if (lifestate_offset == -1)
  1.1545 -	{
  1.1546 -		if (!g_pGameConf->GetOffset("m_lifeState", &lifestate_offset))
  1.1547 -		{
  1.1548 -			lifestate_offset = -2;
  1.1549 -		}
  1.1550 -	}
  1.1551 -
  1.1552 -	if (lifestate_offset < 0)
  1.1553 -	{
  1.1554 -		IPlayerInfo *info = GetPlayerInfo();
  1.1555 -		if (info == NULL)
  1.1556 -		{
  1.1557 -			return PLAYER_LIFE_UNKNOWN;
  1.1558 -		}
  1.1559 -		return info->IsDead() ? PLAYER_LIFE_DEAD : PLAYER_LIFE_ALIVE;
  1.1560 -	}
  1.1561 -
  1.1562 -	if (m_pEdict == NULL)
  1.1563 -	{
  1.1564 -		return PLAYER_LIFE_UNKNOWN;
  1.1565 -	}
  1.1566 -
  1.1567 -	CBaseEntity *pEntity;
  1.1568 -	IServerUnknown *pUnknown = m_pEdict->GetUnknown();
  1.1569 -	if (pUnknown == NULL || (pEntity = pUnknown->GetBaseEntity()) == NULL)
  1.1570 -	{
  1.1571 -		return PLAYER_LIFE_UNKNOWN;
  1.1572 -	}
  1.1573 -
  1.1574 -	if (*((uint8_t *)pEntity + lifestate_offset) == LIFE_ALIVE)
  1.1575 -	{
  1.1576 -		return PLAYER_LIFE_ALIVE;
  1.1577 -	}
  1.1578 -	else
  1.1579 -	{
  1.1580 -		return PLAYER_LIFE_DEAD;
  1.1581 -	}
  1.1582 -}