summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bridge/bridge.cpp18
-rw-r--r--src/bridge/bridge.hpp7
-rw-r--r--src/irc/irc_channel.cpp5
-rw-r--r--src/irc/irc_channel.hpp4
-rw-r--r--src/irc/irc_client.cpp15
-rw-r--r--src/irc/irc_user.cpp30
-rw-r--r--src/irc/irc_user.hpp6
-rw-r--r--src/xmpp/xmpp_component.cpp48
-rw-r--r--src/xmpp/xmpp_component.hpp9
9 files changed, 67 insertions, 75 deletions
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp
index 7f245db..fb3afc7 100644
--- a/src/bridge/bridge.cpp
+++ b/src/bridge/bridge.cpp
@@ -189,14 +189,18 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho
void Bridge::send_user_join(const std::string& hostname,
const std::string& chan_name,
- const IrcUser* user)
+ const IrcUser* user,
+ const bool self)
{
- this->xmpp->send_user_join(chan_name + "%" + hostname, user->nick, user->host, this->user_jid);
-}
-
-void Bridge::send_self_join(const std::string& hostname, const std::string& chan_name, const std::string nick)
-{
- this->xmpp->send_self_join(chan_name + "%" + hostname, nick, this->user_jid);
+ std::string affiliation = "participant";
+ std::string role = "none";
+ if (user->modes.find('o') != user->modes.end())
+ {
+ affiliation = "admin";
+ role = "moderator";
+ }
+ this->xmpp->send_user_join(chan_name + "%" + hostname, user->nick, user->host,
+ affiliation, role, this->user_jid, self);
}
void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string topic)
diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp
index b5bee9e..a4eeaa4 100644
--- a/src/bridge/bridge.hpp
+++ b/src/bridge/bridge.hpp
@@ -66,11 +66,8 @@ public:
*/
void send_user_join(const std::string& hostname,
const std::string& chan_name,
- const IrcUser* user);
- /**
- * Send the self presence of an user when the MUC is fully joined.
- */
- void send_self_join(const std::string& hostname, const std::string& chan_name, const std::string nick);
+ const IrcUser* user,
+ const bool self);
/**
* Send the topic of the MUC to the user
*/
diff --git a/src/irc/irc_channel.cpp b/src/irc/irc_channel.cpp
index 6daf708..80e9b24 100644
--- a/src/irc/irc_channel.cpp
+++ b/src/irc/irc_channel.cpp
@@ -12,9 +12,10 @@ void IrcChannel::set_self(const std::string& name)
this->self = std::make_unique<IrcUser>(name);
}
-IrcUser* IrcChannel::add_user(const std::string& name)
+IrcUser* IrcChannel::add_user(const std::string& name,
+ const std::map<char, char> prefix_to_mode)
{
- this->users.emplace_back(std::make_unique<IrcUser>(name));
+ this->users.emplace_back(std::make_unique<IrcUser>(name, prefix_to_mode));
return this->users.back().get();
}
diff --git a/src/irc/irc_channel.hpp b/src/irc/irc_channel.hpp
index c4b6d2c..edb779a 100644
--- a/src/irc/irc_channel.hpp
+++ b/src/irc/irc_channel.hpp
@@ -5,6 +5,7 @@
#include <memory>
#include <string>
#include <vector>
+#include <map>
/**
* Keep the state of a joined channel (the list of occupants with their
@@ -19,7 +20,8 @@ public:
std::string topic;
void set_self(const std::string& name);
IrcUser* get_self() const;
- IrcUser* add_user(const std::string& name);
+ IrcUser* add_user(const std::string& name,
+ const std::map<char, char> prefix_to_mode);
IrcUser* find_user(const std::string& name);
void remove_user(const IrcUser* user);
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index 912ee45..cdda2b5 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -235,11 +235,16 @@ void IrcClient::set_and_forward_user_list(const IrcMessage& message)
std::vector<std::string> nicks = utils::split(message.arguments[3], ' ');
for (const std::string& nick: nicks)
{
- const IrcUser* user = channel->add_user(nick);
+ const IrcUser* user = channel->add_user(nick, this->prefix_to_mode);
if (user->nick != channel->get_self()->nick)
{
log_debug("Adding user [" << nick << "] to chan " << chan_name);
- this->bridge->send_user_join(this->hostname, chan_name, user);
+ this->bridge->send_user_join(this->hostname, chan_name, user, false);
+ }
+ else
+ {
+ // we now know the modes of self, so copy the modes into self
+ channel->get_self()->modes = user->modes;
}
}
}
@@ -256,8 +261,8 @@ void IrcClient::on_channel_join(const IrcMessage& message)
}
else
{
- const IrcUser* user = channel->add_user(nick);
- this->bridge->send_user_join(this->hostname, chan_name, user);
+ const IrcUser* user = channel->add_user(nick, this->prefix_to_mode);
+ this->bridge->send_user_join(this->hostname, chan_name, user, false);
}
}
@@ -319,7 +324,7 @@ void IrcClient::on_channel_completely_joined(const IrcMessage& message)
{
const std::string chan_name = utils::tolower(message.arguments[1]);
IrcChannel* channel = this->get_channel(chan_name);
- this->bridge->send_self_join(this->hostname, chan_name, channel->get_self()->nick);
+ this->bridge->send_user_join(this->hostname, chan_name, channel->get_self(), true);
this->bridge->send_topic(this->hostname, chan_name, channel->topic);
}
diff --git a/src/irc/irc_user.cpp b/src/irc/irc_user.cpp
index f9866ef..934988a 100644
--- a/src/irc/irc_user.cpp
+++ b/src/irc/irc_user.cpp
@@ -2,26 +2,26 @@
#include <iostream>
-IrcUser::IrcUser(const std::string& name)
+IrcUser::IrcUser(const std::string& name,
+ const std::map<char, char>& prefix_to_mode)
{
+ if (name.empty())
+ return ;
const std::string::size_type sep = name.find("!");
+ const std::map<char, char>::const_iterator prefix = prefix_to_mode.find(name[0]);
+ const size_t name_begin = prefix == prefix_to_mode.end()? 0: 1;
if (sep == std::string::npos)
- {
- if (name[0] == '~' || name[0] == '&'
- || name[0] == '@' || name[0] == '%'
- || name[0] == '+')
- this->nick = name.substr(1);
- else
- this->nick = name;
- }
+ this->nick = name.substr(name_begin);
else
{
- if (name[0] == '~' || name[0] == '&'
- || name[0] == '@' || name[0] == '%'
- || name[0] == '+')
- this->nick = name.substr(1, sep);
- else
- this->nick = name.substr(0, sep);
+ this->nick = name.substr(name_begin, sep);
this->host = name.substr(sep+1);
}
+ if (prefix != prefix_to_mode.end())
+ this->modes.insert(prefix->second);
+}
+
+IrcUser::IrcUser(const std::string& name):
+ IrcUser(name, {})
+{
}
diff --git a/src/irc/irc_user.hpp b/src/irc/irc_user.hpp
index b76b2ef..f30da4d 100644
--- a/src/irc/irc_user.hpp
+++ b/src/irc/irc_user.hpp
@@ -2,6 +2,8 @@
# define IRC_USER_INCLUDED
#include <string>
+#include <map>
+#include <set>
/**
* Keeps various information about one IRC channel user
@@ -9,10 +11,12 @@
class IrcUser
{
public:
+ explicit IrcUser(const std::string& name,
+ const std::map<char, char>& prefix_to_mode);
explicit IrcUser(const std::string& name);
-
std::string nick;
std::string host;
+ std::set<char> modes;
private:
IrcUser(const IrcUser&) = delete;
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 1cc4c25..f0d1d3a 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -294,7 +294,10 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con
void XmppComponent::send_user_join(const std::string& from,
const std::string& nick,
const std::string& realjid,
- const std::string& to)
+ const std::string& affiliation,
+ const std::string& role,
+ const std::string& to,
+ const bool self)
{
XmlNode node("presence");
node["to"] = to;
@@ -305,8 +308,8 @@ void XmppComponent::send_user_join(const std::string& from,
// TODO: put real values here
XmlNode item("item");
- item["affiliation"] = "member";
- item["role"] = "participant";
+ item["affiliation"] = affiliation;
+ item["role"] = role;
if (!realjid.empty())
{
const std::string preped_jid = jidprep(realjid);
@@ -315,35 +318,15 @@ void XmppComponent::send_user_join(const std::string& from,
}
item.close();
x.add_child(std::move(item));
- x.close();
- node.add_child(std::move(x));
- node.close();
- this->send_stanza(node);
-}
-
-void XmppComponent::send_self_join(const std::string& from, const std::string& nick, const std::string& to)
-{
- XmlNode node("presence");
- node["to"] = to;
- node["from"] = from + "@" + this->served_hostname + "/" + nick;
-
- XmlNode x("x");
- x["xmlns"] = MUC_USER_NS;
-
- // TODO: put real values here
- XmlNode item("item");
- item["affiliation"] = "member";
- item["role"] = "participant";
- item.close();
- x.add_child(std::move(item));
-
- XmlNode status("status");
- status["code"] = "110";
- status.close();
- x.add_child(std::move(status));
+ if (self)
+ {
+ XmlNode status("status");
+ status["code"] = "110";
+ status.close();
+ x.add_child(std::move(status));
+ }
x.close();
-
node.add_child(std::move(x));
node.close();
this->send_stanza(node);
@@ -438,10 +421,7 @@ void XmppComponent::send_nick_change(const std::string& muc_name, const std::str
presence.close();
this->send_stanza(presence);
- if (self)
- this->send_self_join(muc_name, new_nick, jid_to);
- else
- this->send_user_join(muc_name, new_nick, "", jid_to);
+ this->send_user_join(muc_name, new_nick, "", "participant", "none", jid_to, self);
}
void XmppComponent::kick_user(const std::string& muc_name,
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 63eb88f..c10f10a 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -78,11 +78,10 @@ public:
void send_user_join(const std::string& from,
const std::string& nick,
const std::string& realjid,
- const std::string& to);
- /**
- * Send the self join to the user
- */
- void send_self_join(const std::string& from, const std::string& nick, const std::string& to);
+ const std::string& affiliation,
+ const std::string& role,
+ const std::string& to,
+ const bool self);
/**
* Send the MUC topic to the user
*/