From 56324208278521fde6ac78fb9bef65500486f295 Mon Sep 17 00:00:00 2001 From: KliPPy Date: Fri, 8 Dec 2017 00:06:37 +0100 Subject: [PATCH] Add wrappers for natives with string flags (#389) * Add wrappers for natives with string flags * Add default/none constants, update docs --- amxmodx/amxmodx.cpp | 39 +++++++++++++++ plugins/include/amxconst.inc | 65 ++++++++++++++++++++++++ plugins/include/amxmisc.inc | 60 +++++++++++++++++++++++ plugins/include/amxmodx.inc | 95 +++++++++++++++++++++++++++++++++--- 4 files changed, 251 insertions(+), 8 deletions(-) diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index afbddb60..bfd7ee5e 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -8,6 +8,7 @@ // https://alliedmods.net/amxmodx-license #include +#include #include "amxmodx.h" #include "CMenu.h" #include "newmenus.h" @@ -1814,6 +1815,24 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) return handle; } +// native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...); +static cell AMX_NATIVE_CALL register_event_ex(AMX *amx, cell *params) +{ + cell amx_addr; + cell *phys_addr; + char strFlags[8]; + + amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr); + UTIL_GetFlags(strFlags, params[3]); + set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1); + + params[3] = amx_addr; + cell ret = register_event(amx, params); + amx_Release(amx, amx_addr); + + return ret; +} + static cell AMX_NATIVE_CALL enable_event(AMX *amx, cell *params) { auto handle = EventHandles.lookup(params[1]); @@ -2370,6 +2389,24 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */ return result; } +// native find_player_ex(FindPlayerFlags:flags, ...); +static cell AMX_NATIVE_CALL find_player_ex(AMX *amx, cell *params) +{ + cell amx_addr; + cell *phys_addr; + char strFlags[14]; + + amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr); + UTIL_GetFlags(strFlags, params[1]); + set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1); + + params[1] = amx_addr; + cell ret = find_player(amx, params); + amx_Release(amx, amx_addr); + + return ret; +} + static cell AMX_NATIVE_CALL get_maxplayers(AMX *amx, cell *params) { return gpGlobals->maxClients; @@ -4571,6 +4608,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"engclient_cmd", engclient_cmd}, {"engclient_print", engclient_print}, {"find_player", find_player}, + {"find_player_ex", find_player_ex}, {"find_plugin_byfile", find_plugin_byfile}, {"force_unmodified", force_unmodified}, {"format_time", format_time}, @@ -4680,6 +4718,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"register_concmd", register_concmd}, {"register_dictionary", register_dictionary}, {"register_event", register_event}, + {"register_event_ex", register_event_ex}, {"enable_event", enable_event}, {"disable_event", disable_event}, {"register_logevent", register_logevent}, diff --git a/plugins/include/amxconst.inc b/plugins/include/amxconst.inc index 1207a500..1e7ac379 100755 --- a/plugins/include/amxconst.inc +++ b/plugins/include/amxconst.inc @@ -451,4 +451,69 @@ enum HashType Hash_Keccak_512 // Provides Keccak 512 bit hashing }; +/** + * SetTaskFlags constants for set_task_ex() + */ +enum SetTaskFlags (<<= 1) +{ + SetTask_Once = 0, // None; execute callback after the specified amount of time (Default) + SetTask_RepeatTimes = 1, // Repeat timer a set amount of times + SetTask_Repeat, // Loop indefinitely until timer is stopped + SetTask_AfterMapStart, // Time interval is treated as absolute time after map start + SetTask_BeforeMapChange // Time interval is treated as absolute time before map change +}; + +/** + * RegisterEventFlags constants for register_event_ex() + */ +enum RegisterEventFlags (<<= 1) +{ + RegisterEvent_None = 0, // None + RegisterEvent_Global = 1, // Global event (sent to every client) + RegisterEvent_Single, // Event sent to single client + RegisterEvent_OnceForMultiple, // Call only once when repeated to multiple clients + RegisterEvent_OnlyDead, // Call only if sent to dead client + RegisterEvent_OnlyAlive, // Call only if sent to alive client + RegisterEvent_OnlyHuman, // Call only if sent to human client (RegisterEvent_Single required) + RegisterEvent_OnlyBots // Call only if sent to bot (RegisterEvent_Single required) +}; + +/** + * GetPlayerFlags constants for get_players_ex() + */ +enum GetPlayersFlags (<<= 1) +{ + GetPlayers_None = 0, // No filter (Default) + GetPlayers_ExcludeDead = 1, // Do not include dead clients + GetPlayers_ExcludeAlive, // Do not include alive clients + GetPlayers_ExcludeBots, // Do not include bots + GetPlayers_ExcludeHuman, // Do not include human clients + GetPlayers_MatchTeam, // Match with team + GetPlayers_MatchNameSubstring, // Match with part of name + GetPlayers_CaseInsensitive, // Match case insensitive + GetPlayers_ExcludeHLTV, // Do not include HLTV proxies + GetPlayers_IncludeConnecting // Include connecting clients +}; + +/** + * FindPlayerFlags constants for find_player_ex() + */ +enum FindPlayerFlags (<<= 1) +{ + FindPlayer_None = 0, // None + FindPlayer_MatchName = 1, // Match with name + FindPlayer_MatchNameSubstring, // Match with name substring + FindPlayer_MatchAuthId, // Match with authid + FindPlayer_MatchIP, // Match with ip + FindPlayer_MatchTeam, // Match with team name + FindPlayer_ExcludeDead, // Do not include dead clients + FindPlayer_ExcludeAlive, // Do not include alive clients + FindPlayer_ExcludeBots, // Do not include bots + FindPlayer_ExcludeHuman, // Do not include human clients + FindPlayer_LastMatched, // Return last matched client instead of the first + FindPlayer_MatchUserId, // Match with userid + FindPlayer_CaseInsensitive, // Match case insensitively + FindPlayer_IncludeConnecting // Include connecting clients +} + #include // To keep backward compatibility diff --git a/plugins/include/amxmisc.inc b/plugins/include/amxmisc.inc index 4a22a270..772b7f00 100755 --- a/plugins/include/amxmisc.inc +++ b/plugins/include/amxmisc.inc @@ -809,3 +809,63 @@ stock reset_menu(index) { show_menu(index, 0, "", 0); } + +/** + * Calls a function after a specified time has elapsed. + * + * @param time Time interval to assign + * @param function Function to execute + * @param id Task id to assign + * @param parameter Data to pass through to callback + * @param len Size of data + * @param flags Optional flags (enum SetTaskFlags); valid flags are: + * SetTask_Once - Execute callback once (Default) + * SetTask_RepeatTimes - repeat timer a set amount of times + * SetTask_Repeat - loop indefinitely until timer is stopped + * SetTask_AfterMapStart - time interval is treated as absolute + * time after map start + * SetTask_BeforeMapChange - time interval is treated as absolute + * time before map change + * @param repeat If the SetTask_RepeatTimes flag is set, the task will be repeated this + * many times + * + * @noreturn + * @error If an invalid callback function is provided, an error is + * thrown. + */ +stock set_task_ex(Float:time, const function[], id = 0, const any:parameter[] = "", len = 0, SetTaskFlags:flags = SetTask_Once, repeat = 0) +{ + new strFlags[2]; // There should never be a need to set more than 1 flag + get_flags(_:flags, strFlags, charsmax(strFlags)); + set_task(time, function, id, parameter, len, strFlags, repeat); +} + +/** + * Stores a filtered list of client indexes to an array. + * + * @note Example retrieving all alive CTs: + * get_players_ex(players, num, GetPlayers_ExcludeDead | GetPlayers_MatchTeam, "CT") + * + * @param players Array to store indexes to + * @param num Variable to store number of indexes to + * @param flags Optional filtering flags (enum GetPlayersFlags); valid flags are: + * GetPlayers_None - No filter (Default) + * GetPlayers_ExcludeDead - do not include dead clients + * GetPlayers_ExcludeAlive - do not include alive clients + * GetPlayers_ExcludeBots - do not include bots + * GetPlayers_ExcludeHuman - do not include human clients + * GetPlayers_MatchTeam - match with team + * GetPlayers_MatchNameSubstring - match with part of name + * GetPlayers_CaseInsensitive - match case insensitive + * GetPlayers_ExcludeHLTV - do not include HLTV proxies + * GetPlayers_IncludeConnecting - include connecting clients + * @param team String to match against if the "e" or "f" flag is specified + * + * @noreturn + */ +stock get_players_ex(players[MAX_PLAYERS], &num, GetPlayersFlags:flags = GetPlayers_None, const team[] = "") +{ + new strFlags[10]; + get_flags(_:flags, strFlags, charsmax(strFlags)); + get_players(players, num, strFlags, team); +} diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index 304d578f..e24059e6 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -497,6 +497,8 @@ native console_cmd(id, const cmd[], any:...); /** * Registers a function to be called on a given game event. * + * @note Please consider using register_event_ex() instead which allows you to + * use named constants for flags instead of letters. * @note Examples for event conditions: * "2=c4" - Second parameter of message must be the string "c4" * "3>10" - Third parameter of message must be greater than 10 @@ -539,9 +541,53 @@ native console_cmd(id, const cmd[], any:...); native register_event(const event[], const function[], const flags[], const cond[] = "", ...); /** - * Enables a function hook of a game event which has been previously registered with register_event(). + * Registers a function to be called on a given game event. * - * @param handle Value returned from register_event() + * @note Examples for event conditions: + * "2=c4" - Second parameter of message must be the string "c4" + * "3>10" - Third parameter of message must be greater than 10 + * "3!4" - Third parameter of message must not be equal to 4 + * "2&Buy" - Second parameter of message must contain "Buy" substring + * "2!Buy" - Second parameter of message must not equal "Buy" + * @note Due to a long-standing bug that would break compatibility with older + * plugins, the client id should be checked for alive/dead state if using + * flags "d" or "e". + * @note If multiple conditions are specified for a single parameter, only one + * of them has to hold true for the event function to be called. + * + * @param event Name of event that should be hooked + * @param function Name of callback function + * @param flags Flags used for filtering events (enum RegisterEventFlags); the valid flags are: + * RegisterEvent_Global - Global event (sent to every client) + * RegisterEvent_Single - Event sent to single client + * RegisterEvent_OnceForMultiple - Call only once when repeated to multiple clients + * RegisterEvent_OnlyDead - Call only if sent to dead client + * RegisterEvent_OnlyAlive - Call only if sent to alive client + * RegisterEvent_OnlyHuman - Call only if sent to human client (RegisterEvent_Single required) + * RegisterEvent_OnlyBots - Call only if sent to bot (RegisterEvent_Single required) + * @param cond Condition string used for filtering events, built as: + * "" + * Argument number is the argument position to be filtered + * The comparison operator may be: + * "=" for equality comparison (all argument types) + * "!" for inequality comparison (all argument types) + * "&" for bitwise and (int argument) or substring + * comparison (string argument) + * "<" for less than comparison (int/float arguments) + * ">" for greater than comparison (int/float arguments) + * The argument is compared to the specified value accordingly + * @param ... Any number of additional conditions + * + * @return Event handle + * @error If an invalid event name or callback function is provided, + * an error will be thrown. + */ +native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...); + +/** + * Enables a function hook of a game event which has been previously registered with register_event_ex(). + * + * @param handle Value returned from register_event_ex() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. @@ -549,9 +595,9 @@ native register_event(const event[], const function[], const flags[], const cond native enable_event(handle); /** - * Disables a function hook of a game event which has been previously registered with register_event(). + * Disables a function hook of a game event which has been previously registered with register_event_ex(). * - * @param handle Value returned from register_event() + * @param handle Value returned from register_event_ex() * * @noreturn * @error If an invalid handle is provided, an error will be thrown. @@ -739,7 +785,7 @@ native show_menu(index, keys, const menu[], time = -1, const title[] = ""); /** * Retrieves values from a client message. * - * @note For use within callbacks registered with register_event() + * @note For use within callbacks registered with register_event_ex() * @note Usage examples: * value = read_data(1); * read_data(2, floatvalue); @@ -767,7 +813,7 @@ native read_data(value, any:...); /** * Returns the number of values in the client message. * - * @note For use within callbacks registered with register_event() + * @note For use within callbacks registered with register_event_ex() * * @return Number of values in client message */ @@ -776,7 +822,7 @@ native read_datanum(); /** * Returns the message id of the client message. * - * @note For use within callbacks registered with register_event() + * @note For use within callbacks registered with register_event_ex() * * @return Message id of the client message */ @@ -1325,7 +1371,9 @@ native get_playersnum(flag = 0); /** * Stores a filtered list of client indexes to an array. * - * @note Example retrieving all alive CTs: get_players(players, num, "ae", "CT") + * @note Please consider using get_players_ex() instead which allows you to + * use named constants for flags instead of letters. + * @note Example retrieving all alive CTs: get_players(players, num "ae", "CT") * * @param players Array to store indexes to * @param num Variable to store number of indexes to @@ -1431,6 +1479,8 @@ native get_flags(flags, output[], len); /** * Find a player given a filter. * + * @note Please consider using find_player_ex() instead which allows you to + * use named constants for flags instead of letters. * @note If matching by userid, do not also specify the "a", "b" or "c" flags, * or the function may not return a correct result. * @@ -1454,6 +1504,32 @@ native get_flags(flags, output[], len); */ native find_player(const flags[], ...); +/** + * Find a player given a filter. + * + * @note If matching by userid, do not also specify FindPlayer_MatchName, FindPlayer_MatchNameSubstring + * or FindPlayer_MatchAuthId, or the function may not return a correct result. + * + * @param flags Filtering flags (enum FindPlayerFlags); valid flags are: + * FindPlayer_MatchName - match with name + * FindPlayer_MatchNameSubstring - match with name substring + * FindPlayer_MatchAuthId - match with authid + * FindPlayer_MatchIP - match with ip + * FindPlayer_MatchTeam - match with team name + * FindPlayer_ExcludeDead - do not include dead clients + * FindPlayer_ExcludeAlive - do not include alive clients + * FindPlayer_ExcludeBots - do not include bots + * FindPlayer_ExcludeHuman - do not include human clients + * FindPlayer_LastMatched - return last matched client instead of the first + * FindPlayer_MatchUserId - match with userid + * FindPlayer_CaseInsensitive - match case insensitively + * FindPlayer_IncludeConnecting - include connecting clients + * @param ... String to match against (integer if FindPlayer_MatchUserId is specified) + * + * @return Client index, or 0 if no client was found + */ +native find_player_ex(FindPlayerFlags:flags, ...); + /** * Removes double-quotes from the beginning and end of a string. * @@ -1665,6 +1741,9 @@ native parse_time(const input[], const format[], time = -1); /** * Calls a function after a specified time has elapsed. * + * @note Please consider using set_task_ex() instead which allows you to + * use named constants for flags instead of letters. + * * @param time Time interval to assign * @param function Function to execute * @param id Task id to assign