From 41b11480051b4d9620cc9944d3b3e61868710666 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Mon, 27 Jan 2025 17:46:07 -0800 Subject: [PATCH] add on_chat layer --- bot.cpp | 35 ++++++++++++++++++----------------- bot.hpp | 4 ++-- client.cpp | 33 +++++++++++++++++++++++++++++---- client.hpp | 14 ++++++++++++++ 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/bot.cpp b/bot.cpp index ba65858..1b13993 100644 --- a/bot.cpp +++ b/bot.cpp @@ -6,14 +6,15 @@ auto Bot::start(std::shared_ptr self) -> std::shared_ptr { const auto thread = std::make_shared(std::move(self)); - thread->self_->get_connection().sig_ircmsg.connect([thread](const auto cmd, auto &msg) { - thread->on_ircmsg(cmd, msg); + + thread->self_->sig_chat.connect([thread](auto &chat) { + thread->on_chat(chat); }); return thread; } -auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> void +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; @@ -32,7 +33,7 @@ auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> void std::string_view oper; std::string_view account; - for (auto [key, value] : msg.tags) + for (auto [key, value] : chat.tags) { if (key == "account") { @@ -45,8 +46,8 @@ auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> void } sig_command({ - .source = msg.args[0], - .target = msg.args[1], + .source = chat.source, + .target = chat.target, .oper = oper, .account = account, .command = command, @@ -54,20 +55,20 @@ auto Bot::process_command(std::string_view message, const IrcMsg &msg) -> void }); } -auto Bot::on_ircmsg(const IrcCommand cmd, const IrcMsg &msg) -> void +auto Bot::on_chat(const Chat &chat) -> void { - if (cmd == IrcCommand::PRIVMSG) + if (not chat.is_notice) { - const auto target = msg.args[0]; - const auto message = msg.args[1]; - if (self_->is_my_nick(target)) + if (self_->is_my_nick(chat.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); + 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); } } } diff --git a/bot.hpp b/bot.hpp index d28448d..dedab87 100644 --- a/bot.hpp +++ b/bot.hpp @@ -28,8 +28,8 @@ struct Bot : std::enable_shared_from_this , command_prefix_{'!'} {} - auto on_ircmsg(IrcCommand, const IrcMsg &) -> void; - auto process_command(std::string_view message, const IrcMsg &msg) -> void; + auto on_chat(const Chat &) -> void; + auto process_command(std::string_view message, const Chat &msg) -> void; static auto start(std::shared_ptr) -> std::shared_ptr; auto shutdown() -> void; diff --git a/client.cpp b/client.cpp index f4f3ee0..a5f59bd 100644 --- a/client.cpp +++ b/client.cpp @@ -37,7 +37,7 @@ auto Client::on_join(const IrcMsg &irc) -> void { if (is_my_mask(irc.source)) { - channels_.insert(std::string{irc.args[0]}); + channels_.insert(casemap(irc.args[0])); } } @@ -45,7 +45,7 @@ auto Client::on_kick(const IrcMsg &irc) -> void { if (is_my_nick(irc.args[1])) { - channels_.erase(std::string{irc.args[0]}); + channels_.erase(casemap(irc.args[0])); } } @@ -53,7 +53,7 @@ auto Client::on_part(const IrcMsg &irc) -> void { if (is_my_mask(irc.source)) { - channels_.erase(std::string{irc.args[0]}); + channels_.erase(casemap(irc.args[0])); } } @@ -118,6 +118,25 @@ auto Client::on_isupport(const IrcMsg &msg) -> void } } +auto Client::on_chat(bool notice, const IrcMsg &irc) -> void +{ + char status_msg = '\0'; + std::string_view target = irc.args[0]; + if (not target.empty() && status_msg_.find(target[0]) != std::string::npos) + { + status_msg = target[0]; + target = target.substr(1); + } + sig_chat({ + .tags = irc.tags, + .is_notice = notice, + .status_msg = '\0', + .source = irc.source, + .target = irc.args[0], + .message = irc.args[1], + }); +} + auto Client::start(Connection &connection) -> std::shared_ptr { auto thread = std::make_shared(connection); @@ -125,6 +144,12 @@ auto Client::start(Connection &connection) -> std::shared_ptr connection.sig_ircmsg.connect([thread](auto cmd, auto &msg) { switch (cmd) { + case IrcCommand::PRIVMSG: + thread->on_chat(false, msg); + break; + case IrcCommand::NOTICE: + thread->on_chat(true, msg); + break; case IrcCommand::JOIN: thread->on_join(msg); break; @@ -190,7 +215,7 @@ auto Client::is_my_nick(std::string_view nick) const -> bool auto Client::is_my_mask(std::string_view mask) const -> bool { const auto bang = mask.find('!'); - return bang != std::string_view::npos && nickname_ == mask.substr(0, bang); + return bang != std::string_view::npos && is_my_nick(mask.substr(0, bang)); } auto Client::is_channel(std::string_view name) const -> bool diff --git a/client.hpp b/client.hpp index 7c0b0b5..36c2831 100644 --- a/client.hpp +++ b/client.hpp @@ -5,6 +5,7 @@ #include #include +#include struct Connection; struct IrcMsg; @@ -16,6 +17,15 @@ enum class Casemap Ascii, }; +struct Chat { + std::span tags; + bool is_notice; + char status_msg; + std::string_view source; + std::string_view target; + std::string_view message; +}; + /** * @brief Thread to track this connection's identity, and IRC state. * @@ -34,6 +44,7 @@ class Client Casemap casemap_; std::string channel_prefix_; + std::string status_msg_; std::unordered_map caps_available_; std::unordered_set caps_; @@ -49,15 +60,18 @@ class Client auto on_cap(const IrcMsg &irc) -> void; auto on_authenticate(std::string_view) -> void; auto on_registered() -> void; + auto on_chat(bool, const IrcMsg &irc) -> void; public: boost::signals2::signal sig_registered; boost::signals2::signal &)> sig_cap_ls; + boost::signals2::signal sig_chat; Client(Connection &connection) : connection_{connection} , casemap_{Casemap::Rfc1459} , channel_prefix_{"#&"} + , status_msg_{"+@"} { }