3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
15 #include "PlayerManager.h"
16 #include "AdminCache.h"
17 #include "sm_stringutil.h"
18 #include "HalfLife2.h"
19 #include "sourcemod.h"
20 #include "ChatTriggers.h"
21 #include <inetchannel.h>
24 ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY|FCVAR_PROTECTED, "Activity display setting (see sourcemod.cfg)");
26 static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
30 return g_Players.NumPlayers();
33 int maxplayers = g_Players.MaxClients();
35 for (int i=1; i<=maxplayers; ++i)
37 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
38 if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
44 return (g_Players.NumPlayers() + count);
47 static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
49 return g_Players.MaxClients();
52 static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
54 int index = params[1];
58 static ConVar *hostname = NULL;
61 hostname = icvar->FindVar("hostname");
64 return pCtx->ThrowNativeError("Could not find \"hostname\" cvar");
67 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), hostname->GetString(), NULL);
71 if ((index < 1) || (index > g_Players.GetMaxClients()))
73 return pCtx->ThrowNativeError("Client index %d is invalid", index);
76 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
77 if (!pPlayer->IsConnected())
79 return pCtx->ThrowNativeError("Client %d is not connected", index);
82 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pPlayer->GetName(), NULL);
86 static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
88 int index = params[1];
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);
101 strcpy(buf, pPlayer->GetIPAddress());
103 if (params[4] && (ptr = strchr(buf, ':')))
108 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), buf);
112 static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
114 int index = params[1];
115 if ((index < 1) || (index > g_Players.GetMaxClients()))
117 return pCtx->ThrowNativeError("Client index %d is invalid", index);
120 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
121 if (!pPlayer->IsConnected())
123 return pCtx->ThrowNativeError("Client %d is not connected", index);
126 if (!pPlayer->IsAuthorized())
131 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
136 static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
138 int index = params[1];
139 if ((index < 1) || (index > g_Players.GetMaxClients()))
141 return pCtx->ThrowNativeError("Client index %d is invalid", index);
144 return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
147 static cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
149 int index = params[1];
150 if ((index < 1) || (index > g_Players.GetMaxClients()))
152 return pCtx->ThrowNativeError("Client index %d is invalid", index);
155 return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
158 static cell_t sm_IsClientAuthorized(IPluginContext *pCtx, const cell_t *params)
160 int index = params[1];
161 if ((index < 1) || (index > g_Players.GetMaxClients()))
163 return pCtx->ThrowNativeError("Client index %d is invalid", index);
166 return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
169 static cell_t sm_IsClientFakeClient(IPluginContext *pCtx, const cell_t *params)
171 int index = params[1];
172 if ((index < 1) || (index > g_Players.GetMaxClients()))
174 return pCtx->ThrowNativeError("Client index %d is invalid", index);
177 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
178 if (!pPlayer->IsConnected())
180 return pCtx->ThrowNativeError("Client %d is not connected", index);
183 return (pPlayer->IsFakeClient()) ? 1 : 0;
186 static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
188 int client = params[1];
190 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
193 return pContext->ThrowNativeError("Client index %d is invalid", client);
194 } else if (!pPlayer->IsInGame()) {
195 return pContext->ThrowNativeError("Client %d is not in game", client);
198 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
201 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
204 return pInfo->IsObserver() ? 1 : 0;
207 static cell_t sm_GetClientInfo(IPluginContext *pContext, const cell_t *params)
209 int client = params[1];
210 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
213 return pContext->ThrowNativeError("Client index %d is invalid", client);
215 if (!pPlayer->IsConnected())
217 return pContext->ThrowNativeError("Client %d is not connected", client);
221 pContext->LocalToString(params[2], &key);
223 const char *val = engine->GetClientConVarValue(client, key);
229 pContext->StringToLocalUTF8(params[3], params[4], val, NULL);
233 static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
235 int client = params[1];
236 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
239 return pContext->ThrowNativeError("Client index %d is invalid", client);
241 if (!pPlayer->IsConnected())
243 return pContext->ThrowNativeError("Client %d is not connected", client);
245 if (!g_Admins.IsValidAdmin(params[2]))
247 return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
250 pPlayer->SetAdminId(params[2], params[3] ? true : false);
255 static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
257 int client = params[1];
258 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
261 return pContext->ThrowNativeError("Client index %d is invalid", client);
263 if (!pPlayer->IsConnected())
265 return pContext->ThrowNativeError("Client %d is not connected", client);
268 return pPlayer->GetAdminId();
271 static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
273 int client = params[1];
274 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
277 return pContext->ThrowNativeError("Client index %d is invalid", client);
279 if (!pPlayer->IsConnected())
281 return pContext->ThrowNativeError("Client %d is not connected", client);
285 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
287 id = g_Admins.CreateAdmin(NULL);
288 pPlayer->SetAdminId(id, true);
292 for (int i=2; i<=params[0]; i++)
294 pContext->LocalToPhysAddr(params[i], &addr);
295 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
301 static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
303 int client = params[1];
304 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
307 return pContext->ThrowNativeError("Client index %d is invalid", client);
309 if (!pPlayer->IsConnected())
311 return pContext->ThrowNativeError("Client %d is not connected", client);
315 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
321 for (int i=2; i<=params[0]; i++)
323 pContext->LocalToPhysAddr(params[i], &addr);
324 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
330 static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
332 int client = params[1];
333 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
336 return pContext->ThrowNativeError("Client index %d is invalid", client);
338 if (!pPlayer->IsConnected())
340 return pContext->ThrowNativeError("Client %d is not connected", client);
344 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
346 id = g_Admins.CreateAdmin(NULL);
347 pPlayer->SetAdminId(id, true);
350 g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
355 static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
357 int client = params[1];
358 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
361 return pContext->ThrowNativeError("Client index %d is invalid", client);
363 if (!pPlayer->IsConnected())
365 return pContext->ThrowNativeError("Client %d is not connected", client);
369 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
374 return g_Admins.GetAdminFlags(id, Access_Effective);
377 static cell_t GetClientUserId(IPluginContext *pContext, const cell_t *params)
379 int client = params[1];
380 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
383 return pContext->ThrowNativeError("Client index %d is invalid", client);
385 if (!pPlayer->IsConnected())
387 return pContext->ThrowNativeError("Client %d is not connected", client);
390 return engine->GetPlayerUserId(pPlayer->GetEdict());
393 static cell_t CanUserTarget(IPluginContext *pContext, const cell_t *params)
395 int client = params[1];
396 int target = params[2];
403 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
406 return pContext->ThrowNativeError("Client index %d is invalid", client);
407 } else if (!pPlayer->IsConnected()) {
408 return pContext->ThrowNativeError("Client %d is not connected", client);
411 CPlayer *pTarget = g_Players.GetPlayerByIndex(target);
414 return pContext->ThrowNativeError("Client index %d is invalid", target);
415 } else if (!pTarget->IsConnected()) {
416 return pContext->ThrowNativeError("Client %d is not connected", target);
419 return g_Admins.CanAdminTarget(pPlayer->GetAdminId(), pTarget->GetAdminId()) ? 1 : 0;
422 static cell_t GetClientTeam(IPluginContext *pContext, const cell_t *params)
424 int client = params[1];
426 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
429 return pContext->ThrowNativeError("Client index %d is invalid", client);
430 } else if (!pPlayer->IsInGame()) {
431 return pContext->ThrowNativeError("Client %d is not in game", client);
434 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
437 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
440 return pInfo->GetTeamIndex();
443 static cell_t GetFragCount(IPluginContext *pContext, const cell_t *params)
445 int client = params[1];
447 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
450 return pContext->ThrowNativeError("Client index %d is invalid", client);
451 } else if (!pPlayer->IsInGame()) {
452 return pContext->ThrowNativeError("Client %d is not in game", client);
455 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
458 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
461 return pInfo->GetFragCount();
464 static cell_t GetDeathCount(IPluginContext *pContext, const cell_t *params)
466 int client = params[1];
468 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
471 return pContext->ThrowNativeError("Client index %d is invalid", client);
472 } else if (!pPlayer->IsInGame()) {
473 return pContext->ThrowNativeError("Client %d is not in game", client);
476 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
479 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
482 return pInfo->GetDeathCount();
485 static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params)
487 int client = params[1];
489 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
492 return pContext->ThrowNativeError("Client index %d is invalid", client);
493 } else if (!pPlayer->IsInGame()) {
494 return pContext->ThrowNativeError("Client %d is not in game", client);
497 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
500 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
503 return pInfo->GetArmorValue();
506 static cell_t GetAbsOrigin(IPluginContext *pContext, const cell_t *params)
508 int client = params[1];
510 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
513 return pContext->ThrowNativeError("Client index %d is invalid", client);
514 } else if (!pPlayer->IsInGame()) {
515 return pContext->ThrowNativeError("Client %d is not in game", client);
518 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
521 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
525 pContext->LocalToPhysAddr(params[2], &pVec);
527 Vector vec = pInfo->GetAbsOrigin();
528 pVec[0] = sp_ftoc(vec.x);
529 pVec[1] = sp_ftoc(vec.y);
530 pVec[2] = sp_ftoc(vec.z);
535 static cell_t GetAbsAngles(IPluginContext *pContext, const cell_t *params)
537 int client = params[1];
539 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
542 return pContext->ThrowNativeError("Client index %d is invalid", client);
543 } else if (!pPlayer->IsInGame()) {
544 return pContext->ThrowNativeError("Client %d is not in game", client);
547 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
550 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
554 pContext->LocalToPhysAddr(params[2], &pAng);
556 QAngle ang = pInfo->GetAbsAngles();
557 pAng[0] = sp_ftoc(ang.x);
558 pAng[1] = sp_ftoc(ang.y);
559 pAng[2] = sp_ftoc(ang.z);
564 static cell_t GetPlayerMins(IPluginContext *pContext, const cell_t *params)
566 int client = params[1];
568 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
571 return pContext->ThrowNativeError("Client index %d is invalid", client);
572 } else if (!pPlayer->IsInGame()) {
573 return pContext->ThrowNativeError("Client %d is not in game", client);
576 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
579 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
583 pContext->LocalToPhysAddr(params[2], &pVec);
585 Vector vec = pInfo->GetPlayerMins();
586 pVec[0] = sp_ftoc(vec.x);
587 pVec[1] = sp_ftoc(vec.y);
588 pVec[2] = sp_ftoc(vec.z);
593 static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params)
595 int client = params[1];
597 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
600 return pContext->ThrowNativeError("Client index %d is invalid", client);
601 } else if (!pPlayer->IsInGame()) {
602 return pContext->ThrowNativeError("Client %d is not in game", client);
605 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
608 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
612 pContext->LocalToPhysAddr(params[2], &pVec);
614 Vector vec = pInfo->GetPlayerMaxs();
615 pVec[0] = sp_ftoc(vec.x);
616 pVec[1] = sp_ftoc(vec.y);
617 pVec[2] = sp_ftoc(vec.z);
622 static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params)
624 int client = params[1];
626 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
629 return pContext->ThrowNativeError("Client index %d is invalid", client);
630 } else if (!pPlayer->IsInGame()) {
631 return pContext->ThrowNativeError("Client %d is not in game", client);
634 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
637 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
640 const char *weapon = pInfo->GetWeaponName();
641 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL);
646 static cell_t GetModelName(IPluginContext *pContext, const cell_t *params)
648 int client = params[1];
650 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
653 return pContext->ThrowNativeError("Client index %d is invalid", client);
654 } else if (!pPlayer->IsInGame()) {
655 return pContext->ThrowNativeError("Client %d is not in game", client);
658 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
661 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
664 const char *model = pInfo->GetModelName();
665 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), model ? model : "", NULL);
670 static cell_t GetHealth(IPluginContext *pContext, const cell_t *params)
672 int client = params[1];
674 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
677 return pContext->ThrowNativeError("Client index %d is invalid", client);
678 } else if (!pPlayer->IsInGame()) {
679 return pContext->ThrowNativeError("Client %d is not in game", client);
682 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
685 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
688 return pInfo->GetHealth();
691 static cell_t GetTimeConnected(IPluginContext *pContext, const cell_t *params)
693 int client = params[1];
695 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
698 return pContext->ThrowNativeError("Client index %d is invalid", client);
699 } else if (!pPlayer->IsInGame()) {
700 return pContext->ThrowNativeError("Client %d is not in game", client);
701 } else if (pPlayer->IsFakeClient()) {
702 return pContext->ThrowNativeError("Client %d is a bot", client);
705 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
707 return sp_ftoc(pInfo->GetTimeConnected());
710 static cell_t GetDataRate(IPluginContext *pContext, const cell_t *params)
712 int client = params[1];
714 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
717 return pContext->ThrowNativeError("Client index %d is invalid", client);
718 } else if (!pPlayer->IsInGame()) {
719 return pContext->ThrowNativeError("Client %d is not in game", client);
720 } else if (pPlayer->IsFakeClient()) {
721 return pContext->ThrowNativeError("Client %d is a bot", client);
724 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
726 return pInfo->GetDataRate();
729 static cell_t IsTimingOut(IPluginContext *pContext, const cell_t *params)
731 int client = params[1];
733 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
736 return pContext->ThrowNativeError("Client index %d is invalid", client);
737 } else if (!pPlayer->IsInGame()) {
738 return pContext->ThrowNativeError("Client %d is not in game", client);
739 } else if (pPlayer->IsFakeClient()) {
740 return pContext->ThrowNativeError("Client %d is a bot", client);
743 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
745 return pInfo->IsTimingOut() ? 1 : 0;
748 static cell_t GetLatency(IPluginContext *pContext, const cell_t *params)
750 int client = params[1];
752 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
755 return pContext->ThrowNativeError("Client index %d is invalid", client);
756 } else if (!pPlayer->IsInGame()) {
757 return pContext->ThrowNativeError("Client %d is not in game", client);
758 } else if (pPlayer->IsFakeClient()) {
759 return pContext->ThrowNativeError("Client %d is a bot", client);
762 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
764 return sp_ftoc(pInfo->GetLatency(params[2]));
767 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
769 int client = params[1];
771 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
774 return pContext->ThrowNativeError("Client index %d is invalid", client);
775 } else if (!pPlayer->IsInGame()) {
776 return pContext->ThrowNativeError("Client %d is not in game", client);
777 } else if (pPlayer->IsFakeClient()) {
778 return pContext->ThrowNativeError("Client %d is a bot", client);
781 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
783 return sp_ftoc(pInfo->GetAvgLatency(params[2]));
786 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
788 int client = params[1];
790 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
793 return pContext->ThrowNativeError("Client index %d is invalid", client);
794 } else if (!pPlayer->IsInGame()) {
795 return pContext->ThrowNativeError("Client %d is not in game", client);
796 } else if (pPlayer->IsFakeClient()) {
797 return pContext->ThrowNativeError("Client %d is a bot", client);
800 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
802 return sp_ftoc(pInfo->GetAvgLoss(params[2]));
805 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
807 int client = params[1];
809 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
812 return pContext->ThrowNativeError("Client index %d is invalid", client);
813 } else if (!pPlayer->IsInGame()) {
814 return pContext->ThrowNativeError("Client %d is not in game", client);
815 } else if (pPlayer->IsFakeClient()) {
816 return pContext->ThrowNativeError("Client %d is a bot", client);
819 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
821 return sp_ftoc(pInfo->GetAvgChoke(params[2]));
824 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
826 int client = params[1];
828 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
831 return pContext->ThrowNativeError("Client index %d is invalid", client);
832 } else if (!pPlayer->IsInGame()) {
833 return pContext->ThrowNativeError("Client %d is not in game", client);
834 } else if (pPlayer->IsFakeClient()) {
835 return pContext->ThrowNativeError("Client %d is a bot", client);
838 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
840 return sp_ftoc(pInfo->GetAvgData(params[2]));
843 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
845 int client = params[1];
847 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
850 return pContext->ThrowNativeError("Client index %d is invalid", client);
851 } else if (!pPlayer->IsInGame()) {
852 return pContext->ThrowNativeError("Client %d is not in game", client);
853 } else if (pPlayer->IsFakeClient()) {
854 return pContext->ThrowNativeError("Client %d is a bot", client);
857 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
859 return sp_ftoc(pInfo->GetAvgPackets(params[2]));
862 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
864 return g_Players.GetClientOfUserId(params[1]);
867 static cell_t _ShowActivity(IPluginContext *pContext, const cell_t *params, const char *tag, cell_t fmt_param)
871 int value = sm_show_activity.GetInt();
872 unsigned int replyto = g_ChatTriggers.GetReplyTo();
873 int client = params[1];
875 const char *name = "Console";
876 const char *sign = "ADMIN";
877 bool display_in_chat = false;
880 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
881 if (!pPlayer || !pPlayer->IsConnected())
883 return pContext->ThrowNativeError("Client index %d is invalid", client);
885 name = pPlayer->GetName();
886 AdminId id = pPlayer->GetAdminId();
887 if (id == INVALID_ADMIN_ID
888 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
893 /* Display the message to the client? */
894 if (replyto == SM_REPLY_CONSOLE)
896 g_SourceMod.SetGlobalTarget(client);
897 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
898 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
899 engine->ClientPrintf(pPlayer->GetEdict(), message);
900 display_in_chat = true;
903 g_SourceMod.SetGlobalTarget(LANG_SERVER);
904 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
905 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
906 META_CONPRINT(message);
914 int maxClients = g_Players.GetMaxClients();
915 for (int i=1; i<=maxClients; i++)
917 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
918 if (!pPlayer->IsInGame()
919 || pPlayer->IsFakeClient()
920 || (display_in_chat && i == client))
924 AdminId id = pPlayer->GetAdminId();
925 g_SourceMod.SetGlobalTarget(i);
926 if (id == INVALID_ADMIN_ID
927 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
929 /* Treat this as a normal user */
930 if ((value & 1) || (value & 2))
932 const char *newsign = sign;
937 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
938 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
939 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
942 /* Treat this as an admin user */
943 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
946 || ((value & 16) && is_root))
948 const char *newsign = sign;
949 if ((value & 8) || ((value & 16) && is_root))
953 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
954 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
955 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
963 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
965 return _ShowActivity(pContext, params, "[SM] ", 2);
968 static cell_t ShowActivityEx(IPluginContext *pContext, const cell_t *params)
971 pContext->LocalToString(params[2], &str);
973 return _ShowActivity(pContext, params, str, 3);
976 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
978 int client = params[1];
980 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
983 return pContext->ThrowNativeError("Client index %d is invalid", client);
984 } else if (!pPlayer->IsConnected()) {
985 return pContext->ThrowNativeError("Client %d is not connected", client);
988 if (pPlayer->IsFakeClient())
991 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
993 engine->ServerCommand(kickcmd);
997 INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
998 IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
1000 g_SourceMod.SetGlobalTarget(client);
1003 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1005 pClient->Disconnect("%s", buffer);
1010 static cell_t ChangeClientTeam(IPluginContext *pContext, const cell_t *params)
1012 int client = params[1];
1014 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1017 return pContext->ThrowNativeError("Client index %d is invalid", client);
1018 } else if (!pPlayer->IsInGame()) {
1019 return pContext->ThrowNativeError("Client %d is not in game", client);
1022 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
1025 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
1028 pInfo->ChangeTeam(params[2]);
1033 REGISTER_NATIVES(playernatives)
1035 {"AddUserFlags", AddUserFlags},
1036 {"CanUserTarget", CanUserTarget},
1037 {"ChangeClientTeam", ChangeClientTeam},
1038 {"GetClientAuthString", sm_GetClientAuthStr},
1039 {"GetClientCount", sm_GetClientCount},
1040 {"GetClientInfo", sm_GetClientInfo},
1041 {"GetClientIP", sm_GetClientIP},
1042 {"GetClientName", sm_GetClientName},
1043 {"GetClientTeam", GetClientTeam},
1044 {"GetClientUserId", GetClientUserId},
1045 {"GetMaxClients", sm_GetMaxClients},
1046 {"GetUserAdmin", GetUserAdmin},
1047 {"GetUserFlagBits", GetUserFlagBits},
1048 {"IsClientAuthorized", sm_IsClientAuthorized},
1049 {"IsClientConnected", sm_IsClientConnected},
1050 {"IsFakeClient", sm_IsClientFakeClient},
1051 {"IsPlayerInGame", sm_IsClientInGame}, /* Backwards compat shim */
1052 {"IsClientInGame", sm_IsClientInGame},
1053 {"IsClientObserver", IsClientObserver},
1054 {"RemoveUserFlags", RemoveUserFlags},
1055 {"SetUserAdmin", SetUserAdmin},
1056 {"SetUserFlagBits", SetUserFlagBits},
1057 {"GetClientDeaths", GetDeathCount},
1058 {"GetClientFrags", GetFragCount},
1059 {"GetClientArmor", GetArmorValue},
1060 {"GetClientAbsOrigin", GetAbsOrigin},
1061 {"GetClientAbsAngles", GetAbsAngles},
1062 {"GetClientMins", GetPlayerMins},
1063 {"GetClientMaxs", GetPlayerMaxs},
1064 {"GetClientWeapon", GetWeaponName},
1065 {"GetClientModel", GetModelName},
1066 {"GetClientHealth", GetHealth},
1067 {"GetClientTime", GetTimeConnected},
1068 {"GetClientDataRate", GetDataRate},
1069 {"IsClentTimingOut", IsTimingOut},
1070 {"GetClientLatency", GetLatency},
1071 {"GetClientAvgLatency", GetAvgLatency},
1072 {"GetClientAvgLoss", GetAvgLoss},
1073 {"GetClientAvgChoke", GetAvgChoke},
1074 {"GetClientAvgData", GetAvgData},
1075 {"GetClientAvgPackets", GetAvgPackets},
1076 {"GetClientOfUserId", GetClientOfUserId},
1077 {"ShowActivity", ShowActivity},
1078 {"ShowActivityEx", ShowActivityEx},
1079 {"KickClient", KickClient},