From 8928310fd8308c583609edd1cb111276ffe79f8e Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Jun 2014 13:27:04 +0200 Subject: [PATCH 1/8] Fixed possible confusion. If a command handler gets an error then the player will receive an unknown command error. This can be confusing for players. --- src/Bindings/PluginManager.cpp | 8 +++++++- src/Bindings/PluginManager.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 9bcd8e3b7..f9035e869 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1356,7 +1356,13 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command ASSERT(cmd->second.m_Plugin != NULL); - return cmd->second.m_Plugin->HandleCommand(Split, a_Player); + if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) + { + a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", Split[0].c_str())); + return true; // The command handler was found and executed, so we return true. + } + + return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index be40bd2f7..0b0498280 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -321,7 +321,7 @@ private: /** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */ bool AddPlugin(cPlugin * a_Plugin); - /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */ + /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is executed. */ bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden); bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { From 15ae4ce23371ec6bc1b1f61f4dd7c4ffbd1adf64 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Jun 2014 14:55:15 +0200 Subject: [PATCH 2/8] HandleCommand now returns an CommandResult enum. --- src/Bindings/PluginManager.cpp | 28 +++++++++++----------------- src/Bindings/PluginManager.h | 14 ++++++++------ 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index f9035e869..abbb05ae0 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -257,18 +257,13 @@ bool cPluginManager::CallHookBlockToPickups( bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { - bool WasCommandForbidden = false; - if (HandleCommand(a_Player, a_Message, true, WasCommandForbidden)) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool + if (HandleCommand(a_Player, a_Message, true) != crUnknownCommand) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool { return true; // Chat message was handled as command } - else if (WasCommandForbidden) // Couldn't be handled as command, was it because of insufficient permissions? - { - return true; // Yes - message was sent in HandleCommand, abort - } // Check if it was a standard command (starts with a slash) - // If it was, we know that it was completely unrecognised (WasCommandForbidden == false) + // If it was, we know that it was completely unrecognised if (!a_Message.empty() && (a_Message[0] == '/')) { AStringVector Split(StringSplit(a_Message, " ")); @@ -1318,28 +1313,28 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT -bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden) +cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { ASSERT(a_Player != NULL); AStringVector Split(StringSplit(a_Command, " ")); if (Split.empty()) { - return false; + return crUnknownCommand; } CommandMap::iterator cmd = m_Commands.find(Split[0]); if (cmd == m_Commands.end()) { // Command not found - return false; + return crUnknownCommand; } // Ask plugins first if a command is okay to execute the command: if (CallHookExecuteCommand(a_Player, Split)) { LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str()); - return false; + return crError; } if ( @@ -1350,8 +1345,7 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command { a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); - a_WasCommandForbidden = true; - return false; + return crError; } ASSERT(cmd->second.m_Plugin != NULL); @@ -1359,10 +1353,10 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) { a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", Split[0].c_str())); - return true; // The command handler was found and executed, so we return true. + return crError; } - return true; + return crExecuted; } @@ -1561,7 +1555,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command) bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) { - return HandleCommand(a_Player, a_Command, true); + return (HandleCommand(a_Player, a_Command, true) == crExecuted); } @@ -1570,7 +1564,7 @@ bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Comman bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) { - return HandleCommand(a_Player, a_Command, false); + return (HandleCommand(a_Player, a_Command, false) == crExecuted); } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 0b0498280..049e70b49 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -58,6 +58,13 @@ public: // tolua_export // Called each tick virtual void Tick(float a_Dt); + enum CommandResult + { + crExecuted, + crUnknownCommand, + crError, + } ; + // tolua_begin enum PluginHook { @@ -322,12 +329,7 @@ private: bool AddPlugin(cPlugin * a_Plugin); /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is executed. */ - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden); - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) - { - bool DummyBoolean = false; - return HandleCommand(a_Player, a_Command, a_ShouldCheckPermissions, DummyBoolean); - } + cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); } ; // tolua_export From 008a6ce311d3020927d5ef4b0d53905df48bcae5 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Jun 2014 16:19:31 +0200 Subject: [PATCH 3/8] Added crBlocked and crNoPermission --- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index abbb05ae0..c317ae362 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1334,7 +1334,7 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, if (CallHookExecuteCommand(a_Player, Split)) { LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str()); - return crError; + return crBlocked; } if ( @@ -1345,7 +1345,7 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, { a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); - return crError; + return crNoPermission; } ASSERT(cmd->second.m_Plugin != NULL); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 049e70b49..96b7a979b 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -63,6 +63,8 @@ public: // tolua_export crExecuted, crUnknownCommand, crError, + crBlocked, + crNoPermission, } ; // tolua_begin From e0a9f37d909e9d82ccac88dae910ce21a7fdba6f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 18 Jun 2014 12:13:01 +0200 Subject: [PATCH 4/8] (Force)ExecuteCommand returns the CommandResult enums Exported and documented the CommandResult enums --- MCServer/Plugins/APIDump/APIDesc.lua | 19 +++++++++++++++++-- src/Bindings/PluginManager.cpp | 8 ++++---- src/Bindings/PluginManager.h | 8 ++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 19ca971e2..fe38d94c7 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1872,9 +1872,9 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." }, DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." }, - ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." }, + ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." }, FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" }, - ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Same as ExecuteCommand, but doesn't check permissions" }, + ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" }, ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature:
function(Command, Permission, HelpString)
. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." }, ForEachConsoleCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindConsoleCommand(). The CallbackFn has the following signature:
function (Command, HelpString)
. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." }, Get = { Params = "", Return = "cPluginManager", Notes = "(STATIC) Returns the single instance of the plugin manager" }, @@ -1890,8 +1890,23 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); LogStackTrace = { Params = "", Return = "", Notes = "(STATIC) Logs a current stack trace of the Lua engine to the server console log. Same format as is used when the plugin fails." }, ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" }, }, + ConstantGroups= + { + CommandResult = + { + Include = "^cr.*", + TextBefore = [[ + Results that the (Force)ExecuteCommand return. This gives information if the command is executed or not and the reason. + ]], + }, + }, Constants = { + crBlocked = { Notes = "When a plugin stopped the command using the OnExecuteCommand hook" }, + crError = { Notes = "When the command handler for the given command results in an error" }, + crExecuted = { Notes = "When the command is successfully executed." }, + crNoPermission = { Notes = "When the player doesn't have permission to execute the given command." }, + crUnknownCommand = { Notes = "When the given command doesn't exist." }, HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" }, HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." }, HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" }, diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index c317ae362..2cd514211 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1553,18 +1553,18 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command) -bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) { - return (HandleCommand(a_Player, a_Command, true) == crExecuted); + return HandleCommand(a_Player, a_Command, true); } -bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) { - return (HandleCommand(a_Player, a_Command, false) == crExecuted); + return HandleCommand(a_Player, a_Command, false); } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 96b7a979b..e2bd9cd94 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -57,7 +57,8 @@ public: // tolua_export // Called each tick virtual void Tick(float a_Dt); - + + // tolua_begin enum CommandResult { crExecuted, @@ -67,7 +68,6 @@ public: // tolua_export crNoPermission, } ; - // tolua_begin enum PluginHook { HOOK_BLOCK_SPREAD, @@ -254,10 +254,10 @@ public: // tolua_export AString GetCommandPermission(const AString & a_Command); // tolua_export /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */ - bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */ - bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export /** Removes all console command bindings that the specified plugin has made */ void RemovePluginConsoleCommands(cPlugin * a_Plugin); From 085cb4256ed9dd343ab4049b6f1e3d4ef53855e8 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 28 Jun 2014 21:55:21 +0200 Subject: [PATCH 5/8] Fixed doxycomments --- src/Bindings/PluginManager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index e2bd9cd94..545f41107 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -253,10 +253,10 @@ public: // tolua_export /** Returns the permission needed for the specified command; empty string if command not found */ AString GetCommandPermission(const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */ + /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */ + /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export /** Removes all console command bindings that the specified plugin has made */ @@ -330,7 +330,7 @@ private: /** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */ bool AddPlugin(cPlugin * a_Plugin); - /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is executed. */ + /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); } ; // tolua_export From aa81a3ff3e2d9c66e699e244cab0b624167a9127 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Fri, 4 Jul 2014 14:29:19 +0200 Subject: [PATCH 6/8] Fixed ExecuteCommand description. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index fe38d94c7..412fcc405 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1872,7 +1872,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." }, DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." }, - ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." }, + ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns a {{cPluginManager#CommandResult|CommandResult}} value." }, FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" }, ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" }, ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature:
function(Command, Permission, HelpString)
. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." }, From 41747f05002821901afc05dd25eb9567eac56eb6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Fri, 4 Jul 2014 15:07:41 +0200 Subject: [PATCH 7/8] Moved sending error messages to cPluginManager:CallHookChat --- src/Bindings/PluginManager.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 2cd514211..8a6ac26fa 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -257,9 +257,13 @@ bool cPluginManager::CallHookBlockToPickups( bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { - if (HandleCommand(a_Player, a_Message, true) != crUnknownCommand) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool + switch (HandleCommand(a_Player, a_Message, true)) { - return true; // Chat message was handled as command + case crExecuted: return true; + case crError: a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); return true; + case crBlocked: return true; // The plugin that blocked the command probably wants to send a message to the player. + case crNoPermission: a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); return true; + case crUnknownCommand: break; } // Check if it was a standard command (starts with a slash) @@ -1343,7 +1347,6 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, !a_Player->HasPermission(cmd->second.m_Permission) ) { - a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); return crNoPermission; } @@ -1352,7 +1355,6 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) { - a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", Split[0].c_str())); return crError; } From 546aab7b4a3e1fd28e912a9cb6507f04dbf7bd17 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Fri, 4 Jul 2014 15:36:29 +0200 Subject: [PATCH 8/8] Removed useless sentence in cPluginManager:ExecuteCommand description. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 412fcc405..271340090 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1872,7 +1872,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." }, DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." }, - ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns a {{cPluginManager#CommandResult|CommandResult}} value." }, + ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions." }, FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" }, ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" }, ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature:
function(Command, Permission, HelpString)
. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },