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