From c3c24fd8fb8f91696b4e38e0f212a35a8e1fe137 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Sun, 22 Jul 2012 18:13:24 +0100 Subject: Allow nick changing and restart for Swiftob bots diff --git a/Swiftob/Commands.cpp b/Swiftob/Commands.cpp index 18f9fb0..38e5f57 100644 --- a/Swiftob/Commands.cpp +++ b/Swiftob/Commands.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -22,16 +23,28 @@ Commands::Commands(Users* users, Swift::Client* client, Storage* storage, MUCs* resetCommands(); } -void Commands::resetCommands() { +Commands::~Commands() { + clearCommands(); +} + +void Commands::clearCommands() { foreach (NamedCommand command, commands_) { delete command.second; } commands_.clear(); + +} + +void Commands::resetCommands() { + clearCommands(); registerCommand("quit", Owner, "Quit the bot", boost::bind(&Commands::handleQuitCommand, this, _1, _2, _3)); registerCommand("help", Anyone, "Get help", boost::bind(&Commands::handleHelpCommand, this, _1, _2, _3)); registerCommand("join", Owner, "Join a MUC", boost::bind(&Commands::handleJoinCommand, this, _1, _2, _3)); registerCommand("part", Owner, "Leave a MUC", boost::bind(&Commands::handlePartCommand, this, _1, _2, _3)); registerCommand("rehash", Owner, "Reload scripts", boost::bind(&Commands::handleRehashCommand, this, _1, _2, _3)); + registerCommand("restart", Owner, "Restart bot", boost::bind(&Commands::handleRestartCommand, this, _1, _2, _3)); + registerCommand("nick", Owner, "Change nick (requires restart)", boost::bind(&Commands::handleChangeNick, this, _1, _2, _3)); + //registerCommand("owner", Owner, "Change owner settinsg", boost::bind(&Commands::handleChangeOwner, this, _1, _2, _3)); onReset(); } @@ -76,6 +89,27 @@ bool Commands::roleIn(const Users::User::Role userRole, RoleList roleList) { return false; } +void Commands::handleChangeNick(const std::string& /*command*/, const std::string& params, Swift::Message::ref message) { + std::string nick(params); + boost::algorithm::trim(nick); + if (nick.empty()) { + replyTo(message, "Current nick is '" + mucs_->getDefaultNick() + "'. Run the command with a new nick to change it."); + } + else { + if (mucs_->setDefaultNick(params)) { + replyTo(message, "Default nick now set to '" + nick + "' - restart the bot for this to take effect."); + } + else { + replyTo(message, "Can't set invalid nick '" + nick + "'."); + } + } +} + +void Commands::handleChangeOwner(const std::string& /*command*/, const std::string& /*params*/, Swift::Message::ref /*message*/) { + /* Oh, right. I don't have user persistence coded yet. + * Probably not worth doing this until I have.*/ +} + void Commands::handleQuitCommand(const std::string& /*command*/, const std::string& /*params*/, Swift::Message::ref message) { replyTo(message, "Shutting down"); std::cout << "Quitting at the behest of " << message->getFrom().toString() << std::endl; @@ -102,6 +136,13 @@ void Commands::handleRehashCommand(const std::string& /*command*/, const std::st } } +void Commands::handleRestartCommand(const std::string& /*command*/, const std::string& /*params*/, Swift::Message::ref message) { + rehashError_ = ""; + replyTo(message, "Restarting now."); + std::cout << "Restarting at the behest of " << message->getFrom().toString() << std::endl; + onRestartRequested(); +} + void Commands::handleJoinCommand(const std::string& /*command*/, const std::string& params, Swift::Message::ref message) { Swift::JID room(params); if (!room.isValid() || !room.getResource().empty() || room.getNode().empty()) { diff --git a/Swiftob/Commands.h b/Swiftob/Commands.h index 5c55f39..d5aac2c 100644 --- a/Swiftob/Commands.h +++ b/Swiftob/Commands.h @@ -42,6 +42,7 @@ class Commands { public: Commands(Users* users, Swift::Client* client, Storage* storage, MUCs* mucs); + ~Commands(); 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); @@ -53,7 +54,9 @@ class Commands { public: boost::signal onReset; + boost::signal onRestartRequested; private: + void clearCommands(); bool roleIn(const Users::User::Role userRole, RoleList roles); void handleQuitCommand(const std::string& command, const std::string& params, Swift::Message::ref message); void handleHelpCommand(const std::string& command, const std::string& params, Swift::Message::ref message); @@ -62,6 +65,9 @@ class Commands { void handleJoinCommandFailure(const Swift::JID& room, const std::string& error, Swift::Message::ref message); void handlePartCommand(const std::string& /*command*/, const std::string& params, Swift::Message::ref message); void handleRehashCommand(const std::string& command, const std::string& params, Swift::Message::ref message); + void handleRestartCommand(const std::string& command, const std::string& params, Swift::Message::ref message); + void handleChangeNick(const std::string& command, const std::string& params, Swift::Message::ref message); + void handleChangeOwner(const std::string& command, const std::string& params, Swift::Message::ref message); private: std::map commands_; std::vector listeners_; diff --git a/Swiftob/MUCs.cpp b/Swiftob/MUCs.cpp index 695cbd9..5bad3a1 100644 --- a/Swiftob/MUCs.cpp +++ b/Swiftob/MUCs.cpp @@ -18,12 +18,17 @@ #include #define MUC_LIST_SETTING "muc_list" +#define NICK "default_nick" typedef std::pair JIDMUCPair; MUCs::MUCs(Client* client, Storage* storage) : defaultNick_("Kanchil+") { client_ = client; storage_ = storage; + std::string storedNick = storage_->getSetting(NICK); + if (!storedNick.empty()) { + defaultNick_ = storedNick; + } client_->onConnected.connect(boost::bind(&MUCs::handleConnected, this)); } @@ -118,3 +123,13 @@ void MUCs::save() { MUC::ref MUCs::getMUC(const JID& room) { return (mucs_.find(room) != mucs_.end()) ? mucs_[room] : MUC::ref(); } + +bool MUCs::setDefaultNick(const std::string& nick) { + JID testJID("alice", "wonderland.lit", nick); + if (testJID.isValid()) { + defaultNick_ = testJID.getResource(); + storage_->saveSetting(NICK, defaultNick_); + return true; + } + return false; +} diff --git a/Swiftob/MUCs.h b/Swiftob/MUCs.h index e727ec2..8f56182 100644 --- a/Swiftob/MUCs.h +++ b/Swiftob/MUCs.h @@ -30,6 +30,8 @@ class MUCs { void part(const JID& room); bool contains(const JID& room); MUC::ref getMUC(const JID& room); + const std::string& getDefaultNick() const {return defaultNick_;} + bool setDefaultNick(const std::string& nick); private: void handleConnected(); void handleJoinFailed(const JID& room, ErrorPayload::ref error, boost::function failureCallback); diff --git a/Swiftob/Swiftob.cpp b/Swiftob/Swiftob.cpp index 6f36b3d..1578e34 100644 --- a/Swiftob/Swiftob.cpp +++ b/Swiftob/Swiftob.cpp @@ -32,14 +32,14 @@ po::options_description Swiftob::getOptionsDescription() { } Swiftob::Swiftob(const po::variables_map& options) : options_(options), networkFactories_(&eventLoop_), quitting_(false) { - std::string path; - path = options["path"].as(); + path_ = options["path"].as(); client_ = new Swift::Client(Swift::JID(options["jid"].as()), options["password"].as(), &networkFactories_); - storage_ = new Storage(boost::filesystem::path(path) / "settings.txt"); - mucs_ = new MUCs(client_, storage_); - users_ = new Users(client_, mucs_); - commands_ = new Commands(users_, client_, storage_, mucs_); - lua_ = new LuaCommands(commands_, path, client_, networkFactories_.getTimerFactory(), mucs_); + storage_ = new Storage(boost::filesystem::path(path_) / "settings.txt"); + mucs_ = NULL; + users_ = NULL; + commands_ = NULL; + lua_ = NULL; + init(); client_->onConnected.connect(boost::bind(&Swiftob::handleConnected, this)); client_->onDisconnected.connect(boost::bind(&Swiftob::handleDisconnected, this, _1)); client_->onMessageReceived.connect(boost::bind(&Swiftob::handleMessageReceived, this, _1)); @@ -54,6 +54,23 @@ Swiftob::Swiftob(const po::variables_map& options) : options_(options), networkF eventLoop_.run(); } +void Swiftob::init() { + delete mucs_; + mucs_ = new MUCs(client_, storage_); + delete users_; + users_ = new Users(client_, mucs_); + delete commands_; + commands_ = new Commands(users_, client_, storage_, mucs_); + commands_->onRestartRequested.connect(boost::bind(&Swiftob::handleRestartRequested, this)); + delete lua_; + lua_ = new LuaCommands(commands_, path_, client_, networkFactories_.getTimerFactory(), mucs_); +} + +void Swiftob::handleRestartRequested() { + client_->disconnect(); + init(); +} + void Swiftob::handleConnected() { std::cout << "Connected" << std::endl; if (options_.count("init") > 0) {}{ /* FIXME: Not ready for persistence yet*/ diff --git a/Swiftob/Swiftob.h b/Swiftob/Swiftob.h index ad4e9b8..36091e4 100644 --- a/Swiftob/Swiftob.h +++ b/Swiftob/Swiftob.h @@ -32,6 +32,8 @@ class Swiftob { int exec(); ~Swiftob(); private: + void init(); + void handleRestartRequested(); void handleConnected(); void handleDisconnected(const boost::optional&); void handleMessageReceived(Swift::Message::ref); @@ -45,5 +47,6 @@ class Swiftob { MUCs* mucs_; bool quitting_; Users* users_; + std::string path_; Swift::Client* client_; }; -- cgit v0.10.2-6-g49f6