diff --git a/core/concmd_cleaner.h b/core/concmd_cleaner.h index 2779aea3..cfd90be8 100644 --- a/core/concmd_cleaner.h +++ b/core/concmd_cleaner.h @@ -38,6 +38,7 @@ public: virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0; }; +ConCommandBase *FindConCommandBase(const char *name); void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void Global_OnUnlinkConCommandBase(ConCommandBase *pBase); diff --git a/core/smn_console.cpp b/core/smn_console.cpp index 921639f2..418a0915 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -42,6 +42,7 @@ #include "AdminCache.h" #include #include +#include #define NET_SETCONVAR 5 @@ -79,6 +80,61 @@ public: } } s_ConsoleHelpers; +class CommandFlagsHelper : public IConCommandTracker +{ +public: + void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) + { + m_CmdFlags.remove(name); + } + bool GetFlags(const char *name, int *flags) + { + ConCommandBase **ppCmd; + ConCommandBase *pCmd; + if ((ppCmd=m_CmdFlags.retrieve(name))) + { + TrackConCommandBase((*ppCmd), this); + *flags = (*ppCmd)->GetFlags(); + return true; + } + else if ((pCmd=FindConCommandBase(name))) + { + m_CmdFlags.insert(name, pCmd); + TrackConCommandBase(pCmd, this); + *flags = pCmd->GetFlags(); + return true; + } + else + { + return false; + } + } + bool SetFlags(const char *name, int flags) + { + ConCommandBase **ppCmd; + ConCommandBase *pCmd; + if ((ppCmd=m_CmdFlags.retrieve(name))) + { + (*ppCmd)->SetFlags(flags); + TrackConCommandBase((*ppCmd), this); + return true; + } + else if ((pCmd=FindConCommandBase(name))) + { + m_CmdFlags.insert(name, pCmd); + pCmd->SetFlags(flags); + TrackConCommandBase(pCmd, this); + return true; + } + else + { + return false; + } + } +private: + KTrie m_CmdFlags; +} s_CommandFlagsHelper; + static void ReplicateConVar(ConVar *pConVar) { int maxClients = g_Players.GetMaxClients(); @@ -1025,6 +1081,23 @@ static cell_t IsChatTrigger(IPluginContext *pContext, const cell_t *params) return g_ChatTriggers.IsChatTrigger() ? 1 : 0; } +static cell_t SetCommandFlags(IPluginContext *pContext, const cell_t *params) +{ + char *name; + pContext->LocalToString(params[1], &name); + + return (s_CommandFlagsHelper.SetFlags(name, params[2])) ? 1 : 0; +} + +static cell_t GetCommandFlags(IPluginContext *pContext, const cell_t *params) +{ + char *name; + int flags; + pContext->LocalToString(params[1], &name); + + return (s_CommandFlagsHelper.GetFlags(name, &flags)) ? flags : -1; +} + REGISTER_NATIVES(consoleNatives) { {"CreateConVar", sm_CreateConVar}, @@ -1067,5 +1140,7 @@ REGISTER_NATIVES(consoleNatives) {"CheckCommandAccess", CheckCommandAccess}, {"FakeClientCommandEx", FakeClientCommandEx}, {"IsChatTrigger", IsChatTrigger}, + {"SetCommandFlags", SetCommandFlags}, + {"GetCommandFlags", GetCommandFlags}, {NULL, NULL} }; diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 7a821ff3..919ab59a 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -35,6 +35,8 @@ #endif #define _console_included +#define INVALID_FCVAR_FLAGS (-1) + /** * Console variable bound values used with Get/SetConVarBounds() */ @@ -698,3 +700,20 @@ stock bool:IsValidConVarChar(c) { return (c == '_' || IsCharAlpha(c) || IsCharNumeric(c)); } + +/** + * Returns the bitstring of flags of a command. + * + * @param name Name of the command. + * @return A bitstring containing the FCVAR_* flags that are enabled or INVALID_FCVAR_FLAGS if command not found. + */ +native GetCommandFlags(const String:name[]); + +/** + * Sets the bitstring of flags of a command. + * + * @param name Name of the command. + * @param flags A bitstring containing the FCVAR_* flags to enable. + * @return True on success, otherwise false. + */ +native bool:SetCommandFlags(const String:name[], flags);