summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-07-21 18:15:37 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-07-21 18:56:03 (GMT)
commit12024c66fe21c62b158552abe26b1bcfa142ffe8 (patch)
treecfedc6e34b147bbb05fedfd69eeaad27bd5eadbd
parent2a690f23a71f5f24550df112e0544b32826655db (diff)
downloadswift-contrib-12024c66fe21c62b158552abe26b1bcfa142ffe8.zip
swift-contrib-12024c66fe21c62b158552abe26b1bcfa142ffe8.tar.bz2
Allowing generic message listeners for Swiftob bots
-rw-r--r--Swiftob/Commands.cpp11
-rw-r--r--Swiftob/Commands.h4
-rw-r--r--Swiftob/LuaCommands.cpp31
-rw-r--r--Swiftob/LuaCommands.h3
-rw-r--r--Swiftob/Swiftob.cpp4
-rw-r--r--Swiftob/scripts/logAllMessages.lua6
6 files changed, 58 insertions, 1 deletions
diff --git a/Swiftob/Commands.cpp b/Swiftob/Commands.cpp
index cf24196..18f9fb0 100644
--- a/Swiftob/Commands.cpp
+++ b/Swiftob/Commands.cpp
@@ -41,6 +41,10 @@ void Commands::registerCommand(const std::string& name, RoleList roles, const st
command->onReceived.connect(callback);
}
+void Commands::registerListener(ListenerCallback listener) {
+ listeners_.push_back(listener);
+}
+
bool Commands::hasCommand(const std::string& name) {
return commands_.find(name) != commands_.end();
}
@@ -57,6 +61,12 @@ bool Commands::runCommand(const std::string& name, const std::string& params, Sw
return false;
}
+void Commands::runListeners(Swift::Message::ref message) {
+ foreach (ListenerCallback listener, listeners_) {
+ listener(message);
+ }
+}
+
bool Commands::roleIn(const Users::User::Role userRole, RoleList roleList) {
switch (roleList) {
case Owner : return userRole == Users::User::Owner;
@@ -84,6 +94,7 @@ void Commands::handleRehashCommand(const std::string& /*command*/, const std::st
replyTo(message, "Rehashing now.");
std::cout << "Rehashing at the behest of " << message->getFrom().toString() << std::endl;
resetCommands();
+ listeners_.clear();
if (rehashError_.empty()) {
replyTo(message, "Rehash complete");
} else {
diff --git a/Swiftob/Commands.h b/Swiftob/Commands.h
index 8423252..5c55f39 100644
--- a/Swiftob/Commands.h
+++ b/Swiftob/Commands.h
@@ -21,6 +21,7 @@ namespace Swift {
class Storage;
class Commands {
+ typedef boost::function<void(Swift::Message::ref)> ListenerCallback;
public:
enum RoleList {Anyone, Owner};
public:
@@ -43,8 +44,10 @@ class Commands {
Commands(Users* users, Swift::Client* client, Storage* storage, MUCs* mucs);
bool hasCommand(const std::string&);
bool runCommand(const std::string& command, const std::string& params, Swift::Message::ref message);
+ void runListeners(Swift::Message::ref message);
void replyTo(Swift::Message::ref source, std::string replyBody, bool outOfMUC = false);
void registerCommand(const std::string& name, RoleList roles, const std::string& description, boost::function<void(const std::string& /*command*/, const std::string& /*params*/, Swift::Message::ref)> callback);
+ void registerListener(ListenerCallback);
void resetCommands();
void setRehashError(const std::string& error);
@@ -61,6 +64,7 @@ class Commands {
void handleRehashCommand(const std::string& command, const std::string& params, Swift::Message::ref message);
private:
std::map<std::string, Command*> commands_;
+ std::vector<ListenerCallback> listeners_;
Users* users_;
Swift::Client* client_;
Storage* storage_;
diff --git a/Swiftob/LuaCommands.cpp b/Swiftob/LuaCommands.cpp
index 9f99d82..8cc614d 100644
--- a/Swiftob/LuaCommands.cpp
+++ b/Swiftob/LuaCommands.cpp
@@ -42,6 +42,21 @@ 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;
lua_getfield(L, LUA_REGISTRYINDEX, LUA_COMMANDS);
@@ -313,6 +328,21 @@ 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);
lua_pushstring(L, command.c_str());
@@ -363,6 +393,7 @@ void LuaCommands::loadScript(boost::filesystem::path filePath) {
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);
lua_register(lua, "swiftob_muc_input_to_jid", &l_muc_input_to_jid);
diff --git a/Swiftob/LuaCommands.h b/Swiftob/LuaCommands.h
index fc743ca..b82959e 100644
--- a/Swiftob/LuaCommands.h
+++ b/Swiftob/LuaCommands.h
@@ -64,8 +64,9 @@ class LuaCommands {
};
LuaCommands(Commands* commands, const std::string& path, Client* client, TimerFactory* timerFactory, MUCs* mucs);
- /* Public but isn't really part of the API */
+ /* Public but aren't really part of the API */
void handleLuaCommand(int callbackIndex, lua_State* L, const std::string& command, const std::string& params, Message::ref message);
+ void handleLuaListener(int callbackIndex, lua_State* L, Message::ref message);
Commands* getCommands() {return commands_;}
int get_software_version(lua_State *L);
int muc_input_to_jid(lua_State *L);
diff --git a/Swiftob/Swiftob.cpp b/Swiftob/Swiftob.cpp
index 331e55e..6f36b3d 100644
--- a/Swiftob/Swiftob.cpp
+++ b/Swiftob/Swiftob.cpp
@@ -87,6 +87,10 @@ void Swiftob::handleMessageReceived(Swift::Message::ref message) {
std::cout << "Not handling empty body" << std::endl;
return;
}
+
+ /* Run through any full-message listeners */
+ commands_->runListeners(message);
+
/*Convert body into !command if it's not a MUC, and it misses the bang*/
std::string bangBody(body);
if (type != Swift::Message::Groupchat && body[0] != '!') {
diff --git a/Swiftob/scripts/logAllMessages.lua b/Swiftob/scripts/logAllMessages.lua
new file mode 100644
index 0000000..a14c0f3
--- /dev/null
+++ b/Swiftob/scripts/logAllMessages.lua
@@ -0,0 +1,6 @@
+function log_a_message(body, muc, nick, message)
+ print("Received line from '" .. nick .. "' in '" .. muc .. "':")
+ print(body)
+end
+
+swiftob_register_listener(log_a_message)