X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcorenetwork.h;h=d596c5380c17c37be925659c48ade627f7965e11;hp=f0f56257676b8c585ad496839ebaf1d01fa337f1;hb=3966090a1e7093c417560f7ee13ab310215d9ccd;hpb=0a43227b8cd44625f4881cc1545d42c8c8a4876c diff --git a/src/core/corenetwork.h b/src/core/corenetwork.h index f0f56257..d596c538 100644 --- a/src/core/corenetwork.h +++ b/src/core/corenetwork.h @@ -25,6 +25,9 @@ #include "coreircchannel.h" #include "coreircuser.h" +// IRCv3 capabilities +#include "irccap.h" + #include #ifdef HAVE_SSL @@ -102,14 +105,6 @@ public: // IRCv3 capability negotiation - /** - * Checks if a given capability is enabled. - * - * @param[in] capability Name of capability - * @returns True if enabled, otherwise false - */ - inline bool capEnabled(const QString &capability) const { return _capsSupported.contains(capability); } - /** * Checks if capability negotiation is currently ongoing. * @@ -118,75 +113,34 @@ public: inline bool capNegotiationInProgress() const { return !_capsQueued.empty(); } /** - * Gets the value of an enabled or pending capability, e.g. sasl=plain. - * - * @param[in] capability Name of capability - * @returns Value of capability if one was specified, otherwise empty string - */ - QString capValue(const QString &capability) const; - - /** - * Gets the next capability to request, removing it from the queue. + * Queues a capability to be requested. * - * @returns Name of capability to request - */ - QString takeQueuedCap(); - - // Specific capabilities for easy reference - - /** - * Gets the status of the sasl authentication capability. - * - * http://ircv3.net/specs/extensions/sasl-3.2.html - * - * @returns True if SASL authentication is enabled, otherwise false - */ - inline bool useCapSASL() const { return capEnabled("sasl"); } - - /** - * Gets the status of the away-notify capability. - * - * http://ircv3.net/specs/extensions/away-notify-3.1.html - * - * @returns True if away-notify is enabled, otherwise false - */ - inline bool useCapAwayNotify() const { return capEnabled("away-notify"); } - - /** - * Gets the status of the account-notify capability. - * - * http://ircv3.net/specs/extensions/account-notify-3.1.html - * - * @returns True if account-notify is enabled, otherwise false - */ - inline bool useCapAccountNotify() const { return capEnabled("account-notify"); } - - /** - * Gets the status of the extended-join capability. + * Adds to the list of capabilities being requested. If non-empty, CAP REQ messages are sent + * to the IRC server. This may happen at login or if capabilities are announced via CAP NEW. * - * http://ircv3.net/specs/extensions/extended-join-3.1.html - * - * @returns True if extended-join is enabled, otherwise false + * @param[in] capability Name of the capability */ - inline bool useCapExtendedJoin() const { return capEnabled("extended-join"); } + void queueCap(const QString &capability); /** - * Gets the status of the userhost-in-names capability. + * Begins capability negotiation if capabilities are queued, otherwise returns. * - * http://ircv3.net/specs/extensions/userhost-in-names-3.2.html - * - * @returns True if userhost-in-names is enabled, otherwise false + * If any capabilities are queued, this will begin the cycle of taking each capability and + * requesting it. When no capabilities remain, capability negotiation is suitably ended. */ - inline bool useCapUserhostInNames() const { return capEnabled("userhost-in-names"); } + void beginCapNegotiation(); /** - * Gets the status of the multi-prefix capability. + * List of capabilities requiring further core<->server messages to configure. * - * http://ircv3.net/specs/extensions/multi-prefix-3.1.html + * For example, SASL requires the back-and-forth of AUTHENTICATE, so the next capability cannot + * be immediately sent. * - * @returns True if multi-prefix is enabled, otherwise false + * See: http://ircv3.net/specs/extensions/sasl-3.2.html */ - inline bool useCapMultiPrefix() const { return capEnabled("multi-prefix"); } + const QStringList capsRequiringConfiguration = QStringList { + IrcCap::SASL + }; public slots: virtual void setMyNick(const QString &mynick); @@ -202,12 +156,67 @@ 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); void userInput(BufferInfo bufferInfo, QString msg); - void putRawLine(QByteArray input); - void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); - void putCmd(const QString &cmd, const QList> ¶ms, 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 ¶ms, 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> ¶ms, const QByteArray &prefix = QByteArray(), const bool prependAll = false); void setChannelJoined(const QString &channel); void setChannelParted(const QString &channel); @@ -225,40 +234,39 @@ public slots: // IRCv3 capability negotiation (can be connected to signals) /** - * Marks a capability as accepted, providing an optional value. + * Indicates a capability is now available, with optional value in Network::capValue(). * - * Removes it from queue of pending capabilities and triggers any capability-specific - * activation. + * @see Network::addCap() * * @param[in] capability Name of the capability - * @param[in] value - * @parblock - * Optional value of the capability, e.g. sasl=plain. If left empty, will be copied from the - * pending capability. - * @endparblock */ - void addCap(const QString &capability, const QString &value = QString()); + void serverCapAdded(const QString &capability); /** - * Marks a capability as denied. + * Indicates a capability was acknowledged (enabled by the IRC server). * - * Removes it from the queue of pending capabilities and triggers any capability-specific - * deactivation. + * @see Network::acknowledgeCap() * * @param[in] capability Name of the capability */ - void removeCap(const QString &capability); + void serverCapAcknowledged(const QString &capability); /** - * Queues a capability as available but not yet accepted or denied. + * Indicates a capability was removed from the list of available capabilities. * - * Capabilities should be queued when registration pauses for CAP LS for capabilities are only - * requested during login. + * @see Network::removeCap() * * @param[in] capability Name of the capability - * @param[in] value Optional value of the capability, e.g. sasl=plain */ - void queuePendingCap(const QString &capability, const QString &value = QString()); + void serverCapRemoved(const QString &capability); + + /** + * Sends the next capability from the queue. + * + * During nick registration if any capabilities remain queued, this will take the next and + * request it. When no capabilities remain, capability negotiation is ended. + */ + void sendNextCap(); void setAutoWhoEnabled(bool enabled); void setAutoWhoInterval(int interval); @@ -376,11 +384,20 @@ private: QHash _autoWhoPending; QTimer _autoWhoTimer, _autoWhoCycleTimer; - // CAPs may have parameter values + // Maintain a list of CAPs that are being checked; if empty, negotiation finished // See http://ircv3.net/specs/core/capability-negotiation-3.2.html - QStringList _capsQueued; /// Capabilities to be checked - QHash _capsPending; /// Capabilities pending 'CAP ACK' from server - QHash _capsSupported; /// Enabled capabilities that received 'CAP ACK' + QStringList _capsQueued; /// Capabilities to be checked + bool _capNegotiationActive; /// Whether or not full capability negotiation was started + // Avoid displaying repeat "negotiation finished" messages + bool _capInitialNegotiationEnded; /// Whether or not initial capability negotiation finished + // Avoid sending repeat "CAP END" replies when registration is already ended + + /** + * Gets the next capability to request, removing it from the queue. + * + * @returns Name of capability to request + */ + QString takeQueuedCap(); QTimer _tokenBucketTimer; int _messageDelay; // token refill speed in ms