3 * ================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ================================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License,
10 * version 3.0, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to
21 * link the code of this program (as well as its derivative works) to
22 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
23 * Game MODs that run on software by the Valve Corporation. You must
24 * obey the GNU General Public License in all respects for all other
25 * code used. Additionally, AlliedModders LLC grants this exception
26 * to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version
28 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
33 #include "PlayerManager.h"
34 #include "AdminCache.h"
35 #include "sm_stringutil.h"
36 #include "HalfLife2.h"
37 #include "sourcemod.h"
38 #include "ChatTriggers.h"
39 #include <inetchannel.h>
42 ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY|FCVAR_PROTECTED, "Activity display setting (see sourcemod.cfg)");
44 static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
48 return g_Players.NumPlayers();
51 int maxplayers = g_Players.MaxClients();
53 for (int i=1; i<=maxplayers; ++i)
55 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
56 if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
62 return (g_Players.NumPlayers() + count);
65 static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
67 return g_Players.MaxClients();
70 static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
72 int index = params[1];
76 static ConVar *hostname = NULL;
79 hostname = icvar->FindVar("hostname");
82 return pCtx->ThrowNativeError("Could not find \"hostname\" cvar");
85 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), hostname->GetString(), NULL);
89 if ((index < 1) || (index > g_Players.GetMaxClients()))
91 return pCtx->ThrowNativeError("Client index %d is invalid", index);
94 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
95 if (!pPlayer->IsConnected())
97 return pCtx->ThrowNativeError("Client %d is not connected", index);
100 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pPlayer->GetName(), NULL);
104 static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
106 int index = params[1];
107 if ((index < 1) || (index > g_Players.GetMaxClients()))
109 return pCtx->ThrowNativeError("Client index %d is invalid", index);
112 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
113 if (!pPlayer->IsConnected())
115 return pCtx->ThrowNativeError("Client %d is not connected", index);
119 strcpy(buf, pPlayer->GetIPAddress());
121 if (params[4] && (ptr = strchr(buf, ':')))
126 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), buf);
130 static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
132 int index = params[1];
133 if ((index < 1) || (index > g_Players.GetMaxClients()))
135 return pCtx->ThrowNativeError("Client index %d is invalid", index);
138 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
139 if (!pPlayer->IsConnected())
141 return pCtx->ThrowNativeError("Client %d is not connected", index);
144 if (!pPlayer->IsAuthorized())
149 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
154 static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
156 int index = params[1];
157 if ((index < 1) || (index > g_Players.GetMaxClients()))
159 return pCtx->ThrowNativeError("Client index %d is invalid", index);
162 return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
165 static cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
167 int index = params[1];
168 if ((index < 1) || (index > g_Players.GetMaxClients()))
170 return pCtx->ThrowNativeError("Client index %d is invalid", index);
173 return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
176 static cell_t sm_IsClientAuthorized(IPluginContext *pCtx, const cell_t *params)
178 int index = params[1];
179 if ((index < 1) || (index > g_Players.GetMaxClients()))
181 return pCtx->ThrowNativeError("Client index %d is invalid", index);
184 return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
187 static cell_t sm_IsClientFakeClient(IPluginContext *pCtx, const cell_t *params)
189 int index = params[1];
190 if ((index < 1) || (index > g_Players.GetMaxClients()))
192 return pCtx->ThrowNativeError("Client index %d is invalid", index);
195 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
196 if (!pPlayer->IsConnected())
198 return pCtx->ThrowNativeError("Client %d is not connected", index);
201 return (pPlayer->IsFakeClient()) ? 1 : 0;
204 static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
206 int client = params[1];
208 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
211 return pContext->ThrowNativeError("Client index %d is invalid", client);
212 } else if (!pPlayer->IsInGame()) {
213 return pContext->ThrowNativeError("Client %d is not in game", client);
216 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
219 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
222 return pInfo->IsObserver() ? 1 : 0;
225 static cell_t sm_GetClientInfo(IPluginContext *pContext, const cell_t *params)
227 int client = params[1];
228 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
231 return pContext->ThrowNativeError("Client index %d is invalid", client);
233 if (!pPlayer->IsConnected())
235 return pContext->ThrowNativeError("Client %d is not connected", client);
239 pContext->LocalToString(params[2], &key);
241 const char *val = engine->GetClientConVarValue(client, key);
247 pContext->StringToLocalUTF8(params[3], params[4], val, NULL);
251 static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
253 int client = params[1];
254 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
257 return pContext->ThrowNativeError("Client index %d is invalid", client);
259 if (!pPlayer->IsConnected())
261 return pContext->ThrowNativeError("Client %d is not connected", client);
263 if (!g_Admins.IsValidAdmin(params[2]))
265 return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
268 pPlayer->SetAdminId(params[2], params[3] ? true : false);
273 static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
275 int client = params[1];
276 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
279 return pContext->ThrowNativeError("Client index %d is invalid", client);
281 if (!pPlayer->IsConnected())
283 return pContext->ThrowNativeError("Client %d is not connected", client);
286 return pPlayer->GetAdminId();
289 static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
291 int client = params[1];
292 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
295 return pContext->ThrowNativeError("Client index %d is invalid", client);
297 if (!pPlayer->IsConnected())
299 return pContext->ThrowNativeError("Client %d is not connected", client);
303 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
305 id = g_Admins.CreateAdmin(NULL);
306 pPlayer->SetAdminId(id, true);
310 for (int i=2; i<=params[0]; i++)
312 pContext->LocalToPhysAddr(params[i], &addr);
313 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
319 static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
321 int client = params[1];
322 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
325 return pContext->ThrowNativeError("Client index %d is invalid", client);
327 if (!pPlayer->IsConnected())
329 return pContext->ThrowNativeError("Client %d is not connected", client);
333 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
339 for (int i=2; i<=params[0]; i++)
341 pContext->LocalToPhysAddr(params[i], &addr);
342 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
348 static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
350 int client = params[1];
351 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
354 return pContext->ThrowNativeError("Client index %d is invalid", client);
356 if (!pPlayer->IsConnected())
358 return pContext->ThrowNativeError("Client %d is not connected", client);
362 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
364 id = g_Admins.CreateAdmin(NULL);
365 pPlayer->SetAdminId(id, true);
368 g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
373 static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
375 int client = params[1];
376 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
379 return pContext->ThrowNativeError("Client index %d is invalid", client);
381 if (!pPlayer->IsConnected())
383 return pContext->ThrowNativeError("Client %d is not connected", client);
387 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
392 return g_Admins.GetAdminFlags(id, Access_Effective);
395 static cell_t GetClientUserId(IPluginContext *pContext, const cell_t *params)
397 int client = params[1];
398 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
401 return pContext->ThrowNativeError("Client index %d is invalid", client);
403 if (!pPlayer->IsConnected())
405 return pContext->ThrowNativeError("Client %d is not connected", client);
408 return engine->GetPlayerUserId(pPlayer->GetEdict());
411 static cell_t CanUserTarget(IPluginContext *pContext, const cell_t *params)
413 int client = params[1];
414 int target = params[2];
421 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
424 return pContext->ThrowNativeError("Client index %d is invalid", client);
425 } else if (!pPlayer->IsConnected()) {
426 return pContext->ThrowNativeError("Client %d is not connected", client);
429 CPlayer *pTarget = g_Players.GetPlayerByIndex(target);
432 return pContext->ThrowNativeError("Client index %d is invalid", target);
433 } else if (!pTarget->IsConnected()) {
434 return pContext->ThrowNativeError("Client %d is not connected", target);
437 return g_Admins.CanAdminTarget(pPlayer->GetAdminId(), pTarget->GetAdminId()) ? 1 : 0;
440 static cell_t GetClientTeam(IPluginContext *pContext, const cell_t *params)
442 int client = params[1];
444 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
447 return pContext->ThrowNativeError("Client index %d is invalid", client);
448 } else if (!pPlayer->IsInGame()) {
449 return pContext->ThrowNativeError("Client %d is not in game", client);
452 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
455 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
458 return pInfo->GetTeamIndex();
461 static cell_t GetFragCount(IPluginContext *pContext, const cell_t *params)
463 int client = params[1];
465 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
468 return pContext->ThrowNativeError("Client index %d is invalid", client);
469 } else if (!pPlayer->IsInGame()) {
470 return pContext->ThrowNativeError("Client %d is not in game", client);
473 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
476 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
479 return pInfo->GetFragCount();
482 static cell_t GetDeathCount(IPluginContext *pContext, const cell_t *params)
484 int client = params[1];
486 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
489 return pContext->ThrowNativeError("Client index %d is invalid", client);
490 } else if (!pPlayer->IsInGame()) {
491 return pContext->ThrowNativeError("Client %d is not in game", client);
494 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
497 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
500 return pInfo->GetDeathCount();
503 static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params)
505 int client = params[1];
507 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
510 return pContext->ThrowNativeError("Client index %d is invalid", client);
511 } else if (!pPlayer->IsInGame()) {
512 return pContext->ThrowNativeError("Client %d is not in game", client);
515 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
518 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
521 return pInfo->GetArmorValue();
524 static cell_t GetAbsOrigin(IPluginContext *pContext, const cell_t *params)
526 int client = params[1];
528 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
531 return pContext->ThrowNativeError("Client index %d is invalid", client);
532 } else if (!pPlayer->IsInGame()) {
533 return pContext->ThrowNativeError("Client %d is not in game", client);
536 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
539 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
543 pContext->LocalToPhysAddr(params[2], &pVec);
545 Vector vec = pInfo->GetAbsOrigin();
546 pVec[0] = sp_ftoc(vec.x);
547 pVec[1] = sp_ftoc(vec.y);
548 pVec[2] = sp_ftoc(vec.z);
553 static cell_t GetAbsAngles(IPluginContext *pContext, const cell_t *params)
555 int client = params[1];
557 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
560 return pContext->ThrowNativeError("Client index %d is invalid", client);
561 } else if (!pPlayer->IsInGame()) {
562 return pContext->ThrowNativeError("Client %d is not in game", client);
565 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
568 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
572 pContext->LocalToPhysAddr(params[2], &pAng);
574 QAngle ang = pInfo->GetAbsAngles();
575 pAng[0] = sp_ftoc(ang.x);
576 pAng[1] = sp_ftoc(ang.y);
577 pAng[2] = sp_ftoc(ang.z);
582 static cell_t GetPlayerMins(IPluginContext *pContext, const cell_t *params)
584 int client = params[1];
586 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
589 return pContext->ThrowNativeError("Client index %d is invalid", client);
590 } else if (!pPlayer->IsInGame()) {
591 return pContext->ThrowNativeError("Client %d is not in game", client);
594 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
597 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
601 pContext->LocalToPhysAddr(params[2], &pVec);
603 Vector vec = pInfo->GetPlayerMins();
604 pVec[0] = sp_ftoc(vec.x);
605 pVec[1] = sp_ftoc(vec.y);
606 pVec[2] = sp_ftoc(vec.z);
611 static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params)
613 int client = params[1];
615 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
618 return pContext->ThrowNativeError("Client index %d is invalid", client);
619 } else if (!pPlayer->IsInGame()) {
620 return pContext->ThrowNativeError("Client %d is not in game", client);
623 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
626 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
630 pContext->LocalToPhysAddr(params[2], &pVec);
632 Vector vec = pInfo->GetPlayerMaxs();
633 pVec[0] = sp_ftoc(vec.x);
634 pVec[1] = sp_ftoc(vec.y);
635 pVec[2] = sp_ftoc(vec.z);
640 static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params)
642 int client = params[1];
644 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
647 return pContext->ThrowNativeError("Client index %d is invalid", client);
648 } else if (!pPlayer->IsInGame()) {
649 return pContext->ThrowNativeError("Client %d is not in game", client);
652 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
655 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
658 const char *weapon = pInfo->GetWeaponName();
659 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL);
664 static cell_t GetModelName(IPluginContext *pContext, const cell_t *params)
666 int client = params[1];
668 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
671 return pContext->ThrowNativeError("Client index %d is invalid", client);
672 } else if (!pPlayer->IsInGame()) {
673 return pContext->ThrowNativeError("Client %d is not in game", client);
676 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
679 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
682 const char *model = pInfo->GetModelName();
683 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), model ? model : "", NULL);
688 static cell_t GetHealth(IPluginContext *pContext, const cell_t *params)
690 int client = params[1];
692 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
695 return pContext->ThrowNativeError("Client index %d is invalid", client);
696 } else if (!pPlayer->IsInGame()) {
697 return pContext->ThrowNativeError("Client %d is not in game", client);
700 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
703 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
706 return pInfo->GetHealth();
709 static cell_t GetTimeConnected(IPluginContext *pContext, const cell_t *params)
711 int client = params[1];
713 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
716 return pContext->ThrowNativeError("Client index %d is invalid", client);
717 } else if (!pPlayer->IsInGame()) {
718 return pContext->ThrowNativeError("Client %d is not in game", client);
719 } else if (pPlayer->IsFakeClient()) {
720 return pContext->ThrowNativeError("Client %d is a bot", client);
723 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
725 return sp_ftoc(pInfo->GetTimeConnected());
728 static cell_t GetDataRate(IPluginContext *pContext, const cell_t *params)
730 int client = params[1];
732 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
735 return pContext->ThrowNativeError("Client index %d is invalid", client);
736 } else if (!pPlayer->IsInGame()) {
737 return pContext->ThrowNativeError("Client %d is not in game", client);
738 } else if (pPlayer->IsFakeClient()) {
739 return pContext->ThrowNativeError("Client %d is a bot", client);
742 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
744 return pInfo->GetDataRate();
747 static cell_t IsTimingOut(IPluginContext *pContext, const cell_t *params)
749 int client = params[1];
751 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
754 return pContext->ThrowNativeError("Client index %d is invalid", client);
755 } else if (!pPlayer->IsInGame()) {
756 return pContext->ThrowNativeError("Client %d is not in game", client);
757 } else if (pPlayer->IsFakeClient()) {
758 return pContext->ThrowNativeError("Client %d is a bot", client);
761 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
763 return pInfo->IsTimingOut() ? 1 : 0;
766 static cell_t GetLatency(IPluginContext *pContext, const cell_t *params)
768 int client = params[1];
770 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
773 return pContext->ThrowNativeError("Client index %d is invalid", client);
774 } else if (!pPlayer->IsInGame()) {
775 return pContext->ThrowNativeError("Client %d is not in game", client);
776 } else if (pPlayer->IsFakeClient()) {
777 return pContext->ThrowNativeError("Client %d is a bot", client);
780 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
782 return sp_ftoc(pInfo->GetLatency(params[2]));
785 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
787 int client = params[1];
789 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
792 return pContext->ThrowNativeError("Client index %d is invalid", client);
793 } else if (!pPlayer->IsInGame()) {
794 return pContext->ThrowNativeError("Client %d is not in game", client);
795 } else if (pPlayer->IsFakeClient()) {
796 return pContext->ThrowNativeError("Client %d is a bot", client);
799 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
801 return sp_ftoc(pInfo->GetAvgLatency(params[2]));
804 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
806 int client = params[1];
808 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
811 return pContext->ThrowNativeError("Client index %d is invalid", client);
812 } else if (!pPlayer->IsInGame()) {
813 return pContext->ThrowNativeError("Client %d is not in game", client);
814 } else if (pPlayer->IsFakeClient()) {
815 return pContext->ThrowNativeError("Client %d is a bot", client);
818 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
820 return sp_ftoc(pInfo->GetAvgLoss(params[2]));
823 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
825 int client = params[1];
827 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
830 return pContext->ThrowNativeError("Client index %d is invalid", client);
831 } else if (!pPlayer->IsInGame()) {
832 return pContext->ThrowNativeError("Client %d is not in game", client);
833 } else if (pPlayer->IsFakeClient()) {
834 return pContext->ThrowNativeError("Client %d is a bot", client);
837 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
839 return sp_ftoc(pInfo->GetAvgChoke(params[2]));
842 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
844 int client = params[1];
846 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
849 return pContext->ThrowNativeError("Client index %d is invalid", client);
850 } else if (!pPlayer->IsInGame()) {
851 return pContext->ThrowNativeError("Client %d is not in game", client);
852 } else if (pPlayer->IsFakeClient()) {
853 return pContext->ThrowNativeError("Client %d is a bot", client);
856 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
858 return sp_ftoc(pInfo->GetAvgData(params[2]));
861 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
863 int client = params[1];
865 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
868 return pContext->ThrowNativeError("Client index %d is invalid", client);
869 } else if (!pPlayer->IsInGame()) {
870 return pContext->ThrowNativeError("Client %d is not in game", client);
871 } else if (pPlayer->IsFakeClient()) {
872 return pContext->ThrowNativeError("Client %d is a bot", client);
875 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
877 return sp_ftoc(pInfo->GetAvgPackets(params[2]));
880 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
882 return g_Players.GetClientOfUserId(params[1]);
885 static cell_t _ShowActivity(IPluginContext *pContext, const cell_t *params, const char *tag, cell_t fmt_param)
889 int value = sm_show_activity.GetInt();
890 unsigned int replyto = g_ChatTriggers.GetReplyTo();
891 int client = params[1];
893 const char *name = "Console";
894 const char *sign = "ADMIN";
895 bool display_in_chat = false;
898 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
899 if (!pPlayer || !pPlayer->IsConnected())
901 return pContext->ThrowNativeError("Client index %d is invalid", client);
903 name = pPlayer->GetName();
904 AdminId id = pPlayer->GetAdminId();
905 if (id == INVALID_ADMIN_ID
906 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
911 /* Display the message to the client? */
912 if (replyto == SM_REPLY_CONSOLE)
914 g_SourceMod.SetGlobalTarget(client);
915 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
916 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
917 engine->ClientPrintf(pPlayer->GetEdict(), message);
918 display_in_chat = true;
921 g_SourceMod.SetGlobalTarget(LANG_SERVER);
922 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
923 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
924 META_CONPRINT(message);
932 int maxClients = g_Players.GetMaxClients();
933 for (int i=1; i<=maxClients; i++)
935 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
936 if (!pPlayer->IsInGame()
937 || pPlayer->IsFakeClient()
938 || (display_in_chat && i == client))
942 AdminId id = pPlayer->GetAdminId();
943 g_SourceMod.SetGlobalTarget(i);
944 if (id == INVALID_ADMIN_ID
945 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
947 /* Treat this as a normal user */
948 if ((value & 1) || (value & 2))
950 const char *newsign = sign;
955 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
956 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
957 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
960 /* Treat this as an admin user */
961 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
964 || ((value & 16) && is_root))
966 const char *newsign = sign;
967 if ((value & 8) || ((value & 16) && is_root))
971 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
972 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
973 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
981 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
983 return _ShowActivity(pContext, params, "[SM] ", 2);
986 static cell_t ShowActivityEx(IPluginContext *pContext, const cell_t *params)
989 pContext->LocalToString(params[2], &str);
991 return _ShowActivity(pContext, params, str, 3);
994 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
996 int client = params[1];
998 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1001 return pContext->ThrowNativeError("Client index %d is invalid", client);
1002 } else if (!pPlayer->IsConnected()) {
1003 return pContext->ThrowNativeError("Client %d is not connected", client);
1006 if (pPlayer->IsFakeClient())
1009 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
1011 engine->ServerCommand(kickcmd);
1015 INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
1016 IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
1018 g_SourceMod.SetGlobalTarget(client);
1021 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1023 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1028 pClient->Disconnect("%s", buffer);
1033 static cell_t ChangeClientTeam(IPluginContext *pContext, const cell_t *params)
1035 int client = params[1];
1037 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1040 return pContext->ThrowNativeError("Client index %d is invalid", client);
1041 } else if (!pPlayer->IsInGame()) {
1042 return pContext->ThrowNativeError("Client %d is not in game", client);
1045 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
1048 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
1051 pInfo->ChangeTeam(params[2]);
1056 static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
1058 int client = params[1];
1060 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1063 return pContext->ThrowNativeError("Client index %d is invalid", client);
1064 } else if (!pPlayer->IsInGame()) {
1065 return pContext->ThrowNativeError("Client %d is not in game", client);
1066 } else if (!pPlayer->IsAuthorized()) {
1067 return pContext->ThrowNativeError("Client %d is not authorized", client);
1070 AdminId id = pPlayer->GetAdminId();
1071 pPlayer->DoBasicAdminChecks();
1073 return (id != pPlayer->GetAdminId()) ? 1 : 0;
1076 static cell_t NotifyPostAdminCheck(IPluginContext *pContext, const cell_t *params)
1078 int client = params[1];
1080 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1083 return pContext->ThrowNativeError("Client index %d is invalid", client);
1084 } else if (!pPlayer->IsInGame()) {
1085 return pContext->ThrowNativeError("Client %d is not in game", client);
1086 } else if (!pPlayer->IsAuthorized()) {
1087 return pContext->ThrowNativeError("Client %d is not authorized", client);
1090 pPlayer->NotifyPostAdminChecks();
1095 REGISTER_NATIVES(playernatives)
1097 {"AddUserFlags", AddUserFlags},
1098 {"CanUserTarget", CanUserTarget},
1099 {"ChangeClientTeam", ChangeClientTeam},
1100 {"GetClientAuthString", sm_GetClientAuthStr},
1101 {"GetClientCount", sm_GetClientCount},
1102 {"GetClientInfo", sm_GetClientInfo},
1103 {"GetClientIP", sm_GetClientIP},
1104 {"GetClientName", sm_GetClientName},
1105 {"GetClientTeam", GetClientTeam},
1106 {"GetClientUserId", GetClientUserId},
1107 {"GetMaxClients", sm_GetMaxClients},
1108 {"GetUserAdmin", GetUserAdmin},
1109 {"GetUserFlagBits", GetUserFlagBits},
1110 {"IsClientAuthorized", sm_IsClientAuthorized},
1111 {"IsClientConnected", sm_IsClientConnected},
1112 {"IsFakeClient", sm_IsClientFakeClient},
1113 {"IsPlayerInGame", sm_IsClientInGame}, /* Backwards compat shim */
1114 {"IsClientInGame", sm_IsClientInGame},
1115 {"IsClientObserver", IsClientObserver},
1116 {"RemoveUserFlags", RemoveUserFlags},
1117 {"SetUserAdmin", SetUserAdmin},
1118 {"SetUserFlagBits", SetUserFlagBits},
1119 {"GetClientDeaths", GetDeathCount},
1120 {"GetClientFrags", GetFragCount},
1121 {"GetClientArmor", GetArmorValue},
1122 {"GetClientAbsOrigin", GetAbsOrigin},
1123 {"GetClientAbsAngles", GetAbsAngles},
1124 {"GetClientMins", GetPlayerMins},
1125 {"GetClientMaxs", GetPlayerMaxs},
1126 {"GetClientWeapon", GetWeaponName},
1127 {"GetClientModel", GetModelName},
1128 {"GetClientHealth", GetHealth},
1129 {"GetClientTime", GetTimeConnected},
1130 {"GetClientDataRate", GetDataRate},
1131 {"IsClentTimingOut", IsTimingOut},
1132 {"GetClientLatency", GetLatency},
1133 {"GetClientAvgLatency", GetAvgLatency},
1134 {"GetClientAvgLoss", GetAvgLoss},
1135 {"GetClientAvgChoke", GetAvgChoke},
1136 {"GetClientAvgData", GetAvgData},
1137 {"GetClientAvgPackets", GetAvgPackets},
1138 {"GetClientOfUserId", GetClientOfUserId},
1139 {"ShowActivity", ShowActivity},
1140 {"ShowActivityEx", ShowActivityEx},
1141 {"KickClient", KickClient},
1142 {"RunAdminCacheChecks", RunAdminCacheChecks},
1143 {"NotifyPostAdminCheck", NotifyPostAdminCheck},