#include "bot.hpp" #include auto Bot::start(std::shared_ptr self) -> std::shared_ptr { const auto thread = std::make_shared(std::move(self)); thread->self_->sig_chat.connect([thread](auto &chat) { thread->on_chat(chat); }); return thread; } auto Bot::process_command(std::string_view message, const Chat &chat) -> void { const auto cmdstart = message.find_first_not_of(' '); if (cmdstart == message.npos) return; message = message.substr(cmdstart); if (not message.starts_with(command_prefix_)) return; message = message.substr(1); // discard the prefix auto cmdend = message.find(' '); std::string_view command = cmdend == message.npos ? message : message.substr(0, cmdend); std::string_view arguments = cmdend == message.npos ? std::string_view{} : message.substr(cmdend + 1); std::string_view oper; std::string_view account; for (auto [key, value] : chat.tags) { if (key == "account") { account = value; } else if (key == "solanum.chat/oper") { oper = value; } } sig_command({ .source = chat.source, .target = chat.target, .oper = oper, .account = account, .command = command, .arguments = arguments }); } auto Bot::on_chat(const Chat &chat) -> void { if (not chat.is_notice) { if (self_->is_my_nick(chat.target)) { process_command(chat.message, chat); } else if (self_->is_channel(chat.target)) { const auto colon = chat.message.find(':'); if (colon == chat.message.npos) return; if (not self_->is_my_nick(chat.message.substr(0, colon))) return; process_command(chat.message.substr(colon + 1), chat); } } } auto Bot::shutdown() -> void { sig_command.disconnect_all_slots(); }