Handle IRCv3 servers without any capabilities
[quassel.git] / src / core / corenetwork.h
index 74540be..2bf57d6 100644 (file)
@@ -130,6 +130,14 @@ public:
      */
     void beginCapNegotiation();
 
+    /**
+     * Ends capability negotiation.
+     *
+     * This won't have effect if other CAP commands are in the command queue before calling this
+     * command.  It should only be called when capability negotiation is complete.
+     */
+    void endCapNegotiation();
+
     /**
      * List of capabilities requiring further core<->server messages to configure.
      *
@@ -156,12 +164,78 @@ public slots:
     void setPingInterval(int interval);
 
     void connectToIrc(bool reconnecting = false);
-    void disconnectFromIrc(bool requested = true, const QString &reason = QString(), bool withReconnect = false);
+    /**
+     * Disconnect from the IRC server.
+     *
+     * Begin disconnecting from the IRC server, including optionally reconnecting.
+     *
+     * @param requested       If true, user requested this disconnect; don't try to reconnect
+     * @param reason          Reason for quitting, defaulting to the user-configured quit reason
+     * @param withReconnect   Reconnect to the network after disconnecting (e.g. ping timeout)
+     * @param forceImmediate  Immediately disconnect from network, skipping queue of other commands
+     */
+    void disconnectFromIrc(bool requested = true, const QString &reason = QString(),
+                           bool withReconnect = false, bool forceImmediate = false);
+
+    /**
+     * Forcibly close the IRC server socket, waiting for it to close.
+     *
+     * Call CoreNetwork::disconnectFromIrc() first, allow the event loop to run, then if you need to
+     * be sure the network's disconencted (e.g. clean-up), call this.
+     *
+     * @param msecs  Maximum time to wait for socket to close, in milliseconds.
+     * @return True if socket closes successfully; false if error occurs or timeout reached
+     */
+    bool forceDisconnect(int msecs = 1000);
 
     void userInput(BufferInfo bufferInfo, QString msg);
-    void putRawLine(QByteArray input);
-    void putCmd(const QString &cmd, const QList<QByteArray> &params, const QByteArray &prefix = QByteArray());
-    void putCmd(const QString &cmd, const QList<QList<QByteArray>> &params, const QByteArray &prefix = QByteArray());
+
+    /**
+     * Sends the raw (encoded) line, adding to the queue if needed, optionally with higher priority.
+     *
+     * @param[in] input   QByteArray of encoded characters
+     * @param[in] prepend
+     * @parmblock
+     * If true, the line is prepended into the start of the queue, otherwise, it's appended to the
+     * end.  This should be used sparingly, for if either the core or the IRC server cannot maintain
+     * PING/PONG replies, the other side will close the connection.
+     * @endparmblock
+     */
+    void putRawLine(const QByteArray input, const bool prepend = false);
+
+    /**
+     * Sends the command with encoded parameters, with optional prefix or high priority.
+     *
+     * @param[in] cmd      Command to send, ignoring capitalization
+     * @param[in] params   Parameters for the command, encoded within a QByteArray
+     * @param[in] prefix   Optional command prefix
+     * @param[in] prepend
+     * @parmblock
+     * If true, the command is prepended into the start of the queue, otherwise, it's appended to
+     * the end.  This should be used sparingly, for if either the core or the IRC server cannot
+     * maintain PING/PONG replies, the other side will close the connection.
+     * @endparmblock
+     */
+    void putCmd(const QString &cmd, const QList<QByteArray> &params, const QByteArray &prefix = QByteArray(), const bool prepend = false);
+
+    /**
+     * Sends the command for each set of encoded parameters, with optional prefix or high priority.
+     *
+     * @param[in] cmd         Command to send, ignoring capitalization
+     * @param[in] params
+     * @parmblock
+     * List of parameter lists for the command, encoded within a QByteArray.  The command will be
+     * sent multiple times, once for each set of params stored within the outer list.
+     * @endparmblock
+     * @param[in] prefix      Optional command prefix
+     * @param[in] prependAll
+     * @parmblock
+     * If true, ALL of the commands are prepended into the start of the queue, otherwise, they're
+     * appended to the end.  This should be used sparingly, for if either the core or the IRC server
+     * cannot maintain PING/PONG replies, the other side will close the connection.
+     * @endparmblock
+     */
+    void putCmd(const QString &cmd, const QList<QList<QByteArray>> &params, const QByteArray &prefix = QByteArray(), const bool prependAll = false);
 
     void setChannelJoined(const QString &channel);
     void setChannelParted(const QString &channel);
@@ -317,6 +391,10 @@ private:
     bool _quitRequested;
     QString _quitReason;
 
+    bool _disconnectExpected;  /// If true, connection is quitting, expect a socket close
+    // This avoids logging a spurious RemoteHostClosedError whenever disconnect is called without
+    // specifying a permanent (saved to core session) disconnect.
+
     bool _previousConnectionAttemptFailed;
     int _lastUsedServerIndex;