Triggered build, something funky happened....
3 * =============================================================================
5 * Copyright (C) 2004-2008 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, "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]) && params[2] != INVALID_ADMIN_ID)
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];
770 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
773 return pContext->ThrowNativeError("Client index %d is invalid", client);
775 else if (!pPlayer->IsInGame())
777 return pContext->ThrowNativeError("Client %d is not in game", client);
779 else if (pPlayer->IsFakeClient())
781 return pContext->ThrowNativeError("Client %d is a bot", client);
784 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
786 if (params[2] == MAX_FLOWS)
788 value = pInfo->GetLatency(FLOW_INCOMING) + pInfo->GetLatency(FLOW_OUTGOING);
792 value = pInfo->GetLatency(params[2]);
795 return sp_ftoc(value);
798 static cell_t GetAvgLatency(IPluginContext *pContext, const cell_t *params)
800 int client = params[1];
803 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
806 return pContext->ThrowNativeError("Client index %d is invalid", client);
808 else if (!pPlayer->IsInGame())
810 return pContext->ThrowNativeError("Client %d is not in game", client);
812 else if (pPlayer->IsFakeClient())
814 return pContext->ThrowNativeError("Client %d is a bot", client);
817 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
819 if (params[2] == MAX_FLOWS)
821 value = pInfo->GetAvgLatency(FLOW_INCOMING) + pInfo->GetAvgLatency(FLOW_OUTGOING);
825 value = pInfo->GetAvgLatency(params[2]);
828 return sp_ftoc(value);
831 static cell_t GetAvgLoss(IPluginContext *pContext, const cell_t *params)
833 int client = params[1];
836 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
839 return pContext->ThrowNativeError("Client index %d is invalid", client);
841 else if (!pPlayer->IsInGame())
843 return pContext->ThrowNativeError("Client %d is not in game", client);
845 else if (pPlayer->IsFakeClient())
847 return pContext->ThrowNativeError("Client %d is a bot", client);
850 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
852 if (params[2] == MAX_FLOWS)
854 value = pInfo->GetAvgLoss(FLOW_INCOMING) + pInfo->GetAvgLoss(FLOW_OUTGOING);
858 value = pInfo->GetAvgLoss(params[2]);
861 return sp_ftoc(value);
864 static cell_t GetAvgChoke(IPluginContext *pContext, const cell_t *params)
866 int client = params[1];
869 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
872 return pContext->ThrowNativeError("Client index %d is invalid", client);
874 else if (!pPlayer->IsInGame())
876 return pContext->ThrowNativeError("Client %d is not in game", client);
878 else if (pPlayer->IsFakeClient())
880 return pContext->ThrowNativeError("Client %d is a bot", client);
883 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
885 if (params[2] == MAX_FLOWS)
887 value = pInfo->GetAvgChoke(FLOW_INCOMING) + pInfo->GetAvgChoke(FLOW_OUTGOING);
891 value = pInfo->GetAvgChoke(params[2]);
894 return sp_ftoc(value);
897 static cell_t GetAvgData(IPluginContext *pContext, const cell_t *params)
899 int client = params[1];
902 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
905 return pContext->ThrowNativeError("Client index %d is invalid", client);
907 else if (!pPlayer->IsInGame())
909 return pContext->ThrowNativeError("Client %d is not in game", client);
911 else if (pPlayer->IsFakeClient())
913 return pContext->ThrowNativeError("Client %d is a bot", client);
916 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
918 if (params[2] == MAX_FLOWS)
920 value = pInfo->GetAvgData(FLOW_INCOMING) + pInfo->GetAvgData(FLOW_OUTGOING);
924 value = pInfo->GetAvgData(params[2]);
927 return sp_ftoc(value);
930 static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
932 int client = params[1];
935 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
938 return pContext->ThrowNativeError("Client index %d is invalid", client);
940 else if (!pPlayer->IsInGame())
942 return pContext->ThrowNativeError("Client %d is not in game", client);
944 else if (pPlayer->IsFakeClient())
946 return pContext->ThrowNativeError("Client %d is a bot", client);
949 INetChannelInfo *pInfo = engine->GetPlayerNetInfo(client);
951 if (params[2] == MAX_FLOWS)
953 value = pInfo->GetAvgPackets(FLOW_INCOMING) + pInfo->GetAvgPackets(FLOW_OUTGOING);
957 value = pInfo->GetAvgPackets(params[2]);
960 return sp_ftoc(value);
963 static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params)
965 return g_Players.GetClientOfUserId(params[1]);
968 static cell_t _ShowActivity(IPluginContext *pContext,
969 const cell_t *params,
975 int value = sm_show_activity.GetInt();
976 unsigned int replyto = g_ChatTriggers.GetReplyTo();
977 int client = params[1];
979 const char *name = "Console";
980 const char *sign = "ADMIN";
981 bool display_in_chat = false;
984 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
985 if (!pPlayer || !pPlayer->IsConnected())
987 return pContext->ThrowNativeError("Client index %d is invalid", client);
989 name = pPlayer->GetName();
990 AdminId id = pPlayer->GetAdminId();
991 if (id == INVALID_ADMIN_ID
992 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
997 /* Display the message to the client? */
998 if (replyto == SM_REPLY_CONSOLE)
1000 g_SourceMod.SetGlobalTarget(client);
1001 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1003 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1008 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
1009 engine->ClientPrintf(pPlayer->GetEdict(), message);
1010 display_in_chat = true;
1015 g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1016 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1018 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1023 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
1024 META_CONPRINT(message);
1032 int maxClients = g_Players.GetMaxClients();
1033 for (int i=1; i<=maxClients; i++)
1035 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
1036 if (!pPlayer->IsInGame()
1037 || pPlayer->IsFakeClient()
1038 || (display_in_chat && i == client))
1042 AdminId id = pPlayer->GetAdminId();
1043 g_SourceMod.SetGlobalTarget(i);
1044 if (id == INVALID_ADMIN_ID
1045 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
1047 /* Treat this as a normal user */
1048 if ((value & 1) || (value & 2))
1050 const char *newsign = sign;
1051 if ((value & 2) || (i == client))
1055 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1057 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1062 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
1063 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
1068 /* Treat this as an admin user */
1069 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
1072 || ((value & 16) && is_root))
1074 const char *newsign = sign;
1075 if ((value & 8) || ((value & 16) && is_root) || (i == client))
1079 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1081 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1086 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
1087 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
1095 static cell_t _ShowActivity2(IPluginContext *pContext,
1096 const cell_t *params,
1102 int value = sm_show_activity.GetInt();
1103 unsigned int replyto = g_ChatTriggers.GetReplyTo();
1104 int client = params[1];
1106 const char *name = "Console";
1107 const char *sign = "ADMIN";
1110 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1111 if (!pPlayer || !pPlayer->IsConnected())
1113 return pContext->ThrowNativeError("Client index %d is invalid", client);
1115 name = pPlayer->GetName();
1116 AdminId id = pPlayer->GetAdminId();
1117 if (id == INVALID_ADMIN_ID
1118 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
1123 g_SourceMod.SetGlobalTarget(client);
1124 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1126 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1131 /* We don't display directly to the console because the chat text
1132 * simply gets added to the console, so we don't want it to print
1135 if (replyto == SM_REPLY_CONSOLE)
1138 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
1139 engine->ClientPrintf(pPlayer->GetEdict(), message);
1141 UTIL_Format(message, sizeof(message), "%s%s", tag, buffer);
1142 g_HL2.TextMsg(client, HUD_PRINTTALK, message);
1146 UTIL_Format(message, sizeof(message), "%s%s", tag, buffer);
1147 g_HL2.TextMsg(client, HUD_PRINTTALK, message);
1152 g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1153 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1155 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1160 UTIL_Format(message, sizeof(message), "%s%s\n", tag, buffer);
1161 META_CONPRINT(message);
1169 int maxClients = g_Players.GetMaxClients();
1170 for (int i=1; i<=maxClients; i++)
1172 CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
1173 if (!pPlayer->IsInGame()
1174 || pPlayer->IsFakeClient()
1179 AdminId id = pPlayer->GetAdminId();
1180 g_SourceMod.SetGlobalTarget(i);
1181 if (id == INVALID_ADMIN_ID
1182 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
1184 /* Treat this as a normal user */
1185 if ((value & 1) || (value & 2))
1187 const char *newsign = sign;
1192 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1194 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1199 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
1200 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
1205 /* Treat this as an admin user */
1206 bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective);
1209 || ((value & 16) && is_root))
1211 const char *newsign = sign;
1212 if ((value & 8) || ((value & 16) && is_root))
1216 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
1218 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1223 UTIL_Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
1224 g_HL2.TextMsg(i, HUD_PRINTTALK, message);
1232 static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params)
1234 return _ShowActivity(pContext, params, "[SM] ", 2);
1237 static cell_t ShowActivityEx(IPluginContext *pContext, const cell_t *params)
1240 pContext->LocalToString(params[2], &str);
1242 return _ShowActivity(pContext, params, str, 3);
1245 static cell_t ShowActivity2(IPluginContext *pContext, const cell_t *params)
1248 pContext->LocalToString(params[2], &str);
1250 return _ShowActivity2(pContext, params, str, 3);
1253 static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
1255 int client = params[1];
1257 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1260 return pContext->ThrowNativeError("Client index %d is invalid", client);
1262 else if (!pPlayer->IsConnected())
1264 return pContext->ThrowNativeError("Client %d is not connected", client);
1267 /* Ignore duplicate kicks */
1268 if (pPlayer->IsInKickQueue())
1273 pPlayer->MarkAsBeingKicked();
1275 if (pPlayer->IsFakeClient())
1278 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
1280 engine->ServerCommand(kickcmd);
1284 g_SourceMod.SetGlobalTarget(client);
1287 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1289 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1294 g_HL2.AddDelayedKick(client, pPlayer->GetUserId(), buffer);
1299 static cell_t KickClientEx(IPluginContext *pContext, const cell_t *params)
1301 int client = params[1];
1303 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1306 return pContext->ThrowNativeError("Client index %d is invalid", client);
1308 else if (!pPlayer->IsConnected())
1310 return pContext->ThrowNativeError("Client %d is not connected", client);
1313 /* Ignore duplicate kicks */
1314 if (pPlayer->IsInKickQueue())
1319 pPlayer->MarkAsBeingKicked();
1321 if (pPlayer->IsFakeClient())
1324 UTIL_Format(kickcmd, sizeof(kickcmd), "kick %s\n", pPlayer->GetName());
1326 engine->ServerCommand(kickcmd);
1330 g_SourceMod.SetGlobalTarget(client);
1333 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1335 if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1340 pPlayer->Kick(buffer);
1345 static cell_t ChangeClientTeam(IPluginContext *pContext, const cell_t *params)
1347 int client = params[1];
1349 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1352 return pContext->ThrowNativeError("Client index %d is invalid", client);
1354 else if (!pPlayer->IsInGame())
1356 return pContext->ThrowNativeError("Client %d is not in game", client);
1359 IPlayerInfo *pInfo = pPlayer->GetPlayerInfo();
1362 return pContext->ThrowNativeError("IPlayerInfo not supported by game");
1365 pInfo->ChangeTeam(params[2]);
1370 static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
1372 int client = params[1];
1374 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1377 return pContext->ThrowNativeError("Client index %d is invalid", client);
1379 else if (!pPlayer->IsInGame())
1381 return pContext->ThrowNativeError("Client %d is not in game", client);
1383 else if (!pPlayer->IsAuthorized())
1385 return pContext->ThrowNativeError("Client %d is not authorized", client);
1388 AdminId id = pPlayer->GetAdminId();
1389 pPlayer->DoBasicAdminChecks();
1391 return (id != pPlayer->GetAdminId()) ? 1 : 0;
1394 static cell_t NotifyPostAdminCheck(IPluginContext *pContext, const cell_t *params)
1396 int client = params[1];
1398 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1401 return pContext->ThrowNativeError("Client index %d is invalid", client);
1403 else if (!pPlayer->IsInGame()) {
1404 return pContext->ThrowNativeError("Client %d is not in game", client);
1406 else if (!pPlayer->IsAuthorized())
1408 return pContext->ThrowNativeError("Client %d is not authorized", client);
1411 pPlayer->NotifyPostAdminChecks();
1416 static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params)
1418 int client = params[1];
1420 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1424 return pContext->ThrowNativeError("Client index %d is invalid", client);
1426 else if (!pPlayer->IsConnected())
1428 return pContext->ThrowNativeError("Client %d is not in game", client);
1431 return pPlayer->IsInKickQueue() ? 1 : 0;
1434 static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
1436 cmd_target_info_t info;
1438 pContext->LocalToString(params[1], (char **)&info.pattern);
1439 info.admin = params[2];
1440 pContext->LocalToPhysAddr(params[3], &info.targets);
1441 info.max_targets = params[4];
1442 info.flags = params[5];
1443 pContext->LocalToString(params[6], &info.target_name);
1444 info.target_name_maxlength = params[7];
1447 pContext->LocalToPhysAddr(params[8], &tn_is_ml);
1449 g_Players.ProcessCommandTarget(&info);
1451 if (info.target_name_style == COMMAND_TARGETNAME_ML)
1460 if (info.num_targets == 0)
1466 return info.num_targets;
1470 static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
1477 const char *identity[2] = {"Console", "ADMIN"};
1482 if ((pTarget = g_Players.GetPlayerByIndex(target)) == NULL)
1484 return pContext->ThrowNativeError("Invalid client index %d", target);
1486 if (!pTarget->IsConnected())
1488 return pContext->ThrowNativeError("Client %d not connected", target);
1491 value = sm_show_activity.GetInt();
1497 if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
1499 return pContext->ThrowNativeError("Invalid client index %d", client);
1501 if (!pPlayer->IsConnected())
1503 return pContext->ThrowNativeError("Client %d not connected", client);
1506 identity[0] = pPlayer->GetName();
1508 AdminId id = pPlayer->GetAdminId();
1509 if (id == INVALID_ADMIN_ID
1510 || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective))
1512 identity[1] = "PLAYER";
1517 bool bShowActivity = false;
1519 if ((aidTarget = pTarget->GetAdminId()) == INVALID_ADMIN_ID
1520 || !g_Admins.GetAdminFlag(aidTarget, Admin_Generic, Access_Effective))
1522 /* Treat this as a normal user */
1523 if ((value & 1) || (value & 2))
1525 if ((value & 2) || (target == client))
1529 bShowActivity = true;
1534 /* Treat this as an admin user */
1535 bool is_root = g_Admins.GetAdminFlag(aidTarget, Admin_Root, Access_Effective);
1538 || ((value & 16) && is_root))
1540 if ((value & 8) || ((value & 16) && is_root) || (target == client))
1544 bShowActivity = true;
1548 /* Otherwise, send it back to the script. */
1549 pContext->StringToLocalUTF8(params[3], params[4], identity[mode], NULL);
1551 return bShowActivity ? 1 : 0;
1554 REGISTER_NATIVES(playernatives)
1556 {"AddUserFlags", AddUserFlags},
1557 {"CanUserTarget", CanUserTarget},
1558 {"ChangeClientTeam", ChangeClientTeam},
1559 {"GetClientAuthString", sm_GetClientAuthStr},
1560 {"GetClientCount", sm_GetClientCount},
1561 {"GetClientInfo", sm_GetClientInfo},
1562 {"GetClientIP", sm_GetClientIP},
1563 {"GetClientName", sm_GetClientName},
1564 {"GetClientTeam", GetClientTeam},
1565 {"GetClientUserId", GetClientUserId},
1566 {"GetMaxClients", sm_GetMaxClients},
1567 {"GetUserAdmin", GetUserAdmin},
1568 {"GetUserFlagBits", GetUserFlagBits},
1569 {"IsClientAuthorized", sm_IsClientAuthorized},
1570 {"IsClientConnected", sm_IsClientConnected},
1571 {"IsFakeClient", sm_IsClientFakeClient},
1572 {"IsClientInGame", sm_IsClientInGame},
1573 {"IsClientObserver", IsClientObserver},
1574 {"RemoveUserFlags", RemoveUserFlags},
1575 {"SetUserAdmin", SetUserAdmin},
1576 {"SetUserFlagBits", SetUserFlagBits},
1577 {"GetClientDeaths", GetDeathCount},
1578 {"GetClientFrags", GetFragCount},
1579 {"GetClientArmor", GetArmorValue},
1580 {"GetClientAbsOrigin", GetAbsOrigin},
1581 {"GetClientAbsAngles", GetAbsAngles},
1582 {"GetClientMins", GetPlayerMins},
1583 {"GetClientMaxs", GetPlayerMaxs},
1584 {"GetClientWeapon", GetWeaponName},
1585 {"GetClientModel", GetModelName},
1586 {"GetClientHealth", GetHealth},
1587 {"GetClientTime", GetTimeConnected},
1588 {"GetClientDataRate", GetDataRate},
1589 {"IsClientTimingOut", IsTimingOut},
1590 {"GetClientLatency", GetLatency},
1591 {"GetClientAvgLatency", GetAvgLatency},
1592 {"GetClientAvgLoss", GetAvgLoss},
1593 {"GetClientAvgChoke", GetAvgChoke},
1594 {"GetClientAvgData", GetAvgData},
1595 {"GetClientAvgPackets", GetAvgPackets},
1596 {"GetClientOfUserId", GetClientOfUserId},
1597 {"ShowActivity", ShowActivity},
1598 {"ShowActivityEx", ShowActivityEx},
1599 {"ShowActivity2", ShowActivity2},
1600 {"KickClient", KickClient},
1601 {"KickClientEx", KickClientEx},
1602 {"RunAdminCacheChecks", RunAdminCacheChecks},
1603 {"NotifyPostAdminCheck", NotifyPostAdminCheck},
1604 {"IsClientInKickQueue", IsClientInKickQueue},
1605 {"ProcessTargetString", ProcessTargetString},
1606 {"FormatActivitySource", FormatActivitySource},