1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 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 | #ifndef NETWORK_H |
22 | #define NETWORK_H |
23 | |
24 | #include <QString> |
25 | #include <QStringList> |
26 | #include <QList> |
27 | #include <QNetworkProxy> |
28 | #include <QHash> |
29 | #include <QVariantMap> |
30 | #include <QPointer> |
31 | #include <QMutex> |
32 | #include <QByteArray> |
33 | |
34 | #include "types.h" |
35 | #include "util.h" |
36 | #include "syncableobject.h" |
37 | |
38 | #include "signalproxy.h" |
39 | #include "ircuser.h" |
40 | #include "ircchannel.h" |
41 | |
42 | // defined below! |
43 | struct NetworkInfo; |
44 | |
45 | // TODO: ConnectionInfo to propagate and sync the current state of NetworkConnection, encodings etcpp |
46 | |
47 | class Network : public SyncableObject |
48 | { |
49 | SYNCABLE_OBJECT |
50 | Q_OBJECT |
51 | Q_ENUMS(ConnectionState) |
52 | |
53 | Q_PROPERTY(QString networkName READ networkName WRITE setNetworkName) |
54 | Q_PROPERTY(QString currentServer READ currentServer WRITE setCurrentServer) |
55 | Q_PROPERTY(QString myNick READ myNick WRITE setMyNick) |
56 | Q_PROPERTY(int latency READ latency WRITE setLatency) |
57 | Q_PROPERTY(QByteArray codecForServer READ codecForServer WRITE setCodecForServer) |
58 | Q_PROPERTY(QByteArray codecForEncoding READ codecForEncoding WRITE setCodecForEncoding) |
59 | Q_PROPERTY(QByteArray codecForDecoding READ codecForDecoding WRITE setCodecForDecoding) |
60 | Q_PROPERTY(IdentityId identityId READ identity WRITE setIdentity) |
61 | Q_PROPERTY(bool isConnected READ isConnected WRITE setConnected) |
62 | //Q_PROPERTY(Network::ConnectionState connectionState READ connectionState WRITE setConnectionState) |
63 | Q_PROPERTY(int connectionState READ connectionState WRITE setConnectionState) |
64 | Q_PROPERTY(bool useRandomServer READ useRandomServer WRITE setUseRandomServer) |
65 | Q_PROPERTY(QStringList perform READ perform WRITE setPerform) |
66 | Q_PROPERTY(bool useAutoIdentify READ useAutoIdentify WRITE setUseAutoIdentify) |
67 | Q_PROPERTY(QString autoIdentifyService READ autoIdentifyService WRITE setAutoIdentifyService) |
68 | Q_PROPERTY(QString autoIdentifyPassword READ autoIdentifyPassword WRITE setAutoIdentifyPassword) |
69 | Q_PROPERTY(bool useSasl READ useSasl WRITE setUseSasl) |
70 | Q_PROPERTY(QString saslAccount READ saslAccount WRITE setSaslAccount) |
71 | Q_PROPERTY(QString saslPassword READ saslPassword WRITE setSaslPassword) |
72 | Q_PROPERTY(bool useAutoReconnect READ useAutoReconnect WRITE setUseAutoReconnect) |
73 | Q_PROPERTY(quint32 autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval) |
74 | Q_PROPERTY(quint16 autoReconnectRetries READ autoReconnectRetries WRITE setAutoReconnectRetries) |
75 | Q_PROPERTY(bool unlimitedReconnectRetries READ unlimitedReconnectRetries WRITE setUnlimitedReconnectRetries) |
76 | Q_PROPERTY(bool rejoinChannels READ rejoinChannels WRITE setRejoinChannels) |
77 | |
78 | public : |
79 | enum ConnectionState { |
80 | Disconnected, |
81 | Connecting, |
82 | Initializing, |
83 | Initialized, |
84 | Reconnecting, |
85 | Disconnecting |
86 | }; |
87 | |
88 | // see: |
89 | // http://www.irc.org/tech_docs/005.html |
90 | // http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt |
91 | enum ChannelModeType { |
92 | NOT_A_CHANMODE = 0x00, |
93 | A_CHANMODE = 0x01, |
94 | B_CHANMODE = 0x02, |
95 | C_CHANMODE = 0x04, |
96 | D_CHANMODE = 0x08 |
97 | }; |
98 | |
99 | struct Server { |
100 | QString host; |
101 | uint port; |
102 | QString password; |
103 | bool useSsl; |
104 | int sslVersion; |
105 | |
106 | bool useProxy; |
107 | int proxyType; |
108 | QString proxyHost; |
109 | uint proxyPort; |
110 | QString proxyUser; |
111 | QString proxyPass; |
112 | |
113 | Server() : port(6667), useSsl(false), sslVersion(0), useProxy(false), proxyType(QNetworkProxy::Socks5Proxy), proxyHost("localhost" ), proxyPort(8080) {} |
114 | Server(const QString &host, uint port, const QString &password, bool useSsl) |
115 | : host(host), port(port), password(password), useSsl(useSsl), sslVersion(0), |
116 | useProxy(false), proxyType(QNetworkProxy::Socks5Proxy), proxyHost("localhost" ), proxyPort(8080) {} |
117 | bool operator==(const Server &other) const; |
118 | bool operator!=(const Server &other) const; |
119 | }; |
120 | typedef QList<Server> ServerList; |
121 | |
122 | Network(const NetworkId &networkid, QObject *parent = 0); |
123 | ~Network(); |
124 | |
125 | inline NetworkId networkId() const { return _networkId; } |
126 | |
127 | inline SignalProxy *proxy() const { return _proxy; } |
128 | inline void setProxy(SignalProxy *proxy) { _proxy = proxy; } |
129 | |
130 | inline bool isMyNick(const QString &nick) const { return (myNick().toLower() == nick.toLower()); } |
131 | inline bool isMe(IrcUser *ircuser) const { return (ircuser->nick().toLower() == myNick().toLower()); } |
132 | |
133 | bool isChannelName(const QString &channelname) const; |
134 | |
135 | inline bool isConnected() const { return _connected; } |
136 | //Network::ConnectionState connectionState() const; |
137 | inline int connectionState() const { return _connectionState; } |
138 | |
139 | QString prefixToMode(const QString &prefix) const; |
140 | inline QString prefixToMode(const QCharRef &prefix) const { return prefixToMode(QString(prefix)); } |
141 | QString modeToPrefix(const QString &mode) const; |
142 | inline QString modeToPrefix(const QCharRef &mode) const { return modeToPrefix(QString(mode)); } |
143 | |
144 | ChannelModeType channelModeType(const QString &mode); |
145 | inline ChannelModeType channelModeType(const QCharRef &mode) { return channelModeType(QString(mode)); } |
146 | |
147 | inline const QString &networkName() const { return _networkName; } |
148 | inline const QString ¤tServer() const { return _currentServer; } |
149 | inline const QString &myNick() const { return _myNick; } |
150 | inline int latency() const { return _latency; } |
151 | inline IrcUser *me() const { return ircUser(myNick()); } |
152 | inline IdentityId identity() const { return _identity; } |
153 | QStringList nicks() const; |
154 | inline QStringList channels() const { return _ircChannels.keys(); } |
155 | inline const ServerList &serverList() const { return _serverList; } |
156 | inline bool useRandomServer() const { return _useRandomServer; } |
157 | inline const QStringList &perform() const { return _perform; } |
158 | inline bool useAutoIdentify() const { return _useAutoIdentify; } |
159 | inline const QString &autoIdentifyService() const { return _autoIdentifyService; } |
160 | inline const QString &autoIdentifyPassword() const { return _autoIdentifyPassword; } |
161 | inline bool useSasl() const { return _useSasl; } |
162 | inline const QString &saslAccount() const { return _saslAccount; } |
163 | inline const QString &saslPassword() const { return _saslPassword; } |
164 | inline bool useAutoReconnect() const { return _useAutoReconnect; } |
165 | inline quint32 autoReconnectInterval() const { return _autoReconnectInterval; } |
166 | inline quint16 autoReconnectRetries() const { return _autoReconnectRetries; } |
167 | inline bool unlimitedReconnectRetries() const { return _unlimitedReconnectRetries; } |
168 | inline bool rejoinChannels() const { return _rejoinChannels; } |
169 | |
170 | NetworkInfo networkInfo() const; |
171 | void setNetworkInfo(const NetworkInfo &); |
172 | |
173 | QString prefixes() const; |
174 | QString prefixModes() const; |
175 | void determinePrefixes() const; |
176 | |
177 | bool supports(const QString ¶m) const { return _supports.contains(param); } |
178 | QString support(const QString ¶m) const; |
179 | |
180 | IrcUser *newIrcUser(const QString &hostmask, const QVariantMap &initData = QVariantMap()); |
181 | inline IrcUser *newIrcUser(const QByteArray &hostmask) { return newIrcUser(decodeServerString(hostmask)); } |
182 | IrcUser *ircUser(QString nickname) const; |
183 | inline IrcUser *ircUser(const QByteArray &nickname) const { return ircUser(decodeServerString(nickname)); } |
184 | inline QList<IrcUser *> ircUsers() const { return _ircUsers.values(); } |
185 | inline quint32 ircUserCount() const { return _ircUsers.count(); } |
186 | |
187 | IrcChannel *newIrcChannel(const QString &channelname, const QVariantMap &initData = QVariantMap()); |
188 | inline IrcChannel *newIrcChannel(const QByteArray &channelname) { return newIrcChannel(decodeServerString(channelname)); } |
189 | IrcChannel *ircChannel(QString channelname) const; |
190 | inline IrcChannel *ircChannel(const QByteArray &channelname) const { return ircChannel(decodeServerString(channelname)); } |
191 | inline QList<IrcChannel *> ircChannels() const { return _ircChannels.values(); } |
192 | inline quint32 ircChannelCount() const { return _ircChannels.count(); } |
193 | |
194 | QByteArray codecForServer() const; |
195 | QByteArray codecForEncoding() const; |
196 | QByteArray codecForDecoding() const; |
197 | void setCodecForServer(QTextCodec *codec); |
198 | void setCodecForEncoding(QTextCodec *codec); |
199 | void setCodecForDecoding(QTextCodec *codec); |
200 | |
201 | QString decodeString(const QByteArray &text) const; |
202 | QByteArray encodeString(const QString &string) const; |
203 | QString decodeServerString(const QByteArray &text) const; |
204 | QByteArray encodeServerString(const QString &string) const; |
205 | |
206 | static QByteArray defaultCodecForServer(); |
207 | static QByteArray defaultCodecForEncoding(); |
208 | static QByteArray defaultCodecForDecoding(); |
209 | static void setDefaultCodecForServer(const QByteArray &name); |
210 | static void setDefaultCodecForEncoding(const QByteArray &name); |
211 | static void setDefaultCodecForDecoding(const QByteArray &name); |
212 | |
213 | inline bool autoAwayActive() const { return _autoAwayActive; } |
214 | inline void setAutoAwayActive(bool active) { _autoAwayActive = active; } |
215 | |
216 | public slots: |
217 | void setNetworkName(const QString &networkName); |
218 | void setCurrentServer(const QString ¤tServer); |
219 | void setConnected(bool isConnected); |
220 | void setConnectionState(int state); |
221 | virtual void setMyNick(const QString &mynick); |
222 | void setLatency(int latency); |
223 | void setIdentity(IdentityId); |
224 | |
225 | void setServerList(const QVariantList &serverList); |
226 | void setUseRandomServer(bool); |
227 | void setPerform(const QStringList &); |
228 | void setUseAutoIdentify(bool); |
229 | void setAutoIdentifyService(const QString &); |
230 | void setAutoIdentifyPassword(const QString &); |
231 | void setUseSasl(bool); |
232 | void setSaslAccount(const QString &); |
233 | void setSaslPassword(const QString &); |
234 | virtual void setUseAutoReconnect(bool); |
235 | virtual void setAutoReconnectInterval(quint32); |
236 | virtual void setAutoReconnectRetries(quint16); |
237 | void setUnlimitedReconnectRetries(bool); |
238 | void setRejoinChannels(bool); |
239 | |
240 | void setCodecForServer(const QByteArray &codecName); |
241 | void setCodecForEncoding(const QByteArray &codecName); |
242 | void setCodecForDecoding(const QByteArray &codecName); |
243 | |
244 | void addSupport(const QString ¶m, const QString &value = QString()); |
245 | void removeSupport(const QString ¶m); |
246 | |
247 | inline void addIrcUser(const QString &hostmask) { newIrcUser(hostmask); } |
248 | inline void addIrcChannel(const QString &channel) { newIrcChannel(channel); } |
249 | |
250 | //init geters |
251 | QVariantMap initSupports() const; |
252 | inline QVariantList initServerList() const { return toVariantList(serverList()); } |
253 | virtual QVariantMap initIrcUsersAndChannels() const; |
254 | |
255 | //init seters |
256 | void initSetSupports(const QVariantMap &supports); |
257 | inline void initSetServerList(const QVariantList &serverList) { _serverList = fromVariantList<Server>(serverList); } |
258 | virtual void initSetIrcUsersAndChannels(const QVariantMap &usersAndChannels); |
259 | |
260 | IrcUser *updateNickFromMask(const QString &mask); |
261 | |
262 | // these slots are to keep the hashlists of all users and the |
263 | // channel lists up to date |
264 | void ircUserNickChanged(QString newnick); |
265 | |
266 | virtual inline void requestConnect() const { REQUEST(NO_ARG) } |
267 | virtual inline void requestDisconnect() const { REQUEST(NO_ARG) } |
268 | virtual inline void requestSetNetworkInfo(const NetworkInfo &info) { REQUEST(ARG(info)) } |
269 | |
270 | void emitConnectionError(const QString &); |
271 | |
272 | protected slots: |
273 | virtual void removeIrcUser(IrcUser *ircuser); |
274 | virtual void removeIrcChannel(IrcChannel *ircChannel); |
275 | virtual void removeChansAndUsers(); |
276 | |
277 | signals: |
278 | void aboutToBeDestroyed(); |
279 | void networkNameSet(const QString &networkName); |
280 | void currentServerSet(const QString ¤tServer); |
281 | void connectedSet(bool isConnected); |
282 | void connectionStateSet(Network::ConnectionState); |
283 | // void connectionStateSet(int); |
284 | void connectionError(const QString &errorMsg); |
285 | void myNickSet(const QString &mynick); |
286 | // void latencySet(int latency); |
287 | void identitySet(IdentityId); |
288 | |
289 | void configChanged(); |
290 | |
291 | // void serverListSet(QVariantList serverList); |
292 | // void useRandomServerSet(bool); |
293 | // void performSet(const QStringList &); |
294 | // void useAutoIdentifySet(bool); |
295 | // void autoIdentifyServiceSet(const QString &); |
296 | // void autoIdentifyPasswordSet(const QString &); |
297 | // void useAutoReconnectSet(bool); |
298 | // void autoReconnectIntervalSet(quint32); |
299 | // void autoReconnectRetriesSet(quint16); |
300 | // void unlimitedReconnectRetriesSet(bool); |
301 | // void rejoinChannelsSet(bool); |
302 | |
303 | // void codecForServerSet(const QByteArray &codecName); |
304 | // void codecForEncodingSet(const QByteArray &codecName); |
305 | // void codecForDecodingSet(const QByteArray &codecName); |
306 | |
307 | // void supportAdded(const QString ¶m, const QString &value); |
308 | // void supportRemoved(const QString ¶m); |
309 | |
310 | // void ircUserAdded(const QString &hostmask); |
311 | void ircUserAdded(IrcUser *); |
312 | // void ircChannelAdded(const QString &channelname); |
313 | void ircChannelAdded(IrcChannel *); |
314 | |
315 | // void connectRequested() const; |
316 | // void disconnectRequested() const; |
317 | // void setNetworkInfoRequested(const NetworkInfo &) const; |
318 | |
319 | protected: |
320 | inline virtual IrcChannel *ircChannelFactory(const QString &channelname) { return new IrcChannel(channelname, this); } |
321 | inline virtual IrcUser *ircUserFactory(const QString &hostmask) { return new IrcUser(hostmask, this); } |
322 | |
323 | private: |
324 | QPointer<SignalProxy> _proxy; |
325 | |
326 | NetworkId _networkId; |
327 | IdentityId _identity; |
328 | |
329 | QString _myNick; |
330 | int _latency; |
331 | QString _networkName; |
332 | QString _currentServer; |
333 | bool _connected; |
334 | ConnectionState _connectionState; |
335 | |
336 | mutable QString _prefixes; |
337 | mutable QString _prefixModes; |
338 | |
339 | QHash<QString, IrcUser *> _ircUsers; // stores all known nicks for the server |
340 | QHash<QString, IrcChannel *> _ircChannels; // stores all known channels |
341 | QHash<QString, QString> _supports; // stores results from RPL_ISUPPORT |
342 | |
343 | ServerList _serverList; |
344 | bool _useRandomServer; |
345 | QStringList _perform; |
346 | |
347 | bool _useAutoIdentify; |
348 | QString _autoIdentifyService; |
349 | QString _autoIdentifyPassword; |
350 | |
351 | bool _useSasl; |
352 | QString _saslAccount; |
353 | QString _saslPassword; |
354 | |
355 | bool _useAutoReconnect; |
356 | quint32 _autoReconnectInterval; |
357 | quint16 _autoReconnectRetries; |
358 | bool _unlimitedReconnectRetries; |
359 | bool _rejoinChannels; |
360 | |
361 | QTextCodec *_codecForServer; |
362 | QTextCodec *_codecForEncoding; |
363 | QTextCodec *_codecForDecoding; |
364 | |
365 | static QTextCodec *_defaultCodecForServer; |
366 | static QTextCodec *_defaultCodecForEncoding; |
367 | static QTextCodec *_defaultCodecForDecoding; |
368 | |
369 | bool _autoAwayActive; // when this is active handle305 and handle306 don't trigger any output |
370 | |
371 | friend class IrcUser; |
372 | friend class IrcChannel; |
373 | }; |
374 | |
375 | |
376 | //! Stores all editable information about a network (as opposed to runtime state). |
377 | struct NetworkInfo { |
378 | // set some default values, note that this does not initialize e.g. name and id |
379 | NetworkInfo(); |
380 | |
381 | NetworkId networkId; |
382 | QString networkName; |
383 | IdentityId identity; |
384 | |
385 | bool useCustomEncodings; // not used! |
386 | QByteArray codecForServer; |
387 | QByteArray codecForEncoding; |
388 | QByteArray codecForDecoding; |
389 | |
390 | Network::ServerList serverList; |
391 | bool useRandomServer; |
392 | |
393 | QStringList perform; |
394 | |
395 | bool useAutoIdentify; |
396 | QString autoIdentifyService; |
397 | QString autoIdentifyPassword; |
398 | |
399 | bool useSasl; |
400 | QString saslAccount; |
401 | QString saslPassword; |
402 | |
403 | bool useAutoReconnect; |
404 | quint32 autoReconnectInterval; |
405 | quint16 autoReconnectRetries; |
406 | bool unlimitedReconnectRetries; |
407 | bool rejoinChannels; |
408 | |
409 | bool operator==(const NetworkInfo &other) const; |
410 | bool operator!=(const NetworkInfo &other) const; |
411 | }; |
412 | |
413 | QDataStream &operator<<(QDataStream &out, const NetworkInfo &info); |
414 | QDataStream &operator>>(QDataStream &in, NetworkInfo &info); |
415 | QDebug operator<<(QDebug dbg, const NetworkInfo &i); |
416 | Q_DECLARE_METATYPE(NetworkInfo) |
417 | |
418 | QDataStream &operator<<(QDataStream &out, const Network::Server &server); |
419 | QDataStream &operator>>(QDataStream &in, Network::Server &server); |
420 | QDebug operator<<(QDebug dbg, const Network::Server &server); |
421 | Q_DECLARE_METATYPE(Network::Server) |
422 | |
423 | #endif |
424 | |