-NetworkInfo::NetworkInfo()
- : networkId(0),
- identity(1),
- useRandomServer(false),
- useAutoIdentify(false),
- autoIdentifyService("NickServ"),
- useSasl(false),
- useAutoReconnect(true),
- autoReconnectInterval(60),
- autoReconnectRetries(20),
- unlimitedReconnectRetries(false),
- rejoinChannels(true)
-{
-}
-
-
-bool NetworkInfo::operator==(const NetworkInfo &other) const
-{
- if (networkId != other.networkId) return false;
- if (networkName != other.networkName) return false;
- if (identity != other.identity) return false;
- if (codecForServer != other.codecForServer) return false;
- if (codecForEncoding != other.codecForEncoding) return false;
- if (codecForDecoding != other.codecForDecoding) return false;
- if (serverList != other.serverList) return false;
- if (useRandomServer != other.useRandomServer) return false;
- if (perform != other.perform) return false;
- if (useAutoIdentify != other.useAutoIdentify) return false;
- if (autoIdentifyService != other.autoIdentifyService) return false;
- if (autoIdentifyPassword != other.autoIdentifyPassword) return false;
- if (useSasl != other.useSasl) return false;
- if (saslAccount != other.saslAccount) return false;
- if (saslPassword != other.saslPassword) return false;
- if (useAutoReconnect != other.useAutoReconnect) return false;
- if (autoReconnectInterval != other.autoReconnectInterval) return false;
- if (autoReconnectRetries != other.autoReconnectRetries) return false;
- if (unlimitedReconnectRetries != other.unlimitedReconnectRetries) return false;
- if (rejoinChannels != other.rejoinChannels) return false;
- return true;
-}
-
-
-bool NetworkInfo::operator!=(const NetworkInfo &other) const
+QString NetworkInfo::skipCapsToString() const {
+ // Sort the list of capabilities when rendering to a string. This isn't required as
+ // Network::setSkipCaps() will sort as well, but this looks nicer when displayed to the user.
+ // This also results in the list being sorted before storing in the database, too.
+ auto sortedSkipCaps = skipCaps;
+ sortedSkipCaps.sort();
+
+ // IRCv3 capabilities are transmitted space-separated, so it should be safe to assume spaces
+ // won't ever be inside them
+ //
+ // See https://ircv3.net/specs/core/capability-negotiation
+ return sortedSkipCaps.join(" ");
+}
+
+void NetworkInfo::skipCapsFromString(const QString& flattenedSkipCaps) {
+ // IRCv3 capabilities should all use lowercase capability names, though it's not strictly
+ // required by the specification. Quassel currently converts all caps to lowercase before doing
+ // any comparisons.
+ //
+ // This would only become an issue if two capabilities have the same name and only differ by
+ // case, or if an IRC server transmits an uppercase capability and compares case-sensitively.
+ //
+ // (QString::toLower() is always done in the C locale, so locale-dependent case-sensitivity
+ // won't ever be an issue, thankfully.)
+ //
+ // See Network::addCap(), Network::acknowledgeCap(), and friends
+ // And https://ircv3.net/specs/core/capability-negotiation
+ skipCaps = flattenedSkipCaps.toLower().split(" ", QString::SplitBehavior::SkipEmptyParts);
+}
+
+bool NetworkInfo::operator==(const NetworkInfo& other) const
+{
+ return networkName == other.networkName
+ && serverList == other.serverList
+ && perform == other.perform
+ && skipCaps == other.skipCaps
+ && autoIdentifyService == other.autoIdentifyService
+ && autoIdentifyPassword == other.autoIdentifyPassword
+ && saslAccount == other.saslAccount
+ && saslPassword == other.saslPassword
+ && codecForServer == other.codecForServer
+ && codecForEncoding == other.codecForEncoding
+ && codecForDecoding == other.codecForDecoding
+ && networkId == other.networkId
+ && identity == other.identity
+ && messageRateBurstSize == other.messageRateBurstSize
+ && messageRateDelay == other.messageRateDelay
+ && autoReconnectInterval == other.autoReconnectInterval
+ && autoReconnectRetries == other.autoReconnectRetries
+ && rejoinChannels == other.rejoinChannels
+ && useRandomServer == other.useRandomServer
+ && useAutoIdentify == other.useAutoIdentify
+ && useSasl == other.useSasl
+ && useAutoReconnect == other.useAutoReconnect
+ && unlimitedReconnectRetries == other.unlimitedReconnectRetries
+ && useCustomMessageRate == other.useCustomMessageRate
+ && unlimitedMessageRate == other.unlimitedMessageRate
+ ;
+}
+
+bool NetworkInfo::operator!=(const NetworkInfo& other) const