summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/bridge/bridge.cpp7
-rw-r--r--src/irc/irc_channel.hpp1
-rw-r--r--src/irc/irc_client.cpp43
-rw-r--r--src/irc/irc_client.hpp19
-rw-r--r--src/utils/split.cpp18
-rw-r--r--src/utils/split.hpp10
-rw-r--r--src/xmpp/xmpp_component.cpp5
8 files changed, 84 insertions, 21 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0fae9e..7f7633b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -70,7 +70,7 @@ target_link_libraries(xmpp bridge network utils
file(GLOB source_bridge
src/bridge/*.[hc]pp)
add_library(bridge STATIC ${source_bridge})
-target_link_libraries(bridge xmpp irc)
+target_link_libraries(bridge xmpp irc utils)
#
## Main executable
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp
index d292af3..0b26a7f 100644
--- a/src/bridge/bridge.cpp
+++ b/src/bridge/bridge.cpp
@@ -4,6 +4,7 @@
#include <network/poller.hpp>
#include <utils/encoding.hpp>
+#include <utils/split.hpp>
#include <iostream>
static const char* action_prefix = "\01ACTION ";
@@ -83,6 +84,12 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
std::cout << "Cannot send message: no client exist for server " << iid.server << std::endl;
return;
}
+ if (body.substr(0, 6) == "/mode ")
+ {
+ std::vector<std::string> args = utils::split(body.substr(6), ' ', false);
+ irc->send_mode_command(iid.chan, args);
+ return;
+ }
if (body.substr(0, 4) == "/me ")
irc->send_channel_message(iid.chan, action_prefix + body.substr(4) + "\01");
else
diff --git a/src/irc/irc_channel.hpp b/src/irc/irc_channel.hpp
index 3786697..c4b6d2c 100644
--- a/src/irc/irc_channel.hpp
+++ b/src/irc/irc_channel.hpp
@@ -26,7 +26,6 @@ public:
private:
std::unique_ptr<IrcUser> self;
std::vector<std::unique_ptr<IrcUser>> users;
-
IrcChannel(const IrcChannel&) = delete;
IrcChannel(IrcChannel&&) = delete;
IrcChannel& operator=(const IrcChannel&) = delete;
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index 30b1204..0d8c614 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -162,9 +162,15 @@ void IrcClient::send_part_command(const std::string& chan_name, const std::strin
{
IrcChannel* channel = this->get_channel(chan_name);
if (channel->joined == true)
- {
- this->send_message(IrcMessage("PART", {chan_name, status_message}));
- }
+ this->send_message(IrcMessage("PART", {chan_name, status_message}));
+}
+
+void IrcClient::send_mode_command(const std::string& chan_name, const std::vector<std::string>& arguments)
+{
+ std::vector<std::string> args(arguments);
+ args.insert(args.begin(), chan_name);
+ IrcMessage m("MODE", std::move(args));
+ this->send_message(std::move(m));
}
void IrcClient::send_pong_command(const IrcMessage& message)
@@ -325,3 +331,34 @@ void IrcClient::on_nick(const IrcMessage& message)
}
}
+void IrcClient::on_mode(const IrcMessage& message)
+{
+ const std::string target = message.arguments[0];
+ if (target[0] == '&' || target[0] == '#' ||
+ target[0] == '!' || target[0] == '+')
+ this->on_channel_mode(message);
+ else
+ this->on_user_mode(message);
+}
+
+void IrcClient::on_channel_mode(const IrcMessage& message)
+{
+ // For now, just transmit the modes so the user can know what happens
+ // TODO, actually interprete the mode.
+ Iid iid;
+ iid.chan = message.arguments[0];
+ iid.server = this->hostname;
+ IrcUser user(message.prefix);
+ this->bridge->send_message(iid, "", std::string("Mode ") + iid.chan +
+ " [" + message.arguments[1] +
+ (message.arguments.size() > 2 ? (" " + message.arguments[2]): "")
+ + "] by " + user.nick,
+ true);
+}
+
+void IrcClient::on_user_mode(const IrcMessage& message)
+{
+ this->bridge->send_xmpp_message(this->hostname, "",
+ std::string("User mode for ") + message.arguments[0] +
+ " is [" + message.arguments[1] + "]");
+}
diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp
index d9ea069..722f850 100644
--- a/src/irc/irc_client.hpp
+++ b/src/irc/irc_client.hpp
@@ -88,6 +88,10 @@ public:
*/
void send_part_command(const std::string& chan_name, const std::string& status_message);
/**
+ * Send the MODE irc command
+ */
+ void send_mode_command(const std::string& chan_name, const std::vector<std::string>& arguments);
+ /**
* Forward the server message received from IRC to the XMPP component
*/
void forward_server_message(const IrcMessage& message);
@@ -118,17 +122,20 @@ public:
* When a message 001 is received, join the rooms we wanted to join, and set our actual nickname
*/
void on_welcome_message(const IrcMessage& message);
- /**
- * When a PART message is received
- */
void on_part(const IrcMessage& message);
+ void on_nick(const IrcMessage& message);
+ void on_mode(const IrcMessage& message);
/**
- * When a NICK message is received
+ * A mode towards our own user is received (note, that is different from a
+ * channel mode towards or own nick, see
+ * http://tools.ietf.org/html/rfc2812#section-3.1.5 VS #section-3.2.3)
*/
- void on_nick(const IrcMessage& message);
+ void on_user_mode(const IrcMessage& message);
/**
- * When a QUIT message is received
+ * A mode towards a channel. Note that this can change the mode of the
+ * channel itself or an IrcUser in it.
*/
+ void on_channel_mode(const IrcMessage& message);
void on_quit(const IrcMessage& message);
private:
diff --git a/src/utils/split.cpp b/src/utils/split.cpp
new file mode 100644
index 0000000..82852ee
--- /dev/null
+++ b/src/utils/split.cpp
@@ -0,0 +1,18 @@
+#include <utils/split.hpp>
+
+namespace utils
+{
+ std::vector<std::string> split(const std::string &s, const char delim, const bool allow_empty)
+ {
+ std::vector<std::string> ret;
+ std::stringstream ss(s);
+ std::string item;
+ while (std::getline(ss, item, delim))
+ {
+ if (item.empty() && !allow_empty)
+ continue ;
+ ret.emplace_back(std::move(item));
+ }
+ return ret;
+ }
+}
diff --git a/src/utils/split.hpp b/src/utils/split.hpp
index 0067131..9fee90a 100644
--- a/src/utils/split.hpp
+++ b/src/utils/split.hpp
@@ -7,15 +7,7 @@
namespace utils
{
- std::vector<std::string> split(const std::string &s, const char delim)
- {
- std::vector<std::string> ret;
- std::stringstream ss(s);
- std::string item;
- while (std::getline(ss, item, delim))
- ret.emplace_back(std::move(item));
- return ret;
- }
+ std::vector<std::string> split(const std::string &s, const char delim, const bool allow_empty=true);
}
#endif // SPLIT_INCLUDED
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index e2063ba..c36a141 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -294,7 +294,10 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
{
Stanza message("message");
message["to"] = jid_to;
- message["from"] = muc_name + "@" + this->served_hostname + "/" + nick;
+ if (!nick.empty())
+ message["from"] = muc_name + "@" + this->served_hostname + "/" + nick;
+ else // Message from the room itself
+ message["from"] = muc_name + "@" + this->served_hostname;
message["type"] = "groupchat";
XmlNode body("body");
body.set_inner(body_str);