clazy: Convert many old-style connects into function pointer based
[quassel.git] / src / core / corenetwork.cpp
index 2b73969..e033209 100644 (file)
@@ -33,7 +33,6 @@
 // IRCv3 capabilities
 #include "irccap.h"
 
-INIT_SYNCABLE_OBJECT(CoreNetwork)
 CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session)
     : Network(networkid, session),
     _coreSession(session),
@@ -52,10 +51,10 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session)
     _debugLogRawNetId = Quassel::optionValue("debug-irc-id").toInt();
 
     _autoReconnectTimer.setSingleShot(true);
-    connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout()));
+    connect(&_socketCloseTimer, &QTimer::timeout, this, &CoreNetwork::socketCloseTimeout);
 
     setPingInterval(networkConfig()->pingInterval());
-    connect(&_pingTimer, SIGNAL(timeout()), this, SLOT(sendPing()));
+    connect(&_pingTimer, &QTimer::timeout, this, &CoreNetwork::sendPing);
 
     setAutoWhoDelay(networkConfig()->autoWhoDelay());
     setAutoWhoInterval(networkConfig()->autoWhoInterval());
@@ -70,39 +69,39 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session)
         storeChannelCipherKey(buffer.toLower(), bufferCiphers[buffer]);
     }
 
-    connect(networkConfig(), SIGNAL(pingTimeoutEnabledSet(bool)), SLOT(enablePingTimeout(bool)));
-    connect(networkConfig(), SIGNAL(pingIntervalSet(int)), SLOT(setPingInterval(int)));
-    connect(networkConfig(), SIGNAL(autoWhoEnabledSet(bool)), SLOT(setAutoWhoEnabled(bool)));
-    connect(networkConfig(), SIGNAL(autoWhoIntervalSet(int)), SLOT(setAutoWhoInterval(int)));
-    connect(networkConfig(), SIGNAL(autoWhoDelaySet(int)), SLOT(setAutoWhoDelay(int)));
+    connect(networkConfig(), &NetworkConfig::pingTimeoutEnabledSet, this, &CoreNetwork::enablePingTimeout);
+    connect(networkConfig(), &NetworkConfig::pingIntervalSet, this, &CoreNetwork::setPingInterval);
+    connect(networkConfig(), &NetworkConfig::autoWhoEnabledSet, this, &CoreNetwork::setAutoWhoEnabled);
+    connect(networkConfig(), &NetworkConfig::autoWhoIntervalSet, this, &CoreNetwork::setAutoWhoInterval);
+    connect(networkConfig(), &NetworkConfig::autoWhoDelaySet, this, &CoreNetwork::setAutoWhoDelay);
 
-    connect(&_autoReconnectTimer, SIGNAL(timeout()), this, SLOT(doAutoReconnect()));
-    connect(&_autoWhoTimer, SIGNAL(timeout()), this, SLOT(sendAutoWho()));
-    connect(&_autoWhoCycleTimer, SIGNAL(timeout()), this, SLOT(startAutoWhoCycle()));
-    connect(&_tokenBucketTimer, SIGNAL(timeout()), this, SLOT(checkTokenBucket()));
+    connect(&_autoReconnectTimer, &QTimer::timeout, this, &CoreNetwork::doAutoReconnect);
+    connect(&_autoWhoTimer, &QTimer::timeout, this, &CoreNetwork::sendAutoWho);
+    connect(&_autoWhoCycleTimer, &QTimer::timeout, this, &CoreNetwork::startAutoWhoCycle);
+    connect(&_tokenBucketTimer, &QTimer::timeout, this, &CoreNetwork::checkTokenBucket);
 
     connect(&socket, SIGNAL(connected()), this, SLOT(socketInitialized()));
     connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
-    connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));
-    connect(&socket, SIGNAL(readyRead()), this, SLOT(socketHasData()));
+    connect(&socket, &QAbstractSocket::stateChanged, this, &CoreNetwork::socketStateChanged);
+    connect(&socket, &QIODevice::readyRead, this, &CoreNetwork::socketHasData);
 #ifdef HAVE_SSL
     connect(&socket, SIGNAL(encrypted()), this, SLOT(socketInitialized()));
     connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
 #endif
-    connect(this, SIGNAL(newEvent(Event *)), coreSession()->eventManager(), SLOT(postEvent(Event *)));
+    connect(this, &CoreNetwork::newEvent, coreSession()->eventManager(), &EventManager::postEvent);
 
     // Custom rate limiting
     // These react to the user changing settings in the client
-    connect(this, SIGNAL(useCustomMessageRateSet(bool)), SLOT(updateRateLimiting()));
-    connect(this, SIGNAL(messageRateBurstSizeSet(quint32)), SLOT(updateRateLimiting()));
-    connect(this, SIGNAL(messageRateDelaySet(quint32)), SLOT(updateRateLimiting()));
-    connect(this, SIGNAL(unlimitedMessageRateSet(bool)), SLOT(updateRateLimiting()));
+    connect(this, &Network::useCustomMessageRateSet, this, &CoreNetwork::updateRateLimiting);
+    connect(this, &Network::messageRateBurstSizeSet, this, &CoreNetwork::updateRateLimiting);
+    connect(this, &Network::messageRateDelaySet, this, &CoreNetwork::updateRateLimiting);
+    connect(this, &Network::unlimitedMessageRateSet, this, &CoreNetwork::updateRateLimiting);
 
     // IRCv3 capability handling
     // These react to CAP messages from the server
-    connect(this, SIGNAL(capAdded(QString)), this, SLOT(serverCapAdded(QString)));
-    connect(this, SIGNAL(capAcknowledged(QString)), this, SLOT(serverCapAcknowledged(QString)));
-    connect(this, SIGNAL(capRemoved(QString)), this, SLOT(serverCapRemoved(QString)));
+    connect(this, &Network::capAdded, this, &CoreNetwork::serverCapAdded);
+    connect(this, &Network::capAcknowledged, this, &CoreNetwork::serverCapAcknowledged);
+    connect(this, &Network::capRemoved, this, &CoreNetwork::serverCapRemoved);
 
     if (Quassel::isOptionSet("oidentd")) {
         connect(this, SIGNAL(socketInitialized(const CoreIdentity*, QHostAddress, quint16, QHostAddress, quint16, qint64)),
@@ -122,23 +121,12 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session)
 
 CoreNetwork::~CoreNetwork()
 {
-    // Request a proper disconnect, but don't count as user-requested disconnect
-    if (socketConnected()) {
-        // Only try if the socket's fully connected (not initializing or disconnecting).
-        // Force an immediate disconnect, jumping the command queue.  Ensures the proper QUIT is
-        // shown even if other messages are queued.
-        disconnectFromIrc(false, QString(), false, true);
-        // Process the putCmd events that trigger the quit.  Without this, shutting down the core
-        // results in abrubtly closing the socket rather than sending the QUIT as expected.
-        QCoreApplication::processEvents();
-        // Wait briefly for each network to disconnect.  Sometimes it takes a little while to send.
-        if (!forceDisconnect()) {
-            qWarning() << "Timed out quitting network" << networkName() <<
-                          "(user ID " << userId() << ")";
-        }
+    // Ensure we don't get any more signals from the socket while shutting down
+    disconnect(&socket, nullptr, this, nullptr);
+    if (!forceDisconnect()) {
+        qWarning() << QString{"Could not disconnect from network %1 (network ID: %2, user ID: %3)"}
+                      .arg(networkName()).arg(networkId().toInt()).arg(userId().toInt());
     }
-    disconnect(&socket, 0, this, 0); // this keeps the socket from triggering events during clean up
-    delete _userInputHandler;
 }
 
 
@@ -150,8 +138,10 @@ bool CoreNetwork::forceDisconnect(int msecs)
     }
     // Request a socket-level disconnect if not already happened
     socket.disconnectFromHost();
-    // Return the result of waiting for disconnect; true if successful, otherwise false
-    return socket.waitForDisconnected(msecs);
+    if (socket.state() != QAbstractSocket::UnconnectedState) {
+        return socket.waitForDisconnected(msecs);
+    }
+    return true;
 }
 
 
@@ -197,6 +187,10 @@ QByteArray CoreNetwork::userEncode(const QString &userNick, const QString &strin
 
 void CoreNetwork::connectToIrc(bool reconnecting)
 {
+    if (_shuttingDown) {
+        return;
+    }
+
     if (Core::instance()->identServer()) {
         _socketId = Core::instance()->identServer()->addWaitingSocket();
     }
@@ -287,8 +281,7 @@ void CoreNetwork::connectToIrc(bool reconnecting)
 }
 
 
-void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool withReconnect,
-                                    bool forceImmediate)
+void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool withReconnect)
 {
     // Disconnecting from the network, should expect a socket close or error
     _disconnectExpected = true;
@@ -316,20 +309,38 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool
     displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason));
     if (socket.state() == QAbstractSocket::UnconnectedState) {
         socketDisconnected();
-    } else {
+    }
+    else {
         if (socket.state() == QAbstractSocket::ConnectedState) {
-            userInputHandler()->issueQuit(_quitReason, forceImmediate);
-        } else {
+            // If shutting down, prioritize the QUIT command
+            userInputHandler()->issueQuit(_quitReason, _shuttingDown);
+        }
+        else {
             socket.close();
         }
-        if (requested || withReconnect) {
-            // the irc server has 10 seconds to close the socket
+        if (socket.state() != QAbstractSocket::UnconnectedState) {
+            // Wait for up to 10 seconds for the socket to close cleanly, then it will be forcefully aborted
             _socketCloseTimer.start(10000);
         }
     }
 }
 
 
+void CoreNetwork::socketCloseTimeout()
+{
+    qWarning() << QString{"Timed out quitting network %1 (network ID: %2, user ID: %3)"}
+                  .arg(networkName()).arg(networkId().toInt()).arg(userId().toInt());
+    socket.abort();
+}
+
+
+void CoreNetwork::shutdown()
+{
+    _shuttingDown = true;
+    disconnectFromIrc(false, {}, false);
+}
+
+
 void CoreNetwork::userInput(BufferInfo buf, QString msg)
 {
     userInputHandler()->handleUserInput(buf, msg);
@@ -427,32 +438,32 @@ void CoreNetwork::removeChannelKey(const QString &channel)
 Cipher *CoreNetwork::cipher(const QString &target)
 {
     if (target.isEmpty())
-        return 0;
+        return nullptr;
 
     if (!Cipher::neededFeaturesAvailable())
-        return 0;
+        return nullptr;
 
-    CoreIrcChannel *channel = qobject_cast<CoreIrcChannel *>(ircChannel(target));
+    auto *channel = qobject_cast<CoreIrcChannel *>(ircChannel(target));
     if (channel) {
         return channel->cipher();
     }
-    CoreIrcUser *user = qobject_cast<CoreIrcUser *>(ircUser(target));
+    auto *user = qobject_cast<CoreIrcUser *>(ircUser(target));
     if (user) {
         return user->cipher();
     } else if (!isChannelName(target)) {
         return qobject_cast<CoreIrcUser*>(newIrcUser(target))->cipher();
     }
-    return 0;
+    return nullptr;
 }
 
 
 QByteArray CoreNetwork::cipherKey(const QString &target) const
 {
-    CoreIrcChannel *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
+    auto *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
     if (c)
         return c->cipher()->key();
 
-    CoreIrcUser *u = qobject_cast<CoreIrcUser*>(ircUser(target));
+    auto *u = qobject_cast<CoreIrcUser*>(ircUser(target));
     if (u)
         return u->cipher()->key();
 
@@ -462,14 +473,14 @@ QByteArray CoreNetwork::cipherKey(const QString &target) const
 
 void CoreNetwork::setCipherKey(const QString &target, const QByteArray &key)
 {
-    CoreIrcChannel *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
+    auto *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
     if (c) {
         c->setEncrypted(c->cipher()->setKey(key));
         coreSession()->setBufferCipher(networkId(), target, key);
         return;
     }
 
-    CoreIrcUser *u = qobject_cast<CoreIrcUser*>(ircUser(target));
+    auto *u = qobject_cast<CoreIrcUser*>(ircUser(target));
     if (!u && !isChannelName(target))
         u = qobject_cast<CoreIrcUser*>(newIrcUser(target));
 
@@ -483,10 +494,10 @@ void CoreNetwork::setCipherKey(const QString &target, const QByteArray &key)
 
 bool CoreNetwork::cipherUsesCBC(const QString &target)
 {
-    CoreIrcChannel *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
+    auto *c = qobject_cast<CoreIrcChannel*>(ircChannel(target));
     if (c)
         return c->cipher()->usesCBC();
-    CoreIrcUser *u = qobject_cast<CoreIrcUser*>(ircUser(target));
+    auto *u = qobject_cast<CoreIrcUser*>(ircUser(target));
     if (u)
         return u->cipher()->usesCBC();
 
@@ -728,8 +739,8 @@ void CoreNetwork::sendPerform()
             restoreUserModes();
         }
         else {
-            connect(me_, SIGNAL(userModesSet(QString)), this, SLOT(restoreUserModes()));
-            connect(me_, SIGNAL(userModesAdded(QString)), this, SLOT(restoreUserModes()));
+            connect(me_, &IrcUser::userModesSet, this, &CoreNetwork::restoreUserModes);
+            connect(me_, &IrcUser::userModesAdded, this, &CoreNetwork::restoreUserModes);
         }
     }
 
@@ -763,8 +774,8 @@ void CoreNetwork::restoreUserModes()
     IrcUser *me_ = me();
     Q_ASSERT(me_);
 
-    disconnect(me_, SIGNAL(userModesSet(QString)), this, SLOT(restoreUserModes()));
-    disconnect(me_, SIGNAL(userModesAdded(QString)), this, SLOT(restoreUserModes()));
+    disconnect(me_, &IrcUser::userModesSet, this, &CoreNetwork::restoreUserModes);
+    disconnect(me_, &IrcUser::userModesAdded, this, &CoreNetwork::restoreUserModes);
 
     QString modesDelta = Core::userModes(userId(), networkId());
     QString currentModes = me_->userModes();
@@ -803,20 +814,20 @@ void CoreNetwork::updateIssuedModes(const QString &requestedModes)
     QString removeModes;
     bool addMode = true;
 
-    for (int i = 0; i < requestedModes.length(); i++) {
-        if (requestedModes[i] == '+') {
+    for (auto requestedMode : requestedModes) {
+        if (requestedMode == '+') {
             addMode = true;
             continue;
         }
-        if (requestedModes[i] == '-') {
+        if (requestedMode == '-') {
             addMode = false;
             continue;
         }
         if (addMode) {
-            addModes += requestedModes[i];
+            addModes += requestedMode;
         }
         else {
-            removeModes += requestedModes[i];
+            removeModes += requestedMode;
         }
     }
 
@@ -1322,16 +1333,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);
@@ -1516,6 +1517,9 @@ Network::Server CoreNetwork::usedServer() const
 
 void CoreNetwork::requestConnect() const
 {
+    if (_shuttingDown) {
+        return;
+    }
     if (connectionState() != Disconnected) {
         qWarning() << "Requesting connect while already being connected!";
         return;
@@ -1526,6 +1530,9 @@ void CoreNetwork::requestConnect() const
 
 void CoreNetwork::requestDisconnect() const
 {
+    if (_shuttingDown) {
+        return;
+    }
     if (connectionState() == Disconnected) {
         qWarning() << "Requesting disconnect while not being connected!";
         return;