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