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 -}