core/PlayerManager.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1288 ae5f77aef635
child 1335 2047dc42d800
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

(This day shall henceforth be known as the Eighty Column Massacre of '07)
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 <inetchannel.h>
dvander@1161
    42
#include <iclient.h>
dvander@1161
    43
#include "TimerSys.h"
dvander@591
    44
dvander@616
    45
PlayerManager g_Players;
dvander@848
    46
bool g_OnMapStarted = false;
dvander@1273
    47
IForward *PreAdminCheck = NULL;
dvander@1273
    48
IForward *PostAdminCheck = NULL;
dvander@591
    49
dvander@591
    50
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
dvander@591
    51
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
dvander@591
    52
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
dvander@591
    53
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
dvander@591
    54
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
dvander@591
    55
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
dvander@591
    56
dvander@1161
    57
class KickPlayerTimer : public ITimedEvent
dvander@1161
    58
{
dvander@1161
    59
public:
dvander@1161
    60
	ResultType OnTimer(ITimer *pTimer, void *pData)
dvander@1161
    61
	{
dvander@1161
    62
		int userid = (int)pData;
dvander@1161
    63
		int client = g_Players.GetClientOfUserId(userid);
dvander@1161
    64
		if (client)
dvander@1161
    65
		{
dvander@1161
    66
			CPlayer *player = g_Players.GetPlayerByIndex(client);
dvander@1161
    67
			player->Kick("Your name is reserved by SourceMod; set your password to use it.");
dvander@1161
    68
		}
dvander@1161
    69
		return Pl_Stop;
dvander@1161
    70
	}
dvander@1161
    71
	void OnTimerEnd(ITimer *pTimer, void *pData)
dvander@1161
    72
	{
dvander@1161
    73
	}
dvander@1161
    74
} s_KickPlayerTimer;
dvander@1161
    75
dvander@616
    76
PlayerManager::PlayerManager()
dvander@591
    77
{
dvander@591
    78
	m_AuthQueue = NULL;
dvander@591
    79
	m_FirstPass = true;
faluco@682
    80
faluco@682
    81
	m_UserIdLookUp = new int[USHRT_MAX];
faluco@682
    82
	memset(m_UserIdLookUp, 0, sizeof(int) * USHRT_MAX);
dvander@591
    83
}
dvander@591
    84
dvander@616
    85
PlayerManager::~PlayerManager()
dvander@591
    86
{
dvander@591
    87
	delete [] m_AuthQueue;
faluco@682
    88
	delete [] m_UserIdLookUp;
dvander@591
    89
}
dvander@591
    90
dvander@616
    91
void PlayerManager::OnSourceModAllInitialized()
dvander@591
    92
{
dvander@616
    93
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
dvander@616
    94
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect_Post, true);
dvander@616
    95
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
dvander@616
    96
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
dvander@616
    97
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
dvander@616
    98
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
dvander@616
    99
	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
dvander@616
   100
	SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
dvander@591
   101
dvander@591
   102
	g_ShareSys.AddInterface(NULL, this);
dvander@591
   103
dvander@591
   104
	ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
dvander@591
   105
	ParamType p2[] = {Param_Cell};
dvander@591
   106
dvander@591
   107
	m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
dvander@591
   108
	m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
dvander@591
   109
	m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
dvander@591
   110
	m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
dvander@591
   111
	m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 2, NULL, Param_Cell, Param_Cell);
dvander@591
   112
	m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
dvander@591
   113
	m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
dvander@643
   114
	m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL);
dvander@717
   115
	m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL);
dvander@1273
   116
dvander@1273
   117
	PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1);
dvander@1273
   118
	PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1);
dvander@591
   119
}
dvander@591
   120
dvander@616
   121
void PlayerManager::OnSourceModShutdown()
dvander@591
   122
{
dvander@616
   123
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
dvander@616
   124
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
dvander@616
   125
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
dvander@616
   126
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
dvander@616
   127
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false);
dvander@616
   128
	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true);
dvander@616
   129
	SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true);
dvander@591
   130
dvander@591
   131
	/* Release forwards */
dvander@591
   132
	g_Forwards.ReleaseForward(m_clconnect);
dvander@591
   133
	g_Forwards.ReleaseForward(m_clputinserver);
dvander@591
   134
	g_Forwards.ReleaseForward(m_cldisconnect);
dvander@591
   135
	g_Forwards.ReleaseForward(m_cldisconnect_post);
dvander@591
   136
	g_Forwards.ReleaseForward(m_clcommand);
dvander@591
   137
	g_Forwards.ReleaseForward(m_clinfochanged);
dvander@591
   138
	g_Forwards.ReleaseForward(m_clauth);
dvander@643
   139
	g_Forwards.ReleaseForward(m_onActivate);
dvander@717
   140
	g_Forwards.ReleaseForward(m_onActivate2);
dvander@591
   141
dvander@1273
   142
	g_Forwards.ReleaseForward(PreAdminCheck);
dvander@1273
   143
	g_Forwards.ReleaseForward(PostAdminCheck);
dvander@1273
   144
dvander@591
   145
	delete [] m_Players;
dvander@591
   146
}
dvander@591
   147
dvander@1160
   148
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key, 
dvander@1160
   149
												 const char *value, 
dvander@1160
   150
												 ConfigSource source, 
dvander@1160
   151
												 char *error, 
dvander@1160
   152
												 size_t maxlength)
dvander@1160
   153
{
dvander@1160
   154
	if (strcmp(key, "PassInfoVar") == 0)
dvander@1160
   155
	{
dvander@1160
   156
		if (strcmp(value, "_password") != 0)
dvander@1160
   157
		{
dvander@1160
   158
			m_PassInfoVar.assign(value);
dvander@1160
   159
		}
dvander@1160
   160
		return ConfigResult_Accept;
dvander@1160
   161
	}
dvander@1160
   162
	return ConfigResult_Ignore;
dvander@1160
   163
}
dvander@1160
   164
dvander@616
   165
void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
dvander@591
   166
{
dvander@591
   167
	if (m_FirstPass)
dvander@591
   168
	{
dvander@591
   169
		/* Initialize all players */
dvander@591
   170
		m_maxClients = clientMax;
dvander@591
   171
		m_PlayerCount = 0;
dvander@591
   172
		m_Players = new CPlayer[m_maxClients + 1];
dvander@591
   173
		m_AuthQueue = new unsigned int[m_maxClients + 1];
dvander@591
   174
		m_FirstPass = false;
dvander@591
   175
dvander@591
   176
		memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
dvander@591
   177
	}
dvander@643
   178
	m_onActivate->Execute(NULL);
dvander@717
   179
	m_onActivate2->Execute(NULL);
dvander@848
   180
dvander@848
   181
	g_OnMapStarted = true;
dvander@978
   182
dvander@978
   183
	SM_ExecuteAllConfigs();
dvander@591
   184
}
dvander@591
   185
dvander@1160
   186
bool PlayerManager::CheckSetAdmin(int index, CPlayer *pPlayer, AdminId id)
dvander@930
   187
{
dvander@930
   188
	const char *password = g_Admins.GetAdminPassword(id);
dvander@930
   189
	if (password != NULL)
dvander@930
   190
	{
dvander@1160
   191
		if (m_PassInfoVar.size() < 1)
dvander@1160
   192
		{
dvander@1160
   193
			return false;
dvander@1160
   194
		}
dvander@1160
   195
dvander@930
   196
		/* Whoa... the user needs a password! */
dvander@1160
   197
		const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
dvander@930
   198
		if (!given || strcmp(given, password) != 0)
dvander@930
   199
		{
dvander@930
   200
			return false;
dvander@930
   201
		}
dvander@930
   202
	}
dvander@930
   203
dvander@930
   204
	pPlayer->SetAdminId(id, false);
dvander@930
   205
dvander@930
   206
	return true;
dvander@930
   207
}
dvander@930
   208
dvander@1161
   209
bool PlayerManager::CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id)
dvander@1161
   210
{
dvander@1161
   211
	const char *password = g_Admins.GetAdminPassword(id);
dvander@1161
   212
	if (password == NULL)
dvander@1161
   213
	{
dvander@1161
   214
		return false;
dvander@1161
   215
	}
dvander@1161
   216
dvander@1161
   217
	if (m_PassInfoVar.size() < 1)
dvander@1161
   218
	{
dvander@1161
   219
		return false;
dvander@1161
   220
	}
dvander@1161
   221
dvander@1161
   222
	/* Whoa... the user needs a password! */
dvander@1161
   223
	const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
dvander@1161
   224
	if (!given || strcmp(given, password) != 0)
dvander@1161
   225
	{
dvander@1161
   226
		return false;
dvander@1161
   227
	}
dvander@1161
   228
dvander@1161
   229
	pPlayer->SetAdminId(id, false);
dvander@1161
   230
dvander@1161
   231
	return true;
dvander@1161
   232
}
dvander@1161
   233
dvander@616
   234
void PlayerManager::RunAuthChecks()
dvander@591
   235
{
dvander@591
   236
	CPlayer *pPlayer;
dvander@591
   237
	const char *authstr;
dvander@591
   238
	unsigned int removed = 0;
dvander@591
   239
	for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
dvander@591
   240
	{
dvander@591
   241
		pPlayer = GetPlayerByIndex(m_AuthQueue[i]);
dvander@591
   242
		authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
dvander@591
   243
		if (authstr && authstr[0] != '\0'
dvander@591
   244
			&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
dvander@591
   245
		{
dvander@591
   246
			/* Set authorization */
dvander@1161
   247
			pPlayer->Authorize(authstr);
dvander@591
   248
dvander@647
   249
			/* Mark as removed from queue */
dvander@649
   250
			unsigned int client = m_AuthQueue[i];
dvander@647
   251
			m_AuthQueue[i] = 0;
dvander@647
   252
			removed++;
dvander@647
   253
dvander@591
   254
			/* Send to extensions */
dvander@591
   255
			List<IClientListener *>::iterator iter;
dvander@591
   256
			IClientListener *pListener;
dvander@591
   257
			for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   258
			{
dvander@591
   259
				pListener = (*iter);
dvander@648
   260
				pListener->OnClientAuthorized(client, authstr);
dvander@647
   261
				if (!pPlayer->IsConnected())
dvander@647
   262
				{
dvander@647
   263
					break;
dvander@647
   264
				}
dvander@591
   265
			}
dvander@591
   266
dvander@647
   267
			/* Send to plugins if player is still connected */
dvander@647
   268
			if (pPlayer->IsConnected() && m_clauth->GetFunctionCount())
dvander@591
   269
			{
dvander@647
   270
				/* :TODO: handle the case of a player disconnecting in the middle */
dvander@648
   271
				m_clauth->PushCell(client);
dvander@591
   272
				m_clauth->PushString(authstr);
dvander@591
   273
				m_clauth->Execute(NULL);
dvander@591
   274
			}
dvander@1161
   275
dvander@1161
   276
			if (pPlayer->IsConnected())
dvander@1161
   277
			{
dvander@1161
   278
				pPlayer->Authorize_Post();
dvander@1161
   279
			}
dvander@591
   280
		}
dvander@591
   281
	}
dvander@591
   282
dvander@591
   283
	/* Clean up the queue */
dvander@591
   284
	if (removed)
dvander@591
   285
	{
ds@729
   286
		/* We don't have to compact the list if it's empty */
dvander@591
   287
		if (removed != m_AuthQueue[0])
dvander@591
   288
		{
dvander@591
   289
			unsigned int diff = 0;
dvander@591
   290
			for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
dvander@591
   291
			{
dvander@591
   292
				/* If this member is removed... */
dvander@591
   293
				if (m_AuthQueue[i] == 0)
dvander@591
   294
				{
dvander@591
   295
					/* Increase the differential */
dvander@591
   296
					diff++;
dvander@591
   297
				} else {
dvander@591
   298
					/* diff cannot increase faster than i+1 */
dvander@591
   299
					assert(i > diff);
dvander@591
   300
					assert(i - diff >= 1);
dvander@591
   301
					/* move this index down */
dvander@591
   302
					m_AuthQueue[i - diff] = m_AuthQueue[i];
dvander@591
   303
				}
dvander@591
   304
			}
dvander@591
   305
			m_AuthQueue[0] -= removed;
dvander@591
   306
		} else {
dvander@591
   307
			m_AuthQueue[0] = 0;
dvander@591
   308
			g_SourceMod.SetAuthChecking(false);
dvander@591
   309
		}
dvander@591
   310
	}
dvander@591
   311
}
dvander@591
   312
dvander@616
   313
bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
dvander@591
   314
{
dvander@591
   315
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   316
dvander@591
   317
	List<IClientListener *>::iterator iter;
dvander@591
   318
	IClientListener *pListener = NULL;
dvander@591
   319
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   320
	{
dvander@591
   321
		pListener = (*iter);
dvander@591
   322
		if (!pListener->InterceptClientConnect(client, reject, maxrejectlen))
dvander@591
   323
		{
dvander@591
   324
			return false;
dvander@591
   325
		}
dvander@591
   326
	}
dvander@591
   327
dvander@591
   328
	cell_t res = 1;
dvander@591
   329
dvander@591
   330
	m_Players[client].Initialize(pszName, pszAddress, pEntity);
dvander@591
   331
	m_clconnect->PushCell(client);
dvander@591
   332
	m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
dvander@591
   333
	m_clconnect->PushCell(maxrejectlen);
dvander@591
   334
	m_clconnect->Execute(&res, NULL);
dvander@591
   335
dvander@591
   336
	if (res)
dvander@591
   337
	{
dvander@644
   338
		if (!m_Players[client].IsAuthorized())
dvander@644
   339
		{
dvander@644
   340
			m_AuthQueue[++m_AuthQueue[0]] = client;
dvander@644
   341
			g_SourceMod.SetAuthChecking(true);
dvander@644
   342
		}
dvander@591
   343
	} else {
dvander@591
   344
		RETURN_META_VALUE(MRES_SUPERCEDE, false);
dvander@591
   345
	}
dvander@591
   346
faluco@682
   347
	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = client;
faluco@682
   348
dvander@591
   349
	return true;
dvander@591
   350
}
dvander@591
   351
dvander@616
   352
bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
dvander@591
   353
{
dvander@591
   354
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   355
	bool orig_value = META_RESULT_ORIG_RET(bool);
dvander@930
   356
	CPlayer *pPlayer = GetPlayerByIndex(client);
dvander@591
   357
	if (orig_value)
dvander@591
   358
	{
dvander@591
   359
		List<IClientListener *>::iterator iter;
dvander@591
   360
		IClientListener *pListener = NULL;
dvander@591
   361
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   362
		{
dvander@591
   363
			pListener = (*iter);
dvander@591
   364
			pListener->OnClientConnected(client);
dvander@930
   365
			if (!pPlayer->IsConnected())
dvander@930
   366
			{
dvander@930
   367
				break;
dvander@930
   368
			}
dvander@930
   369
		}
dvander@930
   370
	}
dvander@930
   371
dvander@591
   372
	return true;
dvander@591
   373
}
dvander@591
   374
dvander@616
   375
void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
dvander@591
   376
{
dvander@591
   377
	cell_t res;
dvander@591
   378
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   379
dvander@591
   380
	CPlayer *pPlayer = GetPlayerByIndex(client);
dvander@644
   381
	/* If they're not connected, they're a bot */
dvander@591
   382
	if (!pPlayer->IsConnected())
dvander@591
   383
	{
dvander@591
   384
		/* Run manual connection routines */
dvander@591
   385
		char error[255];
dvander@644
   386
		const char *authid = engine->GetPlayerNetworkIDString(pEntity);
dvander@644
   387
		pPlayer->Authorize(authid);
dvander@591
   388
		if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
dvander@591
   389
		{
dvander@591
   390
			/* :TODO: kick the bot if it's rejected */
dvander@591
   391
			return;
dvander@591
   392
		}
dvander@591
   393
		List<IClientListener *>::iterator iter;
dvander@591
   394
		IClientListener *pListener = NULL;
dvander@591
   395
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   396
		{
dvander@591
   397
			pListener = (*iter);
dvander@591
   398
			pListener->OnClientConnected(client);
dvander@644
   399
			/* See if bot was kicked */
dvander@644
   400
			if (!pPlayer->IsConnected())
dvander@644
   401
			{
dvander@644
   402
				return;
dvander@644
   403
			}
dvander@591
   404
		}
dvander@644
   405
		/* Now do authorization */
dvander@644
   406
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@644
   407
		{
dvander@644
   408
			pListener = (*iter);
dvander@644
   409
			pListener->OnClientAuthorized(client, authid);
dvander@644
   410
			/* See if bot was kicked */
dvander@644
   411
			if (!pPlayer->IsConnected())
dvander@644
   412
			{
dvander@644
   413
				return;
dvander@644
   414
			}
dvander@644
   415
		}
dvander@644
   416
		/* Finally, tell plugins */
dvander@644
   417
		if (m_clauth->GetFunctionCount())
dvander@644
   418
		{
dvander@644
   419
			m_clauth->PushCell(client);
dvander@644
   420
			m_clauth->PushString(authid);
dvander@644
   421
			m_clauth->Execute(NULL);
dvander@1161
   422
			if (!pPlayer->IsConnected())
dvander@1161
   423
			{
dvander@1161
   424
				return;
dvander@1161
   425
			}
dvander@1161
   426
		}
dvander@1161
   427
		pPlayer->Authorize_Post();
dvander@1161
   428
		if (!pPlayer->IsConnected())
dvander@1161
   429
		{
dvander@1161
   430
			return;
dvander@644
   431
		}
dvander@644
   432
	}
dvander@644
   433
dvander@644
   434
	if (playerinfo)
dvander@644
   435
	{
dvander@644
   436
		pPlayer->m_Info = playerinfo->GetPlayerInfo(pEntity);
dvander@591
   437
	}
dvander@591
   438
dvander@591
   439
	List<IClientListener *>::iterator iter;
dvander@591
   440
	IClientListener *pListener = NULL;
dvander@591
   441
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   442
	{
dvander@591
   443
		pListener = (*iter);
dvander@591
   444
		pListener->OnClientPutInServer(client);
dvander@644
   445
		/* See if player was kicked */
dvander@644
   446
		if (!pPlayer->IsConnected())
dvander@644
   447
		{
dvander@644
   448
			return;
dvander@644
   449
		}
dvander@591
   450
	}
dvander@591
   451
dvander@591
   452
	m_Players[client].Connect();
dvander@591
   453
	m_PlayerCount++;
dvander@591
   454
	m_clputinserver->PushCell(client);
dvander@591
   455
	m_clputinserver->Execute(&res, NULL);
dvander@591
   456
}
dvander@591
   457
dvander@916
   458
void PlayerManager::OnSourceModLevelEnd()
dvander@916
   459
{
dvander@916
   460
	/* Disconnect all bots still in game */
dvander@916
   461
	for (int i=1; i<=m_maxClients; i++)
dvander@916
   462
	{
dvander@916
   463
		if (m_Players[i].IsConnected() && m_Players[i].IsFakeClient())
dvander@916
   464
		{
dvander@916
   465
			OnClientDisconnect(m_Players[i].GetEdict());
dvander@916
   466
		}
dvander@916
   467
	}
dvander@916
   468
}
dvander@916
   469
dvander@616
   470
void PlayerManager::OnClientDisconnect(edict_t *pEntity)
dvander@591
   471
{
dvander@591
   472
	cell_t res;
dvander@591
   473
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   474
dvander@591
   475
	if (m_Players[client].IsConnected())
dvander@591
   476
	{
dvander@591
   477
		m_cldisconnect->PushCell(client);
dvander@591
   478
		m_cldisconnect->Execute(&res, NULL);
dvander@591
   479
	}
dvander@591
   480
dvander@591
   481
	if (m_Players[client].IsInGame())
dvander@591
   482
	{
dvander@591
   483
		m_PlayerCount--;
dvander@591
   484
	}
dvander@591
   485
dvander@591
   486
	List<IClientListener *>::iterator iter;
dvander@591
   487
	IClientListener *pListener = NULL;
dvander@591
   488
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   489
	{
dvander@591
   490
		pListener = (*iter);
dvander@591
   491
		pListener->OnClientDisconnecting(client);
dvander@591
   492
	}
dvander@591
   493
dvander@591
   494
	/**
dvander@591
   495
	 * Remove client from auth queue if necessary
dvander@591
   496
	 */
dvander@591
   497
	if (!m_Players[client].IsAuthorized())
dvander@591
   498
	{
dvander@591
   499
		for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
dvander@591
   500
		{
dvander@591
   501
			if (m_AuthQueue[i] == (unsigned)client)
dvander@591
   502
			{
dvander@591
   503
				/* Move everything ahead of us back by one */
dvander@591
   504
				for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
dvander@591
   505
				{
dvander@591
   506
					m_AuthQueue[j-1] = m_AuthQueue[j];
dvander@591
   507
				}
dvander@591
   508
				/* Remove us and break */
dvander@591
   509
				m_AuthQueue[0]--;
dvander@591
   510
				break;
dvander@591
   511
			}
dvander@591
   512
		}
dvander@591
   513
	}
dvander@591
   514
dvander@591
   515
	m_Players[client].Disconnect();
faluco@682
   516
	m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = 0;
dvander@591
   517
}
dvander@591
   518
dvander@616
   519
void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
dvander@591
   520
{
dvander@591
   521
	cell_t res;
dvander@591
   522
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   523
dvander@591
   524
	m_cldisconnect_post->PushCell(client);
dvander@591
   525
	m_cldisconnect_post->Execute(&res, NULL);
dvander@591
   526
dvander@591
   527
	List<IClientListener *>::iterator iter;
dvander@591
   528
	IClientListener *pListener = NULL;
dvander@591
   529
	for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@591
   530
	{
dvander@591
   531
		pListener = (*iter);
dvander@591
   532
		pListener->OnClientDisconnected(client);
dvander@591
   533
	}
dvander@591
   534
}
dvander@591
   535
dvander@616
   536
void PlayerManager::OnClientCommand(edict_t *pEntity)
dvander@591
   537
{
dvander@780
   538
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   539
	cell_t res = Pl_Continue;
dvander@591
   540
dvander@769
   541
	bool result = g_ValveMenuStyle.OnClientCommand(client);
dvander@769
   542
	if (result)
dvander@769
   543
	{
dvander@769
   544
		res = Pl_Handled;
dvander@780
   545
	} else {
dvander@780
   546
		result = g_RadioMenuStyle.OnClientCommand(client);
dvander@780
   547
		if (result)
dvander@780
   548
		{
dvander@780
   549
			res = Pl_Handled;
dvander@780
   550
		}
dvander@780
   551
	}
dvander@780
   552
dvander@780
   553
	int args = engine->Cmd_Argc() - 1;
dvander@780
   554
dvander@780
   555
	cell_t res2 = Pl_Continue;
dvander@780
   556
	m_clcommand->PushCell(client);
dvander@780
   557
	m_clcommand->PushCell(args);
dvander@780
   558
	m_clcommand->Execute(&res2, NULL);
dvander@780
   559
dvander@780
   560
	if (res2 > res)
dvander@780
   561
	{
dvander@780
   562
		res = res2;
dvander@780
   563
	}
dvander@780
   564
dvander@780
   565
	if (res >= Pl_Stop)
dvander@780
   566
	{
dvander@780
   567
		RETURN_META(MRES_SUPERCEDE);
dvander@769
   568
	}
dvander@769
   569
dvander@591
   570
	res = g_ConCmds.DispatchClientCommand(client, (ResultType)res);
dvander@591
   571
dvander@591
   572
	if (res >= Pl_Handled)
dvander@591
   573
	{
dvander@591
   574
		RETURN_META(MRES_SUPERCEDE);
dvander@591
   575
	}
dvander@591
   576
}
dvander@591
   577
dvander@616
   578
void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
dvander@591
   579
{
dvander@591
   580
	cell_t res;
dvander@591
   581
	int client = engine->IndexOfEdict(pEntity);
dvander@591
   582
dvander@591
   583
	m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
dvander@591
   584
	m_clinfochanged->Execute(&res, NULL);
dvander@1161
   585
dvander@1161
   586
	IPlayerInfo *info = m_Players[client].GetPlayerInfo();
dvander@1161
   587
	const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
dvander@1161
   588
	const char *old_name = m_Players[client].m_Name.c_str();
dvander@1161
   589
dvander@1161
   590
	if (strcmp(old_name, new_name) != 0)
dvander@1161
   591
	{
dvander@1161
   592
		AdminId id = g_Admins.FindAdminByIdentity("name", new_name);
dvander@1161
   593
		if (id != INVALID_ADMIN_ID && m_Players[client].GetAdminId() != id)
dvander@1161
   594
		{
dvander@1161
   595
			if (!CheckSetAdminName(client, &m_Players[client], id))
dvander@1161
   596
			{
dvander@1161
   597
				m_Players[client].Kick("Your name is reserved by SourceMod; set your password to use it.");
dvander@1161
   598
				RETURN_META(MRES_IGNORED);
dvander@1161
   599
			}
dvander@1161
   600
		} else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
dvander@1161
   601
			if (id == m_Players[client].GetAdminId())
dvander@1161
   602
			{
dvander@1161
   603
				/* This player is changing their name; force them to drop admin privileges! */
dvander@1161
   604
				m_Players[client].SetAdminId(INVALID_ADMIN_ID, false);
dvander@1161
   605
			}
dvander@1161
   606
		}
dvander@1161
   607
		m_Players[client].SetName(new_name);
dvander@1161
   608
	}
dvander@1161
   609
	
dvander@1161
   610
	if (m_PassInfoVar.size() > 0)
dvander@1161
   611
	{
dvander@1161
   612
		/* Try for a password change */
dvander@1161
   613
		const char *old_pass = m_Players[client].m_LastPassword.c_str();
dvander@1161
   614
		const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str());
dvander@1161
   615
		if (strcmp(old_pass, new_pass) != 0)
dvander@1161
   616
		{
dvander@1161
   617
			m_Players[client].m_LastPassword.assign(new_pass);
dvander@1161
   618
			if (m_Players[client].IsInGame() && m_Players[client].IsAuthorized())
dvander@1161
   619
			{
dvander@1161
   620
				/* If there is already an admin id assigned, this will just bail out. */
dvander@1161
   621
				m_Players[client].DoBasicAdminChecks();
dvander@1161
   622
			}
dvander@1161
   623
		}
dvander@1161
   624
	}
dvander@591
   625
}
dvander@591
   626
dvander@616
   627
int PlayerManager::GetMaxClients()
dvander@591
   628
{
dvander@591
   629
	return m_maxClients;
dvander@591
   630
}
dvander@591
   631
dvander@616
   632
CPlayer *PlayerManager::GetPlayerByIndex(int client) const
dvander@591
   633
{
dvander@591
   634
	if (client > m_maxClients || client < 1)
dvander@591
   635
	{
dvander@591
   636
		return NULL;
dvander@591
   637
	}
dvander@591
   638
	return &m_Players[client];
dvander@591
   639
}
dvander@591
   640
dvander@616
   641
int PlayerManager::GetNumPlayers()
dvander@591
   642
{
dvander@591
   643
	return m_PlayerCount;
dvander@591
   644
}
dvander@591
   645
faluco@682
   646
int PlayerManager::GetClientOfUserId(int userid)
faluco@682
   647
{
dvander@719
   648
	if (userid < 0 || userid > USHRT_MAX)
dvander@719
   649
	{
dvander@719
   650
		return 0;
dvander@719
   651
	}
dvander@719
   652
	
dvander@719
   653
	int client = m_UserIdLookUp[userid];
dvander@719
   654
dvander@719
   655
	/* Verify the userid.  The cache can get messed up with older
dvander@719
   656
	 * Valve engines.  :TODO: If this gets fixed, do an old engine 
dvander@719
   657
	 * check before invoking this backwards compat code.
dvander@719
   658
	 */
dvander@719
   659
	if (client)
dvander@719
   660
	{
dvander@719
   661
		CPlayer *player = GetPlayerByIndex(client);
dvander@719
   662
		if (player && player->IsConnected())
dvander@719
   663
		{
dvander@719
   664
			int realUserId = engine->GetPlayerUserId(player->GetEdict());
dvander@719
   665
			if (realUserId == userid)
dvander@719
   666
			{
dvander@719
   667
				return client;
dvander@719
   668
			}
dvander@719
   669
		}
dvander@719
   670
	}
dvander@719
   671
dvander@719
   672
	/* If we can't verify the userid, we have to do a manual loop */
dvander@719
   673
	CPlayer *player;
dvander@719
   674
	for (int i = 1; i <= m_maxClients; i++)
dvander@719
   675
	{
dvander@719
   676
		player = GetPlayerByIndex(i);
dvander@719
   677
		if (!player || !player->IsConnected())
dvander@719
   678
		{
dvander@719
   679
			continue;
dvander@719
   680
		}
dvander@719
   681
		if (engine->GetPlayerUserId(player->GetEdict()) == userid)
dvander@719
   682
		{
dvander@720
   683
			m_UserIdLookUp[userid] = i;
dvander@719
   684
			return i;
dvander@719
   685
		}
dvander@719
   686
	}
dvander@719
   687
dvander@719
   688
	return 0;
faluco@682
   689
}
faluco@682
   690
dvander@616
   691
void PlayerManager::AddClientListener(IClientListener *listener)
dvander@591
   692
{
dvander@591
   693
	m_hooks.push_back(listener);
dvander@591
   694
}
dvander@591
   695
dvander@616
   696
void PlayerManager::RemoveClientListener(IClientListener *listener)
dvander@591
   697
{
dvander@591
   698
	m_hooks.remove(listener);
dvander@591
   699
}
dvander@591
   700
dvander@616
   701
IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict)
dvander@591
   702
{
dvander@591
   703
	int index = engine->IndexOfEdict(pEdict);
dvander@591
   704
	return GetGamePlayer(index);
dvander@591
   705
}
dvander@591
   706
dvander@616
   707
IGamePlayer *PlayerManager::GetGamePlayer(int client)
dvander@591
   708
{
dvander@591
   709
	return GetPlayerByIndex(client);
dvander@591
   710
}
dvander@591
   711
dvander@616
   712
void PlayerManager::ClearAdminId(AdminId id)
dvander@591
   713
{
dvander@591
   714
	for (int i=1; i<=m_maxClients; i++)
dvander@591
   715
	{
dvander@591
   716
		if (m_Players[i].m_Admin == id)
dvander@591
   717
		{
dvander@591
   718
			m_Players[i].DumpAdmin(true);
dvander@591
   719
		}
dvander@591
   720
	}
dvander@591
   721
}
dvander@591
   722
dvander@616
   723
void PlayerManager::ClearAllAdmins()
dvander@591
   724
{
dvander@591
   725
	for (int i=1; i<=m_maxClients; i++)
dvander@591
   726
	{
dvander@591
   727
		m_Players[i].DumpAdmin(true);
dvander@591
   728
	}
dvander@591
   729
}
dvander@591
   730
dvander@1161
   731
const char *PlayerManager::GetPassInfoVar()
dvander@1161
   732
{
dvander@1161
   733
	return m_PassInfoVar.c_str();
dvander@1161
   734
}
dvander@591
   735
dvander@1162
   736
void PlayerManager::RecheckAnyAdmins()
dvander@1162
   737
{
dvander@1162
   738
	for (int i=1; i<=m_maxClients; i++)
dvander@1162
   739
	{
dvander@1162
   740
		if (m_Players[i].IsInGame() && m_Players[i].IsAuthorized())
dvander@1162
   741
		{
dvander@1162
   742
			m_Players[i].DoBasicAdminChecks();
dvander@1162
   743
		}
dvander@1162
   744
	}
dvander@1162
   745
}
dvander@1162
   746
dvander@1162
   747
dvander@591
   748
/*******************
dvander@591
   749
 *** PLAYER CODE ***
dvander@591
   750
 *******************/
dvander@591
   751
dvander@591
   752
CPlayer::CPlayer()
dvander@591
   753
{
dvander@591
   754
	m_IsConnected = false;
dvander@591
   755
	m_IsInGame = false;
dvander@591
   756
	m_IsAuthorized = false;
dvander@591
   757
	m_pEdict = NULL;
dvander@591
   758
	m_Admin = INVALID_ADMIN_ID;
dvander@591
   759
	m_TempAdmin = false;
dvander@644
   760
	m_Info = NULL;
dvander@1273
   761
	m_bAdminCheckSignalled = false;
dvander@1161
   762
	m_LastPassword.clear();
dvander@591
   763
}
dvander@591
   764
dvander@591
   765
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
dvander@591
   766
{
dvander@591
   767
	m_IsConnected = true;
dvander@591
   768
	m_Name.assign(name);
dvander@591
   769
	m_Ip.assign(ip);
dvander@591
   770
	m_pEdict = pEntity;
dvander@1273
   771
	m_iIndex = engine->IndexOfEdict(pEntity);
dvander@1161
   772
dvander@1161
   773
	char ip2[24], *ptr;
dvander@1161
   774
	strncopy(ip2, ip, sizeof(ip2));
dvander@1161
   775
	if ((ptr = strchr(ip2, ':')) != NULL)
dvander@1161
   776
	{
dvander@1161
   777
		*ptr = '\0';
dvander@1161
   778
	}
dvander@1161
   779
	m_IpNoPort.assign(ip2);
dvander@591
   780
}
dvander@591
   781
dvander@591
   782
void CPlayer::Connect()
dvander@591
   783
{
dvander@1161
   784
	if (m_IsInGame)
dvander@1161
   785
	{
dvander@1161
   786
		return;
dvander@1161
   787
	}
dvander@1161
   788
dvander@591
   789
	m_IsInGame = true;
dvander@1161
   790
dvander@1161
   791
	const char *var = g_Players.GetPassInfoVar();
dvander@1161
   792
	int client = engine->IndexOfEdict(m_pEdict);
dvander@1161
   793
	if (var[0] != '\0')
dvander@1161
   794
	{
dvander@1161
   795
		const char *pass = engine->GetClientConVarValue(client, var);
dvander@1161
   796
		m_LastPassword.assign(pass ? pass : "");
dvander@1161
   797
	} else {
dvander@1161
   798
		m_LastPassword.assign("");
dvander@1161
   799
	}
dvander@1161
   800
dvander@1161
   801
	if (m_IsAuthorized)
dvander@1161
   802
	{
dvander@1273
   803
		DoPostConnectAuthorization();
dvander@1161
   804
	}
dvander@591
   805
}
dvander@591
   806
dvander@591
   807
void CPlayer::Authorize(const char *steamid)
dvander@591
   808
{
dvander@1161
   809
	if (m_IsAuthorized)
dvander@1161
   810
	{
dvander@1161
   811
		return;
dvander@1161
   812
	}
dvander@1161
   813
dvander@591
   814
	m_IsAuthorized = true;
dvander@591
   815
	m_AuthID.assign(steamid);
dvander@591
   816
}
dvander@591
   817
dvander@591
   818
void CPlayer::Disconnect()
dvander@591
   819
{
dvander@591
   820
	DumpAdmin(false);
dvander@591
   821
	m_IsConnected = false;
dvander@591
   822
	m_IsInGame = false;
dvander@591
   823
	m_IsAuthorized = false;
dvander@591
   824
	m_Name.clear();
dvander@591
   825
	m_Ip.clear();
dvander@591
   826
	m_AuthID.clear();
dvander@591
   827
	m_pEdict = NULL;
dvander@644
   828
	m_Info = NULL;
dvander@1273
   829
	m_bAdminCheckSignalled = false;
dvander@591
   830
}
dvander@591
   831
dvander@591
   832
void CPlayer::SetName(const char *name)
dvander@591
   833
{
dvander@591
   834
	m_Name.assign(name);
dvander@591
   835
}
dvander@591
   836
dvander@615
   837
const char *CPlayer::GetName()
dvander@591
   838
{
faluco@658
   839
	return (m_Info) ? m_Info->GetName(): m_Name.c_str();
dvander@591
   840
}
dvander@591
   841
dvander@615
   842
const char *CPlayer::GetIPAddress()
dvander@591
   843
{
dvander@591
   844
	return m_Ip.c_str();
dvander@591
   845
}
dvander@591
   846
dvander@615
   847
const char *CPlayer::GetAuthString()
dvander@591
   848
{
dvander@591
   849
	return m_AuthID.c_str();
dvander@591
   850
}
dvander@591
   851
dvander@615
   852
edict_t *CPlayer::GetEdict()
dvander@591
   853
{
dvander@591
   854
	return m_pEdict;
dvander@591
   855
}
dvander@591
   856
dvander@615
   857
bool CPlayer::IsInGame()
dvander@591
   858
{
dvander@591
   859
	return m_IsInGame;
dvander@591
   860
}
dvander@591
   861
dvander@615
   862
bool CPlayer::IsConnected()
dvander@591
   863
{
dvander@591
   864
	return m_IsConnected;
dvander@591
   865
}
dvander@591
   866
dvander@615
   867
bool CPlayer::IsAuthorized()
dvander@591
   868
{
dvander@591
   869
	return m_IsAuthorized;
dvander@591
   870
}
dvander@591
   871
dvander@644
   872
IPlayerInfo *CPlayer::GetPlayerInfo()
dvander@644
   873
{
dvander@644
   874
	return m_Info;
dvander@644
   875
}
dvander@644
   876
dvander@615
   877
bool CPlayer::IsFakeClient()
dvander@591
   878
{
dvander@591
   879
	return (strcmp(m_AuthID.c_str(), "BOT") == 0);
dvander@591
   880
}
dvander@591
   881
dvander@591
   882
void CPlayer::SetAdminId(AdminId id, bool temporary)
dvander@591
   883
{
dvander@591
   884
	if (!m_IsConnected)
dvander@591
   885
	{
dvander@591
   886
		return;
dvander@591
   887
	}
dvander@591
   888
dvander@591
   889
	DumpAdmin(false);
dvander@591
   890
dvander@591
   891
	m_Admin = id;
dvander@591
   892
	m_TempAdmin = temporary;
dvander@591
   893
}
dvander@591
   894
dvander@615
   895
AdminId CPlayer::GetAdminId()
dvander@591
   896
{
dvander@591
   897
	return m_Admin;
dvander@591
   898
}
dvander@591
   899
dvander@591
   900
void CPlayer::DumpAdmin(bool deleting)
dvander@591
   901
{
dvander@591
   902
	if (m_Admin != INVALID_ADMIN_ID)
dvander@591
   903
	{
dvander@591
   904
		if (m_TempAdmin && !deleting)
dvander@591
   905
		{
dvander@591
   906
			g_Admins.InvalidateAdmin(m_Admin);
dvander@591
   907
		}
dvander@591
   908
		m_Admin = INVALID_ADMIN_ID;
dvander@591
   909
		m_TempAdmin = false;
dvander@591
   910
	}
dvander@591
   911
}
dvander@1161
   912
dvander@1161
   913
void CPlayer::Kick(const char *str)
dvander@1161
   914
{
dvander@1273
   915
	INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex));
dvander@1161
   916
	IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
dvander@1161
   917
	pClient->Disconnect("%s", str);
dvander@1161
   918
}
dvander@1161
   919
dvander@1161
   920
void CPlayer::Authorize_Post()
dvander@1161
   921
{
dvander@1161
   922
	if (m_IsInGame)
dvander@1161
   923
	{
dvander@1273
   924
		DoPostConnectAuthorization();
dvander@1273
   925
	}
dvander@1273
   926
}
dvander@1273
   927
dvander@1273
   928
void CPlayer::DoPostConnectAuthorization()
dvander@1273
   929
{
dvander@1288
   930
	cell_t result = 0;
dvander@1273
   931
	PreAdminCheck->PushCell(m_iIndex);
dvander@1273
   932
	PreAdminCheck->Execute(&result);
dvander@1273
   933
dvander@1273
   934
	/* Defer, for better or worse */
dvander@1273
   935
	if ((ResultType)result >= Pl_Handled)
dvander@1273
   936
	{
dvander@1273
   937
		return;
dvander@1273
   938
	}
dvander@1273
   939
dvander@1273
   940
	/* Sanity check */
dvander@1273
   941
	if (!IsConnected())
dvander@1273
   942
	{
dvander@1273
   943
		return;
dvander@1161
   944
	}
dvander@1273
   945
dvander@1273
   946
	/* Otherwise, go ahead and do admin checks */
dvander@1273
   947
	DoBasicAdminChecks();
dvander@1273
   948
dvander@1273
   949
	/* Send the notification out */
dvander@1273
   950
	NotifyPostAdminChecks();
dvander@1273
   951
}
dvander@1273
   952
dvander@1273
   953
void CPlayer::NotifyPostAdminChecks()
dvander@1273
   954
{
dvander@1273
   955
	if (m_bAdminCheckSignalled)
dvander@1273
   956
	{
dvander@1273
   957
		return;
dvander@1273
   958
	}
dvander@1273
   959
dvander@1273
   960
	/* Block beforehand so they can't double-call */
dvander@1273
   961
	m_bAdminCheckSignalled = true;
dvander@1273
   962
dvander@1273
   963
	PostAdminCheck->PushCell(m_iIndex);
dvander@1273
   964
	PostAdminCheck->Execute(NULL);
dvander@1161
   965
}
dvander@1161
   966
dvander@1161
   967
void CPlayer::DoBasicAdminChecks()
dvander@1161
   968
{
dvander@1161
   969
	if (GetAdminId() != INVALID_ADMIN_ID)
dvander@1161
   970
	{
dvander@1161
   971
		return;
dvander@1161
   972
	}
dvander@1161
   973
dvander@1161
   974
	/* First check the name */
dvander@1161
   975
	AdminId id;
dvander@1161
   976
	int client = engine->IndexOfEdict(m_pEdict);
dvander@1161
   977
dvander@1161
   978
	if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
dvander@1161
   979
	{
dvander@1161
   980
		if (!g_Players.CheckSetAdminName(client, this, id))
dvander@1161
   981
		{
dvander@1161
   982
			int userid = engine->GetPlayerUserId(m_pEdict);
dvander@1161
   983
			g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
dvander@1161
   984
		}
dvander@1161
   985
		return;
dvander@1161
   986
	}
dvander@1161
   987
	
dvander@1161
   988
	/* Check IP */
dvander@1161
   989
	if ((id = g_Admins.FindAdminByIdentity("ip", m_IpNoPort.c_str())) != INVALID_ADMIN_ID)
dvander@1161
   990
	{
dvander@1161
   991
		if (g_Players.CheckSetAdmin(client, this, id))
dvander@1161
   992
		{
dvander@1161
   993
			return;
dvander@1161
   994
		}
dvander@1161
   995
	}
dvander@1161
   996
dvander@1161
   997
	/* Check IP address */
dvander@1161
   998
	if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
dvander@1161
   999
	{
dvander@1161
  1000
		if (g_Players.CheckSetAdmin(client, this, id))
dvander@1161
  1001
		{
dvander@1161
  1002
			return;
dvander@1161
  1003
		}
dvander@1161
  1004
	}
dvander@1161
  1005
}