core/PlayerManager.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
child 1993 8c08aaff4d39
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
ds@1952
     1
/**
ds@1952
     2
 * vim: set ts=4 :
ds@1952
     3
 * =============================================================================
ds@1952
     4
 * SourceMod
ds@1952
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1952
     6
 * =============================================================================
ds@1952
     7
 *
ds@1952
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1952
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1952
    10
 * Free Software Foundation.
ds@1952
    11
 * 
ds@1952
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1952
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1952
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1952
    15
 * details.
ds@1952
    16
 *
ds@1952
    17
 * You should have received a copy of the GNU General Public License along with
ds@1952
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
ds@1952
    19
 *
ds@1952
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1952
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1952
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1952
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1952
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1952
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1952
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1952
    27
 * or <http://www.sourcemod.net/license.php>.
ds@1952
    28
 *
ds@1952
    29
 * Version: $Id$
ds@1952
    30
 */
ds@1952
    31
ds@1952
    32
#include "PlayerManager.h"
ds@1952
    33
#include "ForwardSys.h"
ds@1952
    34
#include "ShareSys.h"
ds@1952
    35
#include "AdminCache.h"
ds@1952
    36
#include "ConCmdManager.h"
ds@1952
    37
#include "MenuStyle_Valve.h"
ds@1952
    38
#include "MenuStyle_Radio.h"
ds@1952
    39
#include "sm_stringutil.h"
ds@1952
    40
#include "CoreConfig.h"
ds@1952
    41
#include "TimerSys.h"
ds@1952
    42
#include "Translator.h"
ds@1952
    43
#include "Logger.h"
ds@1952
    44
#include "ChatTriggers.h"
ds@1952
    45
#include "HalfLife2.h"
ds@1952
    46
#include <inetchannel.h>
ds@1952
    47
#include <iclient.h>
ds@1952
    48
#include "GameConfigs.h"
ds@1952
    49
ds@1952
    50
PlayerManager g_Players;
ds@1952
    51
bool g_OnMapStarted = false;
ds@1952
    52
IForward *PreAdminCheck = NULL;
ds@1952
    53
IForward *PostAdminCheck = NULL;
ds@1952
    54
IForward *PostAdminFilter = NULL;
ds@1952
    55
const unsigned int *g_NumPlayersToAuth = NULL;
ds@1952
    56
int lifestate_offset = -1;
ds@1952
    57
List<ICommandTargetProcessor *> target_processors;
ds@1952
    58
ds@1952
    59
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
ds@1952
    60
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
ds@1952
    61
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
ds@1952
    62
#if defined ORANGEBOX_BUILD
ds@1952
    63
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
ds@1952
    64
#else
ds@1952
    65
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
ds@1952
    66
#endif
ds@1952
    67
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
ds@1952
    68
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
ds@1952
    69
ds@1952
    70
class KickPlayerTimer : public ITimedEvent
ds@1952
    71
{
ds@1952
    72
public:
ds@1952
    73
	ResultType OnTimer(ITimer *pTimer, void *pData)
ds@1952
    74
	{
ds@1952
    75
		int userid = (int)pData;
ds@1952
    76
		int client = g_Players.GetClientOfUserId(userid);
ds@1952
    77
		if (client)
ds@1952
    78
		{
ds@1952
    79
			CPlayer *player = g_Players.GetPlayerByIndex(client);
ds@1952
    80
			player->Kick("Your name is reserved by SourceMod; set your password to use it.");
ds@1952
    81
		}
ds@1952
    82
		return Pl_Stop;
ds@1952
    83
	}
ds@1952
    84
	void OnTimerEnd(ITimer *pTimer, void *pData)
ds@1952
    85
	{
ds@1952
    86
	}
ds@1952
    87
} s_KickPlayerTimer;
ds@1952
    88
ds@1952
    89
PlayerManager::PlayerManager()
ds@1952
    90
{
ds@1952
    91
	m_AuthQueue = NULL;
ds@1952
    92
	m_FirstPass = false;
ds@1952
    93
	m_maxClients = 0;
ds@1952
    94
ds@1952
    95
	m_UserIdLookUp = new int[USHRT_MAX+1];
ds@1952
    96
	memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
ds@1952
    97
}
ds@1952
    98
ds@1952
    99
PlayerManager::~PlayerManager()
ds@1952
   100
{
ds@1952
   101
	g_NumPlayersToAuth = NULL;
ds@1952
   102
ds@1952
   103
	delete [] m_AuthQueue;
ds@1952
   104
	delete [] m_UserIdLookUp;
ds@1952
   105
}
ds@1952
   106
ds@1952
   107
void PlayerManager::OnSourceModAllInitialized()
ds@1952
   108
{
ds@1952
   109
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
ds@1952
   110
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect_Post, true);
ds@1952
   111
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
ds@1952
   112
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
ds@1952
   113
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
ds@1952
   114
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
ds@1952
   115
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
ds@1952
   116
	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
ds@1952
   117
ds@1952
   118
	g_ShareSys.AddInterface(NULL, this);
ds@1952
   119
ds@1952
   120
	ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
ds@1952
   121
	ParamType p2[] = {Param_Cell};
ds@1952
   122
ds@1952
   123
	m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
ds@1952
   124
	m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
ds@1952
   125
	m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
ds@1952
   126
	m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
ds@1952
   127
	m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 2, NULL, Param_Cell, Param_Cell);
ds@1952
   128
	m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
ds@1952
   129
	m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
ds@1952
   130
	m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL);
ds@1952
   131
	m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL);
ds@1952
   132
ds@1952
   133
	PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1);
ds@1952
   134
	PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1);
ds@1952
   135
	PostAdminFilter = g_Forwards.CreateForward("OnClientPostAdminFilter", ET_Ignore, 1, p1);
ds@1952
   136
}
ds@1952
   137
ds@1952
   138
void PlayerManager::OnSourceModShutdown()
ds@1952
   139
{
ds@1952
   140
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
ds@1952
   141
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
ds@1952
   142
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
ds@1952
   143
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
ds@1952
   144
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
ds@1952
   145
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
ds@1952
   146
	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
ds@1952
   147
ds@1952
   148
	/* Release forwards */
ds@1952
   149
	g_Forwards.ReleaseForward(m_clconnect);
ds@1952
   150
	g_Forwards.ReleaseForward(m_clputinserver);
ds@1952
   151
	g_Forwards.ReleaseForward(m_cldisconnect);
ds@1952
   152
	g_Forwards.ReleaseForward(m_cldisconnect_post);
ds@1952
   153
	g_Forwards.ReleaseForward(m_clcommand);
ds@1952
   154
	g_Forwards.ReleaseForward(m_clinfochanged);
ds@1952
   155
	g_Forwards.ReleaseForward(m_clauth);
ds@1952
   156
	g_Forwards.ReleaseForward(m_onActivate);
ds@1952
   157
	g_Forwards.ReleaseForward(m_onActivate2);
ds@1952
   158
ds@1952
   159
	g_Forwards.ReleaseForward(PreAdminCheck);
ds@1952
   160
	g_Forwards.ReleaseForward(PostAdminCheck);
ds@1952
   161
	g_Forwards.ReleaseForward(PostAdminFilter);
ds@1952
   162
ds@1952
   163
	delete [] m_Players;
ds@1952
   164
}
ds@1952
   165
ds@1952
   166
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key, 
ds@1952
   167
												 const char *value, 
ds@1952
   168
												 ConfigSource source, 
ds@1952
   169
												 char *error, 
ds@1952
   170
												 size_t maxlength)
ds@1952
   171
{
ds@1952
   172
	if (strcmp(key, "PassInfoVar") == 0)
ds@1952
   173
	{
ds@1952
   174
		if (strcmp(value, "_password") != 0)
ds@1952
   175
		{
ds@1952
   176
			m_PassInfoVar.assign(value);
ds@1952
   177
		}
ds@1952
   178
		return ConfigResult_Accept;
ds@1952
   179
	} else if (strcmp(key, "AllowClLanguageVar") == 0) {
ds@1952
   180
		if (strcasecmp(value, "on") == 0)
ds@1952
   181
		{
ds@1952
   182
			m_QueryLang = true;
ds@1952
   183
		} else if (strcasecmp(value, "off") == 0) {
ds@1952
   184
			m_QueryLang = false;
ds@1952
   185
		} else {
ds@1952
   186
			UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
ds@1952
   187
			return ConfigResult_Reject;
ds@1952
   188
		}
ds@1952
   189
		return ConfigResult_Accept;
ds@1952
   190
	}
ds@1952
   191
	return ConfigResult_Ignore;
ds@1952
   192
}
ds@1952
   193
ds@1952
   194
void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
ds@1952
   195
{
ds@1952
   196
	if (!m_FirstPass)
ds@1952
   197
	{
ds@1952
   198
		/* Initialize all players */
ds@1952
   199
		m_maxClients = clientMax;
ds@1952
   200
		m_PlayerCount = 0;
ds@1952
   201
		m_Players = new CPlayer[m_maxClients + 1];
ds@1952
   202
		m_AuthQueue = new unsigned int[m_maxClients + 1];
ds@1952
   203
		m_FirstPass = true;
ds@1952
   204
ds@1952
   205
		memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
ds@1952
   206
ds@1952
   207
		g_NumPlayersToAuth = &m_AuthQueue[0];
ds@1952
   208
	}
ds@1952
   209
	m_onActivate->Execute(NULL);
ds@1952
   210
	m_onActivate2->Execute(NULL);
ds@1952
   211
ds@1952
   212
	List<IClientListener *>::iterator iter;
ds@1952
   213
	for (iter = m_hooks.begin(); iter != m_hooks.end(); iter++)
ds@1952
   214
	{
ds@1952
   215
		if ((*iter)->GetClientListenerVersion() >= 5)
ds@1952
   216
		{
ds@1952
   217
			(*iter)->OnServerActivated(clientMax);
ds@1952
   218
		}
ds@1952
   219
	}
ds@1952
   220
ds@1952
   221
	g_OnMapStarted = true;
ds@1952
   222
ds@1952
   223
	SM_ExecuteAllConfigs();
ds@1952
   224
}
ds@1952
   225
ds@1952
   226
bool PlayerManager::IsServerActivated()
ds@1952
   227
{
ds@1952
   228
	return m_FirstPass;
ds@1952
   229
}
ds@1952
   230
ds@1952
   231
bool PlayerManager::CheckSetAdmin(int index, CPlayer *pPlayer, AdminId id)
ds@1952
   232
{
ds@1952
   233
	const char *password = g_Admins.GetAdminPassword(id);
ds@1952
   234
	if (password != NULL)
ds@1952
   235
	{
ds@1952
   236
		if (m_PassInfoVar.size() < 1)
ds@1952
   237
		{
ds@1952
   238
			return false;
ds@1952
   239
		}
ds@1952
   240
ds@1952
   241
		/* Whoa... the user needs a password! */
ds@1952
   242
		const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
ds@1952
   243
		if (!given || strcmp(given, password) != 0)
ds@1952
   244
		{
ds@1952
   245
			return false;
ds@1952
   246
		}
ds@1952
   247
	}
ds@1952
   248
ds@1952
   249
	pPlayer->SetAdminId(id, false);
ds@1952
   250
ds@1952
   251
	return true;
ds@1952
   252
}
ds@1952
   253
ds@1952
   254
bool PlayerManager::CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id)
ds@1952
   255
{
ds@1952
   256
	const char *password = g_Admins.GetAdminPassword(id);
ds@1952
   257
	if (password == NULL)
ds@1952
   258
	{
ds@1952
   259
		return false;
ds@1952
   260
	}
ds@1952
   261
ds@1952
   262
	if (m_PassInfoVar.size() < 1)
ds@1952
   263
	{
ds@1952
   264
		return false;
ds@1952
   265
	}
ds@1952
   266
ds@1952
   267
	/* Whoa... the user needs a password! */
ds@1952
   268
	const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
ds@1952
   269
	if (!given || strcmp(given, password) != 0)
ds@1952
   270
	{
ds@1952
   271
		return false;
ds@1952
   272
	}
ds@1952
   273
ds@1952
   274
	pPlayer->SetAdminId(id, false);
ds@1952
   275
ds@1952
   276
	return true;
ds@1952
   277
}
ds@1952
   278
ds@1952
   279
void PlayerManager::RunAuthChecks()
ds@1952
   280
{
ds@1952
   281
	CPlayer *pPlayer;
ds@1952
   282
	const char *authstr;
ds@1952
   283
	unsigned int removed = 0;
ds@1952
   284
	for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
ds@1952
   285
	{
ds@1952
   286
		pPlayer = GetPlayerByIndex(m_AuthQueue[i]);
ds@1952
   287
		authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
ds@1952
   288
		if (authstr && authstr[0] != '\0'
ds@1952
   289
			&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
ds@1952
   290
		{
ds@1952
   291
			/* Set authorization */
ds@1952
   292
			pPlayer->Authorize(authstr);
ds@1952
   293
ds@1952
   294
			/* Mark as removed from queue */
ds@1952
   295
			unsigned int client = m_AuthQueue[i];
ds@1952
   296
			m_AuthQueue[i] = 0;
ds@1952
   297
			removed++;
ds@1952
   298
ds@1952
   299
			/* Send to extensions */
ds@1952
   300
			List<IClientListener *>::iterator iter;
ds@1952
   301
			IClientListener *pListener;
ds@1952
   302
			for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   303
			{
ds@1952
   304
				pListener = (*iter);
ds@1952
   305
				pListener->OnClientAuthorized(client, authstr);
ds@1952
   306
				if (!pPlayer->IsConnected())
ds@1952
   307
				{
ds@1952
   308
					break;
ds@1952
   309
				}
ds@1952
   310
			}
ds@1952
   311
ds@1952
   312
			/* Send to plugins if player is still connected */
ds@1952
   313
			if (pPlayer->IsConnected() && m_clauth->GetFunctionCount())
ds@1952
   314
			{
ds@1952
   315
				/* :TODO: handle the case of a player disconnecting in the middle */
ds@1952
   316
				m_clauth->PushCell(client);
ds@1952
   317
				m_clauth->PushString(authstr);
ds@1952
   318
				m_clauth->Execute(NULL);
ds@1952
   319
			}
ds@1952
   320
ds@1952
   321
			if (pPlayer->IsConnected())
ds@1952
   322
			{
ds@1952
   323
				pPlayer->Authorize_Post();
ds@1952
   324
			}
ds@1952
   325
		}
ds@1952
   326
	}
ds@1952
   327
ds@1952
   328
	/* Clean up the queue */
ds@1952
   329
	if (removed)
ds@1952
   330
	{
ds@1952
   331
		/* We don't have to compact the list if it's empty */
ds@1952
   332
		if (removed != m_AuthQueue[0])
ds@1952
   333
		{
ds@1952
   334
			unsigned int diff = 0;
ds@1952
   335
			for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
ds@1952
   336
			{
ds@1952
   337
				/* If this member is removed... */
ds@1952
   338
				if (m_AuthQueue[i] == 0)
ds@1952
   339
				{
ds@1952
   340
					/* Increase the differential */
ds@1952
   341
					diff++;
ds@1952
   342
				} else {
ds@1952
   343
					/* diff cannot increase faster than i+1 */
ds@1952
   344
					assert(i > diff);
ds@1952
   345
					assert(i - diff >= 1);
ds@1952
   346
					/* move this index down */
ds@1952
   347
					m_AuthQueue[i - diff] = m_AuthQueue[i];
ds@1952
   348
				}
ds@1952
   349
			}
ds@1952
   350
			m_AuthQueue[0] -= removed;
ds@1952
   351
		} else {
ds@1952
   352
			m_AuthQueue[0] = 0;
ds@1952
   353
		}
ds@1952
   354
	}
ds@1952
   355
}
ds@1952
   356
ds@1952
   357
bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
ds@1952
   358
{
ds@1952
   359
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   360
ds@1952
   361
	List<IClientListener *>::iterator iter;
ds@1952
   362
	IClientListener *pListener = NULL;
ds@1952
   363
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   364
	{
ds@1952
   365
		pListener = (*iter);
ds@1952
   366
		if (!pListener->InterceptClientConnect(client, reject, maxrejectlen))
ds@1952
   367
		{
ds@1952
   368
			return false;
ds@1952
   369
		}
ds@1952
   370
	}
ds@1952
   371
ds@1952
   372
	cell_t res = 1;
ds@1952
   373
ds@1952
   374
	m_Players[client].Initialize(pszName, pszAddress, pEntity);
ds@1952
   375
	m_clconnect->PushCell(client);
ds@1952
   376
	m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
ds@1952
   377
	m_clconnect->PushCell(maxrejectlen);
ds@1952
   378
	m_clconnect->Execute(&res, NULL);
ds@1952
   379
ds@1952
   380
	if (res)
ds@1952
   381
	{
ds@1952
   382
		if (!m_Players[client].IsAuthorized())
ds@1952
   383
		{
ds@1952
   384
			m_AuthQueue[++m_AuthQueue[0]] = client;
ds@1952
   385
		}
ds@1952
   386
	} else {
ds@1952
   387
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
ds@1952
   388
	}
ds@1952
   389
ds@1952
   390
	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = client;
ds@1952
   391
ds@1952
   392
	return true;
ds@1952
   393
}
ds@1952
   394
ds@1952
   395
bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
ds@1952
   396
{
ds@1952
   397
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   398
	bool orig_value = META_RESULT_ORIG_RET(bool);
ds@1952
   399
	CPlayer *pPlayer = GetPlayerByIndex(client);
ds@1952
   400
ds@1952
   401
	if (orig_value)
ds@1952
   402
	{
ds@1952
   403
		List<IClientListener *>::iterator iter;
ds@1952
   404
		IClientListener *pListener = NULL;
ds@1952
   405
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   406
		{
ds@1952
   407
			pListener = (*iter);
ds@1952
   408
			pListener->OnClientConnected(client);
ds@1952
   409
			if (!pPlayer->IsConnected())
ds@1952
   410
			{
ds@1952
   411
				break;
ds@1952
   412
			}
ds@1952
   413
		}
ds@1952
   414
	}
ds@1952
   415
ds@1952
   416
	return true;
ds@1952
   417
}
ds@1952
   418
ds@1952
   419
void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
ds@1952
   420
{
ds@1952
   421
	cell_t res;
ds@1952
   422
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   423
ds@1952
   424
	CPlayer *pPlayer = GetPlayerByIndex(client);
ds@1952
   425
	/* If they're not connected, they're a bot */
ds@1952
   426
	if (!pPlayer->IsConnected())
ds@1952
   427
	{
ds@1952
   428
		/* Run manual connection routines */
ds@1952
   429
		char error[255];
ds@1952
   430
		const char *authid = engine->GetPlayerNetworkIDString(pEntity);
ds@1952
   431
		pPlayer->Authorize(authid);
ds@1952
   432
		if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
ds@1952
   433
		{
ds@1952
   434
			/* :TODO: kick the bot if it's rejected */
ds@1952
   435
			return;
ds@1952
   436
		}
ds@1952
   437
		List<IClientListener *>::iterator iter;
ds@1952
   438
		IClientListener *pListener = NULL;
ds@1952
   439
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   440
		{
ds@1952
   441
			pListener = (*iter);
ds@1952
   442
			pListener->OnClientConnected(client);
ds@1952
   443
			/* See if bot was kicked */
ds@1952
   444
			if (!pPlayer->IsConnected())
ds@1952
   445
			{
ds@1952
   446
				return;
ds@1952
   447
			}
ds@1952
   448
		}
ds@1952
   449
		/* Now do authorization */
ds@1952
   450
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   451
		{
ds@1952
   452
			pListener = (*iter);
ds@1952
   453
			pListener->OnClientAuthorized(client, authid);
ds@1952
   454
		}
ds@1952
   455
		/* Finally, tell plugins */
ds@1952
   456
		if (m_clauth->GetFunctionCount())
ds@1952
   457
		{
ds@1952
   458
			m_clauth->PushCell(client);
ds@1952
   459
			m_clauth->PushString(authid);
ds@1952
   460
			m_clauth->Execute(NULL);
ds@1952
   461
		}
ds@1952
   462
		pPlayer->Authorize_Post();
ds@1952
   463
	}
ds@1952
   464
ds@1952
   465
	if (playerinfo)
ds@1952
   466
	{
ds@1952
   467
		pPlayer->m_Info = playerinfo->GetPlayerInfo(pEntity);
ds@1952
   468
	}
ds@1952
   469
ds@1952
   470
	/* Get the client's language */
ds@1952
   471
	if (m_QueryLang)
ds@1952
   472
	{
ds@1952
   473
		const char *name;
ds@1952
   474
		if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
ds@1952
   475
		{
ds@1952
   476
			unsigned int langid;
ds@1952
   477
			pPlayer->m_LangId = (g_Translator.GetLanguageByName(name, &langid)) ? langid : g_Translator.GetServerLanguage();
ds@1952
   478
		} else {
ds@1952
   479
			pPlayer->m_LangId = g_Translator.GetServerLanguage();
ds@1952
   480
		}
ds@1952
   481
	}
ds@1952
   482
ds@1952
   483
	m_Players[client].Connect();
ds@1952
   484
	m_PlayerCount++;
ds@1952
   485
ds@1952
   486
	List<IClientListener *>::iterator iter;
ds@1952
   487
	IClientListener *pListener = NULL;
ds@1952
   488
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   489
	{
ds@1952
   490
		pListener = (*iter);
ds@1952
   491
		pListener->OnClientPutInServer(client);
ds@1952
   492
	}
ds@1952
   493
ds@1952
   494
	m_clputinserver->PushCell(client);
ds@1952
   495
	m_clputinserver->Execute(&res, NULL);
ds@1952
   496
ds@1952
   497
	if (m_Players[client].IsAuthorized())
ds@1952
   498
	{
ds@1952
   499
		m_Players[client].DoPostConnectAuthorization();
ds@1952
   500
	}
ds@1952
   501
}
ds@1952
   502
ds@1952
   503
void PlayerManager::OnSourceModLevelEnd()
ds@1952
   504
{
ds@1952
   505
	/* Disconnect all bots still in game */
ds@1952
   506
	for (int i=1; i<=m_maxClients; i++)
ds@1952
   507
	{
ds@1952
   508
		if (m_Players[i].IsConnected())
ds@1952
   509
		{
ds@1952
   510
			OnClientDisconnect(m_Players[i].GetEdict());
ds@1952
   511
		}
ds@1952
   512
	}
ds@1952
   513
	m_PlayerCount = 0;
ds@1952
   514
}
ds@1952
   515
ds@1952
   516
void PlayerManager::OnClientDisconnect(edict_t *pEntity)
ds@1952
   517
{
ds@1952
   518
	cell_t res;
ds@1952
   519
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   520
ds@1952
   521
	if (m_Players[client].IsConnected())
ds@1952
   522
	{
ds@1952
   523
		m_cldisconnect->PushCell(client);
ds@1952
   524
		m_cldisconnect->Execute(&res, NULL);
ds@1952
   525
	} else {
ds@1952
   526
		/* We don't care, prevent a double call */
ds@1952
   527
		return;
ds@1952
   528
	}
ds@1952
   529
ds@1952
   530
	if (m_Players[client].WasCountedAsInGame())
ds@1952
   531
	{
ds@1952
   532
		m_PlayerCount--;
ds@1952
   533
	}
ds@1952
   534
ds@1952
   535
	List<IClientListener *>::iterator iter;
ds@1952
   536
	IClientListener *pListener = NULL;
ds@1952
   537
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   538
	{
ds@1952
   539
		pListener = (*iter);
ds@1952
   540
		pListener->OnClientDisconnecting(client);
ds@1952
   541
	}
ds@1952
   542
ds@1952
   543
	/**
ds@1952
   544
	 * Remove client from auth queue if necessary
ds@1952
   545
	 */
ds@1952
   546
	if (!m_Players[client].IsAuthorized())
ds@1952
   547
	{
ds@1952
   548
		for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
ds@1952
   549
		{
ds@1952
   550
			if (m_AuthQueue[i] == (unsigned)client)
ds@1952
   551
			{
ds@1952
   552
				/* Move everything ahead of us back by one */
ds@1952
   553
				for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
ds@1952
   554
				{
ds@1952
   555
					m_AuthQueue[j-1] = m_AuthQueue[j];
ds@1952
   556
				}
ds@1952
   557
				/* Remove us and break */
ds@1952
   558
				m_AuthQueue[0]--;
ds@1952
   559
				break;
ds@1952
   560
			}
ds@1952
   561
		}
ds@1952
   562
	}
ds@1952
   563
ds@1952
   564
	m_Players[client].Disconnect();
ds@1952
   565
	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = 0;
ds@1952
   566
}
ds@1952
   567
ds@1952
   568
void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
ds@1952
   569
{
ds@1952
   570
	cell_t res;
ds@1952
   571
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   572
ds@1952
   573
	m_cldisconnect_post->PushCell(client);
ds@1952
   574
	m_cldisconnect_post->Execute(&res, NULL);
ds@1952
   575
ds@1952
   576
	List<IClientListener *>::iterator iter;
ds@1952
   577
	IClientListener *pListener = NULL;
ds@1952
   578
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
ds@1952
   579
	{
ds@1952
   580
		pListener = (*iter);
ds@1952
   581
		pListener->OnClientDisconnected(client);
ds@1952
   582
	}
ds@1952
   583
}
ds@1952
   584
ds@1952
   585
#if defined ORANGEBOX_BUILD
ds@1952
   586
void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args)
ds@1952
   587
{
ds@1952
   588
#else
ds@1952
   589
void PlayerManager::OnClientCommand(edict_t *pEntity)
ds@1952
   590
{
ds@1952
   591
	CCommand args;
ds@1952
   592
#endif
ds@1952
   593
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   594
	cell_t res = Pl_Continue;
ds@1952
   595
ds@1952
   596
	CPlayer *pPlayer = GetPlayerByIndex(client);
ds@1952
   597
	if (!pPlayer || !pPlayer->IsConnected())
ds@1952
   598
	{
ds@1952
   599
		return;
ds@1952
   600
	}
ds@1952
   601
ds@1952
   602
	g_HL2.PushCommandStack(&args);
ds@1952
   603
ds@1952
   604
	int argcount = args.ArgC() - 1;
ds@1952
   605
	const char *cmd = g_HL2.CurrentCommandName();
ds@1952
   606
ds@1952
   607
	bool result = g_ValveMenuStyle.OnClientCommand(client, cmd, args);
ds@1952
   608
	if (result)
ds@1952
   609
	{
ds@1952
   610
		res = Pl_Handled;
ds@1952
   611
	} else {
ds@1952
   612
		result = g_RadioMenuStyle.OnClientCommand(client, cmd, args);
ds@1952
   613
		if (result)
ds@1952
   614
		{
ds@1952
   615
			res = Pl_Handled;
ds@1952
   616
		}
ds@1952
   617
	}
ds@1952
   618
ds@1952
   619
	cell_t res2 = Pl_Continue;
ds@1952
   620
	m_clcommand->PushCell(client);
ds@1952
   621
	m_clcommand->PushCell(argcount);
ds@1952
   622
	m_clcommand->Execute(&res2, NULL);
ds@1952
   623
ds@1952
   624
	if (res2 > res)
ds@1952
   625
	{
ds@1952
   626
		res = res2;
ds@1952
   627
	}
ds@1952
   628
ds@1952
   629
	if (res >= Pl_Stop)
ds@1952
   630
	{
ds@1952
   631
		g_HL2.PopCommandStack();
ds@1952
   632
		RETURN_META(MRES_SUPERCEDE);
ds@1952
   633
	}
ds@1952
   634
ds@1952
   635
	res = g_ConCmds.DispatchClientCommand(client, cmd, argcount, (ResultType)res);
ds@1952
   636
ds@1952
   637
	g_HL2.PopCommandStack();
ds@1952
   638
ds@1952
   639
	if (res >= Pl_Handled)
ds@1952
   640
	{
ds@1952
   641
		RETURN_META(MRES_SUPERCEDE);
ds@1952
   642
	}
ds@1952
   643
}
ds@1952
   644
ds@1952
   645
void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
ds@1952
   646
{
ds@1952
   647
	cell_t res;
ds@1952
   648
	int client = engine->IndexOfEdict(pEntity);
ds@1952
   649
ds@1952
   650
	if (!m_Players[client].IsConnected())
ds@1952
   651
	{
ds@1952
   652
		return;
ds@1952
   653
	}
ds@1952
   654
ds@1952
   655
	m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
ds@1952
   656
	m_clinfochanged->Execute(&res, NULL);
ds@1952
   657
ds@1952
   658
	IPlayerInfo *info = m_Players[client].GetPlayerInfo();
ds@1952
   659
	const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
ds@1952
   660
	const char *old_name = m_Players[client].m_Name.c_str();
ds@1952
   661
ds@1952
   662
	if (strcmp(old_name, new_name) != 0)
ds@1952
   663
	{
ds@1952
   664
		AdminId id = g_Admins.FindAdminByIdentity("name", new_name);
ds@1952
   665
		if (id != INVALID_ADMIN_ID && m_Players[client].GetAdminId() != id)
ds@1952
   666
		{
ds@1952
   667
			if (!CheckSetAdminName(client, &m_Players[client], id))
ds@1952
   668
			{
ds@1952
   669
				m_Players[client].Kick("Your name is reserved by SourceMod; set your password to use it.");
ds@1952
   670
				RETURN_META(MRES_IGNORED);
ds@1952
   671
			}
ds@1952
   672
		} else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
ds@1952
   673
			if (id == m_Players[client].GetAdminId())
ds@1952
   674
			{
ds@1952
   675
				/* This player is changing their name; force them to drop admin privileges! */
ds@1952
   676
				m_Players[client].SetAdminId(INVALID_ADMIN_ID, false);
ds@1952
   677
			}
ds@1952
   678
		}
ds@1952
   679
		m_Players[client].SetName(new_name);
ds@1952
   680
	}
ds@1952
   681
	
ds@1952
   682
	if (m_PassInfoVar.size() > 0)
ds@1952
   683
	{
ds@1952
   684
		/* Try for a password change */
ds@1952
   685
		const char *old_pass = m_Players[client].m_LastPassword.c_str();
ds@1952
   686
		const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str());
ds@1952
   687
		if (strcmp(old_pass, new_pass) != 0)
ds@1952
   688
		{
ds@1952
   689
			m_Players[client].m_LastPassword.assign(new_pass);
ds@1952
   690
			if (m_Players[client].IsInGame() && m_Players[client].IsAuthorized())
ds@1952
   691
			{
ds@1952
   692
				/* If there is already an admin id assigned, this will just bail out. */
ds@1952
   693
				m_Players[client].DoBasicAdminChecks();
ds@1952
   694
			}
ds@1952
   695
		}
ds@1952
   696
	}
ds@1952
   697
}
ds@1952
   698
ds@1952
   699
int PlayerManager::GetMaxClients()
ds@1952
   700
{
ds@1952
   701
	return m_maxClients;
ds@1952
   702
}
ds@1952
   703
ds@1952
   704
CPlayer *PlayerManager::GetPlayerByIndex(int client) const
ds@1952
   705
{
ds@1952
   706
	if (client > m_maxClients || client < 1)
ds@1952
   707
	{
ds@1952
   708
		return NULL;
ds@1952
   709
	}
ds@1952
   710
	return &m_Players[client];
ds@1952
   711
}
ds@1952
   712
ds@1952
   713
int PlayerManager::GetNumPlayers()
ds@1952
   714
{
ds@1952
   715
	return m_PlayerCount;
ds@1952
   716
}
ds@1952
   717
ds@1952
   718
int PlayerManager::GetClientOfUserId(int userid)
ds@1952
   719
{
ds@1952
   720
	if (userid < 0 || userid > USHRT_MAX)
ds@1952
   721
	{
ds@1952
   722
		return 0;
ds@1952
   723
	}
ds@1952
   724
	
ds@1952
   725
	int client = m_UserIdLookUp[userid];
ds@1952
   726
ds@1952
   727
	/* Verify the userid.  The cache can get messed up with older
ds@1952
   728
	 * Valve engines.  :TODO: If this gets fixed, do an old engine 
ds@1952
   729
	 * check before invoking this backwards compat code.
ds@1952
   730
	 */
ds@1952
   731
	if (client)
ds@1952
   732
	{
ds@1952
   733
		CPlayer *player = GetPlayerByIndex(client);
ds@1952
   734
		if (player && player->IsConnected())
ds@1952
   735
		{
ds@1952
   736
			int realUserId = engine->GetPlayerUserId(player->GetEdict());
ds@1952
   737
			if (realUserId == userid)
ds@1952
   738
			{
ds@1952
   739
				return client;
ds@1952
   740
			}
ds@1952
   741
		}
ds@1952
   742
	}
ds@1952
   743
ds@1952
   744
	/* If we can't verify the userid, we have to do a manual loop */
ds@1952
   745
	CPlayer *player;
ds@1952
   746
	for (int i = 1; i <= m_maxClients; i++)
ds@1952
   747
	{
ds@1952
   748
		player = GetPlayerByIndex(i);
ds@1952
   749
		if (!player || !player->IsConnected())
ds@1952
   750
		{
ds@1952
   751
			continue;
ds@1952
   752
		}
ds@1952
   753
		if (engine->GetPlayerUserId(player->GetEdict()) == userid)
ds@1952
   754
		{
ds@1952
   755
			m_UserIdLookUp[userid] = i;
ds@1952
   756
			return i;
ds@1952
   757
		}
ds@1952
   758
	}
ds@1952
   759
ds@1952
   760
	return 0;
ds@1952
   761
}
ds@1952
   762
ds@1952
   763
void PlayerManager::AddClientListener(IClientListener *listener)
ds@1952
   764
{
ds@1952
   765
	m_hooks.push_back(listener);
ds@1952
   766
}
ds@1952
   767
ds@1952
   768
void PlayerManager::RemoveClientListener(IClientListener *listener)
ds@1952
   769
{
ds@1952
   770
	m_hooks.remove(listener);
ds@1952
   771
}
ds@1952
   772
ds@1952
   773
IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict)
ds@1952
   774
{
ds@1952
   775
	int index = engine->IndexOfEdict(pEdict);
ds@1952
   776
	return GetGamePlayer(index);
ds@1952
   777
}
ds@1952
   778
ds@1952
   779
IGamePlayer *PlayerManager::GetGamePlayer(int client)
ds@1952
   780
{
ds@1952
   781
	return GetPlayerByIndex(client);
ds@1952
   782
}
ds@1952
   783
ds@1952
   784
void PlayerManager::ClearAdminId(AdminId id)
ds@1952
   785
{
ds@1952
   786
	for (int i=1; i<=m_maxClients; i++)
ds@1952
   787
	{
ds@1952
   788
		if (m_Players[i].m_Admin == id)
ds@1952
   789
		{
ds@1952
   790
			m_Players[i].DumpAdmin(true);
ds@1952
   791
		}
ds@1952
   792
	}
ds@1952
   793
}
ds@1952
   794
ds@1952
   795
void PlayerManager::ClearAllAdmins()
ds@1952
   796
{
ds@1952
   797
	for (int i=1; i<=m_maxClients; i++)
ds@1952
   798
	{
ds@1952
   799
		m_Players[i].DumpAdmin(true);
ds@1952
   800
	}
ds@1952
   801
}
ds@1952
   802
ds@1952
   803
const char *PlayerManager::GetPassInfoVar()
ds@1952
   804
{
ds@1952
   805
	return m_PassInfoVar.c_str();
ds@1952
   806
}
ds@1952
   807
ds@1952
   808
void PlayerManager::RecheckAnyAdmins()
ds@1952
   809
{
ds@1952
   810
	for (int i=1; i<=m_maxClients; i++)
ds@1952
   811
	{
ds@1952
   812
		if (m_Players[i].IsInGame() && m_Players[i].IsAuthorized())
ds@1952
   813
		{
ds@1952
   814
			m_Players[i].DoBasicAdminChecks();
ds@1952
   815
		}
ds@1952
   816
	}
ds@1952
   817
}
ds@1952
   818
ds@1952
   819
unsigned int PlayerManager::GetReplyTo()
ds@1952
   820
{
ds@1952
   821
	return g_ChatTriggers.GetReplyTo();
ds@1952
   822
}
ds@1952
   823
ds@1952
   824
unsigned int PlayerManager::SetReplyTo(unsigned int reply)
ds@1952
   825
{
ds@1952
   826
	return g_ChatTriggers.SetReplyTo(reply);
ds@1952
   827
}
ds@1952
   828
ds@1952
   829
int PlayerManager::FilterCommandTarget(IGamePlayer *pAdmin, IGamePlayer *pTarget, int flags)
ds@1952
   830
{
ds@1952
   831
	return InternalFilterCommandTarget((CPlayer *)pAdmin, (CPlayer *)pTarget, flags);
ds@1952
   832
}
ds@1952
   833
ds@1952
   834
void PlayerManager::RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler)
ds@1952
   835
{
ds@1952
   836
	target_processors.push_back(pHandler);
ds@1952
   837
}
ds@1952
   838
ds@1952
   839
void PlayerManager::UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler)
ds@1952
   840
{
ds@1952
   841
	target_processors.remove(pHandler);
ds@1952
   842
}
ds@1952
   843
ds@1952
   844
int PlayerManager::InternalFilterCommandTarget(CPlayer *pAdmin, CPlayer *pTarget, int flags)
ds@1952
   845
{
ds@1952
   846
	if ((flags & COMMAND_FILTER_CONNECTED) == COMMAND_FILTER_CONNECTED
ds@1952
   847
		&& !pTarget->IsConnected())
ds@1952
   848
	{
ds@1952
   849
		return COMMAND_TARGET_NONE;
ds@1952
   850
	}
ds@1952
   851
	else if ((flags & COMMAND_FILTER_CONNECTED) != COMMAND_FILTER_CONNECTED && 
ds@1952
   852
		!pTarget->IsInGame())
ds@1952
   853
	{
ds@1952
   854
		return COMMAND_TARGET_NOT_IN_GAME;
ds@1952
   855
	}
ds@1952
   856
ds@1952
   857
	if ((flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS
ds@1952
   858
		&& pTarget->IsFakeClient())
ds@1952
   859
	{
ds@1952
   860
		return COMMAND_TARGET_NOT_HUMAN;
ds@1952
   861
	}
ds@1952
   862
ds@1952
   863
	if (pAdmin != NULL)
ds@1952
   864
	{
ds@1952
   865
		if ((flags & COMMAND_FILTER_NO_IMMUNITY) != COMMAND_FILTER_NO_IMMUNITY
ds@1952
   866
			&& !g_Admins.CanAdminTarget(pAdmin->GetAdminId(), pTarget->GetAdminId()))
ds@1952
   867
		{
ds@1952
   868
			return COMMAND_TARGET_IMMUNE;
ds@1952
   869
		}
ds@1952
   870
	}
ds@1952
   871
ds@1952
   872
	if ((flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE 
ds@1952
   873
		&& pTarget->GetLifeState() != PLAYER_LIFE_ALIVE)
ds@1952
   874
	{
ds@1952
   875
		return COMMAND_TARGET_NOT_ALIVE;
ds@1952
   876
	}
ds@1952
   877
ds@1952
   878
	if ((flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD
ds@1952
   879
		&& pTarget->GetLifeState() != PLAYER_LIFE_DEAD)
ds@1952
   880
	{
ds@1952
   881
		return COMMAND_TARGET_NOT_DEAD;
ds@1952
   882
	}
ds@1952
   883
ds@1952
   884
	return COMMAND_TARGET_VALID;
ds@1952
   885
}
ds@1952
   886
ds@1952
   887
void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
ds@1952
   888
{
ds@1952
   889
	CPlayer *pTarget, *pAdmin;
ds@1952
   890
	int max_clients, total = 0;
ds@1952
   891
ds@1952
   892
	max_clients = GetMaxClients();
ds@1952
   893
ds@1952
   894
	if (info->max_targets < 1)
ds@1952
   895
	{
ds@1952
   896
		info->reason = COMMAND_TARGET_NONE;
ds@1952
   897
		info->num_targets = 0;
ds@1952
   898
	}
ds@1952
   899
ds@1952
   900
	if (info->admin == 0)
ds@1952
   901
	{
ds@1952
   902
		pAdmin = NULL;
ds@1952
   903
	}
ds@1952
   904
	else
ds@1952
   905
	{
ds@1952
   906
		pAdmin = GetPlayerByIndex(info->admin);
ds@1952
   907
	}
ds@1952
   908
ds@1952
   909
	if (info->pattern[0] == '#')
ds@1952
   910
	{
ds@1952
   911
		int userid = atoi(&info->pattern[1]);
ds@1952
   912
		int client = GetClientOfUserId(userid);
ds@1952
   913
ds@1952
   914
		/* See if a valid userid matched */
ds@1952
   915
		if (client > 0)
ds@1952
   916
		{
ds@1952
   917
			IGamePlayer *pTarget = GetPlayerByIndex(client);
ds@1952
   918
			if (pTarget != NULL)
ds@1952
   919
			{
ds@1952
   920
				if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags)) == COMMAND_TARGET_VALID)
ds@1952
   921
				{
ds@1952
   922
					info->targets[0] = client;
ds@1952
   923
					info->num_targets = 1;
ds@1952
   924
					strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
ds@1952
   925
					info->target_name_style = COMMAND_TARGETNAME_RAW;
ds@1952
   926
				}
ds@1952
   927
				else
ds@1952
   928
				{
ds@1952
   929
					info->num_targets = 0;
ds@1952
   930
				}
ds@1952
   931
				return;
ds@1952
   932
			}
ds@1952
   933
		}
ds@1952
   934
ds@1952
   935
		/* Do we need to look for a steam id? */
ds@1952
   936
		if (strncmp(&info->pattern[1], "STEAM_", 6) == 0)
ds@1952
   937
		{
ds@1952
   938
			size_t p, len;
ds@1952
   939
			char new_pattern[256];
ds@1952
   940
ds@1952
   941
			strcpy(new_pattern, "STEAM_");
ds@1952
   942
			len = strlen(&info->pattern[7]);
ds@1952
   943
			for (p = 0; p < len; p++)
ds@1952
   944
			{
ds@1952
   945
				new_pattern[6 + p] = info->pattern[7 + p];
ds@1952
   946
				if (new_pattern[6 + p] == '_')
ds@1952
   947
				{
ds@1952
   948
					new_pattern[6 + p] = ':';
ds@1952
   949
				}
ds@1952
   950
			}
ds@1952
   951
			new_pattern[6 + p] = '\0';
ds@1952
   952
ds@1952
   953
			for (int i = 1; i <= max_clients; i++)
ds@1952
   954
			{
ds@1952
   955
				if ((pTarget = GetPlayerByIndex(i)) == NULL)
ds@1952
   956
				{
ds@1952
   957
					continue;
ds@1952
   958
				}
ds@1952
   959
				if (!pTarget->IsConnected() || !pTarget->IsAuthorized())
ds@1952
   960
				{
ds@1952
   961
					continue;
ds@1952
   962
				}
ds@1952
   963
				if (strcmp(pTarget->GetAuthString(), new_pattern) == 0)
ds@1952
   964
				{
ds@1952
   965
					if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
ds@1952
   966
						== COMMAND_TARGET_VALID)
ds@1952
   967
					{
ds@1952
   968
						info->targets[0] = i;
ds@1952
   969
						info->num_targets = 1;
ds@1952
   970
						strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
ds@1952
   971
						info->target_name_style = COMMAND_TARGETNAME_RAW;
ds@1952
   972
					}
ds@1952
   973
					else
ds@1952
   974
					{
ds@1952
   975
						info->num_targets = 0;
ds@1952
   976
					}
ds@1952
   977
					return;
ds@1952
   978
				}
ds@1952
   979
			}
ds@1952
   980
		}
ds@1952
   981
ds@1952
   982
		/* See if an exact name matches */
ds@1952
   983
		for (int i = 1; i <= max_clients; i++)
ds@1952
   984
		{
ds@1952
   985
			if ((pTarget = GetPlayerByIndex(i)) == NULL)
ds@1952
   986
			{
ds@1952
   987
				continue;
ds@1952
   988
			}
ds@1952
   989
			if  (!pTarget->IsConnected())
ds@1952
   990
			{
ds@1952
   991
				continue;
ds@1952
   992
			}
ds@1952
   993
			if (strcmp(pTarget->GetName(), &info->pattern[1]) == 0)
ds@1952
   994
			{
ds@1952
   995
				if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
ds@1952
   996
					== COMMAND_TARGET_VALID)
ds@1952
   997
				{
ds@1952
   998
					info->targets[0] = i;
ds@1952
   999
					info->num_targets = 1;
ds@1952
  1000
					strncopy(info->target_name, pTarget->GetName(), info->target_name_maxlength);
ds@1952
  1001
					info->target_name_style = COMMAND_TARGETNAME_RAW;
ds@1952
  1002
				}
ds@1952
  1003
				else
ds@1952
  1004
				{
ds@1952
  1005
					info->num_targets = 0;
ds@1952
  1006
				}
ds@1952
  1007
				return;
ds@1952
  1008
			}
ds@1952
  1009
		}
ds@1952
  1010
	}
ds@1952
  1011
ds@1952
  1012
	if (strcmp(info->pattern, "@me") == 0 && info->admin != 0)
ds@1952
  1013
	{
ds@1952
  1014
		info->targets[0] = info->admin;
ds@1952
  1015
		info->num_targets = 1;
ds@1952
  1016
		strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
ds@1952
  1017
		info->target_name_style = COMMAND_TARGETNAME_RAW;
ds@1952
  1018
		return;
ds@1952
  1019
	}
ds@1952
  1020
ds@1952
  1021
	if ((info->flags & COMMAND_FILTER_NO_MULTI) != COMMAND_FILTER_NO_MULTI)
ds@1952
  1022
	{
ds@1952
  1023
		bool is_multi = false;
ds@1952
  1024
		bool bots_only = false;
ds@1952
  1025
		int skip_client = -1;
ds@1952
  1026
ds@1952
  1027
		if (strcmp(info->pattern, "@all") == 0)
ds@1952
  1028
		{
ds@1952
  1029
			is_multi = true;
ds@1952
  1030
			strncopy(info->target_name, "all players", info->target_name_maxlength);
ds@1952
  1031
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1032
		}
ds@1952
  1033
		else if (strcmp(info->pattern, "@dead") == 0)
ds@1952
  1034
		{
ds@1952
  1035
			is_multi = true;
ds@1952
  1036
			if ((info->flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE)
ds@1952
  1037
			{
ds@1952
  1038
				info->num_targets = 0;
ds@1952
  1039
				info->reason = COMMAND_TARGET_NOT_ALIVE;
ds@1952
  1040
				return;
ds@1952
  1041
			}
ds@1952
  1042
			info->flags |= COMMAND_FILTER_DEAD;
ds@1952
  1043
			strncopy(info->target_name, "all dead players", info->target_name_maxlength);
ds@1952
  1044
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1045
		}
ds@1952
  1046
		else if (strcmp(info->pattern, "@alive") == 0)
ds@1952
  1047
		{
ds@1952
  1048
			is_multi = true;
ds@1952
  1049
			if ((info->flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD)
ds@1952
  1050
			{
ds@1952
  1051
				info->num_targets = 0;
ds@1952
  1052
				info->reason = COMMAND_TARGET_NOT_DEAD;
ds@1952
  1053
				return;
ds@1952
  1054
			}
ds@1952
  1055
			strncopy(info->target_name, "all alive players", info->target_name_maxlength);
ds@1952
  1056
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1057
			info->flags |= COMMAND_FILTER_ALIVE;
ds@1952
  1058
		}
ds@1952
  1059
		else if (strcmp(info->pattern, "@bots") == 0)
ds@1952
  1060
		{
ds@1952
  1061
			is_multi = true;
ds@1952
  1062
			if ((info->flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS)
ds@1952
  1063
			{
ds@1952
  1064
				info->num_targets = 0;
ds@1952
  1065
				info->reason = COMMAND_FILTER_NO_BOTS;
ds@1952
  1066
				return;
ds@1952
  1067
			}
ds@1952
  1068
			strncopy(info->target_name, "all bots", info->target_name_maxlength);
ds@1952
  1069
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1070
			bots_only = true;
ds@1952
  1071
		}
ds@1952
  1072
		else if (strcmp(info->pattern, "@humans") == 0)
ds@1952
  1073
		{
ds@1952
  1074
			is_multi = true;
ds@1952
  1075
			strncopy(info->target_name, "all humans", info->target_name_maxlength);
ds@1952
  1076
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1077
			info->flags |= COMMAND_FILTER_NO_BOTS;
ds@1952
  1078
		}
ds@1952
  1079
		else if (strcmp(info->pattern, "@!me") == 0)
ds@1952
  1080
		{
ds@1952
  1081
			is_multi = true;
ds@1952
  1082
			strncopy(info->target_name, "all players", info->target_name_maxlength);
ds@1952
  1083
			info->target_name_style = COMMAND_TARGETNAME_ML;
ds@1952
  1084
			skip_client = info->admin;
ds@1952
  1085
		}
ds@1952
  1086
ds@1952
  1087
		if (is_multi)
ds@1952
  1088
		{
ds@1952
  1089
			for (int i = 1; i <= max_clients && total < info->max_targets; i++)
ds@1952
  1090
			{
ds@1952
  1091
				if ((pTarget = GetPlayerByIndex(i)) == NULL)
ds@1952
  1092
				{
ds@1952
  1093
					continue;
ds@1952
  1094
				}
ds@1952
  1095
				if (FilterCommandTarget(pAdmin, pTarget, info->flags) > 0)
ds@1952
  1096
				{
ds@1952
  1097
					if ((!bots_only || pTarget->IsFakeClient())
ds@1952
  1098
						&& skip_client != i)
ds@1952
  1099
					{
ds@1952
  1100
						info->targets[total++] = i;
ds@1952
  1101
					}
ds@1952
  1102
				}
ds@1952
  1103
			}
ds@1952
  1104
ds@1952
  1105
			info->num_targets = total;
ds@1952
  1106
			info->reason = (info->num_targets) ? COMMAND_TARGET_VALID : COMMAND_TARGET_EMPTY_FILTER;
ds@1952
  1107
			return;
ds@1952
  1108
		}
ds@1952
  1109
	}
ds@1952
  1110
ds@1952
  1111
	List<ICommandTargetProcessor *>::iterator iter;
ds@1952
  1112
	for (iter = target_processors.begin(); iter != target_processors.end(); iter++)
ds@1952
  1113
	{
ds@1952
  1114
		ICommandTargetProcessor *pProcessor = (*iter);
ds@1952
  1115
		if (pProcessor->ProcessCommandTarget(info))
ds@1952
  1116
		{
ds@1952
  1117
			return;
ds@1952
  1118
		}
ds@1952
  1119
	}
ds@1952
  1120
ds@1952
  1121
	/* Check partial names */
ds@1952
  1122
	int found_client = 0;
ds@1952
  1123
	CPlayer *pFoundClient = NULL;
ds@1952
  1124
	for (int i = 1; i <= max_clients; i++)
ds@1952
  1125
	{
ds@1952
  1126
		if ((pTarget = GetPlayerByIndex(i)) == NULL)
ds@1952
  1127
		{
ds@1952
  1128
			continue;
ds@1952
  1129
		}
ds@1952
  1130
ds@1952
  1131
		if (stristr(pTarget->GetName(), info->pattern) != NULL)
ds@1952
  1132
		{
ds@1952
  1133
			if (found_client)
ds@1952
  1134
			{
ds@1952
  1135
				info->num_targets = 0;
ds@1952
  1136
				info->reason = COMMAND_TARGET_AMBIGUOUS;
ds@1952
  1137
				return;
ds@1952
  1138
			}
ds@1952
  1139
			else
ds@1952
  1140
			{
ds@1952
  1141
				found_client = i;
ds@1952
  1142
				pFoundClient = pTarget;
ds@1952
  1143
			}
ds@1952
  1144
		}
ds@1952
  1145
	}
ds@1952
  1146
ds@1952
  1147
	if (found_client)
ds@1952
  1148
	{
ds@1952
  1149
		if ((info->reason = FilterCommandTarget(pAdmin, pFoundClient, info->flags)) 
ds@1952
  1150
			== COMMAND_TARGET_VALID)
ds@1952
  1151
		{
ds@1952
  1152
			info->targets[0] = found_client;
ds@1952
  1153
			info->num_targets = 1;
ds@1952
  1154
			strncopy(info->target_name, pFoundClient->GetName(), info->target_name_maxlength);
ds@1952
  1155
			info->target_name_style = COMMAND_TARGETNAME_RAW;
ds@1952
  1156
		}
ds@1952
  1157
		else
ds@1952
  1158
		{
ds@1952
  1159
			info->num_targets = 0;
ds@1952
  1160
		}
ds@1952
  1161
	}
ds@1952
  1162
	else
ds@1952
  1163
	{
ds@1952
  1164
		info->num_targets = 0;
ds@1952
  1165
		info->reason = COMMAND_TARGET_NONE;
ds@1952
  1166
	}
ds@1952
  1167
}
ds@1952
  1168
ds@1952
  1169
/*******************
ds@1952
  1170
 *** PLAYER CODE ***
ds@1952
  1171
 *******************/
ds@1952
  1172
ds@1952
  1173
CPlayer::CPlayer()
ds@1952
  1174
{
ds@1952
  1175
	m_IsConnected = false;
ds@1952
  1176
	m_IsInGame = false;
ds@1952
  1177
	m_IsAuthorized = false;
ds@1952
  1178
	m_pEdict = NULL;
ds@1952
  1179
	m_Admin = INVALID_ADMIN_ID;
ds@1952
  1180
	m_TempAdmin = false;
ds@1952
  1181
	m_Info = NULL;
ds@1952
  1182
	m_bAdminCheckSignalled = false;
ds@1952
  1183
	m_bIsInKickQueue = false;
ds@1952
  1184
	m_LastPassword.clear();
ds@1952
  1185
	m_LangId = LANGUAGE_ENGLISH;
ds@1952
  1186
}
ds@1952
  1187
ds@1952
  1188
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
ds@1952
  1189
{
ds@1952
  1190
	m_IsConnected = true;
ds@1952
  1191
	m_Name.assign(name);
ds@1952
  1192
	m_Ip.assign(ip);
ds@1952
  1193
	m_pEdict = pEntity;
ds@1952
  1194
	m_iIndex = engine->IndexOfEdict(pEntity);
ds@1952
  1195
	m_LangId = g_Translator.GetServerLanguage();
ds@1952
  1196
ds@1952
  1197
	char ip2[24], *ptr;
ds@1952
  1198
	strncopy(ip2, ip, sizeof(ip2));
ds@1952
  1199
	if ((ptr = strchr(ip2, ':')) != NULL)
ds@1952
  1200
	{
ds@1952
  1201
		*ptr = '\0';
ds@1952
  1202
	}
ds@1952
  1203
	m_IpNoPort.assign(ip2);
ds@1952
  1204
}
ds@1952
  1205
ds@1952
  1206
void CPlayer::Connect()
ds@1952
  1207
{
ds@1952
  1208
	if (m_IsInGame)
ds@1952
  1209
	{
ds@1952
  1210
		return;
ds@1952
  1211
	}
ds@1952
  1212
ds@1952
  1213
	m_IsInGame = true;
ds@1952
  1214
ds@1952
  1215
	const char *var = g_Players.GetPassInfoVar();
ds@1952
  1216
	int client = engine->IndexOfEdict(m_pEdict);
ds@1952
  1217
	if (var[0] != '\0')
ds@1952
  1218
	{
ds@1952
  1219
		const char *pass = engine->GetClientConVarValue(client, var);
ds@1952
  1220
		m_LastPassword.assign(pass ? pass : "");
ds@1952
  1221
	}
ds@1952
  1222
	else
ds@1952
  1223
	{
ds@1952
  1224
		m_LastPassword.assign("");
ds@1952
  1225
	}
ds@1952
  1226
}
ds@1952
  1227
ds@1952
  1228
void CPlayer::Authorize(const char *steamid)
ds@1952
  1229
{
ds@1952
  1230
	if (m_IsAuthorized)
ds@1952
  1231
	{
ds@1952
  1232
		return;
ds@1952
  1233
	}
ds@1952
  1234
ds@1952
  1235
	m_IsAuthorized = true;
ds@1952
  1236
	m_AuthID.assign(steamid);
ds@1952
  1237
}
ds@1952
  1238
ds@1952
  1239
void CPlayer::Disconnect()
ds@1952
  1240
{
ds@1952
  1241
	DumpAdmin(false);
ds@1952
  1242
	m_IsConnected = false;
ds@1952
  1243
	m_IsInGame = false;
ds@1952
  1244
	m_IsAuthorized = false;
ds@1952
  1245
	m_Name.clear();
ds@1952
  1246
	m_Ip.clear();
ds@1952
  1247
	m_AuthID.clear();
ds@1952
  1248
	m_pEdict = NULL;
ds@1952
  1249
	m_Info = NULL;
ds@1952
  1250
	m_bAdminCheckSignalled = false;
ds@1952
  1251
	m_UserId = -1;
ds@1952
  1252
	m_bIsInKickQueue = false;
ds@1952
  1253
}
ds@1952
  1254
ds@1952
  1255
void CPlayer::SetName(const char *name)
ds@1952
  1256
{
ds@1952
  1257
	m_Name.assign(name);
ds@1952
  1258
}
ds@1952
  1259
ds@1952
  1260
const char *CPlayer::GetName()
ds@1952
  1261
{
ds@1952
  1262
	if (m_Info && m_pEdict->GetUnknown())
ds@1952
  1263
	{
ds@1952
  1264
		return m_Info->GetName();
ds@1952
  1265
	}
ds@1952
  1266
	
ds@1952
  1267
	return m_Name.c_str();
ds@1952
  1268
}
ds@1952
  1269
ds@1952
  1270
const char *CPlayer::GetIPAddress()
ds@1952
  1271
{
ds@1952
  1272
	return m_Ip.c_str();
ds@1952
  1273
}
ds@1952
  1274
ds@1952
  1275
const char *CPlayer::GetAuthString()
ds@1952
  1276
{
ds@1952
  1277
	return m_AuthID.c_str();
ds@1952
  1278
}
ds@1952
  1279
ds@1952
  1280
edict_t *CPlayer::GetEdict()
ds@1952
  1281
{
ds@1952
  1282
	return m_pEdict;
ds@1952
  1283
}
ds@1952
  1284
ds@1952
  1285
bool CPlayer::IsInGame()
ds@1952
  1286
{
ds@1952
  1287
	return m_IsInGame && (m_pEdict->GetUnknown() != NULL);
ds@1952
  1288
}
ds@1952
  1289
ds@1952
  1290
bool CPlayer::WasCountedAsInGame()
ds@1952
  1291
{
ds@1952
  1292
	return m_IsInGame;
ds@1952
  1293
}
ds@1952
  1294
ds@1952
  1295
bool CPlayer::IsConnected()
ds@1952
  1296
{
ds@1952
  1297
	return m_IsConnected;
ds@1952
  1298
}
ds@1952
  1299
ds@1952
  1300
bool CPlayer::IsAuthorized()
ds@1952
  1301
{
ds@1952
  1302
	return m_IsAuthorized;
ds@1952
  1303
}
ds@1952
  1304
ds@1952
  1305
IPlayerInfo *CPlayer::GetPlayerInfo()
ds@1952
  1306
{
ds@1952
  1307
	if (m_pEdict->GetUnknown())
ds@1952
  1308
	{
ds@1952
  1309
		return m_Info;
ds@1952
  1310
	}
ds@1952
  1311
ds@1952
  1312
	return NULL;
ds@1952
  1313
}
ds@1952
  1314
ds@1952
  1315
bool CPlayer::IsFakeClient()
ds@1952
  1316
{
ds@1952
  1317
	return (strcmp(m_AuthID.c_str(), "BOT") == 0);
ds@1952
  1318
}
ds@1952
  1319
ds@1952
  1320
void CPlayer::SetAdminId(AdminId id, bool temporary)
ds@1952
  1321
{
ds@1952
  1322
	if (!m_IsConnected)
ds@1952
  1323
	{
ds@1952
  1324
		return;
ds@1952
  1325
	}
ds@1952
  1326
ds@1952
  1327
	DumpAdmin(false);
ds@1952
  1328
ds@1952
  1329
	m_Admin = id;
ds@1952
  1330
	m_TempAdmin = temporary;
ds@1952
  1331
}
ds@1952
  1332
ds@1952
  1333
AdminId CPlayer::GetAdminId()
ds@1952
  1334
{
ds@1952
  1335
	return m_Admin;
ds@1952
  1336
}
ds@1952
  1337
ds@1952
  1338
void CPlayer::DumpAdmin(bool deleting)
ds@1952
  1339
{
ds@1952
  1340
	if (m_Admin != INVALID_ADMIN_ID)
ds@1952
  1341
	{
ds@1952
  1342
		if (m_TempAdmin && !deleting)
ds@1952
  1343
		{
ds@1952
  1344
			g_Admins.InvalidateAdmin(m_Admin);
ds@1952
  1345
		}
ds@1952
  1346
		m_Admin = INVALID_ADMIN_ID;
ds@1952
  1347
		m_TempAdmin = false;
ds@1952
  1348
	}
ds@1952
  1349
}
ds@1952
  1350
ds@1952
  1351
void CPlayer::Kick(const char *str)
ds@1952
  1352
{
ds@1952
  1353
	MarkAsBeingKicked();
ds@1952
  1354
	INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex));
ds@1952
  1355
	IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
ds@1952
  1356
	pClient->Disconnect("%s", str);
ds@1952
  1357
}
ds@1952
  1358
ds@1952
  1359
void CPlayer::Authorize_Post()
ds@1952
  1360
{
ds@1952
  1361
	if (m_IsInGame)
ds@1952
  1362
	{
ds@1952
  1363
		DoPostConnectAuthorization();
ds@1952
  1364
	}
ds@1952
  1365
}
ds@1952
  1366
ds@1952
  1367
void CPlayer::DoPostConnectAuthorization()
ds@1952
  1368
{
ds@1952
  1369
	bool delay = false;
ds@1952
  1370
ds@1952
  1371
	List<IClientListener *>::iterator iter;
ds@1952
  1372
	for (iter = g_Players.m_hooks.begin();
ds@1952
  1373
		 iter != g_Players.m_hooks.end();
ds@1952
  1374
		 iter++)
ds@1952
  1375
	{
ds@1952
  1376
		IClientListener *pListener = (*iter);
ds@1952
  1377
#if defined MIN_API_FOR_ADMINCALLS
ds@1952
  1378
		if (pListener->GetClientListenerVersion() < MIN_API_FOR_ADMINCALLS)
ds@1952
  1379
		{
ds@1952
  1380
			continue;
ds@1952
  1381
		}
ds@1952
  1382
#endif
ds@1952
  1383
		if (!pListener->OnClientPreAdminCheck(m_iIndex))
ds@1952
  1384
		{
ds@1952
  1385
			delay = true;
ds@1952
  1386
		}
ds@1952
  1387
	}
ds@1952
  1388
	
ds@1952
  1389
	cell_t result = 0;
ds@1952
  1390
	PreAdminCheck->PushCell(m_iIndex);
ds@1952
  1391
	PreAdminCheck->Execute(&result);
ds@1952
  1392
ds@1952
  1393
	/* Defer, for better or worse */
ds@1952
  1394
	if (delay || (ResultType)result >= Pl_Handled)
ds@1952
  1395
	{
ds@1952
  1396
		return;
ds@1952
  1397
	}
ds@1952
  1398
ds@1952
  1399
	/* Sanity check */
ds@1952
  1400
	if (!IsConnected())
ds@1952
  1401
	{
ds@1952
  1402
		return;
ds@1952
  1403
	}
ds@1952
  1404
ds@1952
  1405
	/* Otherwise, go ahead and do admin checks */
ds@1952
  1406
	DoBasicAdminChecks();
ds@1952
  1407
ds@1952
  1408
	/* Send the notification out */
ds@1952
  1409
	NotifyPostAdminChecks();
ds@1952
  1410
}
ds@1952
  1411
ds@1952
  1412
bool CPlayer::RunAdminCacheChecks()
ds@1952
  1413
{
ds@1952
  1414
	AdminId old_id = GetAdminId();
ds@1952
  1415
ds@1952
  1416
	DoBasicAdminChecks();
ds@1952
  1417
ds@1952
  1418
	return (GetAdminId() != old_id);
ds@1952
  1419
}
ds@1952
  1420
ds@1952
  1421
void CPlayer::NotifyPostAdminChecks()
ds@1952
  1422
{
ds@1952
  1423
	if (m_bAdminCheckSignalled)
ds@1952
  1424
	{
ds@1952
  1425
		return;
ds@1952
  1426
	}
ds@1952
  1427
ds@1952
  1428
	/* Block beforehand so they can't double-call */
ds@1952
  1429
	m_bAdminCheckSignalled = true;
ds@1952
  1430
ds@1952
  1431
	List<IClientListener *>::iterator iter;
ds@1952
  1432
	for (iter = g_Players.m_hooks.begin();
ds@1952
  1433
		iter != g_Players.m_hooks.end();
ds@1952
  1434
		iter++)
ds@1952
  1435
	{
ds@1952
  1436
		IClientListener *pListener = (*iter);
ds@1952
  1437
#if defined MIN_API_FOR_ADMINCALLS
ds@1952
  1438
		if (pListener->GetClientListenerVersion() < MIN_API_FOR_ADMINCALLS)
ds@1952
  1439
		{
ds@1952
  1440
			continue;
ds@1952
  1441
		}
ds@1952
  1442
#endif
ds@1952
  1443
		pListener->OnClientPostAdminCheck(m_iIndex);
ds@1952
  1444
	}
ds@1952
  1445
ds@1952
  1446
	PostAdminFilter->PushCell(m_iIndex);
ds@1952
  1447
	PostAdminFilter->Execute(NULL);
ds@1952
  1448
ds@1952
  1449
	PostAdminCheck->PushCell(m_iIndex);
ds@1952
  1450
	PostAdminCheck->Execute(NULL);
ds@1952
  1451
}
ds@1952
  1452
ds@1952
  1453
void CPlayer::DoBasicAdminChecks()
ds@1952
  1454
{
ds@1952
  1455
	if (GetAdminId() != INVALID_ADMIN_ID)
ds@1952
  1456
	{
ds@1952
  1457
		return;
ds@1952
  1458
	}
ds@1952
  1459
ds@1952
  1460
	/* First check the name */
ds@1952
  1461
	AdminId id;
ds@1952
  1462
	int client = engine->IndexOfEdict(m_pEdict);
ds@1952
  1463
ds@1952
  1464
	if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
ds@1952
  1465
	{
ds@1952
  1466
		if (!g_Players.CheckSetAdminName(client, this, id))
ds@1952
  1467
		{
ds@1952
  1468
			int userid = engine->GetPlayerUserId(m_pEdict);
ds@1952
  1469
			g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
ds@1952
  1470
		}
ds@1952
  1471
		return;
ds@1952
  1472
	}
ds@1952
  1473
	
ds@1952
  1474
	/* Check IP */
ds@1952
  1475
	if ((id = g_Admins.FindAdminByIdentity("ip", m_IpNoPort.c_str())) != INVALID_ADMIN_ID)
ds@1952
  1476
	{
ds@1952
  1477
		if (g_Players.CheckSetAdmin(client, this, id))
ds@1952
  1478
		{
ds@1952
  1479
			return;
ds@1952
  1480
		}
ds@1952
  1481
	}
ds@1952
  1482
ds@1952
  1483
	/* Check IP address */
ds@1952
  1484
	if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
ds@1952
  1485
	{
ds@1952
  1486
		if (g_Players.CheckSetAdmin(client, this, id))
ds@1952
  1487
		{
ds@1952
  1488
			return;
ds@1952
  1489
		}
ds@1952
  1490
	}
ds@1952
  1491
}
ds@1952
  1492
ds@1952
  1493
unsigned int CPlayer::GetLanguageId()
ds@1952
  1494
{
ds@1952
  1495
	return m_LangId;
ds@1952
  1496
}
ds@1952
  1497
ds@1952
  1498
int CPlayer::GetUserId()
ds@1952
  1499
{
ds@1952
  1500
	if (m_UserId == -1)
ds@1952
  1501
	{
ds@1952
  1502
		m_UserId = engine->GetPlayerUserId(GetEdict());
ds@1952
  1503
	}
ds@1952
  1504
ds@1952
  1505
	return m_UserId;
ds@1952
  1506
}
ds@1952
  1507
ds@1952
  1508
bool CPlayer::IsInKickQueue()
ds@1952
  1509
{
ds@1952
  1510
	return m_bIsInKickQueue;
ds@1952
  1511
}
ds@1952
  1512
ds@1952
  1513
void CPlayer::MarkAsBeingKicked()
ds@1952
  1514
{
ds@1952
  1515
	m_bIsInKickQueue = true;
ds@1952
  1516
}
ds@1952
  1517
ds@1952
  1518
int CPlayer::GetLifeState()
ds@1952
  1519
{
ds@1952
  1520
	if (lifestate_offset == -1)
ds@1952
  1521
	{
ds@1952
  1522
		if (!g_pGameConf->GetOffset("m_lifeState", &lifestate_offset))
ds@1952
  1523
		{
ds@1952
  1524
			lifestate_offset = -2;
ds@1952
  1525
		}
ds@1952
  1526
	}
ds@1952
  1527
ds@1952
  1528
	if (lifestate_offset < 0)
ds@1952
  1529
	{
ds@1952
  1530
		IPlayerInfo *info = GetPlayerInfo();
ds@1952
  1531
		if (info == NULL)
ds@1952
  1532
		{
ds@1952
  1533
			return PLAYER_LIFE_UNKNOWN;
ds@1952
  1534
		}
ds@1952
  1535
		return info->IsDead() ? PLAYER_LIFE_DEAD : PLAYER_LIFE_ALIVE;
ds@1952
  1536
	}
ds@1952
  1537
ds@1952
  1538
	if (m_pEdict == NULL)
ds@1952
  1539
	{
ds@1952
  1540
		return PLAYER_LIFE_UNKNOWN;
ds@1952
  1541
	}
ds@1952
  1542
ds@1952
  1543
	CBaseEntity *pEntity;
ds@1952
  1544
	IServerUnknown *pUnknown = m_pEdict->GetUnknown();
ds@1952
  1545
	if (pUnknown == NULL || (pEntity = pUnknown->GetBaseEntity()) == NULL)
ds@1952
  1546
	{
ds@1952
  1547
		return PLAYER_LIFE_UNKNOWN;
ds@1952
  1548
	}
ds@1952
  1549
ds@1952
  1550
	if (*((uint8_t *)pEntity + lifestate_offset) == LIFE_ALIVE)
ds@1952
  1551
	{
ds@1952
  1552
		return PLAYER_LIFE_ALIVE;
ds@1952
  1553
	}
ds@1952
  1554
	else
ds@1952
  1555
	{
ds@1952
  1556
		return PLAYER_LIFE_DEAD;
ds@1952
  1557
	}
ds@1952
  1558
}