core: Remove away-notify hack for non-spec server
authorShane Synan <digitalcircuit36939@gmail.com>
Fri, 14 Sep 2018 19:54:31 +0000 (14:54 -0500)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 16 Sep 2018 20:37:47 +0000 (22:37 +0200)
Remove the AutoWho-on-JOIN hack for IRC servers that do not fully
comply with the "away-notify" spec by not sending ":AWAY :message"
when a user marked /away joins a channel.

Advantages:
* Less network traffic (no WHO for every nickname that joins)
* Less likely to expose other bugs where an IRC server returns
  something unexpected causing auto-who output to go in the status
  buffer

Disadvantages:
* On non-compliant IRC servers, Quassel will no longer accurately
  know the away status of someone that joins a channel while /away
* On IRC servers that implement "away-notify" but not
  "extended-join", Quassel will no longer learn the logged-in account
  and realname for someone that joins a channel
  (This will break showing realname, fallback avatar fetching)

Remove all functions related to automatic nickname WHO'ng as they are
no longer needed.  Leaving them in wouldn't cause any issues other
than unnecessary work and code clutter.

Add a comment pointing to this commit in case someone decides to
resurrect this workaround.

See https://ircv3.net/specs/extensions/away-notify-3.1.html
And https://bugs.unrealircd.org/view.php?id=5144

src/core/corenetwork.cpp
src/core/corenetwork.h
src/core/coresessioneventprocessor.cpp

index 2b73969..e0be7e6 100644 (file)
@@ -1322,16 +1322,6 @@ void CoreNetwork::queueAutoWhoOneshot(const QString &name)
 }
 
 
-void CoreNetwork::cancelAutoWhoOneshot(const QString &name)
-{
-    // Remove channel/nick from queue if it exists
-    _autoWhoQueue.removeAll(name);
-
-    // The AutoWho timer will detect if the queue is empty and automatically stop, no need to
-    // manually control it.
-}
-
-
 void CoreNetwork::setAutoWhoDelay(int delay)
 {
     _autoWhoTimer.setInterval(delay * 1000);
index 740430c..3efcfca 100644 (file)
@@ -401,18 +401,6 @@ public slots:
      */
     void queueAutoWhoOneshot(const QString &name);
 
-    /**
-     * Removes the given channel/nick from AutoWho queue
-     *
-     * This can avoid needlessly WHO'ng nicknames and channels that are no longer of interest, e.g.
-     * if parting a channel right after joining or if a nick joins then quits.
-     *
-     * For when a periodic channel AutoWho finishes, see CoreNetwork::setAutoWhoDone()
-     *
-     * @param name Channel or nickname
-     */
-    void cancelAutoWhoOneshot(const QString &name);
-
     /**
      * Checks if the given target has an automatic WHO in progress, and sets it as done if so
      *
index defee98..04233f3 100644 (file)
@@ -402,11 +402,16 @@ void CoreSessionEventProcessor::processIrcEventJoin(IrcEvent *e)
             break;
     }
 
-    // If using away-notify, check new users.  Works around buggy IRC servers
-    // forgetting to send :away messages for users who join channels when away.
-    if (net->capEnabled(IrcCap::AWAY_NOTIFY)) {
-        net->queueAutoWhoOneshot(ircuser->nick());
-    }
+    // With "away-notify" enabled, some IRC servers forget to send :away messages for users who join
+    // channels while away.  Unfortunately, working around this involves WHO'ng every single user as
+    // they join, which is not very efficient.  If at all possible, it's better to get the issue
+    // fixed in the IRC server instead.
+    //
+    // If pursuing a workaround instead, this is where you'd do it.  Check the version control
+    // history for the commit that added this comment to see how to implement it - there's some
+    // unexpected situations to watch out for!
+    //
+    // See https://ircv3.net/specs/extensions/away-notify-3.1.html
 
     if (!handledByNetsplit)
         ircuser->joinChannel(channel);
@@ -753,10 +758,6 @@ void CoreSessionEventProcessor::lateProcessIrcEventQuit(IrcEvent *e)
     if (!ircuser)
         return;
 
-    // Clear the user from the AutoWho queue if in it
-    // This avoids needlessly checking a user that quickly joins then parts
-    coreNetwork(e)->cancelAutoWhoOneshot(ircuser->nick());
-
     ircuser->quit();
 }
 
@@ -1138,9 +1139,7 @@ void CoreSessionEventProcessor::processIrcEvent352(IrcEvent *e)
         return;
 
     QString channel = e->params()[0];
-    // Store the nick separate from ircuser for AutoWho check below
-    QString nick = e->params()[4];
-    IrcUser *ircuser = e->network()->ircUser(nick);
+    IrcUser *ircuser = e->network()->ircUser(e->params()[4]);
     if (ircuser) {
         // Only process the WHO information if an IRC user exists.  Don't create an IRC user here;
         // there's no way to track when the user quits, which would leave a phantom IrcUser lying
@@ -1152,10 +1151,7 @@ void CoreSessionEventProcessor::processIrcEvent352(IrcEvent *e)
     }
 
     // Check if channel name has a who in progress.
-    // If not, then check if user nickname has a who in progress.  Use nick directly; don't use
-    // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received).
-    if (coreNetwork(e)->isAutoWhoInProgress(channel) ||
-        (coreNetwork(e)->isAutoWhoInProgress(nick))) {
+    if (coreNetwork(e)->isAutoWhoInProgress(channel)) {
         e->setFlag(EventManager::Silent);
     }
 }
@@ -1242,8 +1238,7 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e)
         return;
 
     QString channel = e->params()[1];
-    QString nick = e->params()[5];
-    IrcUser *ircuser = e->network()->ircUser(nick);
+    IrcUser *ircuser = e->network()->ircUser(e->params()[5]);
     if (ircuser) {
         // Only process the WHO information if an IRC user exists.  Don't create an IRC user here;
         // there's no way to track when the user quits, which would leave a phantom IrcUser lying
@@ -1267,10 +1262,7 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e)
     }
 
     // Check if channel name has a who in progress.
-    // If not, then check if user nickname has a who in progress.  Use nick directly; don't use
-    // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received).
-    if (coreNetwork(e)->isAutoWhoInProgress(channel) ||
-        (coreNetwork(e)->isAutoWhoInProgress(nick))) {
+    if (coreNetwork(e)->isAutoWhoInProgress(channel)) {
         e->setFlag(EventManager::Silent);
     }
 }