summaryrefslogtreecommitdiffstats
path: root/source/ManualBindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/ManualBindings.cpp142
1 files changed, 126 insertions, 16 deletions
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp
index be4a1cb66..8dc55a54c 100644
--- a/source/ManualBindings.cpp
+++ b/source/ManualBindings.cpp
@@ -9,7 +9,6 @@
#include "Plugin.h"
#include "Plugin_NewLua.h"
#include "PluginManager.h"
-#include "LuaCommandBinder.h"
#include "Player.h"
#include "WebAdmin.h"
#include "StringMap.h"
@@ -488,24 +487,74 @@ DEFINE_LUA_FOREACHINCHUNK(cWorld, cFurnaceEntity, ForEachFurnaceInChunk, tolua_c
-static int tolua_cPlugin_GetCommands(lua_State * tolua_S)
+static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S)
{
- cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
+ int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
+ if( NumArgs != 1)
+ {
+ LOGWARN("Error in function call 'ForEachCommand': Requires 1 argument, got %i", NumArgs);
+ return 0;
+ }
- const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands();
+ cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, 0);
+ if (self == NULL)
+ {
+ LOGWARN("Error in function call 'ForEachCommand': Not called on an object instance");
+ return 0;
+ }
- lua_createtable(tolua_S, AllCommands.size(), 0);
- int newTable = lua_gettop(tolua_S);
- int index = 1;
- std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin();
- while(iter != AllCommands.end())
+ if (!lua_isfunction(tolua_S, 2))
{
- const cPlugin::CommandStruct & CS = *iter;
- tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" );
- lua_rawseti(tolua_S, newTable, index);
- ++iter;
- ++index;
+ LOGWARN("Error in function call 'ForEachCommand': Expected a function for parameter #1");
+ return 0;
}
+
+ int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
+ if (FuncRef == LUA_REFNIL)
+ {
+ LOGWARN("Error in function call 'ForEachCommand': Could not get function reference of parameter #1");
+ return 0;
+ }
+
+ class cLuaCallback : public cPluginManager::cCommandEnumCallback
+ {
+ public:
+ cLuaCallback(lua_State * a_LuaState, int a_FuncRef)
+ : LuaState( a_LuaState )
+ , FuncRef( a_FuncRef )
+ {}
+
+ private:
+ virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) override
+ {
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
+ tolua_pushcppstring(LuaState, a_Command);
+ tolua_pushcppstring(LuaState, a_Permission);
+ tolua_pushcppstring(LuaState, a_HelpString);
+
+ int s = lua_pcall(LuaState, 3, 1, 0);
+ if (report_errors(LuaState, s))
+ {
+ return true; /* Abort enumeration */
+ }
+
+ if (lua_isboolean(LuaState, -1))
+ {
+ return (tolua_toboolean( LuaState, -1, 0) > 0);
+ }
+ return false; /* Continue enumeration */
+ }
+ lua_State * LuaState;
+ int FuncRef;
+ } Callback(tolua_S, FuncRef);
+
+ bool bRetVal = self->ForEachCommand(Callback);
+
+ /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */
+ luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef);
+
+ /* Push return value on stack */
+ tolua_pushboolean(tolua_S, bRetVal);
return 1;
}
@@ -547,6 +596,64 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S)
+static int tolua_cPluginManager_BindCommand(lua_State * L)
+{
+ // Function signature: cPluginManager:BindCommand(Command, Permission, Function, HelpString)
+
+ // Get the plugin identification out of LuaState:
+ lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
+ if (!lua_islightuserdata(L, -1))
+ {
+ LOGERROR("cPluginManager:BindCommand() cannot get plugin instance, what have you done to my Lua state? Command-binding aborted.");
+ }
+ cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1);
+ lua_pop(L, 1);
+
+ // Read the arguments to this API call:
+ tolua_Error tolua_err;
+ if (
+ !tolua_isusertype (L, 1, "cPluginManager", 0, &tolua_err) ||
+ !tolua_iscppstring(L, 2, 0, &tolua_err) ||
+ !tolua_iscppstring(L, 3, 0, &tolua_err) ||
+ !tolua_iscppstring(L, 5, 0, &tolua_err) ||
+ !tolua_isnoobj (L, 6, &tolua_err)
+ )
+ {
+ tolua_error(L, "#ferror in function 'BindCommand'.", &tolua_err);
+ return 0;
+ }
+ if (!lua_isfunction(L, 4))
+ {
+ luaL_error(L, "\"BindCommand\" function expects a function as its 3rd parameter. Command-binding aborted.");
+ return 0;
+ }
+ cPluginManager * self = (cPluginManager *)tolua_tousertype(L, 1, 0);
+ AString Command (tolua_tocppstring(L, 2, ""));
+ AString Permission(tolua_tocppstring(L, 3, ""));
+ AString HelpString(tolua_tocppstring(L, 5, ""));
+
+ // Store the function reference:
+ lua_pop(L, 1); // Pop the help string off the stack
+ int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference
+ if (FnRef == LUA_REFNIL)
+ {
+ LOGERROR("\"BindCommand\": Cannot create a function reference. Command \"%s\" not bound.", Command);
+ return 0;
+ }
+
+ if (!self->BindCommand(Command, Plugin, Permission, HelpString))
+ {
+ // Refused. Possibly already bound. Error message has been given, bail out silently.
+ return 0;
+ }
+
+ Plugin->BindCommand(Command, FnRef);
+ return 0;
+}
+
+
+
+
static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
{
@@ -598,6 +705,8 @@ static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S)
+/*
+// TODO: rewrite this for the new API
static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
@@ -651,6 +760,7 @@ static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
return 0;
}
+*/
@@ -927,13 +1037,13 @@ void ManualBindings::Bind( lua_State* tolua_S )
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlugin");
- tolua_function(tolua_S, "GetCommands", tolua_cPlugin_GetCommands);
- tolua_function(tolua_S, "BindCommand", tolua_cPlugin_BindCommand);
tolua_function(tolua_S, "Call", tolua_cPlugin_Call);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPluginManager");
tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins);
+ tolua_function(tolua_S, "BindCommand", tolua_cPluginManager_BindCommand);
+ tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlayer");