xbot/bot.cpp

81 lines
2.0 KiB
C++

#include "bot.hpp"
#include <boost/log/trivial.hpp>
auto Bot::start(std::shared_ptr<Client> self) -> std::shared_ptr<Bot>
{
const auto thread = std::make_shared<Bot>(std::move(self));
auto &connection = *thread->self_->get_connection();
connection.sig_ircmsg.connect([thread](auto cmd, auto &msg) {
thread->on_ircmsg(cmd, msg);
});
return thread;
}
auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> 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] : msg.tags)
{
if (key == "account")
{
account = value;
}
else if (key == "operator")
{
oper = value;
}
}
sig_command({
.source = msg.args[0],
.target = msg.args[1],
.oper = oper,
.account = account,
.command = command,
.arguments = arguments
});
}
auto Bot::on_ircmsg(IrcCommand cmd, const IrcMsg &msg) -> void
{
if (cmd == IrcCommand::PRIVMSG)
{
const auto target = msg.args[0];
const auto message = msg.args[1];
if (self_->is_my_nick(target))
{
process_command(message, msg);
} else if (self_->is_channel(target)) {
const auto colon = message.find(':');
if (colon == message.npos) return;
if (not self_->is_my_nick(message.substr(0, colon))) return;
process_command(message.substr(colon+1), msg);
}
}
}
auto Bot::shutdown() -> void
{
sig_command.disconnect_all_slots();
}