summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst2
-rw-r--r--src/bridge/bridge.cpp34
-rw-r--r--src/irc/irc_client.cpp21
-rw-r--r--src/irc/irc_client.hpp13
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
*/