Basic handling of modes, both ways
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+40
-3
@@ -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] + "]");
|
||||
}
|
||||
|
||||
+14
-7
@@ -87,6 +87,10 @@ public:
|
||||
* Send the PART irc command
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -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);
|
||||
/**
|
||||
* When a NICK message is received
|
||||
*/
|
||||
void on_nick(const IrcMessage& message);
|
||||
void on_mode(const IrcMessage& message);
|
||||
/**
|
||||
* When a QUIT 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_user_mode(const IrcMessage& message);
|
||||
/**
|
||||
* 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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+1
-9
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user