diff options
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | src/bridge/bridge.cpp | 34 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 21 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 13 |
4 files changed, 45 insertions, 25 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0a1df61..8d5b106 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ Version 9.0 ad-hoc configuration form on a server JID. - Add a verify_certificate policy option that lets the admin disable certificate validation per-domain. +- Messages reflections are now properly cut if the body was cut before + being to sent to IRC Version 8.3 - 2018-06-01 ======================== diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index c3c2003..39ee158 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -224,6 +224,23 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std:: bool first = true; for (const std::string& line: lines) { + std::string uuid; +#ifdef USE_DATABASE + const auto xmpp_body = this->make_xmpp_body(line); + if (this->record_history) + uuid = Database::store_muc_message(this->get_bare_jid(), iid.get_local(), iid.get_server(), std::chrono::system_clock::now(), + std::get<0>(xmpp_body), irc->get_own_nick()); +#endif + if (!first || id.empty()) + id = utils::gen_uuid(); + + MessageCallback mirror_to_all_resources = [this, iid, uuid, id](const IrcClient* irc, const IrcMessage& message) { + const std::string& line = message.arguments[1]; + for (const auto& resource: this->resources_in_chan[iid.to_tuple()]) + this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(), this->make_xmpp_body(line), + this->user_jid + "/" + resource, uuid, id); + }; + if (line.substr(0, 5) == "/mode") { std::vector<std::string> args = utils::split(line.substr(5), ' ', false); @@ -232,22 +249,11 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std:: // XMPP user, that’s not a textual message. } else if (line.substr(0, 4) == "/me ") - irc->send_channel_message(iid.get_local(), action_prefix + line.substr(4) + "\01"); + irc->send_channel_message(iid.get_local(), action_prefix + line.substr(4) + "\01", + std::move(mirror_to_all_resources)); else - irc->send_channel_message(iid.get_local(), line); + irc->send_channel_message(iid.get_local(), line, std::move(mirror_to_all_resources)); - std::string uuid; -#ifdef USE_DATABASE - const auto xmpp_body = this->make_xmpp_body(line); - if (this->record_history) - uuid = Database::store_muc_message(this->get_bare_jid(), iid.get_local(), iid.get_server(), std::chrono::system_clock::now(), - std::get<0>(xmpp_body), irc->get_own_nick()); -#endif - if (!first || id.empty()) - id = utils::gen_uuid(); - for (const auto& resource: this->resources_in_chan[iid.to_tuple()]) - this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(), this->make_xmpp_body(line), - this->user_jid + "/" + resource, uuid, id); first = false; } } diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index fee6517..78d0fbf 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -398,8 +398,10 @@ void IrcClient::parse_in_buffer(const size_t) } } -void IrcClient::actual_send(const IrcMessage& message) +void IrcClient::actual_send(std::pair<IrcMessage, MessageCallback> message_pair) { + const IrcMessage& message = message_pair.first; + const MessageCallback& callback = message_pair.second; log_debug("IRC SENDING: (", this->get_hostname(), ") ", message); std::string res; if (!message.prefix.empty()) @@ -417,14 +419,18 @@ void IrcClient::actual_send(const IrcMessage& message) } res += "\r\n"; this->send_data(std::move(res)); + + if (callback) + callback(this, message); } -void IrcClient::send_message(IrcMessage message, bool throttle) +void IrcClient::send_message(IrcMessage message, MessageCallback callback, bool throttle) { + auto message_pair = std::make_pair(std::move(message), std::move(callback)); if (this->tokens_bucket.use_token() || !throttle) - this->actual_send(message); + this->actual_send(std::move(message_pair)); else - message_queue.push_back(std::move(message)); + message_queue.push_back(std::move(message_pair)); } void IrcClient::send_raw(const std::string& txt) @@ -475,7 +481,7 @@ void IrcClient::send_topic_command(const std::string& chan_name, const std::stri void IrcClient::send_quit_command(const std::string& reason) { - this->send_message(IrcMessage("QUIT", {reason}), false); + this->send_message(IrcMessage("QUIT", {reason}), {}, false); } void IrcClient::send_join_command(const std::string& chan_name, const std::string& password) @@ -494,7 +500,8 @@ void IrcClient::send_join_command(const std::string& chan_name, const std::strin this->start(); } -bool IrcClient::send_channel_message(const std::string& chan_name, const std::string& body) +bool IrcClient::send_channel_message(const std::string& chan_name, const std::string& body, + MessageCallback callback) { IrcChannel* channel = this->get_channel(chan_name); if (!channel->joined) @@ -517,7 +524,7 @@ bool IrcClient::send_channel_message(const std::string& chan_name, const std::st ::strlen(":!@ PRIVMSG ") - chan_name.length() - ::strlen(" :\r\n"); const auto lines = cut(body, line_size); for (const auto& line: lines) - this->send_message(IrcMessage("PRIVMSG", {chan_name, line})); + this->send_message(IrcMessage("PRIVMSG", {chan_name, line}), callback); return true; } diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 8c5c0c8..aa314f8 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -21,6 +21,10 @@ #include <set> #include <utils/tokens_bucket.hpp> +class IrcClient; + +using MessageCallback = std::function<void(const IrcClient*, const IrcMessage&)>; + class Bridge; /** @@ -86,9 +90,9 @@ public: * (actually, into our out_buf and signal the poller that we want to wach * for send events to be ready) */ - void send_message(IrcMessage message, bool throttle=true); + void send_message(IrcMessage message, MessageCallback callback={}, bool throttle=true); void send_raw(const std::string& txt); - void actual_send(const IrcMessage& message); + void actual_send(std::pair<IrcMessage, MessageCallback> message_pair); /** * Send the PONG irc command */ @@ -117,7 +121,8 @@ public: * Send a PRIVMSG command for a channel * Return true if the message was actually sent */ - bool send_channel_message(const std::string& chan_name, const std::string& body); + bool send_channel_message(const std::string& chan_name, const std::string& body, + MessageCallback callback); /** * Send a PRIVMSG command for an user */ @@ -336,7 +341,7 @@ private: /** * Where messaged are stored when they are throttled. */ - std::deque<IrcMessage> message_queue{}; + std::deque<std::pair<IrcMessage, MessageCallback>> message_queue{}; /** * The list of joined channels, indexed by name */ |