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