From acf769d83a40e971ccc1346225688841465b36ee Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 29 Dec 2013 19:57:43 +0100 Subject: Use isupport informations to know the user modes when joining Also remove the duplicate send_self_join methods, user only send_user_join --- src/bridge/bridge.cpp | 18 ++++++++++------- src/bridge/bridge.hpp | 7 ++----- src/irc/irc_channel.cpp | 5 +++-- src/irc/irc_channel.hpp | 4 +++- src/irc/irc_client.cpp | 15 +++++++++----- src/irc/irc_user.cpp | 30 ++++++++++++++-------------- src/irc/irc_user.hpp | 6 +++++- src/xmpp/xmpp_component.cpp | 48 +++++++++++++-------------------------------- src/xmpp/xmpp_component.hpp | 9 ++++----- 9 files changed, 67 insertions(+), 75 deletions(-) (limited to 'src') 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(name); } -IrcUser* IrcChannel::add_user(const std::string& name) +IrcUser* IrcChannel::add_user(const std::string& name, + const std::map prefix_to_mode) { - this->users.emplace_back(std::make_unique(name)); + this->users.emplace_back(std::make_unique(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 #include #include +#include /** * 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 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 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 -IrcUser::IrcUser(const std::string& name) +IrcUser::IrcUser(const std::string& name, + const std::map& prefix_to_mode) { + if (name.empty()) + return ; const std::string::size_type sep = name.find("!"); + const std::map::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 +#include +#include /** * Keeps various information about one IRC channel user @@ -9,10 +11,12 @@ class IrcUser { public: + explicit IrcUser(const std::string& name, + const std::map& prefix_to_mode); explicit IrcUser(const std::string& name); - std::string nick; std::string host; + std::set 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 */ -- cgit v1.2.3