diff options
Diffstat (limited to 'Swiftob/LuaCommands.cpp')
-rw-r--r-- | Swiftob/LuaCommands.cpp | 94 |
1 files changed, 90 insertions, 4 deletions
diff --git a/Swiftob/LuaCommands.cpp b/Swiftob/LuaCommands.cpp index 9f99d82..0358f98 100644 --- a/Swiftob/LuaCommands.cpp +++ b/Swiftob/LuaCommands.cpp @@ -15,10 +15,41 @@ #include <Swiften/Client/Client.h> #include <Swiften/Network/TimerFactory.h> +#include <boost/filesystem/operations.hpp> +#include <Swiften/Base/Path.h> #include <Swiftob/Commands.h> +#include <Swiften/Base/BoostFilesystemVersion.h> + #define LUA_COMMANDS "__Lua_Commands" #define STORAGE "__Storage" +static const luaL_Reg defaultLibraries[] = { + {"", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + +static void initialize(lua_State* L) { + lua_gc(L, LUA_GCSTOP, 0); + for (const luaL_Reg* lib = defaultLibraries; lib->func; lib++) { +#if LUA_VERSION_NUM >= 502 + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); +#else + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); +#endif + } + lua_gc(L, LUA_GCRESTART, 0); +} + LuaCommands::LuaCommands(Commands* commands, const std::string& path, Client* client, TimerFactory* timerFactory, MUCs* mucs) : path_(path), scriptsPath_(boost::filesystem::path(path_) / "scripts") { commands_ = commands; @@ -43,4 +74,19 @@ void LuaCommands::registerCommands() { } +static int l_register_listener(lua_State *L) { + LuaCommands* commands = NULL; + lua_getfield(L, LUA_REGISTRYINDEX, LUA_COMMANDS); + commands = static_cast<LuaCommands*>(lua_touserdata(L, -1)); + lua_pop(L, 1); + if (!lua_isfunction(L, 1)) { + return luaL_error(L, "register_listener parameter must be a callback function"); + } + lua_pushvalue(L, 1); + int callbackIndex = luaL_ref(L, LUA_REGISTRYINDEX); + lua_pop(L, 1); + commands->getCommands()->registerListener(boost::bind(&LuaCommands::handleLuaListener, commands, callbackIndex, L, _1)); + return 0; +} + static int l_register_command(lua_State *L) { LuaCommands* commands = NULL; @@ -284,4 +330,23 @@ int LuaCommands::get_software_version(lua_State *L) { } +int LuaCommands::muc_kick(lua_State *L) { + if (!lua_isstring(L, 2)) { + return luaL_error(L, "muc_kick requires a nick to kick"); + } + std::string nick = lua_tostring(L, 2); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "muc_kick requires a muc to kick from"); + } + JID mucJID(lua_tostring(L, 1)); + MUC::ref muc = mucs_->getMUC(mucJID); + muc->kickOccupant(JID(mucJID.getNode(), mucJID.getDomain(), nick)); + return 0; +} + +static int l_muc_kick(lua_State *L) { + LuaCommands* commands = LuaCommands::commandsFromLua(L); + return commands->muc_kick(L); +} + static int l_store_setting(lua_State *L) { return LuaCommands::commandsFromLua(L)->store_setting(L); @@ -314,4 +379,19 @@ int LuaCommands::get_setting(lua_State *L) { } +void LuaCommands::handleLuaListener(int callbackIndex, lua_State* L, Swift::Message::ref message) { + lua_rawgeti(L, LUA_REGISTRYINDEX, callbackIndex); + lua_pushstring(L, message->getBody().c_str()); + lua_pushstring(L, message->getFrom().toBare().toString().c_str()); + lua_pushstring(L, message->getFrom().getResource().c_str()); + messageOntoStack(message, L); + int result = lua_pcall(L, 4, 0, 0); + if (result != 0) { + std::string error(lua_tostring(L, -1)); + lua_pop(L, 1); + error = "Listener failed: " + error; + std::cout << error << std::endl; + } +} + void LuaCommands::handleLuaCommand(int callbackIndex, lua_State* L, const std::string& command, const std::string& params, Swift::Message::ref message) { lua_rawgeti(L, LUA_REGISTRYINDEX, callbackIndex); @@ -353,15 +433,20 @@ void LuaCommands::messageOntoStack(Swift::Message::ref message, lua_State* L) { void LuaCommands::loadScript(boost::filesystem::path filePath) { std::cout << "Trying to load file from " << filePath << std::endl; - lua_State* lua = lua_open(); - luaL_openlibs(lua); + lua_State* lua = luaL_newstate(); + initialize(lua); lua_pushlightuserdata(lua, this); lua_setfield(lua, LUA_REGISTRYINDEX, LUA_COMMANDS); - std::string filename(filePath.filename()); +#if BOOST_FILESYSTEM_VERSION == 2 // TODO: Delete this when boost 1.44 becomes a minimum requirement, and we no longer need v2 + std::string filename = filePath.filename(); +#else + std::string filename = filePath.filename().string(); +#endif filename += ".storage"; - boost::filesystem::path storagePath(boost::filesystem::path(path_) / filename); + boost::filesystem::path storagePath(boost::filesystem::path(path_) / stringToPath(filename)); Storage* storage = new Storage(storagePath); lua_pushlightuserdata(lua, storage); lua_setfield(lua, LUA_REGISTRYINDEX, STORAGE); lua_register(lua, "swiftob_register_command", &l_register_command); + lua_register(lua, "swiftob_register_listener", &l_register_listener); lua_register(lua, "swiftob_reply_to", &l_reply_to); lua_register(lua, "swiftob_get_software_version", &l_get_software_version); @@ -369,4 +454,5 @@ void LuaCommands::loadScript(boost::filesystem::path filePath) { lua_register(lua, "swiftob_store_setting", &l_store_setting); lua_register(lua, "swiftob_get_setting", &l_get_setting); + lua_register(lua, "swiftob_muc_kick", &l_muc_kick); int fileLoaded = luaL_dofile(lua, filePath.string().c_str()); if (fileLoaded == 0 ) { |