diff --git a/core/smn_console.cpp b/core/smn_console.cpp index aec66bb3..e5e65962 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -686,6 +686,8 @@ static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Client %d is not connected", params[1]); } + g_SourceMod.SetGlobalTarget(params[1]); + unsigned int replyto = g_ChatTriggers.GetReplyTo(); if (replyto == SM_REPLY_CONSOLE) { diff --git a/core/smn_player.cpp b/core/smn_player.cpp index fb422ecb..a5b11d74 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -15,8 +15,12 @@ #include "PlayerManager.h" #include "AdminCache.h" #include "sm_stringutil.h" +#include "HalfLife2.h" +#include "sourcemod.h" #include +ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY, "Activity display setting (see sourcemod.cfg)"); + static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params) { if (params[1]) @@ -816,6 +820,84 @@ static cell_t GetClientOfUserId(IPluginContext *pContext, const cell_t *params) return g_Players.GetClientOfUserId(params[1]); } +static cell_t ShowActivity(IPluginContext *pContext, const cell_t *params) +{ + int value = sm_show_activity.GetInt(); + + if (!value) + { + return 0; + } + + int client = params[1]; + + const char *name = "Console"; + const char *sign = "ADMIN"; + if (client != 0) + { + CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); + if (!pPlayer || !pPlayer->IsConnected()) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + name = pPlayer->GetName(); + AdminId id = pPlayer->GetAdminId(); + if (id == INVALID_ADMIN_ID + || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective)) + { + sign = "PLAYER"; + } + } + + char message[255]; + char buffer[255]; + int maxClients = g_Players.GetMaxClients(); + for (int i=1; i<=maxClients; i++) + { + CPlayer *pPlayer = g_Players.GetPlayerByIndex(i); + if (!pPlayer->IsInGame() || pPlayer->IsFakeClient()) + { + continue; + } + AdminId id = pPlayer->GetAdminId(); + g_SourceMod.SetGlobalTarget(i); + if (id == INVALID_ADMIN_ID + || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective)) + { + /* Treat this as a normal user */ + if ((value & 1) || (value & 2)) + { + const char *newsign = sign; + if (value & 2) + { + newsign = name; + } + g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); + UTIL_Format(message, sizeof(message), "[SM] %s: %s", newsign, buffer); + g_HL2.TextMsg(i, HUD_PRINTTALK, message); + } + } else { + /* Treat this as an admin user */ + bool is_root = g_Admins.GetAdminFlag(id, Admin_Root, Access_Effective); + if ((value & 4) + || (value & 8) + || ((value & 16) && is_root)) + { + const char *newsign = sign; + if ((value & 8) || ((value & 16) && is_root)) + { + newsign = name; + } + g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); + UTIL_Format(message, sizeof(message), "[SM] %s: %s", newsign, buffer); + g_HL2.TextMsg(i, HUD_PRINTTALK, message); + } + } + } + + return 1; +} + REGISTER_NATIVES(playernatives) { {"AddUserFlags", AddUserFlags}, @@ -858,5 +940,6 @@ REGISTER_NATIVES(playernatives) {"GetClientAvgData", GetAvgData}, {"GetClientAvgPackets", GetAvgPackets}, {"GetClientOfUserId", GetClientOfUserId}, + {"ShowActivity", ShowActivity}, {NULL, NULL} }; diff --git a/plugins/basecommands.sp b/plugins/basecommands.sp new file mode 100644 index 00000000..7f3e4f3c --- /dev/null +++ b/plugins/basecommands.sp @@ -0,0 +1,88 @@ +/** + * admincmds-basic.sp + * Manages the standard flat files for admins. This is the file to compile. + * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +public Plugin:myinfo = +{ + name = "Basic Commands", + author = "AlliedModders LLC", + description = "Basic Admin Commands", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +public OnPluginStart() +{ + LoadTranslations("core.cfg"); + RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]"); +} + +public Action:Command_Kick(client, args) +{ + if (args < 1) + { + ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]"); + return Plugin_Handled; + } + + new String:arg[65]; + GetCmdArg(1, arg, sizeof(arg)); + + new clients[2]; + new numClients = SearchForClients(arg, clients, 2); + + if (numClients == 0) + { + ReplyToCommand(client, "[SM] %t", "No matching client"); + return Plugin_Handled; + } else if (numClients > 1) { + ReplyToCommand(client, "[SM] %t", "More than one client matches", arg); + return Plugin_Handled; + } + + new userid = GetClientUserId(clients[0]); + new String:name[65]; + + GetClientName(clients[0], name, sizeof(name)); + + decl String:reason[256] + if (args < 2) + { + /* Safely null terminate */ + reason[0] = '\0'; + } else { + GetCmdArg(2, reason, sizeof(reason)); + } + + LogMessage("\"%L\" kicked \"%L\" (reason \"%s\")", client, clients[0], reason); + ShowActivity(client, "%t", "Kicked player", name); + + if (args < 2) + { + ServerCommand("kickid %d", userid); + } else { + ServerCommand("kickid %d \"%s\"", userid, reason); + } + + ReplyToCommand(client, "[SM] Client \"%s\" kicked.", name); + + return Plugin_Handled; +} diff --git a/plugins/include/console.inc b/plugins/include/console.inc index a1d0f8e9..5b90e829 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -165,7 +165,19 @@ native PrintToConsole(client, const String:format[], any:...); * @noreturn * @error If the client is not connected or invalid. */ -native ReplyToCommand(client, const String:fornmat[], any:...); +native ReplyToCommand(client, const String:format[], any:...); + +/** + * Displays usage of an admin command to users depending on the + * setting of the sm_show_activity cvar. + * + * @param client Client index doing the action, or 0 for server. + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * @noreturn + * @error + */ +native ShowActivity(client, const String:format[], any:...); /** * Called when a server-only command is invoked. diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc index c3a59322..1f88c681 100644 --- a/plugins/include/sourcemod.inc +++ b/plugins/include/sourcemod.inc @@ -46,6 +46,7 @@ struct Plugin #include #include #include +#include #include /**