tests: Convert ExpressionMatchTests into a GTest-based test case
[quassel.git] / src / common / network.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #pragma once
22
23 #include "common-export.h"
24
25 #include <QString>
26 #include <QStringList>
27 #include <QList>
28 #include <QNetworkProxy>
29 #include <QHash>
30 #include <QVariantMap>
31 #include <QPointer>
32 #include <QMutex>
33 #include <QByteArray>
34 #include <utility>
35
36 #include "types.h"
37 #include "util.h"
38 #include "syncableobject.h"
39
40 #include "signalproxy.h"
41 #include "ircuser.h"
42 #include "ircchannel.h"
43
44 // IRCv3 capabilities
45 #include "irccap.h"
46
47 // defined below!
48 struct NetworkInfo;
49
50 // TODO: ConnectionInfo to propagate and sync the current state of NetworkConnection, encodings etcpp
51
52 class COMMON_EXPORT Network : public SyncableObject
53 {
54     Q_OBJECT
55     SYNCABLE_OBJECT
56
57     Q_ENUMS(ConnectionState)
58
59     Q_PROPERTY(QString networkName READ networkName WRITE setNetworkName)
60     Q_PROPERTY(QString currentServer READ currentServer WRITE setCurrentServer)
61     Q_PROPERTY(QString myNick READ myNick WRITE setMyNick)
62     Q_PROPERTY(int latency READ latency WRITE setLatency)
63     Q_PROPERTY(QByteArray codecForServer READ codecForServer WRITE setCodecForServer)
64     Q_PROPERTY(QByteArray codecForEncoding READ codecForEncoding WRITE setCodecForEncoding)
65     Q_PROPERTY(QByteArray codecForDecoding READ codecForDecoding WRITE setCodecForDecoding)
66     Q_PROPERTY(IdentityId identityId READ identity WRITE setIdentity)
67     Q_PROPERTY(bool isConnected READ isConnected WRITE setConnected)
68     //Q_PROPERTY(Network::ConnectionState connectionState READ connectionState WRITE setConnectionState)
69     Q_PROPERTY(int connectionState READ connectionState WRITE setConnectionState)
70     Q_PROPERTY(bool useRandomServer READ useRandomServer WRITE setUseRandomServer)
71     Q_PROPERTY(QStringList perform READ perform WRITE setPerform)
72     Q_PROPERTY(bool useAutoIdentify READ useAutoIdentify WRITE setUseAutoIdentify)
73     Q_PROPERTY(QString autoIdentifyService READ autoIdentifyService WRITE setAutoIdentifyService)
74     Q_PROPERTY(QString autoIdentifyPassword READ autoIdentifyPassword WRITE setAutoIdentifyPassword)
75     Q_PROPERTY(bool useSasl READ useSasl WRITE setUseSasl)
76     Q_PROPERTY(QString saslAccount READ saslAccount WRITE setSaslAccount)
77     Q_PROPERTY(QString saslPassword READ saslPassword WRITE setSaslPassword)
78     Q_PROPERTY(bool useAutoReconnect READ useAutoReconnect WRITE setUseAutoReconnect)
79     Q_PROPERTY(quint32 autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval)
80     Q_PROPERTY(quint16 autoReconnectRetries READ autoReconnectRetries WRITE setAutoReconnectRetries)
81     Q_PROPERTY(bool unlimitedReconnectRetries READ unlimitedReconnectRetries WRITE setUnlimitedReconnectRetries)
82     Q_PROPERTY(bool rejoinChannels READ rejoinChannels WRITE setRejoinChannels)
83     // Custom rate limiting
84     Q_PROPERTY(bool useCustomMessageRate READ useCustomMessageRate WRITE setUseCustomMessageRate)
85     Q_PROPERTY(quint32 msgRateBurstSize READ messageRateBurstSize WRITE setMessageRateBurstSize)
86     Q_PROPERTY(quint32 msgRateMessageDelay READ messageRateDelay WRITE setMessageRateDelay)
87     Q_PROPERTY(bool unlimitedMessageRate READ unlimitedMessageRate WRITE setUnlimitedMessageRate)
88
89 public :
90         enum ConnectionState {
91         Disconnected,
92         Connecting,
93         Initializing,
94         Initialized,
95         Reconnecting,
96         Disconnecting
97     };
98
99     // see:
100     //  http://www.irc.org/tech_docs/005.html
101     //  http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
102     enum ChannelModeType {
103         NOT_A_CHANMODE = 0x00,
104         A_CHANMODE = 0x01,
105         B_CHANMODE = 0x02,
106         C_CHANMODE = 0x04,
107         D_CHANMODE = 0x08
108     };
109
110     // Default port assignments according to what many IRC networks have settled on.
111     // Technically not a standard, but it's fairly widespread.
112     // See https://freenode.net/news/port-6697-irc-via-tlsssl
113     enum PortDefaults {
114         PORT_PLAINTEXT = 6667, /// Default port for unencrypted connections
115         PORT_SSL = 6697        /// Default port for encrypted connections
116     };
117
118     struct Server {
119         QString host;
120         uint port{6667};
121         QString password;
122         bool useSsl{false};
123         bool sslVerify{true};     /// If true, validate SSL certificates
124         int sslVersion{0};
125
126         bool useProxy{false};
127         int proxyType{QNetworkProxy::Socks5Proxy};
128         QString proxyHost;
129         uint proxyPort{8080};
130         QString proxyUser;
131         QString proxyPass;
132
133         // sslVerify only applies when useSsl is true.  sslVerify should be enabled by default,
134         // so enabling useSsl offers a more secure default.
135         Server() :  proxyHost("localhost") {}
136
137         Server(QString host, uint port, QString password, bool useSsl,
138                bool sslVerify)
139             : host(std::move(host)), port(port), password(std::move(password)), useSsl(useSsl), sslVerify(sslVerify),
140                proxyType(QNetworkProxy::Socks5Proxy),
141               proxyHost("localhost"), proxyPort(8080) {}
142
143         bool operator==(const Server &other) const;
144         bool operator!=(const Server &other) const;
145     };
146     using ServerList = QList<Server>;
147
148     Network(const NetworkId &networkid, QObject *parent = nullptr);
149     ~Network() override;
150
151     inline NetworkId networkId() const { return _networkId; }
152
153     inline SignalProxy *proxy() const { return _proxy; }
154     inline void setProxy(SignalProxy *proxy) { _proxy = proxy; }
155
156     inline bool isMyNick(const QString &nick) const { return (myNick().toLower() == nick.toLower()); }
157     inline bool isMe(IrcUser *ircuser) const { return (ircuser->nick().toLower() == myNick().toLower()); }
158
159     bool isChannelName(const QString &channelname) const;
160
161     /**
162      * Checks if the target counts as a STATUSMSG
163      *
164      * Status messages are prefixed with one or more characters from the server-provided STATUSMSG
165      * if available, otherwise "@" and "+" are assumed.  Generally, status messages sent to a
166      * channel are only visible to those with the same or higher permissions, e.g. voiced.
167      *
168      * @param[in] target Name of destination, e.g. a channel or query
169      * @returns True if a STATUSMSG, otherwise false
170      */
171     bool isStatusMsg(const QString &target) const;
172
173     inline bool isConnected() const { return _connected; }
174     //Network::ConnectionState connectionState() const;
175     inline int connectionState() const { return _connectionState; }
176
177     /**@{*/
178     /**
179      * Translates a user’s prefix to the channelmode associated with it.
180      * @param prefix Prefix to be translated.
181      */
182     QString prefixToMode(const QString &prefix) const;
183     inline QString prefixToMode(const QCharRef &prefix) const { return prefixToMode(QString(prefix)); }
184     inline QString prefixesToModes(const QString &prefix) const {
185         QString modes;
186         for (QChar c : prefix) {
187             modes += prefixToMode(c);
188         }
189         return modes;
190     }
191     /**@}*/
192
193     /**@{*/
194     /**
195      * Translates a user’s prefix to the channelmode associated with it.
196      * @param prefix Prefix to be translated.
197      */
198     QString modeToPrefix(const QString &mode) const;
199     inline QString modeToPrefix(const QCharRef &mode) const { return modeToPrefix(QString(mode)); }
200     inline QString modesToPrefixes(const QString &mode) const {
201         QString prefixes;
202         for (QChar c : mode) {
203             prefixes += modeToPrefix(c);
204         }
205         return prefixes;
206     }
207     /**@}*/
208
209     /**
210      * Sorts the user channelmodes according to priority set by PREFIX
211      *
212      * Given a list of channel modes, sorts according to the order of PREFIX, putting the highest
213      * modes first.  Any unknown modes are moved to the end in no given order.
214      *
215      * If prefix modes cannot be determined from the network, no changes will be made.
216      *
217      * @param modes User channelmodes
218      * @return Priority-sorted user channelmodes
219      */
220     QString sortPrefixModes(const QString &modes) const;
221
222     /**@{*/
223     /**
224      * Sorts the list of users' channelmodes according to priority set by PREFIX
225      *
226      * Maintains order of the modes list.
227      *
228      * @seealso Network::sortPrefixModes()
229      *
230      * @param modesList List of users' channel modes
231      * @return Priority-sorted list of users' channel modes
232      */
233     inline QStringList sortPrefixModes(const QStringList &modesList) const {
234         QStringList sortedModesList;
235         // Sort each individual mode string, appending back
236         // Must maintain the order received!
237         for (QString modes : modesList) {
238             sortedModesList << sortPrefixModes(modes);
239         }
240         return sortedModesList;
241     }
242     /**@}*/
243
244     ChannelModeType channelModeType(const QString &mode);
245     inline ChannelModeType channelModeType(const QCharRef &mode) { return channelModeType(QString(mode)); }
246
247     inline const QString &networkName() const { return _networkName; }
248     inline const QString &currentServer() const { return _currentServer; }
249     inline const QString &myNick() const { return _myNick; }
250     inline int latency() const { return _latency; }
251     inline IrcUser *me() const { return ircUser(myNick()); }
252     inline IdentityId identity() const { return _identity; }
253     QStringList nicks() const;
254     inline QStringList channels() const { return _ircChannels.keys(); }
255     /**
256      * Gets the list of available capabilities.
257      *
258      * @returns QStringList of available capabilities
259      */
260     inline const QStringList caps() const { return QStringList(_caps.keys()); }
261     /**
262      * Gets the list of enabled (acknowledged) capabilities.
263      *
264      * @returns QStringList of enabled (acknowledged) capabilities
265      */
266     inline const QStringList capsEnabled() const { return _capsEnabled; }
267     inline const ServerList &serverList() const { return _serverList; }
268     inline bool useRandomServer() const { return _useRandomServer; }
269     inline const QStringList &perform() const { return _perform; }
270     inline bool useAutoIdentify() const { return _useAutoIdentify; }
271     inline const QString &autoIdentifyService() const { return _autoIdentifyService; }
272     inline const QString &autoIdentifyPassword() const { return _autoIdentifyPassword; }
273     inline bool useSasl() const { return _useSasl; }
274     inline const QString &saslAccount() const { return _saslAccount; }
275     inline const QString &saslPassword() const { return _saslPassword; }
276     inline bool useAutoReconnect() const { return _useAutoReconnect; }
277     inline quint32 autoReconnectInterval() const { return _autoReconnectInterval; }
278     inline quint16 autoReconnectRetries() const { return _autoReconnectRetries; }
279     inline bool unlimitedReconnectRetries() const { return _unlimitedReconnectRetries; }
280     inline bool rejoinChannels() const { return _rejoinChannels; }
281
282     // Custom rate limiting
283
284     /**
285      * Gets whether or not custom rate limiting is used
286      *
287      * @return True if custom rate limiting is enabled, otherwise false.
288      */
289     inline bool useCustomMessageRate() const { return _useCustomMessageRate; }
290
291     /**
292      * Gets maximum number of messages to send without any delays
293      *
294      * @return
295      * @parblock
296      * Maximum number of messages to send without any delays.  A value of 1 disables message
297      * bursting.
298      * @endparblock
299      */
300     inline quint32 messageRateBurstSize() const { return _messageRateBurstSize; }
301
302     /**
303      * Gets the delay between messages after the maximum number of undelayed messages have been sent
304      *
305      * @return
306      * @parblock
307      * Delay in milliseconds between messages after the maximum number of undelayed messages have
308      * been sent.
309      * @endparblock
310      */
311     inline quint32 messageRateDelay() const { return _messageRateDelay; }
312
313     /**
314      * Gets whether or not all rate limiting is disabled, e.g. for IRC bridges
315      *
316      * @return If true, disable rate limiting, otherwise apply configured limits.
317      */
318     inline bool unlimitedMessageRate() const { return _unlimitedMessageRate; }
319
320     NetworkInfo networkInfo() const;
321     void setNetworkInfo(const NetworkInfo &);
322
323     QString prefixes() const;
324     QString prefixModes() const;
325     void determinePrefixes() const;
326
327     bool supports(const QString &param) const { return _supports.contains(param); }
328     QString support(const QString &param) const;
329
330     /**
331      * Checks if a given capability is advertised by the server.
332      *
333      * These results aren't valid if the network is disconnected or capability negotiation hasn't
334      * happened, and some servers might not correctly advertise capabilities.  Don't treat this as
335      * a guarantee.
336      *
337      * @param[in] capability Name of capability
338      * @returns True if connected and advertised by the server, otherwise false
339      */
340     inline bool capAvailable(const QString &capability) const { return _caps.contains(capability.toLower()); }
341     // IRCv3 specs all use lowercase capability names
342
343     /**
344      * Checks if a given capability is acknowledged and active.
345      *
346      * @param[in] capability Name of capability
347      * @returns True if acknowledged (active), otherwise false
348      */
349     inline bool capEnabled(const QString &capability) const { return _capsEnabled.contains(capability.toLower()); }
350     // IRCv3 specs all use lowercase capability names
351
352     /**
353      * Gets the value of an available capability, e.g. for SASL, "EXTERNAL,PLAIN".
354      *
355      * @param[in] capability Name of capability
356      * @returns Value of capability if one was specified, otherwise empty string
357      */
358     QString capValue(const QString &capability) const { return _caps.value(capability.toLower()); }
359     // IRCv3 specs all use lowercase capability names
360     // QHash returns the default constructed value if not found, in this case, empty string
361     // See:  https://doc.qt.io/qt-4.8/qhash.html#value
362
363     /**
364      * Check if the given authentication mechanism is likely to be supported.
365      *
366      * This depends on the server advertising SASL support and either declaring available mechanisms
367      * (SASL 3.2), or just indicating something is supported (SASL 3.1).
368      *
369      * @param[in] saslMechanism  Desired SASL mechanism
370      * @return True if mechanism supported or unknown, otherwise false
371      */
372     bool saslMaybeSupports(const QString &saslMechanism) const;
373
374     IrcUser *newIrcUser(const QString &hostmask, const QVariantMap &initData = QVariantMap());
375     inline IrcUser *newIrcUser(const QByteArray &hostmask) { return newIrcUser(decodeServerString(hostmask)); }
376     IrcUser *ircUser(QString nickname) const;
377     inline IrcUser *ircUser(const QByteArray &nickname) const { return ircUser(decodeServerString(nickname)); }
378     inline QList<IrcUser *> ircUsers() const { return _ircUsers.values(); }
379     inline quint32 ircUserCount() const { return _ircUsers.count(); }
380
381     IrcChannel *newIrcChannel(const QString &channelname, const QVariantMap &initData = QVariantMap());
382     inline IrcChannel *newIrcChannel(const QByteArray &channelname) { return newIrcChannel(decodeServerString(channelname)); }
383     IrcChannel *ircChannel(QString channelname) const;
384     inline IrcChannel *ircChannel(const QByteArray &channelname) const { return ircChannel(decodeServerString(channelname)); }
385     inline QList<IrcChannel *> ircChannels() const { return _ircChannels.values(); }
386     inline quint32 ircChannelCount() const { return _ircChannels.count(); }
387
388     QByteArray codecForServer() const;
389     QByteArray codecForEncoding() const;
390     QByteArray codecForDecoding() const;
391     void setCodecForServer(QTextCodec *codec);
392     void setCodecForEncoding(QTextCodec *codec);
393     void setCodecForDecoding(QTextCodec *codec);
394
395     QString decodeString(const QByteArray &text) const;
396     QByteArray encodeString(const QString &string) const;
397     QString decodeServerString(const QByteArray &text) const;
398     QByteArray encodeServerString(const QString &string) const;
399
400     static QByteArray defaultCodecForServer();
401     static QByteArray defaultCodecForEncoding();
402     static QByteArray defaultCodecForDecoding();
403     static void setDefaultCodecForServer(const QByteArray &name);
404     static void setDefaultCodecForEncoding(const QByteArray &name);
405     static void setDefaultCodecForDecoding(const QByteArray &name);
406
407     inline bool autoAwayActive() const { return _autoAwayActive; }
408     inline void setAutoAwayActive(bool active) { _autoAwayActive = active; }
409
410 public slots:
411     void setNetworkName(const QString &networkName);
412     void setCurrentServer(const QString &currentServer);
413     void setConnected(bool isConnected);
414     void setConnectionState(int state);
415     virtual void setMyNick(const QString &mynick);
416     void setLatency(int latency);
417     void setIdentity(IdentityId);
418
419     void setServerList(const QVariantList &serverList);
420     void setUseRandomServer(bool);
421     void setPerform(const QStringList &);
422     void setUseAutoIdentify(bool);
423     void setAutoIdentifyService(const QString &);
424     void setAutoIdentifyPassword(const QString &);
425     void setUseSasl(bool);
426     void setSaslAccount(const QString &);
427     void setSaslPassword(const QString &);
428     virtual void setUseAutoReconnect(bool);
429     virtual void setAutoReconnectInterval(quint32);
430     virtual void setAutoReconnectRetries(quint16);
431     void setUnlimitedReconnectRetries(bool);
432     void setRejoinChannels(bool);
433
434     // Custom rate limiting
435
436     /**
437      * Sets whether or not custom rate limiting is used.
438      *
439      * Setting limits too low may get you disconnected from the server!
440      *
441      * @param[in] useCustomRate If true, use custom rate limits, otherwise use Quassel defaults.
442      */
443     void setUseCustomMessageRate(bool useCustomRate);
444
445     /**
446      * Sets maximum number of messages to send without any delays
447      *
448      * @param[in] burstSize
449      * @parblock
450      * Maximum number of messages to send without any delays.  A value of 1 disables message
451      * bursting.  Cannot be less than 1 as sending 0 messages at a time accomplishes nothing.
452      * @endparblock
453      */
454     void setMessageRateBurstSize(quint32 burstSize);
455
456     /**
457      * Sets the delay between messages after the maximum number of undelayed messages have been sent
458      *
459      * @param[in] messageDelay
460      * @parblock
461      * Delay in milliseconds between messages after the maximum number of undelayed messages have
462      * been sent.
463      * @endparblock
464      */
465     void setMessageRateDelay(quint32 messageDelay);
466
467     /**
468      * Sets whether or not all rate limiting is disabled, e.g. for IRC bridges
469      *
470      * Don't use with most normal networks.
471      *
472      * @param[in] unlimitedRate If true, disable rate limiting, otherwise apply configured limits.
473      */
474     void setUnlimitedMessageRate(bool unlimitedRate);
475
476     void setCodecForServer(const QByteArray &codecName);
477     void setCodecForEncoding(const QByteArray &codecName);
478     void setCodecForDecoding(const QByteArray &codecName);
479
480     void addSupport(const QString &param, const QString &value = QString());
481     void removeSupport(const QString &param);
482
483     // IRCv3 capability negotiation (can be connected to signals)
484
485     /**
486      * Add an available capability, optionally providing a value.
487      *
488      * This may happen during first connect, or at any time later if a new capability becomes
489      * available (e.g. SASL service starting).
490      *
491      * @param[in] capability Name of the capability
492      * @param[in] value
493      * @parblock
494      * Optional value of the capability, e.g. sasl=plain.
495      * @endparblock
496      */
497     void addCap(const QString &capability, const QString &value = QString());
498
499     /**
500      * Marks a capability as acknowledged (enabled by the IRC server).
501      *
502      * @param[in] capability Name of the capability
503      */
504     void acknowledgeCap(const QString &capability);
505
506     /**
507      * Removes a capability from the list of available capabilities.
508      *
509      * This may happen during first connect, or at any time later if an existing capability becomes
510      * unavailable (e.g. SASL service stopping).  This also removes the capability from the list
511      * of acknowledged capabilities.
512      *
513      * @param[in] capability Name of the capability
514      */
515     void removeCap(const QString &capability);
516
517     /**
518      * Clears all capabilities from the list of available capabilities.
519      *
520      * This also removes the capability from the list of acknowledged capabilities.
521      */
522     void clearCaps();
523
524     inline void addIrcUser(const QString &hostmask) { newIrcUser(hostmask); }
525     inline void addIrcChannel(const QString &channel) { newIrcChannel(channel); }
526
527     //init geters
528     QVariantMap initSupports() const;
529     /**
530      * Get the initial list of available capabilities.
531      *
532      * @return QVariantMap of <QString, QString> indicating available capabilities and values
533      */
534     QVariantMap initCaps() const;
535     /**
536      * Get the initial list of enabled (acknowledged) capabilities.
537      *
538      * @return QVariantList of QString indicating enabled (acknowledged) capabilities and values
539      */
540     QVariantList initCapsEnabled() const { return toVariantList(capsEnabled()); }
541     inline QVariantList initServerList() const { return toVariantList(serverList()); }
542     virtual QVariantMap initIrcUsersAndChannels() const;
543
544     //init seters
545     void initSetSupports(const QVariantMap &supports);
546     /**
547      * Initialize the list of available capabilities.
548      *
549      * @param[in] caps QVariantMap of <QString, QString> indicating available capabilities and values
550      */
551     void initSetCaps(const QVariantMap &caps);
552     /**
553      * Initialize the list of enabled (acknowledged) capabilities.
554      *
555      * @param[in] caps QVariantList of QString indicating enabled (acknowledged) capabilities and values
556      */
557     inline void initSetCapsEnabled(const QVariantList &capsEnabled) { _capsEnabled = fromVariantList<QString>(capsEnabled); }
558     inline void initSetServerList(const QVariantList &serverList) { _serverList = fromVariantList<Server>(serverList); }
559     virtual void initSetIrcUsersAndChannels(const QVariantMap &usersAndChannels);
560
561     /**
562      * Update IrcUser hostmask and username from mask, creating an IrcUser if one does not exist.
563      *
564      * @param[in] mask   Full nick!user@hostmask string
565      * @return IrcUser of the matching nick if exists, otherwise a new IrcUser
566      */
567     IrcUser *updateNickFromMask(const QString &mask);
568
569     // these slots are to keep the hashlists of all users and the
570     // channel lists up to date
571     void ircUserNickChanged(QString newnick);
572
573     virtual inline void requestConnect() const { REQUEST(NO_ARG) }
574     virtual inline void requestDisconnect() const { REQUEST(NO_ARG) }
575     virtual inline void requestSetNetworkInfo(const NetworkInfo &info) { REQUEST(ARG(info)) }
576
577     void emitConnectionError(const QString &);
578
579 protected slots:
580     virtual void removeIrcUser(IrcUser *ircuser);
581     virtual void removeIrcChannel(IrcChannel *ircChannel);
582     virtual void removeChansAndUsers();
583
584 signals:
585     void aboutToBeDestroyed();
586     void networkNameSet(const QString &networkName);
587     void currentServerSet(const QString &currentServer);
588     void connectedSet(bool isConnected);
589     void connectionStateSet(Network::ConnectionState);
590 //   void connectionStateSet(int);
591     void connectionError(const QString &errorMsg);
592     void myNickSet(const QString &mynick);
593 //   void latencySet(int latency);
594     void identitySet(IdentityId);
595
596     void configChanged();
597
598     //   void serverListSet(QVariantList serverList);
599 //   void useRandomServerSet(bool);
600 //   void performSet(const QStringList &);
601 //   void useAutoIdentifySet(bool);
602 //   void autoIdentifyServiceSet(const QString &);
603 //   void autoIdentifyPasswordSet(const QString &);
604 //   void useAutoReconnectSet(bool);
605 //   void autoReconnectIntervalSet(quint32);
606 //   void autoReconnectRetriesSet(quint16);
607 //   void unlimitedReconnectRetriesSet(bool);
608 //   void rejoinChannelsSet(bool);
609
610     // Custom rate limiting (can drive other slots)
611
612     /**
613      * Signals enabling or disabling custom rate limiting
614      *
615      * @see Network::useCustomMessageRate()
616      *
617      * @param[out] useCustomRate
618      */
619     void useCustomMessageRateSet(const bool useCustomRate);
620
621     /**
622      * Signals a change in maximum number of messages to send without any delays
623      *
624      * @see Network::messageRateBurstSize()
625      *
626      * @param[out] burstSize
627      */
628     void messageRateBurstSizeSet(const quint32 burstSize);
629
630     /**
631      * Signals a change in delay between messages after the max. undelayed messages have been sent
632      *
633      * @see Network::messageRateDelay()
634      *
635      * @param[out] messageDelay
636      */
637     void messageRateDelaySet(const quint32 messageDelay);
638
639     /**
640      * Signals enabling or disabling all rate limiting
641      *
642      * @see Network::unlimitedMessageRate()
643      *
644      * @param[out] unlimitedRate
645      */
646     void unlimitedMessageRateSet(const bool unlimitedRate);
647
648 //   void codecForServerSet(const QByteArray &codecName);
649 //   void codecForEncodingSet(const QByteArray &codecName);
650 //   void codecForDecodingSet(const QByteArray &codecName);
651
652 //   void supportAdded(const QString &param, const QString &value);
653 //   void supportRemoved(const QString &param);
654
655     // IRCv3 capability negotiation (can drive other slots)
656     /**
657      * Indicates a capability is now available, with optional value in Network::capValue().
658      *
659      * @see Network::addCap()
660      *
661      * @param[in] capability Name of the capability
662      */
663     void capAdded (const QString &capability);
664
665     /**
666      * Indicates a capability was acknowledged (enabled by the IRC server).
667      *
668      * @see Network::acknowledgeCap()
669      *
670      * @param[in] capability Name of the capability
671      */
672     void capAcknowledged(const QString &capability);
673
674     /**
675      * Indicates a capability was removed from the list of available capabilities.
676      *
677      * @see Network::removeCap()
678      *
679      * @param[in] capability Name of the capability
680      */
681     void capRemoved(const QString &capability);
682
683 //   void ircUserAdded(const QString &hostmask);
684     void ircUserAdded(IrcUser *);
685 //   void ircChannelAdded(const QString &channelname);
686     void ircChannelAdded(IrcChannel *);
687
688 //   void connectRequested() const;
689 //   void disconnectRequested() const;
690 //   void setNetworkInfoRequested(const NetworkInfo &) const;
691
692 protected:
693     inline virtual IrcChannel *ircChannelFactory(const QString &channelname) { return new IrcChannel(channelname, this); }
694     inline virtual IrcUser *ircUserFactory(const QString &hostmask) { return new IrcUser(hostmask, this); }
695
696 private:
697     QPointer<SignalProxy> _proxy;
698
699     NetworkId _networkId;
700     IdentityId _identity;
701
702     QString _myNick;
703     int _latency;
704     QString _networkName;
705     QString _currentServer;
706     bool _connected;
707     ConnectionState _connectionState;
708
709     mutable QString _prefixes;
710     mutable QString _prefixModes;
711
712     QHash<QString, IrcUser *> _ircUsers; // stores all known nicks for the server
713     QHash<QString, IrcChannel *> _ircChannels; // stores all known channels
714     QHash<QString, QString> _supports; // stores results from RPL_ISUPPORT
715
716     QHash<QString, QString> _caps;  /// Capabilities supported by the IRC server
717     // By synchronizing the supported capabilities, the client could suggest certain behaviors, e.g.
718     // in the Network settings dialog, recommending SASL instead of using NickServ, or warning if
719     // SASL EXTERNAL isn't available.
720     QStringList _capsEnabled;       /// Enabled capabilities that received 'CAP ACK'
721     // _capsEnabled uses the same values from the <name>=<value> pairs stored in _caps
722
723     ServerList _serverList;
724     bool _useRandomServer;
725     QStringList _perform;
726
727     bool _useAutoIdentify;
728     QString _autoIdentifyService;
729     QString _autoIdentifyPassword;
730
731     bool _useSasl;
732     QString _saslAccount;
733     QString _saslPassword;
734
735     bool _useAutoReconnect;
736     quint32 _autoReconnectInterval;
737     quint16 _autoReconnectRetries;
738     bool _unlimitedReconnectRetries;
739     bool _rejoinChannels;
740
741     // Custom rate limiting
742     bool _useCustomMessageRate;         /// If true, use custom rate limits, otherwise use defaults
743     quint32 _messageRateBurstSize;      /// Maximum number of messages to send without any delays
744     quint32 _messageRateDelay;          /// Delay in ms. for messages when max. burst messages sent
745     bool _unlimitedMessageRate;         /// If true, disable rate limiting, otherwise apply limits
746
747     QTextCodec *_codecForServer;
748     QTextCodec *_codecForEncoding;
749     QTextCodec *_codecForDecoding;
750
751     static QTextCodec *_defaultCodecForServer;
752     static QTextCodec *_defaultCodecForEncoding;
753     static QTextCodec *_defaultCodecForDecoding;
754
755     bool _autoAwayActive; // when this is active handle305 and handle306 don't trigger any output
756
757     friend class IrcUser;
758     friend class IrcChannel;
759 };
760
761
762 //! Stores all editable information about a network (as opposed to runtime state).
763 struct COMMON_EXPORT NetworkInfo
764 {
765     QString networkName;
766
767     Network::ServerList serverList;
768     QStringList perform;
769
770     QString autoIdentifyService{"NickServ"};
771     QString autoIdentifyPassword;
772
773     QString saslAccount;
774     QString saslPassword;
775
776     QByteArray codecForServer;
777     QByteArray codecForEncoding;
778     QByteArray codecForDecoding;
779
780     NetworkId networkId {0};
781     IdentityId identity {1};
782
783     quint32 messageRateBurstSize {5};     ///< Maximum number of messages to send without any delays
784     quint32 messageRateDelay     {2200};  ///< Delay in ms. for messages when max. burst messages sent
785
786     quint32 autoReconnectInterval {60};
787     quint16 autoReconnectRetries  {20};
788
789     bool rejoinChannels            {true};
790     bool useRandomServer           {false};
791     bool useAutoIdentify           {false};
792     bool useSasl                   {false};
793     bool useAutoReconnect          {true};
794     bool unlimitedReconnectRetries {false};
795     bool useCustomMessageRate      {false};  ///< If true, use custom rate limits, otherwise use defaults
796     bool unlimitedMessageRate      {false};  ///< If true, disable rate limiting, otherwise apply limits
797
798 public:
799     bool operator==(const NetworkInfo &other) const;
800     bool operator!=(const NetworkInfo &other) const;
801 };
802
803 COMMON_EXPORT QDataStream &operator<<(QDataStream &out, const NetworkInfo &info);
804 COMMON_EXPORT QDataStream &operator>>(QDataStream &in, NetworkInfo &info);
805 COMMON_EXPORT QDebug operator<<(QDebug dbg, const NetworkInfo &i);
806 Q_DECLARE_METATYPE(NetworkInfo)
807
808 COMMON_EXPORT QDataStream &operator<<(QDataStream &out, const Network::Server &server);
809 COMMON_EXPORT QDataStream &operator>>(QDataStream &in, Network::Server &server);
810 COMMON_EXPORT QDebug operator<<(QDebug dbg, const Network::Server &server);
811 Q_DECLARE_METATYPE(Network::Server)