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 "GameConfigs.h"
22 #include <inetchannel.h>
25 ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY|FCVAR_PROTECTED, "Activity display setting (see sourcemod.cfg)");
27 static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
31 return g_Players.NumPlayers();
34 int maxplayers = g_Players.MaxClients();
36 for (int i=1; i<=maxplayers; ++i)
38 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
39 if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
45 return (g_Players.NumPlayers() + count);
48 static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
50 return g_Players.MaxClients();
53 static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
55 int index = params[1];
56 if ((index < 1) || (index > g_Players.GetMaxClients()))
58 return pCtx->ThrowNativeError("Client index %d is invalid", index);
61 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
62 if (!pPlayer->IsConnected())
64 return pCtx->ThrowNativeError("Client %d is not connected", index);
67 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pPlayer->GetName(), NULL);
71 static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
73 int index = params[1];
74 if ((index < 1) || (index > g_Players.GetMaxClients()))
76 return pCtx->ThrowNativeError("Client index %d is invalid", index);
79 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
80 if (!pPlayer->IsConnected())
82 return pCtx->ThrowNativeError("Client %d is not connected", index);
86 strcpy(buf, pPlayer->GetIPAddress());
88 if (params[4] && (ptr = strchr(buf, ':')))
93 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), buf);
97 static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
99 int index = params[1];
100 if ((index < 1) || (index > g_Players.GetMaxClients()))
102 return pCtx->ThrowNativeError("Client index %d is invalid", index);
105 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
106 if (!pPlayer->IsConnected())
108 return pCtx->ThrowNativeError("Client %d is not connected", index);
111 if (!pPlayer->IsAuthorized())
116 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
121 static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
123 int index = params[1];
124 if ((index < 1) || (index > g_Players.GetMaxClients()))
126 return pCtx->ThrowNativeError("Client index %d is invalid", index);
129 return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
132 static cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
134 int index = params[1];
135 if ((index < 1) || (index > g_Players.GetMaxClients()))
137 return pCtx->ThrowNativeError("Client index %d is invalid", index);
140 return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
143 static cell_t sm_IsClientAuthorized(IPluginContext *pCtx, const cell_t *params)
145 int index = params[1];
146 if ((index < 1) || (index > g_Players.GetMaxClients()))
148 return pCtx->ThrowNativeError("Client index %d is invalid", index);
151 return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
154 static cell_t sm_IsClientFakeClient(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 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
163 if (!pPlayer->IsConnected())
165 return pCtx->ThrowNativeError("Client %d is not connected", index);
168 return (pPlayer->IsFakeClient()) ? 1 : 0;
171 static cell_t sm_GetClientInfo(IPluginContext *pContext, const cell_t *params)
173 int client = params[1];
174 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
177 return pContext->ThrowNativeError("Client index %d is invalid", client);
179 if (!pPlayer->IsConnected())
181 return pContext->ThrowNativeError("Client %d is not connected", client);
185 pContext->LocalToString(params[2], &key);
187 const char *val = engine->GetClientConVarValue(client, key);
193 pContext->StringToLocalUTF8(params[3], params[4], val, NULL);
197 static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
199 int client = params[1];
200 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
203 return pContext->ThrowNativeError("Client index %d is invalid", client);
205 if (!pPlayer->IsConnected())
207 return pContext->ThrowNativeError("Client %d is not connected", client);
209 if (!g_Admins.IsValidAdmin(params[2]))
211 return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
214 pPlayer->SetAdminId(params[2], params[3] ? true : false);
219 static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
221 int client = params[1];
222 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
225 return pContext->ThrowNativeError("Client index %d is invalid", client);
227 if (!pPlayer->IsConnected())
229 return pContext->ThrowNativeError("Client %d is not connected", client);
232 return pPlayer->GetAdminId();
235 static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
237 int client = params[1];
238 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
241 return pContext->ThrowNativeError("Client index %d is invalid", client);
243 if (!pPlayer->IsConnected())
245 return pContext->ThrowNativeError("Client %d is not connected", client);
249 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
251 id = g_Admins.CreateAdmin(NULL);
252 pPlayer->SetAdminId(id, true);
256 for (int i=2; i<=params[0]; i++)
258 pContext->LocalToPhysAddr(params[i], &addr);
259 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
265 static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
267 int client = params[1];
268 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
271 return pContext->ThrowNativeError("Client index %d is invalid", client);
273 if (!pPlayer->IsConnected())
275 return pContext->ThrowNativeError("Client %d is not connected", client);
279 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
285 for (int i=2; i<=params[0]; i++)
287 pContext->LocalToPhysAddr(params[i], &addr);
288 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
294 static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
296 int client = params[1];
297 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
300 return pContext->ThrowNativeError("Client index %d is invalid", client);
302 if (!pPlayer->IsConnected())
304 return pContext->ThrowNativeError("Client %d is not connected", client);
308 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
310 id = g_Admins.CreateAdmin(NULL);
311 pPlayer->SetAdminId(id, true);
314 g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
319 static cell_t GetUserFlagBits(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)
338 return g_Admins.GetAdminFlags(id, Access_Effective);
341 static cell_t GetClientUserId(IPluginContext *pContext, const cell_t *params)
343 int client = params[1];
344 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
347 return pContext->ThrowNativeError("Client index %d is invalid", client);
349 if (!pPlayer->IsConnected())
351 return pContext->ThrowNativeError("Client %d is not connected", client);
354 return engine->GetPlayerUserId(pPlayer->GetEdict());
357 static cell_t CanUserTarget(IPluginContext *pContext, const cell_t *params)
359 int client = params[1];
360 int target = params[2];
362 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
365 return pContext->ThrowNativeError("Client index %d is invalid", client);
366 } else if (!pPlayer->IsConnected()) {
367 return pContext->ThrowNativeError("Client %d is not connected", client);
370 CPlayer *pTarget = g_Players.GetPlayerByIndex(target);
373 return pContext->ThrowNativeError("Client index %d is invalid", target);
374 } else if (!pTarget->IsConnected()) {
375 return pContext->ThrowNativeError("Client %d is not connected", target);
378 return g_Admins.CanAdminTarget(pPlayer->GetAdminId(), pTarget->GetAdminId()) ? 1 : 0;
381 static cell_t GetClientTeam(IPluginContext *pContext, const cell_t *params)
383 int client = params[1];
385 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
388 return pContext->ThrowNativeError("Client index %d is invalid", client);
389 } else if (!pPlayer->IsInGame()) {
390 return pContext->ThrowNativeError("Client %d is not in game", client);
393 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
396 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
399 return pInfo->GetTeamIndex();
402 static cell_t GetFragCount(IPluginContext *pContext, const cell_t *params)
404 int client = params[1];
406 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
409 return pContext->ThrowNativeError("Client index %d is invalid", client);
410 } else if (!pPlayer->IsInGame()) {
411 return pContext->ThrowNativeError("Client %d is not in game", client);
414 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
417 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
420 return pInfo->GetFragCount();
423 static cell_t GetDeathCount(IPluginContext *pContext, const cell_t *params)
425 int client = params[1];
427 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
430 return pContext->ThrowNativeError("Client index %d is invalid", client);
431 } else if (!pPlayer->IsInGame()) {
432 return pContext->ThrowNativeError("Client %d is not in game", client);
435 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
438 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
441 return pInfo->GetDeathCount();
444 static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params)
446 int client = params[1];
448 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
451 return pContext->ThrowNativeError("Client index %d is invalid", client);
452 } else if (!pPlayer->IsInGame()) {
453 return pContext->ThrowNativeError("Client %d is not in game", client);
456 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
459 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
462 return pInfo->GetArmorValue();
465 static cell_t GetAbsOrigin(IPluginContext *pContext, const cell_t *params)
467 int client = params[1];
469 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
472 return pContext->ThrowNativeError("Client index %d is invalid", client);
473 } else if (!pPlayer->IsInGame()) {
474 return pContext->ThrowNativeError("Client %d is not in game", client);
477 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
480 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
484 pContext->LocalToPhysAddr(params[2], &pVec);
486 Vector vec = pInfo->GetAbsOrigin();
487 pVec[0] = sp_ftoc(vec.x);
488 pVec[1] = sp_ftoc(vec.y);
489 pVec[2] = sp_ftoc(vec.z);
494 static cell_t GetAbsAngles(IPluginContext *pContext, const cell_t *params)
496 int client = params[1];
498 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
501 return pContext->ThrowNativeError("Client index %d is invalid", client);
502 } else if (!pPlayer->IsInGame()) {
503 return pContext->ThrowNativeError("Client %d is not in game", client);
506 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
509 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
513 pContext->LocalToPhysAddr(params[2], &pAng);
515 QAngle ang = pInfo->GetAbsAngles();
516 pAng[0] = sp_ftoc(ang.x);
517 pAng[1] = sp_ftoc(ang.y);
518 pAng[2] = sp_ftoc(ang.z);
523 static cell_t GetPlayerMins(IPluginContext *pContext, const cell_t *params)
525 int client = params[1];
527 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
535 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
538 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
542 pContext->LocalToPhysAddr(params[2], &pVec);
544 Vector vec = pInfo->GetPlayerMins();
545 pVec[0] = sp_ftoc(vec.x);
546 pVec[1] = sp_ftoc(vec.y);
547 pVec[2] = sp_ftoc(vec.z);
552 static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params)
554 int client = params[1];
556 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
564 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
567 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
571 pContext->LocalToPhysAddr(params[2], &pVec);
573 Vector vec = pInfo->GetPlayerMaxs();
574 pVec[0] = sp_ftoc(vec.x);
575 pVec[1] = sp_ftoc(vec.y);
576 pVec[2] = sp_ftoc(vec.z);
581 static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params)
583 int client = params[1];
585 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
593 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
596 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
599 const char *weapon = pInfo->GetWeaponName();
600 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL);
605 static cell_t GetModelName(IPluginContext *pContext, const cell_t *params)
607 int client = params[1];
609 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
612 return pContext->ThrowNativeError("Client index %d is invalid", client);
613 } else if (!pPlayer->IsInGame()) {
614 return pContext->ThrowNativeError("Client %d is not in game", client);
617 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
620 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
623 const char *model = pInfo->GetModelName();
624 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), model ? model : "", NULL);
629 static cell_t GetHealth(IPluginContext *pContext, const cell_t *params)
631 int client = params[1];
633 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
636 return pContext->ThrowNativeError("Client index %d is invalid", client);
637 } else if (!pPlayer->IsInGame()) {
638 return pContext->ThrowNativeError("Client %d is not in game", client);
641 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
644 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
647 return pInfo->GetHealth();
650 static cell_t GetTimeConnected(IPluginContext *pContext, const cell_t *params)
652 int client = params[1];
654 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
657 return pContext->ThrowNativeError("Client index %d is invalid", client);
658 } else if (!pPlayer->IsInGame()) {
659 return pContext->ThrowNativeError("Client %d is not in game", client);
660 } else if (pPlayer->IsFakeClient()) {
661 return pContext->ThrowNativeError("Client %d is a bot", client);
664 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
666 return sp_ftoc(pInfo->GetTimeConnected());
669 static cell_t GetDataRate(IPluginContext *pContext, const cell_t *params)
671 int client = params[1];
673 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
676 return pContext->ThrowNativeError("Client index %d is invalid", client);
677 } else if (!pPlayer->IsInGame()) {
678 return pContext->ThrowNativeError("Client %d is not in game", client);
679 } else if (pPlayer->IsFakeClient()) {
680 return pContext->ThrowNativeError("Client %d is a bot", client);
683 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
685 return pInfo->GetDataRate();
688 static cell_t IsTimingOut(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);
698 } else if (pPlayer->IsFakeClient()) {
699 return pContext->ThrowNativeError("Client %d is a bot", client);
702 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
704 return pInfo->IsTimingOut() ? 1 : 0;
707 static cell_t GetLatency(IPluginContext *pContext, const cell_t *params)
709 int client = params[1];
711 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
714 return pContext->ThrowNativeError("Client index %d is invalid", client);
715 } else if (!pPlayer->IsInGame()) {
716 return pContext->ThrowNativeError("Client %d is not in game", client);
717 } else if (pPlayer->IsFakeClient()) {
718 return pContext->ThrowNativeError("Client %d is a bot", client);
721 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
723 return sp_ftoc(pInfo->GetLatency(params[2]));
726 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
728 int client = params[1];
730 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
733 return pContext->ThrowNativeError("Client index %d is invalid", client);
734 } else if (!pPlayer->IsInGame()) {
735 return pContext->ThrowNativeError("Client %d is not in game", client);
736 } else if (pPlayer->IsFakeClient()) {
737 return pContext->ThrowNativeError("Client %d is a bot", client);
740 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
742 return sp_ftoc(pInfo->GetAvgLatency(params[2]));
745 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
747 int client = params[1];
749 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
752 return pContext->ThrowNativeError("Client index %d is invalid", client);
753 } else if (!pPlayer->IsInGame()) {
754 return pContext->ThrowNativeError("Client %d is not in game", client);
755 } else if (pPlayer->IsFakeClient()) {
756 return pContext->ThrowNativeError("Client %d is a bot", client);
759 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
761 return sp_ftoc(pInfo->GetAvgLoss(params[2]));
764 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
766 int client = params[1];
768 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
771 return pContext->ThrowNativeError("Client index %d is invalid", client);
772 } else if (!pPlayer->IsInGame()) {
773 return pContext->ThrowNativeError("Client %d is not in game", client);
774 } else if (pPlayer->IsFakeClient()) {
775 return pContext->ThrowNativeError("Client %d is a bot", client);
778 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
780 return sp_ftoc(pInfo->GetAvgChoke(params[2]));
783 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
785 int client = params[1];
787 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
790 return pContext->ThrowNativeError("Client index %d is invalid", client);
791 } else if (!pPlayer->IsInGame()) {
792 return pContext->ThrowNativeError("Client %d is not in game", client);
793 } else if (pPlayer->IsFakeClient()) {
794 return pContext->ThrowNativeError("Client %d is a bot", client);
797 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
799 return sp_ftoc(pInfo->GetAvgData(params[2]));
802 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
804 int client = params[1];
806 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
809 return pContext->ThrowNativeError("Client index %d is invalid", client);
810 } else if (!pPlayer->IsInGame()) {
811 return pContext->ThrowNativeError("Client %d is not in game", client);
812 } else if (pPlayer->IsFakeClient()) {
813 return pContext->ThrowNativeError("Client %d is a bot", client);
816 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
818 return sp_ftoc(pInfo->GetAvgPackets(params[2]));
821 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
823 return g_Players.GetClientOfUserId(params[1]);
826 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
830 int value = sm_show_activity.GetInt();
831 unsigned int replyto = g_ChatTriggers.GetReplyTo();
832 int client = params[1];
834 const char *name = "Console";
835 const char *sign = "ADMIN";
836 bool display_in_chat = false;
839 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
840 if (!pPlayer || !pPlayer->IsConnected())
842 return pContext->ThrowNativeError("Client index %d is invalid", client);
844 name = pPlayer->GetName();
845 AdminId id = pPlayer->GetAdminId();
846 if (id == INVALID_ADMIN_ID
847 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
852 /* Display the message to the client? */
853 if (replyto == SM_REPLY_CONSOLE)
855 g_SourceMod.SetGlobalTarget(client);
856 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
857 UTIL_Format(message, sizeof(message), "[SM] %s\n", buffer);
858 engine->ClientPrintf(pPlayer->GetEdict(), message);
859 display_in_chat = true;
862 g_SourceMod.SetGlobalTarget(LANG_SERVER);
863 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
864 UTIL_Format(message, sizeof(message), "[SM] %s\n", buffer);
865 META_CONPRINT(message);
873 int maxClients = g_Players.GetMaxClients();
874 for (int i=1; i<=maxClients; i++)
876 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
877 if (!pPlayer->IsInGame()
878 || pPlayer->IsFakeClient()
879 || (display_in_chat && i == client))
883 AdminId id = pPlayer->GetAdminId();
884 g_SourceMod.SetGlobalTarget(i);
885 if (id == INVALID_ADMIN_ID
886 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
888 /* Treat this as a normal user */
889 if ((value & 1) || (value & 2))
891 const char *newsign = sign;
896 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
897 UTIL_Format(message, sizeof(message), "[SM] %s: %s", newsign, buffer);
898 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
901 /* Treat this as an admin user */
902 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
905 || ((value & 16) && is_root))
907 const char *newsign = sign;
908 if ((value & 8) || ((value & 16) && is_root))
912 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
913 UTIL_Format(message, sizeof(message), "[SM] %s: %s", newsign, buffer);
914 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
922 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
924 int client = params[1];
926 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
929 return pContext->ThrowNativeError("Client index %d is invalid", client);
930 } else if (!pPlayer->IsConnected()) {
931 return pContext->ThrowNativeError("Client %d is not connected", client);
934 if (pPlayer->IsFakeClient())
938 /* :TODO: Define BotKickCmd in core.games.txt so that "bot_kick" can be used in CS:S */
939 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
941 engine->ServerCommand(kickcmd);
945 INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
946 IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
949 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
951 pClient->Disconnect("%s", buffer);
956 REGISTER_NATIVES(playernatives)
958 {"AddUserFlags", AddUserFlags},
959 {"CanUserTarget", CanUserTarget},
960 {"GetClientAuthString", sm_GetClientAuthStr},
961 {"GetClientCount", sm_GetClientCount},
962 {"GetClientInfo", sm_GetClientInfo},
963 {"GetClientIP", sm_GetClientIP},
964 {"GetClientName", sm_GetClientName},
965 {"GetClientTeam", GetClientTeam},
966 {"GetClientUserId", GetClientUserId},
967 {"GetMaxClients", sm_GetMaxClients},
968 {"GetUserAdmin", GetUserAdmin},
969 {"GetUserFlagBits", GetUserFlagBits},
970 {"IsClientAuthorized", sm_IsClientAuthorized},
971 {"IsClientConnected", sm_IsClientConnected},
972 {"IsFakeClient", sm_IsClientFakeClient},
973 {"IsPlayerInGame", sm_IsClientInGame}, /* Backwards compat shim */
974 {"IsClientInGame", sm_IsClientInGame},
975 {"RemoveUserFlags", RemoveUserFlags},
976 {"SetUserAdmin", SetUserAdmin},
977 {"SetUserFlagBits", SetUserFlagBits},
978 {"GetClientDeaths", GetDeathCount},
979 {"GetClientFrags", GetFragCount},
980 {"GetClientArmor", GetArmorValue},
981 {"GetClientAbsOrigin", GetAbsOrigin},
982 {"GetClientAbsAngles", GetAbsAngles},
983 {"GetClientMins", GetPlayerMins},
984 {"GetClientMaxs", GetPlayerMaxs},
985 {"GetClientWeapon", GetWeaponName},
986 {"GetClientModel", GetModelName},
987 {"GetClientHealth", GetHealth},
988 {"GetClientTime", GetTimeConnected},
989 {"GetClientDataRate", GetDataRate},
990 {"IsClentTimingOut", IsTimingOut},
991 {"GetClientLatency", GetLatency},
992 {"GetClientAvgLatency", GetAvgLatency},
993 {"GetClientAvgLoss", GetAvgLoss},
994 {"GetClientAvgChoke", GetAvgChoke},
995 {"GetClientAvgData", GetAvgData},
996 {"GetClientAvgPackets", GetAvgPackets},
997 {"GetClientOfUserId", GetClientOfUserId},
998 {"ShowActivity", ShowActivity},
999 {"KickClient", KickClient},