Use isupport informations to know the user modes when joining

Also remove the duplicate send_self_join methods, user only send_user_join
This commit is contained in:
Florent Le Coz
2014-01-04 01:59:36 +01:00
parent a075517824
commit acf769d83a
9 changed files with 68 additions and 76 deletions
+11 -7
View File
@@ -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, void Bridge::send_user_join(const std::string& hostname,
const std::string& chan_name, 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); std::string affiliation = "participant";
} std::string role = "none";
if (user->modes.find('o') != user->modes.end())
void Bridge::send_self_join(const std::string& hostname, const std::string& chan_name, const std::string nick) {
{ affiliation = "admin";
this->xmpp->send_self_join(chan_name + "%" + hostname, nick, this->user_jid); 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) void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string topic)
+2 -5
View File
@@ -66,11 +66,8 @@ public:
*/ */
void send_user_join(const std::string& hostname, void send_user_join(const std::string& hostname,
const std::string& chan_name, const std::string& chan_name,
const IrcUser* user); const IrcUser* user,
/** const bool self);
* 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);
/** /**
* Send the topic of the MUC to the user * Send the topic of the MUC to the user
*/ */
+3 -2
View File
@@ -12,9 +12,10 @@ void IrcChannel::set_self(const std::string& name)
this->self = std::make_unique<IrcUser>(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(); return this->users.back().get();
} }
+3 -1
View File
@@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
/** /**
* Keep the state of a joined channel (the list of occupants with their * Keep the state of a joined channel (the list of occupants with their
@@ -19,7 +20,8 @@ public:
std::string topic; std::string topic;
void set_self(const std::string& name); void set_self(const std::string& name);
IrcUser* get_self() const; 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); IrcUser* find_user(const std::string& name);
void remove_user(const IrcUser* user); void remove_user(const IrcUser* user);
+10 -5
View File
@@ -235,11 +235,16 @@ void IrcClient::set_and_forward_user_list(const IrcMessage& message)
std::vector<std::string> nicks = utils::split(message.arguments[3], ' '); std::vector<std::string> nicks = utils::split(message.arguments[3], ' ');
for (const std::string& nick: nicks) 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) if (user->nick != channel->get_self()->nick)
{ {
log_debug("Adding user [" << nick << "] to chan " << chan_name); 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 else
{ {
const IrcUser* user = channel->add_user(nick); const IrcUser* user = channel->add_user(nick, this->prefix_to_mode);
this->bridge->send_user_join(this->hostname, chan_name, user); 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]); const std::string chan_name = utils::tolower(message.arguments[1]);
IrcChannel* channel = this->get_channel(chan_name); 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); this->bridge->send_topic(this->hostname, chan_name, channel->topic);
} }
+15 -15
View File
@@ -2,26 +2,26 @@
#include <iostream> #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::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 (sep == std::string::npos)
{ this->nick = name.substr(name_begin);
if (name[0] == '~' || name[0] == '&'
|| name[0] == '@' || name[0] == '%'
|| name[0] == '+')
this->nick = name.substr(1);
else
this->nick = name;
}
else else
{ {
if (name[0] == '~' || name[0] == '&' this->nick = name.substr(name_begin, sep);
|| name[0] == '@' || name[0] == '%'
|| name[0] == '+')
this->nick = name.substr(1, sep);
else
this->nick = name.substr(0, sep);
this->host = name.substr(sep+1); 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, {})
{
} }
+5 -1
View File
@@ -2,6 +2,8 @@
# define IRC_USER_INCLUDED # define IRC_USER_INCLUDED
#include <string> #include <string>
#include <map>
#include <set>
/** /**
* Keeps various information about one IRC channel user * Keeps various information about one IRC channel user
@@ -9,10 +11,12 @@
class IrcUser class IrcUser
{ {
public: public:
explicit IrcUser(const std::string& name,
const std::map<char, char>& prefix_to_mode);
explicit IrcUser(const std::string& name); explicit IrcUser(const std::string& name);
std::string nick; std::string nick;
std::string host; std::string host;
std::set<char> modes;
private: private:
IrcUser(const IrcUser&) = delete; IrcUser(const IrcUser&) = delete;
+10 -30
View File
@@ -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, void XmppComponent::send_user_join(const std::string& from,
const std::string& nick, const std::string& nick,
const std::string& realjid, 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"); XmlNode node("presence");
node["to"] = to; node["to"] = to;
@@ -305,8 +308,8 @@ void XmppComponent::send_user_join(const std::string& from,
// TODO: put real values here // TODO: put real values here
XmlNode item("item"); XmlNode item("item");
item["affiliation"] = "member"; item["affiliation"] = affiliation;
item["role"] = "participant"; item["role"] = role;
if (!realjid.empty()) if (!realjid.empty())
{ {
const std::string preped_jid = jidprep(realjid); const std::string preped_jid = jidprep(realjid);
@@ -315,35 +318,15 @@ void XmppComponent::send_user_join(const std::string& from,
} }
item.close(); item.close();
x.add_child(std::move(item)); 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));
if (self)
{
XmlNode status("status"); XmlNode status("status");
status["code"] = "110"; status["code"] = "110";
status.close(); status.close();
x.add_child(std::move(status)); x.add_child(std::move(status));
}
x.close(); x.close();
node.add_child(std::move(x)); node.add_child(std::move(x));
node.close(); node.close();
this->send_stanza(node); this->send_stanza(node);
@@ -438,10 +421,7 @@ void XmppComponent::send_nick_change(const std::string& muc_name, const std::str
presence.close(); presence.close();
this->send_stanza(presence); this->send_stanza(presence);
if (self) this->send_user_join(muc_name, new_nick, "", "participant", "none", jid_to, self);
this->send_self_join(muc_name, new_nick, jid_to);
else
this->send_user_join(muc_name, new_nick, "", jid_to);
} }
void XmppComponent::kick_user(const std::string& muc_name, void XmppComponent::kick_user(const std::string& muc_name,
+4 -5
View File
@@ -78,11 +78,10 @@ public:
void send_user_join(const std::string& from, void send_user_join(const std::string& from,
const std::string& nick, const std::string& nick,
const std::string& realjid, const std::string& realjid,
const std::string& to); const std::string& affiliation,
/** const std::string& role,
* Send the self join to the user const std::string& to,
*/ const bool self);
void send_self_join(const std::string& from, const std::string& nick, const std::string& to);
/** /**
* Send the MUC topic to the user * Send the MUC topic to the user
*/ */