Handle nick changes, both ways
This commit is contained in:
+28
-2
@@ -59,10 +59,15 @@ IrcClient* Bridge::get_irc_client(const std::string& hostname)
|
||||
}
|
||||
}
|
||||
|
||||
void Bridge::join_irc_channel(const Iid& iid, const std::string& username)
|
||||
bool Bridge::join_irc_channel(const Iid& iid, const std::string& username)
|
||||
{
|
||||
IrcClient* irc = this->get_irc_client(iid.server, username);
|
||||
if (irc->is_channel_joined(iid.chan) == false)
|
||||
{
|
||||
irc->send_join_command(iid.chan);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Bridge::send_channel_message(const Iid& iid, const std::string& body)
|
||||
@@ -103,6 +108,13 @@ void Bridge::leave_irc_channel(Iid&& iid, std::string&& status_message)
|
||||
irc->send_part_command(iid.chan, status_message);
|
||||
}
|
||||
|
||||
void Bridge::send_irc_nick_change(const Iid& iid, const std::string& new_nick)
|
||||
{
|
||||
IrcClient* irc = this->get_irc_client(iid.server);
|
||||
if (irc)
|
||||
irc->send_nick_command(new_nick);
|
||||
}
|
||||
|
||||
void Bridge::send_message(const Iid& iid, const std::string& nick, const std::string& body, const bool muc)
|
||||
{
|
||||
std::string utf8_body = this->sanitize_for_xmpp(body);
|
||||
@@ -118,11 +130,17 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st
|
||||
this->xmpp->send_message(iid.chan + "%" + iid.server, utf8_body, this->user_jid);
|
||||
}
|
||||
|
||||
void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, std::string&& message, const bool self)
|
||||
void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self)
|
||||
{
|
||||
this->xmpp->send_muc_leave(std::move(iid.chan) + "%" + std::move(iid.server), std::move(nick), this->sanitize_for_xmpp(message), this->user_jid, self);
|
||||
}
|
||||
|
||||
void Bridge::send_nick_change(Iid&& iid, const std::string& old_nick, const std::string& new_nick, const bool self)
|
||||
{
|
||||
this->xmpp->send_nick_change(std::move(iid.chan) + "%" + std::move(iid.server),
|
||||
old_nick, new_nick, this->user_jid, self);
|
||||
}
|
||||
|
||||
void Bridge::send_xmpp_message(const std::string& from, const std::string& author, const std::string& msg)
|
||||
{
|
||||
std::string body;
|
||||
@@ -147,3 +165,11 @@ void Bridge::send_topic(const std::string& hostname, const std::string& chan_nam
|
||||
{
|
||||
this->xmpp->send_topic(chan_name + "%" + hostname, this->sanitize_for_xmpp(topic), this->user_jid);
|
||||
}
|
||||
|
||||
std::string Bridge::get_own_nick(const Iid& iid)
|
||||
{
|
||||
IrcClient* irc = this->get_irc_client(iid.server);
|
||||
if (irc)
|
||||
return irc->get_own_nick();
|
||||
return "";
|
||||
}
|
||||
|
||||
+17
-2
@@ -30,10 +30,15 @@ public:
|
||||
**
|
||||
**/
|
||||
|
||||
void join_irc_channel(const Iid& iid, const std::string& username);
|
||||
/**
|
||||
* Try to join an irc_channel, does nothing and return true if the channel
|
||||
* was already joined.
|
||||
*/
|
||||
bool join_irc_channel(const Iid& iid, const std::string& username);
|
||||
void send_channel_message(const Iid& iid, const std::string& body);
|
||||
void send_private_message(const Iid& iid, const std::string& body);
|
||||
void leave_irc_channel(Iid&& iid, std::string&& status_message);
|
||||
void send_irc_nick_change(const Iid& iid, const std::string& new_nick);
|
||||
|
||||
/***
|
||||
**
|
||||
@@ -65,7 +70,17 @@ public:
|
||||
/**
|
||||
* Send an unavailable presence from this participant
|
||||
*/
|
||||
void send_muc_leave(Iid&& iid, std::string&& nick, std::string&& message, const bool self);
|
||||
void send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self);
|
||||
/**
|
||||
* Send presences to indicate that an user old_nick (ourself if self ==
|
||||
* true) changed his nick to new_nick
|
||||
*/
|
||||
void send_nick_change(Iid&& iid, const std::string& old_nick, const std::string& new_nick, const bool self);
|
||||
|
||||
/**
|
||||
* Misc
|
||||
*/
|
||||
std::string get_own_nick(const Iid& iid);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
+37
-4
@@ -53,6 +53,12 @@ IrcChannel* IrcClient::get_channel(const std::string& name)
|
||||
}
|
||||
}
|
||||
|
||||
bool IrcClient::is_channel_joined(const std::string& name)
|
||||
{
|
||||
IrcChannel* client = this->get_channel(name);
|
||||
return client->joined;
|
||||
}
|
||||
|
||||
std::string IrcClient::get_own_nick() const
|
||||
{
|
||||
return this->current_nick;
|
||||
@@ -91,6 +97,8 @@ void IrcClient::parse_in_buffer()
|
||||
this->on_part(message);
|
||||
else if (message.command == "QUIT")
|
||||
this->on_quit(message);
|
||||
else if (message.command == "NICK")
|
||||
this->on_nick(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +136,8 @@ void IrcClient::send_nick_command(const std::string& nick)
|
||||
void IrcClient::send_join_command(const std::string& chan_name)
|
||||
{
|
||||
if (this->welcomed == false)
|
||||
{
|
||||
this->channels_to_join.push_back(chan_name);
|
||||
return ;
|
||||
}
|
||||
else
|
||||
this->send_message(IrcMessage("JOIN", {chan_name}));
|
||||
}
|
||||
|
||||
@@ -288,7 +294,34 @@ void IrcClient::on_quit(const IrcMessage& message)
|
||||
Iid iid;
|
||||
iid.chan = chan_name;
|
||||
iid.server = this->hostname;
|
||||
this->bridge->send_muc_leave(std::move(iid), std::move(nick), std::move(txt), false);
|
||||
this->bridge->send_muc_leave(std::move(iid), std::move(nick), txt, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IrcClient::on_nick(const IrcMessage& message)
|
||||
{
|
||||
const std::string new_nick = message.arguments[0];
|
||||
for (auto it = this->channels.begin(); it != this->channels.end(); ++it)
|
||||
{
|
||||
const std::string chan_name = it->first;
|
||||
IrcChannel* channel = it->second.get();
|
||||
IrcUser* user = channel->find_user(message.prefix);
|
||||
if (user)
|
||||
{
|
||||
std::string old_nick = user->nick;
|
||||
Iid iid;
|
||||
iid.chan = chan_name;
|
||||
iid.server = this->hostname;
|
||||
bool self = channel->get_self()->nick == old_nick;
|
||||
this->bridge->send_nick_change(std::move(iid), old_nick, new_nick, self);
|
||||
user->nick = new_nick;
|
||||
if (self)
|
||||
{
|
||||
channel->get_self()->nick = new_nick;
|
||||
this->current_nick = new_nick;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ public:
|
||||
* Return the channel with this name, create it if it does not yet exist
|
||||
*/
|
||||
IrcChannel* get_channel(const std::string& name);
|
||||
/**
|
||||
* Returns true if the channel is joined
|
||||
*/
|
||||
bool is_channel_joined(const std::string& name);
|
||||
/**
|
||||
* Return our own nick
|
||||
*/
|
||||
@@ -67,7 +71,7 @@ public:
|
||||
*/
|
||||
void send_nick_command(const std::string& username);
|
||||
/**
|
||||
* Send the JOIN irc command
|
||||
* Send the JOIN irc command.
|
||||
*/
|
||||
void send_join_command(const std::string& chan_name);
|
||||
/**
|
||||
@@ -118,6 +122,10 @@ public:
|
||||
* When a PART message is received
|
||||
*/
|
||||
void on_part(const IrcMessage& message);
|
||||
/**
|
||||
* When a NICK message is received
|
||||
*/
|
||||
void on_nick(const IrcMessage& message);
|
||||
/**
|
||||
* When a QUIT message is received
|
||||
*/
|
||||
|
||||
@@ -167,7 +167,13 @@ void XmppComponent::handle_presence(const Stanza& stanza)
|
||||
if (!iid.chan.empty() && !iid.chan.empty())
|
||||
{ // presence toward a MUC that corresponds to an irc channel
|
||||
if (type.empty())
|
||||
{
|
||||
const std::string own_nick = bridge->get_own_nick(iid);
|
||||
if (!own_nick.empty() && own_nick != to.resource)
|
||||
bridge->send_irc_nick_change(iid, to.resource);
|
||||
else
|
||||
bridge->join_irc_channel(iid, to.resource);
|
||||
}
|
||||
else if (type == "unavailable")
|
||||
{
|
||||
XmlNode* status = stanza.get_child(MUC_USER_NS":status");
|
||||
@@ -317,3 +323,37 @@ void XmppComponent::send_muc_leave(std::string&& muc_name, std::string&& nick, s
|
||||
presence.close();
|
||||
this->send_stanza(presence);
|
||||
}
|
||||
|
||||
void XmppComponent::send_nick_change(const std::string& muc_name, const std::string& old_nick, const std::string& new_nick, const std::string& jid_to, const bool self)
|
||||
{
|
||||
Stanza presence("presence");
|
||||
presence["to"] = jid_to;
|
||||
presence["from"] = muc_name + "@" + this->served_hostname + "/" + old_nick;
|
||||
presence["type"] = "unavailable";
|
||||
XmlNode x("x");
|
||||
x["xmlns"] = MUC_USER_NS;
|
||||
XmlNode item("item");
|
||||
item["nick"] = new_nick;
|
||||
item.close();
|
||||
x.add_child(std::move(item));
|
||||
XmlNode status("status");
|
||||
status["code"] = "303";
|
||||
status.close();
|
||||
x.add_child(std::move(status));
|
||||
if (self)
|
||||
{
|
||||
XmlNode status2("status");
|
||||
status2["code"] = "110";
|
||||
status2.close();
|
||||
x.add_child(std::move(status2));
|
||||
}
|
||||
x.close();
|
||||
presence.add_child(std::move(x));
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,10 @@ public:
|
||||
* Send an unavailable presence for this nick
|
||||
*/
|
||||
void send_muc_leave(std::string&& muc_name, std::string&& nick, std::string&& message, const std::string& jid_to, const bool self);
|
||||
/**
|
||||
* Indicate that a participant changed his nick
|
||||
*/
|
||||
void send_nick_change(const std::string& muc_name, const std::string& old_nick, const std::string& new_nick, const std::string& jid_to, const bool self);
|
||||
/**
|
||||
* Handle the various stanza types
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user