core/smn_player.cpp
author Scott Ehlert <ds@alliedmods.net>
Fri Mar 21 04:26:53 2008 +0000 (2008-03-21)
changeset 1944 17984feecafd
parent 1936 89d6e5038933
child 1947 e73a1e51833b
permissions -rw-r--r--
Merged crash fix (amb1539) from 1.0.1 branch
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "PlayerManager.h"
    33 #include "AdminCache.h"
    34 #include "sm_stringutil.h"
    35 #include "HalfLife2.h"
    36 #include "sourcemod.h"
    37 #include "ChatTriggers.h"
    38 #include <inetchannel.h>
    39 #include <iclient.h>
    40 
    41 ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY, "Activity display setting (see sourcemod.cfg)");
    42 
    43 static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
    44 {
    45 	if (params[1])
    46 	{
    47 		return g_Players.NumPlayers();
    48 	}
    49 
    50 	int maxplayers = g_Players.MaxClients();
    51 	int count = 0;
    52 	for (int i=1; i<=maxplayers; ++i)
    53 	{
    54 		CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
    55 		if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
    56 		{
    57 			count++;
    58 		}
    59 	}
    60 
    61 	return (g_Players.NumPlayers() + count);
    62 }
    63 
    64 static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
    65 {
    66 	return g_Players.MaxClients();
    67 }
    68 
    69 static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
    70 {
    71 	int index = params[1];
    72 
    73 	if (index == 0)
    74 	{
    75 		static ConVar *hostname = NULL;
    76 		if (!hostname)
    77 		{
    78 			hostname = icvar->FindVar("hostname");
    79 			if (!hostname)
    80 			{
    81 				return pCtx->ThrowNativeError("Could not find \"hostname\" cvar");
    82 			}
    83 		}
    84 		pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), hostname->GetString(), NULL);
    85 		return 1;
    86 	}
    87 
    88 	if ((index < 1) || (index > g_Players.GetMaxClients()))
    89 	{
    90 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
    91 	}
    92 
    93 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
    94 	if (!pPlayer->IsConnected())
    95 	{
    96 		return pCtx->ThrowNativeError("Client %d is not connected", index);
    97 	}
    98 
    99 	pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pPlayer->GetName(), NULL);
   100 	return 1;
   101 }
   102 
   103 static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
   104 {
   105 	int index = params[1];
   106 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   107 	{
   108 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   109 	}
   110 
   111 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
   112 	if (!pPlayer->IsConnected())
   113 	{
   114 		return pCtx->ThrowNativeError("Client %d is not connected", index);
   115 	}
   116 
   117 	char buf[64], *ptr;
   118 	strcpy(buf, pPlayer->GetIPAddress());
   119 
   120 	if (params[4] && (ptr = strchr(buf, ':')))
   121 	{
   122 		*ptr = '\0';
   123 	}
   124 
   125 	pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), buf);
   126 	return 1;
   127 }
   128 
   129 static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
   130 {
   131 	int index = params[1];
   132 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   133 	{
   134 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   135 	}
   136 
   137 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
   138 	if (!pPlayer->IsConnected())
   139 	{
   140 		return pCtx->ThrowNativeError("Client %d is not connected", index);
   141 	}
   142 
   143 	if (!pPlayer->IsAuthorized())
   144 	{
   145 		return 0;
   146 	}
   147 
   148 	pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
   149 
   150 	return 1;
   151 }
   152 
   153 static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
   154 {
   155 	int index = params[1];
   156 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   157 	{
   158 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   159 	}
   160 
   161 	return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
   162 }
   163 
   164 static cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
   165 {
   166 	int index = params[1];
   167 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   168 	{
   169 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   170 	}
   171 
   172 	return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
   173 }
   174 
   175 static cell_t sm_IsClientAuthorized(IPluginContext *pCtx, const cell_t *params)
   176 {
   177 	int index = params[1];
   178 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   179 	{
   180 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   181 	}
   182 
   183 	return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
   184 }
   185 
   186 static cell_t sm_IsClientFakeClient(IPluginContext *pCtx, const cell_t *params)
   187 {
   188 	int index = params[1];
   189 	if ((index < 1) || (index > g_Players.GetMaxClients()))
   190 	{
   191 		return pCtx->ThrowNativeError("Client index %d is invalid", index);
   192 	}
   193 
   194 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
   195 	if (!pPlayer->IsConnected())
   196 	{
   197 		return pCtx->ThrowNativeError("Client %d is not connected", index);
   198 	}
   199 
   200 	return (pPlayer->IsFakeClient()) ? 1 : 0;
   201 }
   202 
   203 static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
   204 {
   205 	int client = params[1];
   206 
   207 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   208 	if (!pPlayer)
   209 	{
   210 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   211 	} else if (!pPlayer->IsInGame()) {
   212 		return pContext->ThrowNativeError("Client %d is not in game", client);
   213 	}
   214 
   215 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   216 	if (!pInfo)
   217 	{
   218 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   219 	}
   220 
   221 	return pInfo->IsObserver() ? 1 : 0;
   222 }
   223 
   224 static cell_t sm_GetClientInfo(IPluginContext *pContext, const cell_t *params)
   225 {
   226 	int client = params[1];
   227 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   228 	if (!pPlayer)
   229 	{
   230 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   231 	}
   232 	if (!pPlayer->IsConnected())
   233 	{
   234 		return pContext->ThrowNativeError("Client %d is not connected", client);
   235 	}
   236 
   237 	char *key;
   238 	pContext->LocalToString(params[2], &key);
   239 
   240 	const char *val = engine->GetClientConVarValue(client, key);
   241 	if (!val)
   242 	{
   243 		return false;
   244 	}
   245 
   246 	pContext->StringToLocalUTF8(params[3], params[4], val, NULL);
   247 	return 1;
   248 }
   249 
   250 static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
   251 {
   252 	int client = params[1];
   253 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   254 	if (!pPlayer)
   255 	{
   256 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   257 	}
   258 	if (!pPlayer->IsConnected())
   259 	{
   260 		return pContext->ThrowNativeError("Client %d is not connected", client);
   261 	}
   262 	if (!g_Admins.IsValidAdmin(params[2]) && params[2] != INVALID_ADMIN_ID)
   263 	{
   264 		return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
   265 	}
   266 
   267 	pPlayer->SetAdminId(params[2], params[3] ? true : false);
   268 
   269 	return 1;
   270 }
   271 
   272 static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
   273 {
   274 	int client = params[1];
   275 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   276 	if (!pPlayer)
   277 	{
   278 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   279 	}
   280 	if (!pPlayer->IsConnected())
   281 	{
   282 		return pContext->ThrowNativeError("Client %d is not connected", client);
   283 	}
   284 
   285 	return pPlayer->GetAdminId();
   286 }
   287 
   288 static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
   289 {
   290 	int client = params[1];
   291 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   292 	if (!pPlayer)
   293 	{
   294 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   295 	}
   296 	if (!pPlayer->IsConnected())
   297 	{
   298 		return pContext->ThrowNativeError("Client %d is not connected", client);
   299 	}
   300 
   301 	AdminId id;
   302 	if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
   303 	{
   304 		id = g_Admins.CreateAdmin(NULL);
   305 		pPlayer->SetAdminId(id, true);
   306 	}
   307 
   308 	cell_t *addr;
   309 	for (int i=2; i<=params[0]; i++)
   310 	{
   311 		pContext->LocalToPhysAddr(params[i], &addr);
   312 		g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
   313 	}
   314 
   315 	return 1;
   316 }
   317 
   318 static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
   319 {
   320 	int client = params[1];
   321 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   322 	if (!pPlayer)
   323 	{
   324 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   325 	}
   326 	if (!pPlayer->IsConnected())
   327 	{
   328 		return pContext->ThrowNativeError("Client %d is not connected", client);
   329 	}
   330 	
   331 	AdminId id;
   332 	if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
   333 	{
   334 		return 0;
   335 	}
   336 
   337 	cell_t *addr;
   338 	for (int i=2; i<=params[0]; i++)
   339 	{
   340 		pContext->LocalToPhysAddr(params[i], &addr);
   341 		g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
   342 	}
   343 
   344 	return 1;
   345 }
   346 
   347 static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
   348 {
   349 	int client = params[1];
   350 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   351 	if (!pPlayer)
   352 	{
   353 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   354 	}
   355 	if (!pPlayer->IsConnected())
   356 	{
   357 		return pContext->ThrowNativeError("Client %d is not connected", client);
   358 	}
   359 
   360 	AdminId id;
   361 	if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
   362 	{
   363 		id = g_Admins.CreateAdmin(NULL);
   364 		pPlayer->SetAdminId(id, true);
   365 	}
   366 
   367 	g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
   368 
   369 	return 1;
   370 }
   371 
   372 static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
   373 {
   374 	int client = params[1];
   375 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   376 	if (!pPlayer)
   377 	{
   378 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   379 	}
   380 	if (!pPlayer->IsConnected())
   381 	{
   382 		return pContext->ThrowNativeError("Client %d is not connected", client);
   383 	}
   384 
   385 	AdminId id;
   386 	if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
   387 	{
   388 		return 0;
   389 	}
   390 
   391 	return g_Admins.GetAdminFlags(id, Access_Effective);
   392 }
   393 
   394 static cell_t GetClientUserId(IPluginContext *pContext, const cell_t *params)
   395 {
   396 	int client = params[1];
   397 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   398 	if (!pPlayer)
   399 	{
   400 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   401 	}
   402 	if (!pPlayer->IsConnected())
   403 	{
   404 		return pContext->ThrowNativeError("Client %d is not connected", client);
   405 	}
   406 
   407 	return engine->GetPlayerUserId(pPlayer->GetEdict());
   408 }
   409 
   410 static cell_t CanUserTarget(IPluginContext *pContext, const cell_t *params)
   411 {
   412 	int client = params[1];
   413 	int target = params[2];
   414 
   415 	if (client == 0)
   416 	{
   417 		return 1;
   418 	}
   419 
   420 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   421 	if (!pPlayer)
   422 	{
   423 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   424 	} else if (!pPlayer->IsConnected()) {
   425 		return pContext->ThrowNativeError("Client %d is not connected", client);
   426 	}
   427 
   428 	CPlayer *pTarget = g_Players.GetPlayerByIndex(target);
   429 	if (!pTarget)
   430 	{
   431 		return pContext->ThrowNativeError("Client index %d is invalid", target);
   432 	} else if (!pTarget->IsConnected()) {
   433 		return pContext->ThrowNativeError("Client %d is not connected", target);
   434 	}
   435 
   436 	return g_Admins.CanAdminTarget(pPlayer->GetAdminId(), pTarget->GetAdminId()) ? 1 : 0;
   437 }
   438 
   439 static cell_t GetClientTeam(IPluginContext *pContext, const cell_t *params)
   440 {
   441 	int client = params[1];
   442 
   443 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   444 	if (!pPlayer)
   445 	{
   446 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   447 	} else if (!pPlayer->IsInGame()) {
   448 		return pContext->ThrowNativeError("Client %d is not in game", client);
   449 	}
   450 
   451 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   452 	if (!pInfo)
   453 	{
   454 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   455 	}
   456 
   457 	return pInfo->GetTeamIndex();
   458 }
   459 
   460 static cell_t GetFragCount(IPluginContext *pContext, const cell_t *params)
   461 {
   462 	int client = params[1];
   463 
   464 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   465 	if (!pPlayer)
   466 	{
   467 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   468 	} else if (!pPlayer->IsInGame()) {
   469 		return pContext->ThrowNativeError("Client %d is not in game", client);
   470 	}
   471 
   472 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   473 	if (!pInfo)
   474 	{
   475 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   476 	}
   477 
   478 	return pInfo->GetFragCount();
   479 }
   480 
   481 static cell_t GetDeathCount(IPluginContext *pContext, const cell_t *params)
   482 {
   483 	int client = params[1];
   484 
   485 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   486 	if (!pPlayer)
   487 	{
   488 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   489 	} else if (!pPlayer->IsInGame()) {
   490 		return pContext->ThrowNativeError("Client %d is not in game", client);
   491 	}
   492 
   493 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   494 	if (!pInfo)
   495 	{
   496 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   497 	}
   498 
   499 	return pInfo->GetDeathCount();
   500 }
   501 
   502 static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params)
   503 {
   504 	int client = params[1];
   505 
   506 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   507 	if (!pPlayer)
   508 	{
   509 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   510 	} else if (!pPlayer->IsInGame()) {
   511 		return pContext->ThrowNativeError("Client %d is not in game", client);
   512 	}
   513 
   514 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   515 	if (!pInfo)
   516 	{
   517 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   518 	}
   519 
   520 	return pInfo->GetArmorValue();
   521 }
   522 
   523 static cell_t GetAbsOrigin(IPluginContext *pContext, const cell_t *params)
   524 {
   525 	int client = params[1];
   526 
   527 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   528 	if (!pPlayer)
   529 	{
   530 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   531 	} else if (!pPlayer->IsInGame()) {
   532 		return pContext->ThrowNativeError("Client %d is not in game", client);
   533 	}
   534 
   535 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   536 	if (!pInfo)
   537 	{
   538 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   539 	}
   540 
   541 	cell_t *pVec;
   542 	pContext->LocalToPhysAddr(params[2], &pVec);
   543 
   544 	Vector vec = pInfo->GetAbsOrigin();
   545 	pVec[0] = sp_ftoc(vec.x);
   546 	pVec[1] = sp_ftoc(vec.y);
   547 	pVec[2] = sp_ftoc(vec.z);
   548 
   549 	return 1;
   550 }
   551 
   552 static cell_t GetAbsAngles(IPluginContext *pContext, const cell_t *params)
   553 {
   554 	int client = params[1];
   555 
   556 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   557 	if (!pPlayer)
   558 	{
   559 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   560 	} else if (!pPlayer->IsInGame()) {
   561 		return pContext->ThrowNativeError("Client %d is not in game", client);
   562 	}
   563 
   564 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   565 	if (!pInfo)
   566 	{
   567 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   568 	}
   569 
   570 	cell_t *pAng;
   571 	pContext->LocalToPhysAddr(params[2], &pAng);
   572 
   573 	QAngle ang = pInfo->GetAbsAngles();
   574 	pAng[0] = sp_ftoc(ang.x);
   575 	pAng[1] = sp_ftoc(ang.y);
   576 	pAng[2] = sp_ftoc(ang.z);
   577 
   578 	return 1;
   579 }
   580 
   581 static cell_t GetPlayerMins(IPluginContext *pContext, const cell_t *params)
   582 {
   583 	int client = params[1];
   584 
   585 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   586 	if (!pPlayer)
   587 	{
   588 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   589 	} else if (!pPlayer->IsInGame()) {
   590 		return pContext->ThrowNativeError("Client %d is not in game", client);
   591 	}
   592 
   593 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   594 	if (!pInfo)
   595 	{
   596 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   597 	}
   598 
   599 	cell_t *pVec;
   600 	pContext->LocalToPhysAddr(params[2], &pVec);
   601 
   602 	Vector vec = pInfo->GetPlayerMins();
   603 	pVec[0] = sp_ftoc(vec.x);
   604 	pVec[1] = sp_ftoc(vec.y);
   605 	pVec[2] = sp_ftoc(vec.z);
   606 
   607 	return 1;
   608 }
   609 
   610 static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params)
   611 {
   612 	int client = params[1];
   613 
   614 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   615 	if (!pPlayer)
   616 	{
   617 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   618 	} else if (!pPlayer->IsInGame()) {
   619 		return pContext->ThrowNativeError("Client %d is not in game", client);
   620 	}
   621 
   622 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   623 	if (!pInfo)
   624 	{
   625 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   626 	}
   627 
   628 	cell_t *pVec;
   629 	pContext->LocalToPhysAddr(params[2], &pVec);
   630 
   631 	Vector vec = pInfo->GetPlayerMaxs();
   632 	pVec[0] = sp_ftoc(vec.x);
   633 	pVec[1] = sp_ftoc(vec.y);
   634 	pVec[2] = sp_ftoc(vec.z);
   635 
   636 	return 1;
   637 }
   638 
   639 static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params)
   640 {
   641 	int client = params[1];
   642 
   643 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   644 	if (!pPlayer)
   645 	{
   646 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   647 	} else if (!pPlayer->IsInGame()) {
   648 		return pContext->ThrowNativeError("Client %d is not in game", client);
   649 	}
   650 
   651 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   652 	if (!pInfo)
   653 	{
   654 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   655 	}
   656 
   657 	const char *weapon = pInfo->GetWeaponName();
   658 	pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL);
   659 
   660 	return 1;
   661 }
   662 
   663 static cell_t GetModelName(IPluginContext *pContext, const cell_t *params)
   664 {
   665 	int client = params[1];
   666 
   667 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   668 	if (!pPlayer)
   669 	{
   670 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   671 	} else if (!pPlayer->IsInGame()) {
   672 		return pContext->ThrowNativeError("Client %d is not in game", client);
   673 	}
   674 
   675 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   676 	if (!pInfo)
   677 	{
   678 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   679 	}
   680 
   681 	const char *model = pInfo->GetModelName();
   682 	pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), model ? model : "", NULL);
   683 
   684 	return 1;
   685 }
   686 
   687 static cell_t GetHealth(IPluginContext *pContext, const cell_t *params)
   688 {
   689 	int client = params[1];
   690 
   691 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   692 	if (!pPlayer)
   693 	{
   694 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   695 	} else if (!pPlayer->IsInGame()) {
   696 		return pContext->ThrowNativeError("Client %d is not in game", client);
   697 	}
   698 
   699 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
   700 	if (!pInfo)
   701 	{
   702 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
   703 	}
   704 
   705 	return pInfo->GetHealth();
   706 }
   707 
   708 static cell_t GetTimeConnected(IPluginContext *pContext, const cell_t *params)
   709 {
   710 	int client = params[1];
   711 
   712 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   713 	if (!pPlayer)
   714 	{
   715 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   716 	} else if (!pPlayer->IsInGame()) {
   717 		return pContext->ThrowNativeError("Client %d is not in game", client);
   718 	} else if (pPlayer->IsFakeClient()) {
   719 		return pContext->ThrowNativeError("Client %d is a bot", client);
   720 	}
   721 
   722 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   723 
   724 	return sp_ftoc(pInfo->GetTimeConnected());
   725 }
   726 
   727 static cell_t GetDataRate(IPluginContext *pContext, const cell_t *params)
   728 {
   729 	int client = params[1];
   730 
   731 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   732 	if (!pPlayer)
   733 	{
   734 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   735 	} else if (!pPlayer->IsInGame()) {
   736 		return pContext->ThrowNativeError("Client %d is not in game", client);
   737 	} else if (pPlayer->IsFakeClient()) {
   738 		return pContext->ThrowNativeError("Client %d is a bot", client);
   739 	}
   740 
   741 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   742 
   743 	return pInfo->GetDataRate();
   744 }
   745 
   746 static cell_t IsTimingOut(IPluginContext *pContext, const cell_t *params)
   747 {
   748 	int client = params[1];
   749 
   750 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   751 	if (!pPlayer)
   752 	{
   753 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   754 	} else if (!pPlayer->IsInGame()) {
   755 		return pContext->ThrowNativeError("Client %d is not in game", client);
   756 	} else if (pPlayer->IsFakeClient()) {
   757 		return pContext->ThrowNativeError("Client %d is a bot", client);
   758 	}
   759 
   760 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   761 
   762 	return pInfo->IsTimingOut() ? 1 : 0;
   763 }
   764 
   765 static cell_t GetLatency(IPluginContext *pContext, const cell_t *params)
   766 {
   767 	int client = params[1];
   768 
   769 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   770 	if (!pPlayer)
   771 	{
   772 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   773 	} else if (!pPlayer->IsInGame()) {
   774 		return pContext->ThrowNativeError("Client %d is not in game", client);
   775 	} else if (pPlayer->IsFakeClient()) {
   776 		return pContext->ThrowNativeError("Client %d is a bot", client);
   777 	}
   778 
   779 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   780 
   781 	return sp_ftoc(pInfo->GetLatency(params[2]));
   782 }
   783 
   784 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
   785 {
   786 	int client = params[1];
   787 
   788 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   789 	if (!pPlayer)
   790 	{
   791 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   792 	} else if (!pPlayer->IsInGame()) {
   793 		return pContext->ThrowNativeError("Client %d is not in game", client);
   794 	} else if (pPlayer->IsFakeClient()) {
   795 		return pContext->ThrowNativeError("Client %d is a bot", client);
   796 	}
   797 
   798 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   799 
   800 	return sp_ftoc(pInfo->GetAvgLatency(params[2]));
   801 }
   802 
   803 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
   804 {
   805 	int client = params[1];
   806 
   807 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   808 	if (!pPlayer)
   809 	{
   810 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   811 	} else if (!pPlayer->IsInGame()) {
   812 		return pContext->ThrowNativeError("Client %d is not in game", client);
   813 	} else if (pPlayer->IsFakeClient()) {
   814 		return pContext->ThrowNativeError("Client %d is a bot", client);
   815 	}
   816 
   817 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   818 
   819 	return sp_ftoc(pInfo->GetAvgLoss(params[2]));
   820 }
   821 
   822 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
   823 {
   824 	int client = params[1];
   825 
   826 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   827 	if (!pPlayer)
   828 	{
   829 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   830 	} else if (!pPlayer->IsInGame()) {
   831 		return pContext->ThrowNativeError("Client %d is not in game", client);
   832 	} else if (pPlayer->IsFakeClient()) {
   833 		return pContext->ThrowNativeError("Client %d is a bot", client);
   834 	}
   835 
   836 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   837 
   838 	return sp_ftoc(pInfo->GetAvgChoke(params[2]));
   839 }
   840 
   841 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
   842 {
   843 	int client = params[1];
   844 
   845 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   846 	if (!pPlayer)
   847 	{
   848 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   849 	} else if (!pPlayer->IsInGame()) {
   850 		return pContext->ThrowNativeError("Client %d is not in game", client);
   851 	} else if (pPlayer->IsFakeClient()) {
   852 		return pContext->ThrowNativeError("Client %d is a bot", client);
   853 	}
   854 
   855 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   856 
   857 	return sp_ftoc(pInfo->GetAvgData(params[2]));
   858 }
   859 
   860 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
   861 {
   862 	int client = params[1];
   863 
   864 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   865 	if (!pPlayer)
   866 	{
   867 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   868 	} else if (!pPlayer->IsInGame()) {
   869 		return pContext->ThrowNativeError("Client %d is not in game", client);
   870 	} else if (pPlayer->IsFakeClient()) {
   871 		return pContext->ThrowNativeError("Client %d is a bot", client);
   872 	}
   873 
   874 	INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
   875 
   876 	return sp_ftoc(pInfo->GetAvgPackets(params[2]));
   877 }
   878 
   879 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
   880 {
   881 	return g_Players.GetClientOfUserId(params[1]);
   882 }
   883 
   884 static cell_t _ShowActivity(IPluginContext *pContext,
   885 							const cell_t *params,
   886 							const char *tag,
   887 							cell_t fmt_param)
   888 {
   889 	char message[255];
   890 	char buffer[255];
   891 	int value = sm_show_activity.GetInt();
   892 	unsigned int replyto = g_ChatTriggers.GetReplyTo();
   893 	int client = params[1];
   894 
   895 	const char *name = "Console";
   896 	const char *sign = "ADMIN";
   897 	bool display_in_chat = false;
   898 	if (client != 0)
   899 	{
   900 		CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
   901 		if (!pPlayer || !pPlayer->IsConnected())
   902 		{
   903 			return pContext->ThrowNativeError("Client index %d is invalid", client);
   904 		}
   905 		name = pPlayer->GetName();
   906 		AdminId id = pPlayer->GetAdminId();
   907 		if (id == INVALID_ADMIN_ID
   908 			|| !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
   909 		{
   910 			sign = "PLAYER";
   911 		}
   912 
   913 		/* Display the message to the client? */
   914 		if (replyto == SM_REPLY_CONSOLE)
   915 		{
   916 			g_SourceMod.SetGlobalTarget(client);
   917 			g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
   918 
   919 			if (pContext->GetContext()->n_err != SP_ERROR_NONE)
   920 			{
   921 				return 0;
   922 			}
   923 
   924 			UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
   925 			engine->ClientPrintf(pPlayer->GetEdict(), message);
   926 			display_in_chat = true;
   927 		}
   928 	}
   929 	else
   930 	{
   931 		g_SourceMod.SetGlobalTarget(LANG_SERVER);
   932 		g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
   933 
   934 		if (pContext->GetContext()->n_err != SP_ERROR_NONE)
   935 		{
   936 			return 0;
   937 		}
   938 
   939 		UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
   940 		META_CONPRINT(message);
   941 	}
   942 
   943 	if (!value)
   944 	{
   945 		return 1;
   946 	}
   947 
   948 	int maxClients = g_Players.GetMaxClients();
   949 	for (int i=1; i<=maxClients; i++)
   950 	{
   951 		CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
   952 		if (!pPlayer->IsInGame() 
   953 			|| pPlayer->IsFakeClient()
   954 			|| (display_in_chat && i == client))
   955 		{
   956 			continue;
   957 		}
   958 		AdminId id = pPlayer->GetAdminId();
   959 		g_SourceMod.SetGlobalTarget(i);
   960 		if (id == INVALID_ADMIN_ID
   961 			|| !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
   962 		{
   963 			/* Treat this as a normal user */
   964 			if ((value & 1) || (value & 2))
   965 			{
   966 				const char *newsign = sign;
   967 				if ((value & 2) || (i == client))
   968 				{
   969 					newsign = name;
   970 				}
   971 				g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
   972 
   973 				if (pContext->GetContext()->n_err != SP_ERROR_NONE)
   974 				{
   975 					return 0;
   976 				}
   977 
   978 				UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
   979 				g_HL2.TextMsg(i, HUD_PRINTTALK, message);
   980 			}
   981 		}
   982 		else
   983 		{
   984 			/* Treat this as an admin user */
   985 			bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
   986 			if ((value & 4) 
   987 				|| (value & 8)
   988 				|| ((value & 16) && is_root))
   989 			{
   990 				const char *newsign = sign;
   991 				if ((value & 8) || ((value & 16) && is_root) || (i == client))
   992 				{
   993 					newsign = name;
   994 				}
   995 				g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
   996 
   997 				if (pContext->GetContext()->n_err != SP_ERROR_NONE)
   998 				{
   999 					return 0;
  1000 				}
  1001 
  1002 				UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
  1003 				g_HL2.TextMsg(i, HUD_PRINTTALK, message);
  1004 			}
  1005 		}
  1006 	}
  1007 
  1008 	return 1;
  1009 }
  1010 
  1011 static cell_t _ShowActivity2(IPluginContext *pContext,
  1012 							 const cell_t *params,
  1013 							 const char *tag,
  1014 							 cell_t fmt_param)
  1015 {
  1016 	char message[255];
  1017 	char buffer[255];
  1018 	int value = sm_show_activity.GetInt();
  1019 	unsigned int replyto = g_ChatTriggers.GetReplyTo();
  1020 	int client = params[1];
  1021 
  1022 	const char *name = "Console";
  1023 	const char *sign = "ADMIN";
  1024 	if (client != 0)
  1025 	{
  1026 		CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1027 		if (!pPlayer || !pPlayer->IsConnected())
  1028 		{
  1029 			return pContext->ThrowNativeError("Client index %d is invalid", client);
  1030 		}
  1031 		name = pPlayer->GetName();
  1032 		AdminId id = pPlayer->GetAdminId();
  1033 		if (id == INVALID_ADMIN_ID
  1034 			|| !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
  1035 		{
  1036 			sign = "PLAYER";
  1037 		}
  1038 
  1039 		g_SourceMod.SetGlobalTarget(client);
  1040 		g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
  1041 
  1042 		if (pContext->GetContext()->n_err != SP_ERROR_NONE)
  1043 		{
  1044 			return 0;
  1045 		}
  1046 
  1047 		/* We don't display directly to the console because the chat text 
  1048 		 * simply gets added to the console, so we don't want it to print 
  1049 		 * twice.
  1050 		 */
  1051 		if (replyto == SM_REPLY_CONSOLE)
  1052 		{
  1053 #if 0
  1054 			UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
  1055 			engine->ClientPrintf(pPlayer->GetEdict(), message);
  1056 #endif
  1057 			UTIL_Format(message, sizeof(message), "%s%s", tag, buffer);
  1058 			g_HL2.TextMsg(client, HUD_PRINTTALK, message);
  1059 		}
  1060 		else
  1061 		{
  1062 			UTIL_Format(message, sizeof(message), "%s%s", tag, buffer);
  1063 			g_HL2.TextMsg(client, HUD_PRINTTALK, message);
  1064 		}
  1065 	}
  1066 	else
  1067 	{
  1068 		g_SourceMod.SetGlobalTarget(LANG_SERVER);
  1069 		g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
  1070 
  1071 		if (pContext->GetContext()->n_err != SP_ERROR_NONE)
  1072 		{
  1073 			return 0;
  1074 		}
  1075 
  1076 		UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
  1077 		META_CONPRINT(message);
  1078 	}
  1079 
  1080 	if (!value)
  1081 	{
  1082 		return 1;
  1083 	}
  1084 
  1085 	int maxClients = g_Players.GetMaxClients();
  1086 	for (int i=1; i<=maxClients; i++)
  1087 	{
  1088 		CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
  1089 		if (!pPlayer->IsInGame() 
  1090 			|| pPlayer->IsFakeClient()
  1091 			|| i == client)
  1092 		{
  1093 			continue;
  1094 		}
  1095 		AdminId id = pPlayer->GetAdminId();
  1096 		g_SourceMod.SetGlobalTarget(i);
  1097 		if (id == INVALID_ADMIN_ID
  1098 			|| !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
  1099 		{
  1100 			/* Treat this as a normal user */
  1101 			if ((value & 1) || (value & 2))
  1102 			{
  1103 				const char *newsign = sign;
  1104 				if ((value & 2))
  1105 				{
  1106 					newsign = name;
  1107 				}
  1108 				g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
  1109 
  1110 				if (pContext->GetContext()->n_err != SP_ERROR_NONE)
  1111 				{
  1112 					return 0;
  1113 				}
  1114 
  1115 				UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
  1116 				g_HL2.TextMsg(i, HUD_PRINTTALK, message);
  1117 			}
  1118 		}
  1119 		else
  1120 		{
  1121 			/* Treat this as an admin user */
  1122 			bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
  1123 			if ((value & 4) 
  1124 				|| (value & 8)
  1125 				|| ((value & 16) && is_root))
  1126 			{
  1127 				const char *newsign = sign;
  1128 				if ((value & 8) || ((value & 16) && is_root))
  1129 				{
  1130 					newsign = name;
  1131 				}
  1132 				g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
  1133 
  1134 				if (pContext->GetContext()->n_err != SP_ERROR_NONE)
  1135 				{
  1136 					return 0;
  1137 				}
  1138 
  1139 				UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
  1140 				g_HL2.TextMsg(i, HUD_PRINTTALK, message);
  1141 			}
  1142 		}
  1143 	}
  1144 
  1145 	return 1;
  1146 }
  1147 
  1148 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
  1149 {
  1150 	return _ShowActivity(pContext, params, "[SM] ", 2);
  1151 }
  1152 
  1153 static cell_t ShowActivityEx(IPluginContext *pContext, const cell_t *params)
  1154 {
  1155 	char *str;
  1156 	pContext->LocalToString(params[2], &str);
  1157 
  1158 	return _ShowActivity(pContext, params, str, 3);
  1159 }
  1160 
  1161 static cell_t ShowActivity2(IPluginContext *pContext, const cell_t *params)
  1162 {
  1163 	char *str;
  1164 	pContext->LocalToString(params[2], &str);
  1165 
  1166 	return _ShowActivity2(pContext, params, str, 3);
  1167 }
  1168 
  1169 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
  1170 {
  1171 	int client = params[1];
  1172 
  1173 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1174 	if (!pPlayer)
  1175 	{
  1176 		return pContext->ThrowNativeError("Client index %d is invalid", client);
  1177 	} else if (!pPlayer->IsConnected()) {
  1178 		return pContext->ThrowNativeError("Client %d is not connected", client);
  1179 	}
  1180 
  1181 	pPlayer->MarkAsBeingKicked();
  1182 
  1183 	if (pPlayer->IsFakeClient())
  1184 	{
  1185 		char kickcmd[40];
  1186 		UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
  1187 
  1188 		engine->ServerCommand(kickcmd);
  1189 		return 1;
  1190 	}
  1191 
  1192 	g_SourceMod.SetGlobalTarget(client);
  1193 
  1194 	char buffer[256];
  1195 	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
  1196 
  1197 	if (pContext->GetContext()->n_err != SP_ERROR_NONE)
  1198 	{
  1199 		return 0;
  1200 	}
  1201 
  1202 	pPlayer->Kick(buffer);
  1203 
  1204 	return 1;
  1205 }
  1206 
  1207 static cell_t ChangeClientTeam(IPluginContext *pContext, const cell_t *params)
  1208 {
  1209 	int client = params[1];
  1210 
  1211 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1212 	if (!pPlayer)
  1213 	{
  1214 		return pContext->ThrowNativeError("Client index %d is invalid", client);
  1215 	}
  1216 	else if (!pPlayer->IsInGame())
  1217 	{
  1218 		return pContext->ThrowNativeError("Client %d is not in game", client);
  1219 	}
  1220 
  1221 	IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
  1222 	if (!pInfo)
  1223 	{
  1224 		return pContext->ThrowNativeError("IPlayerInfo not supported by game");
  1225 	}
  1226 
  1227 	pInfo->ChangeTeam(params[2]);
  1228 
  1229 	return 1;
  1230 }
  1231 
  1232 static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
  1233 {
  1234 	int client = params[1];
  1235 
  1236 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1237 	if (!pPlayer)
  1238 	{
  1239 		return pContext->ThrowNativeError("Client index %d is invalid", client);
  1240 	}
  1241 	else if (!pPlayer->IsInGame())
  1242 	{
  1243 		return pContext->ThrowNativeError("Client %d is not in game", client);
  1244 	}
  1245 	else if (!pPlayer->IsAuthorized())
  1246 	{
  1247 		return pContext->ThrowNativeError("Client %d is not authorized", client);
  1248 	}
  1249 
  1250 	AdminId id = pPlayer->GetAdminId();
  1251 	pPlayer->DoBasicAdminChecks();
  1252 
  1253 	return (id != pPlayer->GetAdminId()) ? 1 : 0;
  1254 }
  1255 
  1256 static cell_t NotifyPostAdminCheck(IPluginContext *pContext, const cell_t *params)
  1257 {
  1258 	int client = params[1];
  1259 
  1260 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1261 	if (!pPlayer)
  1262 	{
  1263 		return pContext->ThrowNativeError("Client index %d is invalid", client);
  1264 	}
  1265 	else if (!pPlayer->IsInGame()) {
  1266 		return pContext->ThrowNativeError("Client %d is not in game", client);
  1267 	}
  1268 	else if (!pPlayer->IsAuthorized())
  1269 	{
  1270 		return pContext->ThrowNativeError("Client %d is not authorized", client);
  1271 	}
  1272 
  1273 	pPlayer->NotifyPostAdminChecks();
  1274 
  1275 	return 1;
  1276 }
  1277 
  1278 static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params)
  1279 {
  1280 	int client = params[1];
  1281 
  1282 	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1283 
  1284 	if (!pPlayer)
  1285 	{
  1286 		return pContext->ThrowNativeError("Client index %d is invalid", client);
  1287 	}
  1288 	else if (!pPlayer->IsConnected())
  1289 	{
  1290 		return pContext->ThrowNativeError("Client %d is not in game", client);
  1291 	}
  1292 
  1293 	return pPlayer->IsInKickQueue() ? 1 : 0;
  1294 }
  1295 
  1296 static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
  1297 {
  1298 	cmd_target_info_t info;
  1299 
  1300 	pContext->LocalToString(params[1], (char **)&info.pattern);
  1301 	info.admin = params[2];
  1302 	pContext->LocalToPhysAddr(params[3], &info.targets);
  1303 	info.max_targets = params[4];
  1304 	info.flags = params[5];
  1305 	pContext->LocalToString(params[6], &info.target_name);
  1306 	info.target_name_maxlength = params[7];
  1307 
  1308 	cell_t *tn_is_ml;
  1309 	pContext->LocalToPhysAddr(params[8], &tn_is_ml);
  1310 
  1311 	g_Players.ProcessCommandTarget(&info);
  1312 
  1313 	if (info.target_name_style == COMMAND_TARGETNAME_ML)
  1314 	{
  1315 		*tn_is_ml = 1;
  1316 	}
  1317 	else
  1318 	{
  1319 		*tn_is_ml = 0;
  1320 	}
  1321 
  1322 	if (info.num_targets == 0)
  1323 	{
  1324 		return info.reason;
  1325 	}
  1326 	else
  1327 	{
  1328 		return info.num_targets;
  1329 	}
  1330 }
  1331 
  1332 REGISTER_NATIVES(playernatives)
  1333 {
  1334 	{"AddUserFlags",			AddUserFlags},
  1335 	{"CanUserTarget",			CanUserTarget},
  1336 	{"ChangeClientTeam",		ChangeClientTeam},
  1337 	{"GetClientAuthString",		sm_GetClientAuthStr},
  1338 	{"GetClientCount",			sm_GetClientCount},
  1339 	{"GetClientInfo",			sm_GetClientInfo},
  1340 	{"GetClientIP",				sm_GetClientIP},
  1341 	{"GetClientName",			sm_GetClientName},
  1342 	{"GetClientTeam",			GetClientTeam},
  1343 	{"GetClientUserId",			GetClientUserId},
  1344 	{"GetMaxClients",			sm_GetMaxClients},
  1345 	{"GetUserAdmin",			GetUserAdmin},
  1346 	{"GetUserFlagBits",			GetUserFlagBits},
  1347 	{"IsClientAuthorized",		sm_IsClientAuthorized},
  1348 	{"IsClientConnected",		sm_IsClientConnected},
  1349 	{"IsFakeClient",			sm_IsClientFakeClient},
  1350 	{"IsClientInGame",			sm_IsClientInGame},
  1351 	{"IsClientObserver",		IsClientObserver},
  1352 	{"RemoveUserFlags",			RemoveUserFlags},
  1353 	{"SetUserAdmin",			SetUserAdmin},
  1354 	{"SetUserFlagBits",			SetUserFlagBits},
  1355 	{"GetClientDeaths",			GetDeathCount},
  1356 	{"GetClientFrags",			GetFragCount},
  1357 	{"GetClientArmor",			GetArmorValue},
  1358 	{"GetClientAbsOrigin",		GetAbsOrigin},
  1359 	{"GetClientAbsAngles",		GetAbsAngles},
  1360 	{"GetClientMins",			GetPlayerMins},
  1361 	{"GetClientMaxs",			GetPlayerMaxs},
  1362 	{"GetClientWeapon",			GetWeaponName},
  1363 	{"GetClientModel",			GetModelName},
  1364 	{"GetClientHealth",			GetHealth},
  1365 	{"GetClientTime",			GetTimeConnected},
  1366 	{"GetClientDataRate",		GetDataRate},
  1367 	{"IsClentTimingOut",		IsTimingOut},
  1368 	{"GetClientLatency",		GetLatency},
  1369 	{"GetClientAvgLatency",		GetAvgLatency},
  1370 	{"GetClientAvgLoss",		GetAvgLoss},
  1371 	{"GetClientAvgChoke",		GetAvgChoke},
  1372 	{"GetClientAvgData",		GetAvgData},
  1373 	{"GetClientAvgPackets",		GetAvgPackets},
  1374 	{"GetClientOfUserId",		GetClientOfUserId},
  1375 	{"ShowActivity",			ShowActivity},
  1376 	{"ShowActivityEx",			ShowActivityEx},
  1377 	{"ShowActivity2",			ShowActivity2},
  1378 	{"KickClient",				KickClient},
  1379 	{"RunAdminCacheChecks",		RunAdminCacheChecks},
  1380 	{"NotifyPostAdminCheck",	NotifyPostAdminCheck},
  1381 	{"IsClientInKickQueue",		IsClientInKickQueue},
  1382 	{"ProcessTargetString",		ProcessTargetString},
  1383 	{NULL,						NULL}
  1384 };
  1385