summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiftob/LuaCommands.cpp')
-rw-r--r--Swiftob/LuaCommands.cpp94
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 ) {