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:
+11
-7
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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, {})
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
+15
-35
@@ -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,40 +318,20 @@ 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));
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
XmlNode status("status");
|
||||||
|
status["code"] = "110";
|
||||||
|
status.close();
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
x.close();
|
|
||||||
|
|
||||||
node.add_child(std::move(x));
|
|
||||||
node.close();
|
|
||||||
this->send_stanza(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to)
|
void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to)
|
||||||
{
|
{
|
||||||
XmlNode message("message");
|
XmlNode message("message");
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user