atcprintf() is now fully re-entrant, meaning translations can be used from inside translations
3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
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.
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
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/>.
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>.
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>
41 ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY|FCVAR_PROTECTED, "Activity display setting (see sourcemod.cfg)");
43 static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
47 return g_Players.NumPlayers();
50 int maxplayers = g_Players.MaxClients();
52 for (int i=1; i<=maxplayers; ++i)
54 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
55 if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
61 return (g_Players.NumPlayers() + count);
64 static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
66 return g_Players.MaxClients();
69 static cell_t sm_GetClientName(IPluginContext *pCtx, const cell_t *params)
71 int index = params[1];
75 static ConVar *hostname = NULL;
78 hostname = icvar->FindVar("hostname");
81 return pCtx->ThrowNativeError("Could not find \"hostname\" cvar");
84 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), hostname->GetString(), NULL);
88 if ((index < 1) || (index > g_Players.GetMaxClients()))
90 return pCtx->ThrowNativeError("Client index %d is invalid", index);
93 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
94 if (!pPlayer->IsConnected())
96 return pCtx->ThrowNativeError("Client %d is not connected", index);
99 pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), pPlayer->GetName(), NULL);
103 static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
105 int index = params[1];
106 if ((index < 1) || (index > g_Players.GetMaxClients()))
108 return pCtx->ThrowNativeError("Client index %d is invalid", index);
111 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
112 if (!pPlayer->IsConnected())
114 return pCtx->ThrowNativeError("Client %d is not connected", index);
118 strcpy(buf, pPlayer->GetIPAddress());
120 if (params[4] && (ptr = strchr(buf, ':')))
125 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), buf);
129 static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
131 int index = params[1];
132 if ((index < 1) || (index > g_Players.GetMaxClients()))
134 return pCtx->ThrowNativeError("Client index %d is invalid", index);
137 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
138 if (!pPlayer->IsConnected())
140 return pCtx->ThrowNativeError("Client %d is not connected", index);
143 if (!pPlayer->IsAuthorized())
148 pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
153 static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
155 int index = params[1];
156 if ((index < 1) || (index > g_Players.GetMaxClients()))
158 return pCtx->ThrowNativeError("Client index %d is invalid", index);
161 return (g_Players.GetPlayerByIndex(index)->IsConnected()) ? 1 : 0;
164 static cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
166 int index = params[1];
167 if ((index < 1) || (index > g_Players.GetMaxClients()))
169 return pCtx->ThrowNativeError("Client index %d is invalid", index);
172 return (g_Players.GetPlayerByIndex(index)->IsInGame()) ? 1 : 0;
175 static cell_t sm_IsClientAuthorized(IPluginContext *pCtx, const cell_t *params)
177 int index = params[1];
178 if ((index < 1) || (index > g_Players.GetMaxClients()))
180 return pCtx->ThrowNativeError("Client index %d is invalid", index);
183 return (g_Players.GetPlayerByIndex(index)->IsAuthorized()) ? 1 : 0;
186 static cell_t sm_IsClientFakeClient(IPluginContext *pCtx, const cell_t *params)
188 int index = params[1];
189 if ((index < 1) || (index > g_Players.GetMaxClients()))
191 return pCtx->ThrowNativeError("Client index %d is invalid", index);
194 CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
195 if (!pPlayer->IsConnected())
197 return pCtx->ThrowNativeError("Client %d is not connected", index);
200 return (pPlayer->IsFakeClient()) ? 1 : 0;
203 static cell_t IsClientObserver(IPluginContext *pContext, const cell_t *params)
205 int client = params[1];
207 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
215 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
218 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
221 return pInfo->IsObserver() ? 1 : 0;
224 static cell_t sm_GetClientInfo(IPluginContext *pContext, const cell_t *params)
226 int client = params[1];
227 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
230 return pContext->ThrowNativeError("Client index %d is invalid", client);
232 if (!pPlayer->IsConnected())
234 return pContext->ThrowNativeError("Client %d is not connected", client);
238 pContext->LocalToString(params[2], &key);
240 const char *val = engine->GetClientConVarValue(client, key);
246 pContext->StringToLocalUTF8(params[3], params[4], val, NULL);
250 static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
252 int client = params[1];
253 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
256 return pContext->ThrowNativeError("Client index %d is invalid", client);
258 if (!pPlayer->IsConnected())
260 return pContext->ThrowNativeError("Client %d is not connected", client);
262 if (!g_Admins.IsValidAdmin(params[2]))
264 return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
267 pPlayer->SetAdminId(params[2], params[3] ? true : false);
272 static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
274 int client = params[1];
275 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
278 return pContext->ThrowNativeError("Client index %d is invalid", client);
280 if (!pPlayer->IsConnected())
282 return pContext->ThrowNativeError("Client %d is not connected", client);
285 return pPlayer->GetAdminId();
288 static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
290 int client = params[1];
291 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
294 return pContext->ThrowNativeError("Client index %d is invalid", client);
296 if (!pPlayer->IsConnected())
298 return pContext->ThrowNativeError("Client %d is not connected", client);
302 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
304 id = g_Admins.CreateAdmin(NULL);
305 pPlayer->SetAdminId(id, true);
309 for (int i=2; i<=params[0]; i++)
311 pContext->LocalToPhysAddr(params[i], &addr);
312 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
318 static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
320 int client = params[1];
321 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
324 return pContext->ThrowNativeError("Client index %d is invalid", client);
326 if (!pPlayer->IsConnected())
328 return pContext->ThrowNativeError("Client %d is not connected", client);
332 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
338 for (int i=2; i<=params[0]; i++)
340 pContext->LocalToPhysAddr(params[i], &addr);
341 g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
347 static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
349 int client = params[1];
350 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
353 return pContext->ThrowNativeError("Client index %d is invalid", client);
355 if (!pPlayer->IsConnected())
357 return pContext->ThrowNativeError("Client %d is not connected", client);
361 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
363 id = g_Admins.CreateAdmin(NULL);
364 pPlayer->SetAdminId(id, true);
367 g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
372 static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
374 int client = params[1];
375 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
378 return pContext->ThrowNativeError("Client index %d is invalid", client);
380 if (!pPlayer->IsConnected())
382 return pContext->ThrowNativeError("Client %d is not connected", client);
386 if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
391 return g_Admins.GetAdminFlags(id, Access_Effective);
394 static cell_t GetClientUserId(IPluginContext *pContext, const cell_t *params)
396 int client = params[1];
397 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
400 return pContext->ThrowNativeError("Client index %d is invalid", client);
402 if (!pPlayer->IsConnected())
404 return pContext->ThrowNativeError("Client %d is not connected", client);
407 return engine->GetPlayerUserId(pPlayer->GetEdict());
410 static cell_t CanUserTarget(IPluginContext *pContext, const cell_t *params)
412 int client = params[1];
413 int target = params[2];
420 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
428 CPlayer *pTarget = g_Players.GetPlayerByIndex(target);
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);
436 return g_Admins.CanAdminTarget(pPlayer->GetAdminId(), pTarget->GetAdminId()) ? 1 : 0;
439 static cell_t GetClientTeam(IPluginContext *pContext, const cell_t *params)
441 int client = params[1];
443 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
451 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
454 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
457 return pInfo->GetTeamIndex();
460 static cell_t GetFragCount(IPluginContext *pContext, const cell_t *params)
462 int client = params[1];
464 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
472 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
475 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
478 return pInfo->GetFragCount();
481 static cell_t GetDeathCount(IPluginContext *pContext, const cell_t *params)
483 int client = params[1];
485 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
493 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
496 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
499 return pInfo->GetDeathCount();
502 static cell_t GetArmorValue(IPluginContext *pContext, const cell_t *params)
504 int client = params[1];
506 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
514 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
517 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
520 return pInfo->GetArmorValue();
523 static cell_t GetAbsOrigin(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->GetAbsOrigin();
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 GetAbsAngles(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], &pAng);
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);
581 static cell_t GetPlayerMins(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");
600 pContext->LocalToPhysAddr(params[2], &pVec);
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);
610 static cell_t GetPlayerMaxs(IPluginContext *pContext, const cell_t *params)
612 int client = params[1];
614 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
622 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
625 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
629 pContext->LocalToPhysAddr(params[2], &pVec);
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);
639 static cell_t GetWeaponName(IPluginContext *pContext, const cell_t *params)
641 int client = params[1];
643 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
651 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
654 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
657 const char *weapon = pInfo->GetWeaponName();
658 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), weapon ? weapon : "", NULL);
663 static cell_t GetModelName(IPluginContext *pContext, const cell_t *params)
665 int client = params[1];
667 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
675 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
678 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
681 const char *model = pInfo->GetModelName();
682 pContext->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), model ? model : "", NULL);
687 static cell_t GetHealth(IPluginContext *pContext, const cell_t *params)
689 int client = params[1];
691 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
699 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
702 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
705 return pInfo->GetHealth();
708 static cell_t GetTimeConnected(IPluginContext *pContext, const cell_t *params)
710 int client = params[1];
712 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
722 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
724 return sp_ftoc(pInfo->GetTimeConnected());
727 static cell_t GetDataRate(IPluginContext *pContext, const cell_t *params)
729 int client = params[1];
731 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
741 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
743 return pInfo->GetDataRate();
746 static cell_t IsTimingOut(IPluginContext *pContext, const cell_t *params)
748 int client = params[1];
750 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
760 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
762 return pInfo->IsTimingOut() ? 1 : 0;
765 static cell_t GetLatency(IPluginContext *pContext, const cell_t *params)
767 int client = params[1];
769 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
779 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
781 return sp_ftoc(pInfo->GetLatency(params[2]));
784 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
786 int client = params[1];
788 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
798 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
800 return sp_ftoc(pInfo->GetAvgLatency(params[2]));
803 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
805 int client = params[1];
807 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
817 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
819 return sp_ftoc(pInfo->GetAvgLoss(params[2]));
822 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
824 int client = params[1];
826 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
836 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
838 return sp_ftoc(pInfo->GetAvgChoke(params[2]));
841 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
843 int client = params[1];
845 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
855 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
857 return sp_ftoc(pInfo->GetAvgData(params[2]));
860 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
862 int client = params[1];
864 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
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);
874 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
876 return sp_ftoc(pInfo->GetAvgPackets(params[2]));
879 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
881 return g_Players.GetClientOfUserId(params[1]);
884 static cell_t _ShowActivity(IPluginContext *pContext, const cell_t *params, const char *tag, cell_t fmt_param)
888 int value = sm_show_activity.GetInt();
889 unsigned int replyto = g_ChatTriggers.GetReplyTo();
890 int client = params[1];
892 const char *name = "Console";
893 const char *sign = "ADMIN";
894 bool display_in_chat = false;
897 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
898 if (!pPlayer || !pPlayer->IsConnected())
900 return pContext->ThrowNativeError("Client index %d is invalid", client);
902 name = pPlayer->GetName();
903 AdminId id = pPlayer->GetAdminId();
904 if (id == INVALID_ADMIN_ID
905 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
910 /* Display the message to the client? */
911 if (replyto == SM_REPLY_CONSOLE)
913 g_SourceMod.SetGlobalTarget(client);
914 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
915 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
916 engine->ClientPrintf(pPlayer->GetEdict(), message);
917 display_in_chat = true;
920 g_SourceMod.SetGlobalTarget(LANG_SERVER);
921 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
922 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
923 META_CONPRINT(message);
931 int maxClients = g_Players.GetMaxClients();
932 for (int i=1; i<=maxClients; i++)
934 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
935 if (!pPlayer->IsInGame()
936 || pPlayer->IsFakeClient()
937 || (display_in_chat && i == client))
941 AdminId id = pPlayer->GetAdminId();
942 g_SourceMod.SetGlobalTarget(i);
943 if (id == INVALID_ADMIN_ID
944 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
946 /* Treat this as a normal user */
947 if ((value & 1) || (value & 2))
949 const char *newsign = sign;
954 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
955 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
956 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
959 /* Treat this as an admin user */
960 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
963 || ((value & 16) && is_root))
965 const char *newsign = sign;
966 if ((value & 8) || ((value & 16) && is_root))
970 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
971 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
972 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
980 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
982 return _ShowActivity(pContext, params, "[SM] ", 2);
985 static cell_t ShowActivityEx(IPluginContext *pContext, const cell_t *params)
988 pContext->LocalToString(params[2], &str);
990 return _ShowActivity(pContext, params, str, 3);
993 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
995 int client = params[1];
997 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1000 return pContext->ThrowNativeError("Client index %d is invalid", client);
1001 } else if (!pPlayer->IsConnected()) {
1002 return pContext->ThrowNativeError("Client %d is not connected", client);
1005 pPlayer->MarkAsBeingKicked();
1007 if (pPlayer->IsFakeClient())
1010 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
1012 engine->ServerCommand(kickcmd);
1016 g_SourceMod.SetGlobalTarget(client);
1019 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1021 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
1026 pPlayer->Kick(buffer);
1031 static cell_t ChangeClientTeam(IPluginContext *pContext, const cell_t *params)
1033 int client = params[1];
1035 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1038 return pContext->ThrowNativeError("Client index %d is invalid", client);
1039 } else if (!pPlayer->IsInGame()) {
1040 return pContext->ThrowNativeError("Client %d is not in game", client);
1043 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
1046 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
1049 pInfo->ChangeTeam(params[2]);
1054 static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
1056 int client = params[1];
1058 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1061 return pContext->ThrowNativeError("Client index %d is invalid", client);
1062 } else if (!pPlayer->IsInGame()) {
1063 return pContext->ThrowNativeError("Client %d is not in game", client);
1064 } else if (!pPlayer->IsAuthorized()) {
1065 return pContext->ThrowNativeError("Client %d is not authorized", client);
1068 AdminId id = pPlayer->GetAdminId();
1069 pPlayer->DoBasicAdminChecks();
1071 return (id != pPlayer->GetAdminId()) ? 1 : 0;
1074 static cell_t NotifyPostAdminCheck(IPluginContext *pContext, const cell_t *params)
1076 int client = params[1];
1078 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1081 return pContext->ThrowNativeError("Client index %d is invalid", client);
1082 } else if (!pPlayer->IsInGame()) {
1083 return pContext->ThrowNativeError("Client %d is not in game", client);
1084 } else if (!pPlayer->IsAuthorized()) {
1085 return pContext->ThrowNativeError("Client %d is not authorized", client);
1088 pPlayer->NotifyPostAdminChecks();
1093 static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params)
1095 int client = params[1];
1097 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1101 return pContext->ThrowNativeError("Client index %d is invalid", client);
1103 else if (!pPlayer->IsConnected())
1105 return pContext->ThrowNativeError("Client %d is not in game", client);
1108 return pPlayer->IsInKickQueue() ? 1 : 0;
1111 REGISTER_NATIVES(playernatives)
1113 {"AddUserFlags", AddUserFlags},
1114 {"CanUserTarget", CanUserTarget},
1115 {"ChangeClientTeam", ChangeClientTeam},
1116 {"GetClientAuthString", sm_GetClientAuthStr},
1117 {"GetClientCount", sm_GetClientCount},
1118 {"GetClientInfo", sm_GetClientInfo},
1119 {"GetClientIP", sm_GetClientIP},
1120 {"GetClientName", sm_GetClientName},
1121 {"GetClientTeam", GetClientTeam},
1122 {"GetClientUserId", GetClientUserId},
1123 {"GetMaxClients", sm_GetMaxClients},
1124 {"GetUserAdmin", GetUserAdmin},
1125 {"GetUserFlagBits", GetUserFlagBits},
1126 {"IsClientAuthorized", sm_IsClientAuthorized},
1127 {"IsClientConnected", sm_IsClientConnected},
1128 {"IsFakeClient", sm_IsClientFakeClient},
1129 {"IsPlayerInGame", sm_IsClientInGame}, /* Backwards compat shim */
1130 {"IsClientInGame", sm_IsClientInGame},
1131 {"IsClientObserver", IsClientObserver},
1132 {"RemoveUserFlags", RemoveUserFlags},
1133 {"SetUserAdmin", SetUserAdmin},
1134 {"SetUserFlagBits", SetUserFlagBits},
1135 {"GetClientDeaths", GetDeathCount},
1136 {"GetClientFrags", GetFragCount},
1137 {"GetClientArmor", GetArmorValue},
1138 {"GetClientAbsOrigin", GetAbsOrigin},
1139 {"GetClientAbsAngles", GetAbsAngles},
1140 {"GetClientMins", GetPlayerMins},
1141 {"GetClientMaxs", GetPlayerMaxs},
1142 {"GetClientWeapon", GetWeaponName},
1143 {"GetClientModel", GetModelName},
1144 {"GetClientHealth", GetHealth},
1145 {"GetClientTime", GetTimeConnected},
1146 {"GetClientDataRate", GetDataRate},
1147 {"IsClentTimingOut", IsTimingOut},
1148 {"GetClientLatency", GetLatency},
1149 {"GetClientAvgLatency", GetAvgLatency},
1150 {"GetClientAvgLoss", GetAvgLoss},
1151 {"GetClientAvgChoke", GetAvgChoke},
1152 {"GetClientAvgData", GetAvgData},
1153 {"GetClientAvgPackets", GetAvgPackets},
1154 {"GetClientOfUserId", GetClientOfUserId},
1155 {"ShowActivity", ShowActivity},
1156 {"ShowActivityEx", ShowActivityEx},
1157 {"KickClient", KickClient},
1158 {"RunAdminCacheChecks", RunAdminCacheChecks},
1159 {"NotifyPostAdminCheck", NotifyPostAdminCheck},
1160 {"IsClientInKickQueue", IsClientInKickQueue},