From 04b2845b0dc7141f4ac45f42d87b983019a3a470 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 21 Oct 2007 20:35:15 +0000 Subject: [PATCH] - improved comments on ShowActivity() natives - switched to ShowActivity2() in basecommands - added lifestates offsets to core gamedata file - added a few translation phrases that were missing - added new API calls to IPlayerHelpers for extending target processing --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401629 --- gamedata/core.games.txt | 6 +++ plugins/basecommands.sp | 6 ++- plugins/basecommands/cancelvote.sp | 2 +- plugins/basecommands/execcfg.sp | 2 +- plugins/basecommands/kick.sp | 60 ++++++++++++++++----- plugins/basecommands/map.sp | 4 +- plugins/include/console.inc | 37 +++++++------ public/IPlayerHelpers.h | 78 ++++++++++++++++++++++++++++ translations/common.phrases.txt | 30 ++++++++++- translations/plugin.basecommands.txt | 6 +++ 10 files changed, 194 insertions(+), 37 deletions(-) diff --git a/gamedata/core.games.txt b/gamedata/core.games.txt index d3fd5332..cb9bfd99 100644 --- a/gamedata/core.games.txt +++ b/gamedata/core.games.txt @@ -9,6 +9,12 @@ "windows" "13" "linux" "14" } + + "m_lifeState" + { + "class" "CBasePlayer" + "prop" "m_lifeState" + } } } diff --git a/plugins/basecommands.sp b/plugins/basecommands.sp index 2da8ea6f..5eec5a32 100644 --- a/plugins/basecommands.sp +++ b/plugins/basecommands.sp @@ -300,8 +300,10 @@ public Action:Command_Cvar(client, args) if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED) { - ShowActivity(client, "%t", "Cvar changed", cvarname, value); - } else { + ShowActivity2(client, "[SM] ", "%t", "Cvar changed", cvarname, value); + } + else + { ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value); } diff --git a/plugins/basecommands/cancelvote.sp b/plugins/basecommands/cancelvote.sp index d7f91339..4946645c 100644 --- a/plugins/basecommands/cancelvote.sp +++ b/plugins/basecommands/cancelvote.sp @@ -7,7 +7,7 @@ PerformCancelVote(client) return; } - ShowActivity(client, "%t", "Cancelled Vote"); + ShowActivity2(client, "[SM] ", "%t", "Cancelled Vote"); CancelVote(); } diff --git a/plugins/basecommands/execcfg.sp b/plugins/basecommands/execcfg.sp index 3834b4d4..916d1d9f 100644 --- a/plugins/basecommands/execcfg.sp +++ b/plugins/basecommands/execcfg.sp @@ -8,7 +8,7 @@ PerformExec(client, String:path[]) return; } - ShowActivity(client, "%t", "Executed config", path[4]); + ShowActivity2(client, "[SM] ", "%t", "Executed config", path[4]); LogAction(client, -1, "\"%L\" executed config (file \"%s\")", client, path[4]); diff --git a/plugins/basecommands/kick.sp b/plugins/basecommands/kick.sp index 35ae1363..635fe5cd 100644 --- a/plugins/basecommands/kick.sp +++ b/plugins/basecommands/kick.sp @@ -1,11 +1,6 @@ PerformKick(client, target, const String:reason[]) { - decl String:name[MAX_NAME_LENGTH]; - - GetClientName(target, name, sizeof(name)); - - ShowActivity(client, "%t", "Kicked player", name); LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason); if (reason[0] == '\0') @@ -80,6 +75,9 @@ public MenuHandler_Kick(Handle:menu, MenuAction:action, param1, param2) } else { + decl String:name[MAX_NAME_LENGTH]; + GetClientName(target, name, sizeof(name)); + ShowActivity2(param1, "[SM] ", "%t", "Kicked target", "_S", name); PerformKick(param1, target, ""); } @@ -104,13 +102,7 @@ public Action:Command_Kick(client, args) decl String:arg[65]; new len = BreakString(Arguments, arg, sizeof(arg)); - - new target = FindTarget(client, arg); - if (target == -1) - { - return Plugin_Handled; - } - + if (len == -1) { /* Safely null terminate */ @@ -118,7 +110,49 @@ public Action:Command_Kick(client, args) Arguments[0] = '\0'; } - PerformKick(client, target, Arguments[len]); + decl String:target_name[MAX_TARGET_LENGTH]; + decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml; + + if ((target_count = ProcessTargetString( + arg, + client, + target_list, + MAXPLAYERS, + COMMAND_FILTER_CONNECTED, + target_name, + sizeof(target_name), + tn_is_ml)) > 0) + { + if (tn_is_ml) + { + ShowActivity2(client, "[SM] ", "%t", "Kicked target", target_name); + } + else + { + ShowActivity2(client, "[SM] ", "%t", "Kicked target", "_S", target_name); + } + + new kick_self = 0; + + for (new i = 0; i < target_count; i++) + { + /* Kick everyone else first */ + if (target_list[i] == client) + { + kick_self = client; + } + PerformKick(client, target_list[i], Arguments[len]); + } + + if (kick_self) + { + PerformKick(client, client, Arguments[len]); + } + } + else + { + ReplyToTargetError(client, target_count); + } return Plugin_Handled; } diff --git a/plugins/basecommands/map.sp b/plugins/basecommands/map.sp index d7ed57a9..79456582 100644 --- a/plugins/basecommands/map.sp +++ b/plugins/basecommands/map.sp @@ -14,7 +14,7 @@ public MenuHandler_ChangeMap(Handle:menu, MenuAction:action, param1, param2) GetMenuItem(menu, param2, map, sizeof(map)); - ShowActivity(param1, "%t", "Changing map", map); + ShowActivity2(param1, "[SM] ", "%t", "Changing map", map); LogAction(param1, -1, "\"%L\" changed map to \"%s\"", param1, map); @@ -59,7 +59,7 @@ public Action:Command_Map(client, args) return Plugin_Handled; } - ShowActivity(client, "%t", "Changing map", map); + ShowActivity2(client, "[SM] ", "%t", "Changing map", map); LogAction(client, -1, "\"%L\" changed map to \"%s\"", client, map); diff --git a/plugins/include/console.inc b/plugins/include/console.inc index eb2aa00c..0f1feb93 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -241,10 +241,28 @@ native bool:IsChatTrigger(); /** * Displays usage of an admin command to users depending on the - * setting of the sm_show_activity cvar. + * setting of the sm_show_activity cvar. All users receive a message + * in their chat text, except for the originating client, who receives + * the message based on the current ReplySource. * - * If the original client did not use a console command, they will - * not see the public display in their chat. + * @param client Client index doing the action, or 0 for server. + * @param tag Tag to display before the message string. For example, + * "[SM] " would show "[SM] ". + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * @noreturn + * @error + */ +native ShowActivity2(client, const String:tag[], const String:format[], any:...); + +/** + * Displays usage of an admin command to users depending on the + * setting of the sm_show_activity cvar. + * + * This version does not display a message to the originating client + * if used from chat triggers or menus. If manual replies are used + * for these cases, then this function will suffice. Otherwise, + * ShowActivity2() is slightly more useful. * * @param client Client index doing the action, or 0 for server. * @param format Formatting rules. @@ -267,19 +285,6 @@ native ShowActivity(client, const String:format[], any:...); */ native ShowActivityEx(client, const String:tag[], const String:format[], any:...); -/** - * Same as ShowActivityEx(), except the text will always be mirrored to the - * client's chat (and console, if the reply source specifies as such). - * - * @param client Client index doing the action, or 0 for server. - * @param tag Tag to display with. - * @param format Formatting rules. - * @param ... Variable number of format parameters. - * @noreturn - * @error - */ -native ShowActivity2(client, const String:tag[], const String:format[], any:...); - /** * Called when a server-only command is invoked. * diff --git a/public/IPlayerHelpers.h b/public/IPlayerHelpers.h index 7e33807d..34e3aa8e 100644 --- a/public/IPlayerHelpers.h +++ b/public/IPlayerHelpers.h @@ -232,6 +232,60 @@ namespace SourceMod } }; + #define COMMAND_FILTER_ALIVE (1<<0) /**< Only allow alive players */ + #define COMMAND_FILTER_DEAD (1<<1) /**< Only filter dead players */ + #define COMMAND_FILTER_CONNECTED (1<<2) /**< Allow players not fully in-game */ + #define COMMAND_FILTER_NO_IMMUNITY (1<<3) /**< Ignore immunity rules */ + #define COMMAND_FILTER_NO_MULTI (1<<4) /**< Do not allow multiple target patterns */ + #define COMMAND_FILTER_NO_BOTS (1<<5) /**< Do not allow bots to be targetted */ + + #define COMMAND_TARGET_VALID 1 /**< Client passed the filter */ + #define COMMAND_TARGET_NONE 0 /**< No target was found */ + #define COMMAND_TARGET_NOT_ALIVE -1 /**< Single client is not alive */ + #define COMMAND_TARGET_NOT_DEAD -2 /**< Single client is not dead */ + #define COMMAND_TARGET_NOT_IN_GAME -3 /**< Single client is not in game */ + #define COMMAND_TARGET_IMMUNE -4 /**< Single client is immune */ + #define COMMAND_TARGET_EMPTY_FILTER -5 /**< A multi-filter (such as @all) had no targets */ + #define COMMAND_TARGET_NOT_HUMAN -6 /**< Target was not human */ + #define COMMAND_TARGET_AMBIGUOUS -7 /**< Partial name had too many targets */ + + #define COMMAND_TARGETNAME_RAW 0 /**< Target name is a raw string */ + #define COMMAND_TARGETNAME_ML 1 /**< Target name is a multi-lingual phrase */ + + /** + * @brief Holds the many command target info parameters. + */ + struct cmd_target_info_t + { + const char *pattern; /**< IN: Target pattern string. */ + int admin; /**< IN: Client admin index, or 0 if server .*/ + cell_t *targets; /**< IN: Array to store targets. */ + cell_t max_targets; /**< IN: Max targets (always >= 1) */ + int flags; /**< IN: COMMAND_FILTER flags. */ + char *target_name; /**< OUT: Buffer to store target name. */ + size_t target_name_maxlength; /**< IN: Maximum length of the target name buffer. */ + int target_name_style; /**< OUT: Target name style (COMMAND_TARGETNAME) */ + int reason; /**< OUT: COMMAND_TARGET reason. */ + unsigned int num_targets; /**< OUT: Number of targets. */ + }; + + /** + * @brief Intercepts a command target operation. + */ + class ICommandTargetProcessor + { + public: + /** + * @brief Must process the command target and return a COMMAND_TARGET value. + * + * @param info Struct containing command target information. + * Any members labelled OUT must be filled if processing + * is to be completed (i.e. true returned). + * @return True to end processing, false to let Core continue. + */ + virtual bool ProcessCommandTarget(cmd_target_info_t *info) =0; + }; + class IPlayerManager : public SMInterface { public: @@ -323,6 +377,30 @@ namespace SourceMod * @return Old reply source. */ virtual unsigned int SetReplyTo(unsigned int reply) =0; + + /** + * @brief Tests if a player meets command filtering rules. + * + * @param pAdmin IGamePlayer of the admin, or NULL if the server. + * @param pTarget IGamePlayer of the player being targeted. + * @param flags COMMAND_FILTER flags. + * @return COMMAND_TARGET value. + */ + virtual int FilterCommandTarget(IGamePlayer *pAdmin, IGamePlayer *pTarget, int flags) =0; + + /** + * @brief Registers a command target processor. + * + * @param pHandler Pointer to an ICommandTargetProcessor instance. + */ + virtual void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler) =0; + + /** + * @brief Removes a command target processor. + * + * @param pHandler Pointer to an ICommandTargetProcessor instance. + */ + virtual void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler) =0; }; } diff --git a/translations/common.phrases.txt b/translations/common.phrases.txt index de667946..7f205cff 100644 --- a/translations/common.phrases.txt +++ b/translations/common.phrases.txt @@ -15,12 +15,22 @@ "en" "No matching client was found." } + "No matching clients" + { + "en" "No matching clients were found." + } + "More than one client matches" { "#format" "{1:s}" "en" "More than one client matches the pattern \"{1}\"" } + "More than one client matched" + { + "en" "More than one client matched the given pattern." + } + "Player no longer available" { "en" "The player you selected is no longer available." @@ -90,6 +100,7 @@ "#format" "{1:s}" "en" "Slapped player '{1}'" } + "Slay player" { "en" "Slay player" @@ -185,12 +196,12 @@ "Invalid Amount" { "en" "Invalid amount specified" - } + } "Cannot be performed on dead" { "#format" "{1:s}" - "en" "This action cannot be performed on a dead client \"{1}\"" + "en" "This action cannot be performed on dead client \"{1}\"" } "Player has since died" @@ -316,4 +327,19 @@ { "en" "This command can only be used in-game." } + + "Target must be dead" + { + "en" "This command can only be used on dead players." + } + + "Target must be alive" + { + "en" "This command can only be used on alive players." + } + + "Target is not in game" + { + "en" "The given player is not fully in-game yet." + } } diff --git a/translations/plugin.basecommands.txt b/translations/plugin.basecommands.txt index c0a27b94..85191c99 100644 --- a/translations/plugin.basecommands.txt +++ b/translations/plugin.basecommands.txt @@ -112,4 +112,10 @@ { "en" "Username" } + + "Kicked target" + { + "#format" "{1:t}" + "en" "Kicked {1}" + } }