changeset 227:7a6553094512

Irccd: use two separate list of channels (requested/joined) Ref T2
author David Demelier <markand@malikania.fr>
date Mon, 18 Jul 2016 13:34:18 +0200
parents 127142e02526
children e754e79ca152
files lib/irccd/mod-server.cpp lib/irccd/server.cpp lib/irccd/server.hpp
diffstat 3 files changed, 50 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/mod-server.cpp	Fri Jul 15 10:54:56 2016 +0200
+++ b/lib/irccd/mod-server.cpp	Mon Jul 18 13:34:18 2016 +0200
@@ -119,8 +119,8 @@
     duk_put_prop_string(ctx, -2, "nickname");
     dukx_push_std_string(ctx, server->username());
     duk_put_prop_string(ctx, -2, "username");
-    dukx_push_array(ctx, server->channels(), [] (auto ctx, auto channel) {
-        dukx_push_std_string(ctx, channel.name);
+    dukx_push_array(ctx, server->channels(), [&] (auto ctx, auto channel) {
+        dukx_push_std_string(ctx, channel);
     });
     duk_put_prop_string(ctx, -2, "channels");
 
--- a/lib/irccd/server.cpp	Fri Jul 15 10:54:56 2016 +0200
+++ b/lib/irccd/server.cpp	Mon Jul 18 13:34:18 2016 +0200
@@ -112,6 +112,11 @@
 
 } // !namespace
 
+void Server::removeJoinedChannel(const std::string &channel)
+{
+    m_jchannels.erase(std::remove(m_jchannels.begin(), m_jchannels.end(), channel), m_jchannels.end());
+}
+
 void Server::handleConnect(const char *, const char **) noexcept
 {
     // Reset the number of tried reconnection.
@@ -120,12 +125,15 @@
     // Reset the timer.
     m_cache.pingTimer.reset();
 
+    // Reset joined channels.
+    m_jchannels.clear();
+
     // Don't forget to change state and notify.
     next(std::make_unique<ConnectedState>());
     onConnect(ConnectEvent{shared_from_this()});
 
     // Auto join listed channels.
-    for (const Channel &channel : m_channels) {
+    for (const auto &channel : m_rchannels) {
         log::info() << "server " << m_name << ": auto joining " << channel.name << std::endl;
         join(channel.name, channel.password);
     }
@@ -167,14 +175,22 @@
 
 void Server::handleJoin(const char *orig, const char **params) noexcept
 {
+    if (isSelf(strify(orig)))
+        m_jchannels.push_back(strify(params[0]));
+
     onJoin(JoinEvent{shared_from_this(), strify(orig), strify(params[0])});
 }
 
 void Server::handleKick(const char *orig, const char **params) noexcept
 {
-    // Rejoin the channel if the option has been set and I was kicked.
-    if ((m_flags & AutoRejoin) && isSelf(strify(params[1])))
-        join(strify(params[0]));
+    if (isSelf(strify(params[1]))) {
+        // Remove the channel from the joined list.
+        removeJoinedChannel(strify(params[0]));
+
+        // Rejoin the channel if the option has been set and I was kicked.
+        if (m_flags & AutoRejoin)
+            join(strify(params[0]));
+    }
 
     onKick(KickEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1]), strify(params[2])});
 }
@@ -311,6 +327,10 @@
 
 void Server::handlePart(const char *orig, const char **params) noexcept
 {
+    // Remove the channel from the joined list if I left a channel.
+    if (isSelf(strify(orig)))
+        removeJoinedChannel(strify(params[0]));
+
     onPart(PartEvent{shared_from_this(), strify(orig), strify(params[0]), strify(params[1])});
 }
 
@@ -474,6 +494,9 @@
 
         m_state = std::move(m_stateNext);
         m_stateNext = nullptr;
+
+        // Reset channels.
+        m_jchannels.clear();
     }
 }
 
@@ -544,14 +567,19 @@
 
 void Server::join(std::string channel, std::string password)
 {
-    if (m_session->isConnected())
-        m_queue.push([=] () {
-            const char *ptr = password.empty() ? nullptr : password.c_str();
+    // 1. Add the channel or update it to the requested channels.
+    auto it = std::find_if(m_rchannels.begin(), m_rchannels.end(), [&] (const auto &c) {
+        return c.name == channel;
+    });
 
-            return irc_cmd_join(*m_session, channel.c_str(), ptr) == 0;
-        });
+    if (it == m_rchannels.end())
+        m_rchannels.push_back({ channel, password });
     else
-        m_channels.push_back({ std::move(channel), std::move(password) });
+        *it = { channel, password };
+
+    // 2. Join if not found and connected.
+    if (m_session->isConnected())
+        irc_cmd_join(*m_session, channel.c_str(), password.empty() ? nullptr : password.c_str());
 }
 
 void Server::kick(std::string target, std::string channel, std::string reason)
--- a/lib/irccd/server.hpp	Fri Jul 15 10:54:56 2016 +0200
+++ b/lib/irccd/server.hpp	Mon Jul 18 13:34:18 2016 +0200
@@ -434,9 +434,13 @@
     Signal<WhoisEvent> onWhois;
 
 private:
-    // Misc
+    // Misc.
     std::map<ChannelMode, char> m_modes;
 
+    // Requested and joined channels.
+    std::vector<Channel> m_rchannels;
+    std::vector<std::string> m_jchannels;
+
     // Identifier.
     std::string m_name;
 
@@ -458,9 +462,6 @@
     std::uint16_t m_reconnectDelay{30};
     std::uint16_t m_pingTimeout{300};
 
-    // Various settings.
-    std::vector<Channel> m_channels;
-
     // TODO: find another way.
     Cache m_cache;
 
@@ -474,6 +475,9 @@
     std::unique_ptr<State> m_state;
     std::unique_ptr<State> m_stateNext;
 
+    // Private helpers.
+    void removeJoinedChannel(const std::string &channel);
+
     // Handle libircclient callbacks.
     void handleChannel(const char *, const char **) noexcept;
     void handleChannelMode(const char *, const char **) noexcept;
@@ -787,9 +791,9 @@
      *
      * \return the channels
      */
-    inline const std::vector<Channel> &channels() const noexcept
+    inline const std::vector<std::string> &channels() const noexcept
     {
-        return m_channels;
+        return m_jchannels;
     }
 
     /**