diff options
author | louiz’ <louiz@louiz.org> | 2017-05-18 16:00:32 +0200 |
---|---|---|
committer | louiz’ <louiz@louiz.org> | 2017-05-18 16:12:10 +0200 |
commit | 3079c38d2d6ad418d2591cc7f910c588dfebd279 (patch) | |
tree | 8d4a68c6c3f0e3b0a6932cc5ae96e20a8ca754b5 | |
parent | bb150d587f080af38a74f2420457f1e0b2606a62 (diff) | |
download | biboumi-3079c38d2d6ad418d2591cc7f910c588dfebd279.tar.gz biboumi-3079c38d2d6ad418d2591cc7f910c588dfebd279.tar.bz2 biboumi-3079c38d2d6ad418d2591cc7f910c588dfebd279.tar.xz biboumi-3079c38d2d6ad418d2591cc7f910c588dfebd279.zip |
Refactor the channel::self to point at the existing user
This way, the user is always up to date, instead of being a duplicate out of
sync.
fix #3258
-rw-r--r-- | src/irc/irc_channel.cpp | 24 | ||||
-rw-r--r-- | src/irc/irc_channel.hpp | 5 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 26 |
3 files changed, 34 insertions, 21 deletions
diff --git a/src/irc/irc_channel.cpp b/src/irc/irc_channel.cpp index 40d7f54..53043c7 100644 --- a/src/irc/irc_channel.cpp +++ b/src/irc/irc_channel.cpp @@ -1,21 +1,25 @@ #include <irc/irc_channel.hpp> #include <algorithm> -void IrcChannel::set_self(const std::string& name) +void IrcChannel::set_self(IrcUser* user) { - this->self = std::make_unique<IrcUser>(name); + this->self = user; } 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, prefix_to_mode)); + auto new_user = std::make_unique<IrcUser>(name, prefix_to_mode); + auto old_user = this->find_user(new_user->nick); + if (old_user) + return old_user; + this->users.emplace_back(std::move(new_user)); return this->users.back().get(); } IrcUser* IrcChannel::get_self() const { - return this->self.get(); + return this->self; } IrcUser* IrcChannel::find_user(const std::string& name) const @@ -32,19 +36,27 @@ IrcUser* IrcChannel::find_user(const std::string& name) const void IrcChannel::remove_user(const IrcUser* user) { const auto nick = user->nick; + const bool is_self = (user == this->self); const auto it = std::find_if(this->users.begin(), this->users.end(), [nick](const std::unique_ptr<IrcUser>& u) { return nick == u->nick; }); if (it != this->users.end()) - this->users.erase(it); + { + this->users.erase(it); + if (is_self) + { + this->self = nullptr; + this->joined = false; + } + } } void IrcChannel::remove_all_users() { this->users.clear(); - this->self.reset(); + this->self = nullptr; } DummyIrcChannel::DummyIrcChannel(): diff --git a/src/irc/irc_channel.hpp b/src/irc/irc_channel.hpp index 7c269b9..8f85edb 100644 --- a/src/irc/irc_channel.hpp +++ b/src/irc/irc_channel.hpp @@ -27,7 +27,7 @@ public: bool parting{false}; std::string topic{}; std::string topic_author{}; - void set_self(const std::string& name); + void set_self(IrcUser* user); IrcUser* get_self() const; IrcUser* add_user(const std::string& name, const std::map<char, char>& prefix_to_mode); @@ -38,7 +38,8 @@ public: { return this->users; } protected: - std::unique_ptr<IrcUser> self{}; + // Pointer to one IrcUser stored in users + IrcUser* self{nullptr}; std::vector<std::unique_ptr<IrcUser>> users{}; }; diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index caebb83..0e3926a 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -642,15 +642,18 @@ 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, this->prefix_to_mode); - if (user->nick != channel->get_self()->nick) + // Just create this dummy user to parse and get its modes + IrcUser tmp_user{nick, this->prefix_to_mode}; + // Does this concern ourself + if (channel->get_self() && channel->find_user(tmp_user.nick) == channel->get_self()) { - this->bridge.send_user_join(this->hostname, chan_name, user, user->get_most_significant_mode(this->sorted_user_modes), false); + // We now know our own modes, that’s all. + channel->get_self()->modes = tmp_user.modes; } else - { - // we now know the modes of self, so copy the modes into self - channel->get_self()->modes = user->modes; + { // Otherwise this is a new user + const IrcUser *user = channel->add_user(nick, this->prefix_to_mode); + this->bridge.send_user_join(this->hostname, chan_name, user, user->get_most_significant_mode(this->sorted_user_modes), false); } } } @@ -664,13 +667,11 @@ void IrcClient::on_channel_join(const IrcMessage& message) else channel = this->get_channel(chan_name); const std::string nick = message.prefix; + IrcUser* user = channel->add_user(nick, this->prefix_to_mode); if (channel->joined == false) - channel->set_self(nick); + channel->set_self(user); else - { - const IrcUser* user = channel->add_user(nick, this->prefix_to_mode); - this->bridge.send_user_join(this->hostname, chan_name, user, user->get_most_significant_mode(this->sorted_user_modes), false); - } + this->bridge.send_user_join(this->hostname, chan_name, user, user->get_most_significant_mode(this->sorted_user_modes), false); } void IrcClient::on_channel_message(const IrcMessage& message) @@ -929,15 +930,14 @@ void IrcClient::on_part(const IrcMessage& message) if (user) { std::string nick = user->nick; + bool self = channel->get_self() && channel->get_self()->nick == nick; channel->remove_user(user); Iid iid; iid.set_local(chan_name); iid.set_server(this->hostname); iid.type = Iid::Type::Channel; - bool self = channel->get_self()->nick == nick; if (self) { - channel->joined = false; this->channels.erase(utils::tolower(chan_name)); // channel pointer is now invalid channel = nullptr; |