From 693ffb689c1b970e97cca1bb7d3982695e277eca Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 10 May 2015 22:51:16 +0200 Subject: Exported cPluginManager:ExecuteConsoleCommand() to Lua API. Fixes #1999. --- MCServer/Plugins/APIDump/Classes/Plugins.lua | 1 + src/Bindings/ManualBindings.cpp | 39 +++++++++++++++++++++++++++- src/Bindings/PluginManager.h | 4 ++- src/CommandOutput.cpp | 19 ++++++++------ src/CommandOutput.h | 30 ++++++++++++++++----- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/MCServer/Plugins/APIDump/Classes/Plugins.lua b/MCServer/Plugins/APIDump/Classes/Plugins.lua index ff5d4a180..87f864950 100644 --- a/MCServer/Plugins/APIDump/Classes/Plugins.lua +++ b/MCServer/Plugins/APIDump/Classes/Plugins.lua @@ -68,6 +68,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." }, DoWithPlugin = { Params = "PluginName, CallbackFn", Return = "bool", Notes = "(STATIC) Calls the CallbackFn for the specified plugin, if found. A plugin can be found even if it is currently unloaded, disabled or errored, the callback should check the plugin status. If the plugin is not found, this function returns false, otherwise it returns the bool value that the callback has returned. The CallbackFn has the following signature:
function ({{cPlugin|Plugin}})
" }, ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions." }, + ExecuteConsoleCommand = { Params = "CommandStr", Return = "bool, string", Notes = "Executes the console command as if given by the admin on the console. If the command is successfully executed, returns true and the text that would be output to the console normally. On error it returns false and an error message." }, FindPlugins = { Params = "", Return = "", Notes = "OBSOLETE, use RefreshPluginList() instead"}, 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." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9b3c1555d..bfe280f51 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -5,6 +5,7 @@ #undef TOLUA_TEMPLATE_BIND #include #include +#include #include "tolua++/include/tolua++.h" #include "polarssl/md5.h" #include "polarssl/sha1.h" @@ -33,9 +34,10 @@ #include "../CompositeChat.h" #include "../StringCompression.h" #include "../Broadcaster.h" +#include "../CommandOutput.h" + -#include // Better error reporting for Lua @@ -2000,6 +2002,40 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) +static int tolua_cPluginManager_ExecuteConsoleCommand(lua_State * tolua_S) +{ + /* + Function signature: + cPluginManager:ExecuteConsoleCommand(EntireCommandStr) -> OutputString + */ + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cPluginManager") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString Command; + L.GetStackValues(2, Command); + auto Split = StringSplit(Command, " "); + + // Store the command output in a string: + cStringAccumCommandOutputCallback CommandOutput; + L.Push(cPluginManager::Get()->ExecuteConsoleCommand(Split, CommandOutput, Command)); + L.Push(CommandOutput.GetAccum()); + return 2; +} + + + + + static int tolua_cPluginManager_FindPlugins(lua_State * tolua_S) { // API function no longer exists: @@ -3906,6 +3942,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "BindConsoleCommand", tolua_cPluginManager_BindConsoleCommand); tolua_function(tolua_S, "CallPlugin", tolua_cPluginManager_CallPlugin); tolua_function(tolua_S, "DoWithPlugin", tolua_StaticDoWith); + tolua_function(tolua_S, "ExecuteConsoleCommand", tolua_cPluginManager_ExecuteConsoleCommand); tolua_function(tolua_S, "FindPlugins", tolua_cPluginManager_FindPlugins); tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand); tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index d72bd50a3..6fad98434 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -299,7 +299,9 @@ public: /** Returns true if the console command is in the command map */ bool IsConsoleCommandBound(const AString & a_Command); // tolua_export - /** Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback */ + /** Executes the command split into a_Split, as if it was given on the console. + Returns true if executed. Output is sent to the a_Output callback + Exported in ManualBindings.cpp with a different signature. */ bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_Command); /** Appends all commands beginning with a_Text (case-insensitive) into a_Results. diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 510461d81..255ec3e9b 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -29,29 +29,32 @@ void cCommandOutputCallback::Out(const char * a_Fmt, ...) //////////////////////////////////////////////////////////////////////////////// -// cLogCommandOutputCallback: +// cStringAccumCommandOutputCallback: -void cLogCommandOutputCallback::Out(const AString & a_Text) +void cStringAccumCommandOutputCallback::Out(const AString & a_Text) { - m_Buffer.append(a_Text); + m_Accum.append(a_Text); } +//////////////////////////////////////////////////////////////////////////////// +// cLogCommandOutputCallback: + void cLogCommandOutputCallback::Finished(void) { // Log each line separately: - size_t len = m_Buffer.length(); + size_t len = m_Accum.length(); size_t last = 0; for (size_t i = 0; i < len; i++) { - switch (m_Buffer[i]) + switch (m_Accum[i]) { case '\n': { - LOG("%s", m_Buffer.substr(last, i - last).c_str()); + LOG("%s", m_Accum.substr(last, i - last).c_str()); last = i + 1; break; } @@ -59,11 +62,11 @@ void cLogCommandOutputCallback::Finished(void) } // for i - m_Buffer[] if (last < len) { - LOG("%s", m_Buffer.substr(last).c_str()); + LOG("%s", m_Accum.substr(last).c_str()); } // Clear the buffer for the next command output: - m_Buffer.clear(); + m_Accum.clear(); } diff --git a/src/CommandOutput.h b/src/CommandOutput.h index daa9430c0..6265b74ea 100644 --- a/src/CommandOutput.h +++ b/src/CommandOutput.h @@ -47,18 +47,36 @@ class cNullCommandOutputCallback : -/// Sends all command output to a log, line by line, when the command finishes processing -class cLogCommandOutputCallback : +/** Accumulates all command output into a string. */ +class cStringAccumCommandOutputCallback: public cCommandOutputCallback { + typedef cCommandOutputCallback super; + public: // cCommandOutputCallback overrides: virtual void Out(const AString & a_Text) override; - virtual void Finished(void) override; - + virtual void Finished(void) override {} + + /** Returns the accumulated command output in a string. */ + const AString & GetAccum(void) const { return m_Accum; } + protected: - /// Output is stored here until the command finishes processing - AString m_Buffer; + /** Output is stored here until the command finishes processing */ + AString m_Accum; +} ; + + + + + +/// Sends all command output to a log, line by line, when the command finishes processing +class cLogCommandOutputCallback : + public cStringAccumCommandOutputCallback +{ +public: + // cStringAccumCommandOutputCallback overrides: + virtual void Finished(void) override; } ; -- cgit v1.2.3