1 #ifndef _KVI_IRCCONNECTION_H_
2 #define _KVI_IRCCONNECTION_H_
3 //=============================================================================
4 //
5 //   File : KviIrcConnection.h
6 //   Creation date : Mon 03 May 2004 01:45:42 by Szymon Stefanek
7 //
8 //   This file is part of the KVIrc IRC client distribution
9 //   Copyright (C) 2004-2010 Szymon Stefanek <pragma at kvirc dot net>
10 //
11 //   This program is FREE software. You can redistribute it and/or
12 //   modify it under the terms of the GNU General Public License
13 //   as published by the Free Software Foundation; either version 2
14 //   of the License, or (at your option) any later version.
15 //
16 //   This program is distributed in the HOPE that it will be USEFUL,
17 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
18 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 //   See the GNU General Public License for more details.
20 //
21 //   You should have received a copy of the GNU General Public License
22 //   along with this program. If not, write to the Free Software Foundation,
23 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 //
25 //=============================================================================
26 
27 /**
28 * \file KviIrcConnection.h
29 * \author Szymon Stefanek
30 * \brief An abstraction of a connection to an IRC server
31 */
32 
33 #include "kvi_settings.h"
34 #include "KviQString.h"
35 #include "KviTimeUtils.h"
36 
37 #include <QByteArray>
38 #include <QObject>
39 #include <QStringList>
40 
41 #include <memory>
42 #include <utility>
43 #include <vector>
44 
45 class QTimer;
46 class QTextCodec;
47 class KviConsoleWindow;
48 class KviIrcNetworkData;
49 class KviIrcServer;
50 class KviProxy;
51 class KviIrcSocket;
52 class KviIrcLink;
53 class KviDataBuffer;
54 class KviIrcContext;
55 class KviMainWindow;
56 class KviChannelWindow;
57 class KviQueryWindow;
58 class KviIrcConnectionTarget;
59 class KviIrcUserDataBase;
60 class KviIrcConnectionUserInfo;
61 class KviIrcConnectionServerInfo;
62 class KviIrcConnectionStateData;
63 class KviIrcConnectionAntiCtcpFloodData;
64 class KviIrcConnectionNetsplitDetectorData;
65 class KviIrcConnectionAsyncWhoisData;
66 class KviIrcConnectionStatistics;
67 class KviIrcConnectionRequestQueue;
68 class KviLagMeter;
69 class KviNotifyListManager;
70 class KviDnsResolver;
71 class KviUserIdentity;
72 class KviIdentityProfileSet;
73 class KviCString;
74 
75 /**
76 * \class KviIrcConnection
77 * \brief An abstraction of a connection to an IRC server
78 *
79 * This class deals with the high-level logic of a connection to an IRC server.
80 * It's always attached to a KviIrcContext and thus to a KviConsoleWindow window.
81 * The connection has a KviIrcConnectionTarget object which specifies the
82 * data of the server that needs to be contacted and a KviUserIdentity object
83 * which specifies the user data to use.
84 *
85 * The connection is the upper layer of the KVIrc networking stack. It owns
86 * KviIrcLink which is the layer immediately below and which in turn contains
87 * a KviIrcSocket.
88 *
89 * The connection creates and manages a lot of objects that handle
90 * runtime information. These objects include a KviIrcConnectionUserInfo which
91 * contains the ACTUAL user information, KviIrcConnectionServerInfo which
92 * contains the ACTUAL server information, KviIrcUserDataBase which is
93 * substantially a big hash table containing all the users visible to KVIrc in
94 * this connection, a list of channels, a list of queries etc...
95 */
96 class KVIRC_API KviIrcConnection : public QObject
97 {
98 	friend class KviConsoleWindow;
99 	friend class KviIrcContext;
100 	friend class KviIrcLink;
101 	friend class KviIrcServerParser;
102 	Q_OBJECT
103 protected:
104 	/**
105 	* \brief Creates a KviIrcConnection object.
106 	*
107 	* This is actually used only by KviConsoleWindow.
108 	*
109 	* pContext must not be nullptr and is kept as shallow pointer (that is, it's
110 	* not owned and must persists for the entire life of KviIrcConnection:
111 	* caller is responsable for that).
112 	*
113 	* pTarget must not be nullptr and must be allocated with new as this class
114 	* takes the ownership.
115 	*
116 	* pIdentity must not be nullptr and must be allocated with new as this class
117 	* takes the ownership.
118 	* \param pContext The KviIrcContext we're attacched to
119 	* \param pTarget The server data
120 	* \param pIdentity User information to use in this connection
121 	* \return KviIrcConnection
122 	*/
123 	KviIrcConnection(KviIrcContext * pContext, KviIrcConnectionTarget * pTarget, KviUserIdentity * pIdentity);
124 
125 	/**
126 	* \brief Destroys a KviIrcConnection object. KviConsoleWindow uses this.
127 	*/
128 	~KviIrcConnection();
129 
130 public:
131 	/**
132 	* \enum State
133 	* \brief The possible "high level" states of this connection.
134 	*/
135 	enum State
136 	{
137 		Idle,       /**< The connection is doing nothing */
138 		Connecting, /**< A connection attempt is in progress */
139 		Connected   /**< We're connected to an IRC server */
140 	};
141 
142 private:
143 	KviConsoleWindow * m_pConsole; // shallow, never null
144 	KviIrcContext * m_pContext;    // shallow, never null
145 
146 	State m_eState = Idle;
147 	bool m_bIdentdAttached = false;
148 
149 	KviIrcConnectionTarget * m_pTarget; // owned, never null
150 
151 	KviIrcLink * m_pLink; // owned, never null
152 
153 	// The initial information about the user we'll send out to the server
154 	// Note that the ACTUAL user information are in m_pUserInfo instead
155 	KviUserIdentity * m_pUserIdentity; // owned, never null
156 
157 	// The ACTUAL user information
158 	KviIrcConnectionUserInfo * m_pUserInfo; // owned, never null
159 	// The ACTUAL server information
160 	KviIrcConnectionServerInfo * m_pServerInfo; // owned, never null
161 
162 	KviIrcConnectionStateData * m_pStateData; // owned, never null
163 
164 	std::vector<KviChannelWindow *> m_pChannelList; // elements are borrowed and never null
165 	std::vector<KviQueryWindow *> m_pQueryList;     // elements are borrowed and never null
166 
167 	KviIrcUserDataBase * m_pUserDataBase; // owned, never null
168 
169 	KviNotifyListManager * m_pNotifyListManager = nullptr; // owned, see restartNotifyList()
170 	QTimer * m_pNotifyListTimer = nullptr;       // delayed startup timer for the notify lists
171 
172 	KviLagMeter * m_pLagMeter = nullptr; // owned, may be null (when not running)
173 
174 	KviIrcConnectionAntiCtcpFloodData * m_pAntiCtcpFloodData;       // owned, never null
175 	KviIrcConnectionNetsplitDetectorData * m_pNetsplitDetectorData; // owned, never null
176 	KviIrcConnectionAsyncWhoisData * m_pAsyncWhoisData;             // owned, never null
177 
178 	std::unique_ptr<KviIrcConnectionStatistics> m_pStatistics; // owned, never null
179 
180 	KviDnsResolver * m_pLocalhostDns = nullptr; // FIXME: this should go to an aux structure
181 
182 	QTextCodec * m_pSrvCodec;                       // connection codec: never null
183 	QTextCodec * m_pTextCodec;                      // connection codec: never null
184 	KviIrcConnectionRequestQueue * m_pRequestQueue; // owned, never null
185 public:
186 	/**
187 	* \brief Returns a pointer to the owning console
188 	*
189 	* The pointer is never nullptr
190 	* \return KviConsoleWindow *
191 	*/
console()192 	KviConsoleWindow * console() const { return m_pConsole; }
193 
194 	/**
195 	* \brief Returns a pointer to the owning KviIrcContext.
196 	*
197 	* The returned value is never nullptr
198 	* \return KviIrcContext *
199 	*/
context()200 	KviIrcContext * context() const { return m_pContext; }
201 
202 	/**
203 	* \brief Returns the target of this connection.
204 	*
205 	* Please note that the target doesn't necessairly contain up-to-date data.
206 	* You might want to look at serverInfo() instead.
207 	* The returned pointer is never nullptr.
208 	* \return KviIrcConnectionTarget *
209 	*/
target()210 	KviIrcConnectionTarget * target() const { return m_pTarget; }
211 
212 	/**
213 	* \brief Returns the underlying KviIrcLink object
214 	*
215 	* The returned pointer is never nullptr.
216 	* \return KviIrcLink *
217 	*/
link()218 	KviIrcLink * link() const { return m_pLink; }
219 
220 	/**
221 	* \brief Returns the current state of the connection
222 	* \return State
223 	*/
state()224 	State state() const { return m_eState; }
225 
226 	/**
227 	* \brief Returns a pointer to the big connection user database.
228 	*
229 	* The database contains ALL the users KVIrc can "see" in this connection.
230 	* The returned pointer is never nullptr.
231 	* \return KviIrcUserDataBase *
232 	*/
userDataBase()233 	KviIrcUserDataBase * userDataBase() const { return m_pUserDataBase; }
234 
235 	/**
236 	* \brief Returns a pointer to the KviIrcConnectionUserInfo object
237 	*
238 	* It contains runtime information about the user. This includes the
239 	* current nickname, username, flags and other stuff that KviUserIdentity
240 	* actually doesn't contain (or has only "default" values for).
241 	* The returned pointer is never nullptr.
242 	* Include "KviIrcConnectionUserInfo.h" as the class is only
243 	* forwarded here.
244 	* \return KviIrcConnectionUserInfo *
245 	*/
userInfo()246 	KviIrcConnectionUserInfo * userInfo() const { return m_pUserInfo; }
247 
248 	/**
249 	* \brief Returns a pointer to the KviIrcConnectionServerInfo object
250 	*
251 	* It contains runtime information about the current server. This includes
252 	* the current servername, the server capabilities and other stuff that
253 	* KviConnectionTarget actually doesn't contain (or has only "default"
254 	* values for).
255 	* The returned pointer is never nullptr.
256 	* Include "KviIrcConnectionServerInfo.h" as the class is only
257 	* forwarded here.
258 	* \return KviIrcConnectionServerInfo *
259 	*/
serverInfo()260 	KviIrcConnectionServerInfo * serverInfo() const { return m_pServerInfo; }
261 
262 	/**
263 	* \brief Returns a pointer to the KviIrcConnectionStateData object
264 	*
265 	* It contains _generic_ connection state data. This includes the current
266 	* nickname index at login time, flags that signal "micro-states" etc...
267 	* This data *could* be part of KviIrcConnection itself but we prefer to
268 	* keep it in a separate class in order to cleanup the implementation.
269 	* The returned pointer is never nullptr.
270 	* Include "KviIrcConnectionStateData.h" as the class is only
271 	* forwarded here.
272 	* \return KviIrcConnectionStateData *
273 	*/
stateData()274 	KviIrcConnectionStateData * stateData() const { return m_pStateData; }
275 
276 	/**
277 	* \brief Returns a pointer to the KviIrcConnectionAntiCtcpFloodData object
278 	*
279 	* It contains data private to the Anti CTCP Flood engine. Very similar
280 	* to KviIrcConnectionStateData but dedicated to Ctcp flood.
281 	* The returned pointer is never nullptr.
282 	* Include "KviIrcConnectionAntiCtcpFloodData.h" as the class is
283 	* only forwarded here.
284 	* \return KviIrcConnectionAntiCtcpFloodData *
285 	*/
antiCtcpFloodData()286 	KviIrcConnectionAntiCtcpFloodData * antiCtcpFloodData() const
287 	{
288 		return m_pAntiCtcpFloodData;
289 	}
290 
291 	/**
292 	* \brief Returns a pointer to the KviIrcConnectionNetsplitDetectorData object
293 	*
294 	* It contains data private to the netsplit detector engine. Very similar
295 	* to KviIrcConnectionStateData but dedicated to netsplit detection.
296 	* The returned pointer is never nullptr.
297 	* Include "KviIrcConnectionNetsplitDetectorData.h" as the class is
298 	* only forwarded here.
299 	* \return KviIrcConnectionNetsplitDetectorData *
300 	*/
netsplitDetectorData()301 	KviIrcConnectionNetsplitDetectorData * netsplitDetectorData() const
302 	{
303 		return m_pNetsplitDetectorData;
304 	}
305 
306 	/**
307 	* \brief Returns a pointer to the KviIrcConnectionAsyncWhoisData object
308 	*
309 	* It contains data private to the async whois engine. Very similar to
310 	* KviIrcConnectionStateData but dedicated to async whois.
311 	* The returned pointer is never nullptr.
312 	* Include "KviIrcConnectionAsyncWhoisData.h" as the class is only
313 	* forwarded here.
314 	* \return KviIrcConnectionAsyncWhoisData *
315 	*/
asyncWhoisData()316 	KviIrcConnectionAsyncWhoisData * asyncWhoisData() const
317 	{
318 		return m_pAsyncWhoisData;
319 	}
320 
321 	/**
322 	* \brief Returns a pointer to the KviIrcConnectionStatistics object
323 	*
324 	* It contains runtime statistics about the connection. Very similar to
325 	* KviIrcConnectionStateData but dedicated to statistics.
326 	* The returned pointer is never nullptr.
327 	* Include "KviIrcConnectionStatistics.h" as the class is only
328 	* forwarded here.
329 	* \return KviIrcConnectionStatistics *
330 	*/
statistics()331 	KviIrcConnectionStatistics * statistics() const { return m_pStatistics.get(); }
332 
333 	/**
334 	* \brief Returns a pointer to the current KviNotifyListManager.
335 	*
336 	* The returned pointer is nullptr if notify list management is disabled for
337 	* the current connection.
338 	* \return KviNotifyListManager *
339 	*/
notifyListManager()340 	KviNotifyListManager * notifyListManager() const
341 	{
342 		return m_pNotifyListManager;
343 	}
344 
345 	/**
346 	* \brief Returns a pointer to the current KviLagMeter.
347 	*
348 	* The returned pointer is nullptr if lag measurement is disabled for the
349 	* current connection.
350 	* \return KviLagMeter *
351 	*/
lagMeter()352 	KviLagMeter * lagMeter() const { return m_pLagMeter; }
353 
354 	/**
355 	* \brief Returns a pointer to the current KviIrcConnectionRequestQueue.
356 	* \return KviIrcConnectionRequestQueue *
357 	*/
requestQueue()358 	KviIrcConnectionRequestQueue * requestQueue() const { return m_pRequestQueue; }
359 
360 	/**
361 	* \brief Returns the list of the channels bound to the current connection.
362 	*
363 	* The pointer itself is never null (though the list may be empty).
364 	* \return & std::vector<KviChannelWindow *>
365 	*/
channelList()366 	std::vector<KviChannelWindow *> & channelList() { return m_pChannelList; }
367 
368 	/**
369 	* \brief Helper that provides a shortcut for really common access to serverInfo()->networkName()
370 	* \return const QString &
371 	*/
372 	const QString & currentNetworkName() const;
373 
374 	/**
375 	* \brief Helper that provides a shortcut for really common access to userInfo()->nickName()
376 	* \return const QString &
377 	*/
378 	const QString & currentNickName() const;
379 
380 	/**
381 	* \brief Helper that provides a shortcut for really common access to userInfo()->userName()
382 	* \return const QString &
383 	*/
384 	const QString & currentUserName() const;
385 
386 	/**
387 	* \brief Helper that provides a shortcut for really common access to serverInfo()->name()
388 	* \return const QString &
389 	*/
390 	const QString & currentServerName() const;
391 
392 	//
393 	// Channel management
394 	//
395 	// FIXME: Delegate to a KviChannelManager
396 	//
397 
398 	/**
399 	* \brief Finds the channel with the specified unicode name.
400 	*
401 	* Returns the pointer to the channel found or nullptr if there is no such
402 	* channel.
403 	* \param szName The name of the channel
404 	* \return KviChannelWindow *
405 	*/
406 	KviChannelWindow * findChannel(const QString & szName);
407 
408 	/**
409 	* \brief Returns a list of channels bound to the current connection
410 	*
411 	* This is actually the list of channels that the local user has in common
412 	* with the specified user.
413 	* The list is returned as a comma separated string. If bAddEscapeSequences
414 	* is true, then the string includes special escape sequences for
415 	* KviIrcView that will make the channel names clickable.
416 	*
417 	* Returns the number of channels found.
418 	* \param szNick The nickname of the user
419 	* \param szChansBuffer The buffer where to store data
420 	* \param bAddEscapeSequences Whether to include escape sequences
421 	* \return int
422 	*/
423 	int getCommonChannels(const QString & szNick, QString & szChansBuffer, bool bAddEscapeSequences = true);
424 
425 	/**
426 	* \brief Creates a new channel with the specified name.
427 	*
428 	* This should be called in response to a JOIN message.
429 	* This function _assumes_ that such a channel doesn't exist yet (or if it
430 	* exists then it's actually in DEAD state). You can assume that channel
431 	* creation never fails: if the returned pointer is nullptr then we're screwed
432 	* anyway as virtual memory is exausted.
433 	* \param szName The name of the channel
434 	* \return KviChannelWindow *
435 	*/
436 	KviChannelWindow * createChannel(const QString & szName);
437 
438 	///
439 	/// This is called by KviChannelWindow upon creation. You shouldn't need to call it.
440 	///
441 	/// FIXME: Could be made protected.
442 	///
443 	void registerChannel(KviChannelWindow * c);
444 
445 	///
446 	/// This is called by KviChannelWindow just before destruction. You shouldn't need to call it.
447 	///
448 	/// FIXME: Could be made protected.
449 	///
450 	void unregisterChannel(KviChannelWindow * c);
451 
452 	/**
453 	* \brief Marks all the currently existing channels as DEAD
454 	*
455 	* They are preserved across connections. Marking a channel as dead
456 	* actually removes the ownership of KviChannelWindow from KviIrcConnection and
457 	* moves it to KviIrcContext (as the contex is preserved across
458 	* connections).
459 	* \return void
460 	*/
461 	void keepChannelsOpenAfterDisconnect();
462 
463 	/**
464 	* \brief Closes all the currently open channels not marked as dead.
465 	* \return void
466 	*/
467 	void closeAllChannels();
468 
469 	/**
470 	* \brief Closes all the currently open queries not marked as dead.
471 	* \return void
472 	*/
473 	void closeAllQueries();
474 
475 	//
476 	// Query management
477 	//
478 	// FIXME: Delegate to a KviQueryManager ?
479 	//
480 
481 	/**
482 	* \brief Finds the query with the specified nick.
483 	*
484 	* Returns the pointer to the query found or nullptr if there is no such
485 	* query.
486 	* \param szNick The nickname of the user
487 	* \return KviQueryWindow *
488 	*/
489 	KviQueryWindow * findQuery(const QString & szNick);
490 
491 	/**
492 	* \brief Returns the list of the currently open queries.
493 	*
494 	* The returned pointer is never nullptr (the list may be empty though).
495 	* \return std::vector<KviQueryWindow *> &
496 	*/
queryList()497 	std::vector<KviQueryWindow *> & queryList() { return m_pQueryList; }
498 
499 	///
500 	/// Visibility mode for createQuery()
501 	///
502 	enum CreateQueryVisibilityMode
503 	{
504 		///
505 		/// Create minimized query, overriding settings
506 		///
507 		CreateQueryVisibilityMinimized,
508 		///
509 		/// Create visible query, overriding settings
510 		///
511 		CreateQueryVisibilityVisible,
512 		///
513 		/// Follow global settings.
514 		///
515 		CreateQueryVisibilityFollowSettings
516 	};
517 
518 	/**
519 	* \brief Creates a query with the specified nick as target.
520 	*
521 	* This function assumes that such a query doesn't exist yet (or if it
522 	* exists it's actually marked as dead and needs to be resurrected).
523 	* \param szNick The nickname of the user
524 	* \param eShowMode Specifies the show mode for the window
525 	* \return KviQueryWindow *
526 	*/
527 	KviQueryWindow * createQuery(const QString & szNick, CreateQueryVisibilityMode eVisibilityMode = CreateQueryVisibilityFollowSettings);
528 
529 	///
530 	/// This is called by KviQueryWindow upon creation, you shouldn't need to use it.
531 	///
532 	/// FIXME: Could be made protected.
533 	///
534 	void registerQuery(KviQueryWindow * q);
535 
536 	///
537 	/// This is called by KviQueryWindow just before destruction, you shouldn't need to use it.
538 	///
539 	/// FIXME: Could be made protected.
540 	///
541 	void unregisterQuery(KviQueryWindow * q);
542 
543 	/**
544 	* \brief Marks all the currently open queries as DEAD
545 	*
546 	* They are kept open after a disconnect. Marking a query as dead removes
547 	* ownership from this class and gives it to KviIrcContext (which survives
548 	* disconnects).
549 	* \return void
550 	*/
551 	void keepQueriesOpenAfterDisconnect();
552 
553 	/**
554 	* \brief This is the inverse of keepQueriesOpenAfterDisconnect().
555 	*
556 	* It's meant to be called upon reconnection (as queries don't need a JOIN
557 	* message to be opened).
558 	* \return void
559 	*/
560 	void resurrectDeadQueries();
561 
562 	///
563 	/// This function actually restarts the lag meter.
564 	///
565 	/// FIXME: Why ?
566 	///
567 	void restartLagMeter();
568 
569 	//
570 	// Networking stack public stuff
571 	//
572 
573 	/**
574 	* \brief Sends the specified text on the connected link (and thus socket).
575 	*
576 	* This function basically works like sprintf(). Please note that you
577 	* should send only ENCODED text to the server. This is why the accepted
578 	* parameter is a const char *. IRC is an 8 (I'd say even 7 sometimes) bit
579 	* protocol.
580 	*
581 	* Please note that you don't actually need to append a CRLF pair to your
582 	* buffer:
583 	* the implementation of the networking stack will do it for you. Hovewer
584 	* you can send multiple IRC commands by separating them by CRLF pairs.
585 	* Just take care of avoiding a CRLF after the last command you specify.
586 	*
587 	* Returns true on success or false if the data can't be actually
588 	* enqueued/sent (and this usually means that there is no connection at
589 	* the moment). Please note that it MAY happen that a send attempt on a
590 	* correctly connected link causes the link to actually disconnect (or
591 	* rather "discover" the fact that it's disconnected at OS level).
592 	* \param pcBuffer The _encoded_ text data to send
593 	* \param iBuflen The length of the data: if -1 the length is determined via strlen().
594 	* \return bool
595 	*/
596 	bool sendData(const char * pcBuffer, int iBuflen = -1);
597 
598 	/**
599 	* \brief Sends the specified text on the connected link (and thus socket).
600 	*
601 	* This function basically works like sprintf(). Please note that you
602 	* should send only ENCODED text to the server. This is why the accepted
603 	* parameter is a const char *. IRC is an 8 (I'd say even 7 sometimes) bit
604 	* protocol.
605 	*
606 	* Please note that you don't actually need to append a CRLF pair to your
607 	* buffer:
608 	* the implementation of the networking stack will do it for you. Hovewer
609 	* you can send multiple IRC commands by separating them by CRLF pairs.
610 	* Just take care of avoiding a CRLF after the last command you specify.
611 	*
612 	* Returns true on success or false if the data can't be actually
613 	* enqueued/sent (and this usually means that there is no connection at
614 	* the moment). Please note that it MAY happen that a send attempt on a
615 	* correctly connected link causes the link to actually disconnect (or
616 	* rather "discover" the fact that it's disconnected at OS level).
617 	* \param pcFmt The format string to be first sprintf'ed with the variadic params and then sent
618 	* \param ... The variadic arguments (see man sprintf for an explanation)
619 	* \return bool
620 	*
621 	* FIXME: change name to sendFormattedData() ?
622 	*/
623 	bool sendFmtData(const char * pcFmt, ...);
624 
625 	/**
626 	* Clears the underlying output queue.
627 	* Exposed basically for /context.clearQueue
628 	* You shouldn't need it for any other reason :)
629 	*/
630 	void clearOutputQueue(bool bPrivateMessagesOnly);
631 
632 	/**
633 	* \brief Returns the current size of the output queue.
634 	* \return unsigned int
635 	*/
636 	unsigned int outputQueueSize();
637 
638 	/**
639 	* \brief This function is part of the networking stack.
640 	*
641 	* It's called by KviIrcLink OR KviMexLinkFilter when a message is arriving
642 	* from the server. Needs to be public because subclasses of
643 	* KviMexLinkFilter may call it.
644 	* \param pcMessage The message :)
645 	* \return void
646 	*/
647 	void incomingMessage(const char * pcMessage);
648 
649 	/**
650 	* \brief This function is part of the networking stack.
651 	*
652 	* It's called by KviIrcDataStreamMonitor subclasses when they want to
653 	* inject some message without getting it filtered again
654 	* \param pcMessage The message :)
655 	* \return void
656 	*/
657 	void incomingMessageNoFilter(const char * pcMessage);
658 
659 	//
660 	// Encoding related stuff
661 	//
662 
663 	/**
664 	* \brief Returns a pointer to the current global codec for outbound text.
665 	*
666 	* This codec is a global setting and may be overridden by specific
667 	* windows. The returned pointer may be null if things really went wrong.
668 	* \return QTextCodec *
669 	*/
textCodec()670 	QTextCodec * textCodec() const { return m_pTextCodec; }
671 
672 	/**
673 	* \brief Returns a pointer to the current global codec for inbound data.
674 	*
675 	* This codec is a global setting and may be overridden by specific
676 	* windows. The returned pointer may be null if things really went wrong.
677 	* \return QTextCodec *
678 	*/
serverCodec()679 	QTextCodec * serverCodec() const { return m_pSrvCodec; }
680 
681 	/**
682 	* \brief Sets the global encoding for this connection.
683 	*
684 	* This is a default value and can be overridden by specific windows.
685 	* This is tipically called upon a successful CODEPAGE change (numerical 222)
686 	* response from a server; from now on, the server will translate (encode)
687 	* everything (including IDN hostnames, channel names, messages) using this
688 	* encoding. So we expect this encoding to be the new default for the server
689 	* (connection), the console, each other channel and query.
690 	* \param szEncoding The encoding to use
691 	* \return void
692 	*/
693 	void setEncoding(const QString & szEncoding);
694 
695 	/**
696 	* \brief Decodes the specified text by using the server codec.
697 	*
698 	* You should first attempt to decode the text by using the window codec
699 	* (if you belong to a window).
700 	* \param szText The text to decode
701 	* \return QString
702 	*/
703 	QString decodeText(const char * szText);
704 
705 	/**
706 	* \brief Encodes the specified text by using the local text codec.
707 	*
708 	* You should first attempt to encode the text by using the window codec
709 	* (if you belong to a window).
710 	* \param szText The text to encode
711 	* \return QByteArray
712 	*/
713 	QByteArray encodeText(const QString & szText);
714 
715 protected:
716 	//
717 	// Notify list management
718 	//
719 
720 	/**
721 	* \brief Starts the notify list in 15 seconds
722 	*
723 	* We have this delay to wait an eventual RPL_PROTOCTL from the server
724 	* telling us that the WATCH notify list method is supported
725 	* \return void
726 	*/
727 	void delayedStartNotifyList();
728 
729 	//
730 	// Login operations
731 	//
732 
733 	/**
734 	* \brief Resolves the localhost into an IP address
735 	* \return void
736 	*/
737 	void resolveLocalHost();
738 
739 #ifdef COMPILE_SSL_SUPPORT
740 	void handleFailedInitialStartTls();
741 	bool trySTARTTLS(bool bAppendPing);
742 	void enableStartTlsSupport(bool bEnable);
743 #endif
744 
745 	/**
746 	* \brief Uses the profiles' data as connection data
747 	*
748 	* It checks if the identity profiles are enabled and updates the data
749 	* of the connection if a profile rule matches the network name
750 	* \param pSet The instance of the network identity profile set
751 	* \param szNetwork The name of the network
752 	* \return void
753 	*/
754 	void useProfileData(KviIdentityProfileSet * pSet, const QString & szNetwork);
755 
756 	/**
757 	* Sets the specified real name in the user information set after
758 	* evaluating it via KVS engine (so identifiers are substituted).
759 	* Call this function instead of m_pUserInfo->setRealName().
760 	*/
761 	void useRealName(const QString & szRealName);
762 
763 	/**
764 	* \brief Logins to the irc server
765 	* \return void
766 	*/
767 	void loginToIrcServer();
768 
769 	/**
770 	* Joins a list of channels.
771 	* The first element of the pair is the channel name, the second element of the pair is the eventual password.
772 	* May send multiple JOIN messages.
773 	*/
774 	void joinChannels(const std::vector<std::pair<QString, QString>> & lChannelsAndPasses);
775 
776 	/**
777 	* Gather the list of currently joined channels with the relative passwords.
778 	*/
779 	void gatherChannelAndPasswordPairs(std::vector<std::pair<QString, QString>> & lChannelsAndPasses);
780 
781 	/**
782 	* Gather the list of currently open query names.
783 	*/
784 	void gatherQueryNames(QStringList & lQueryNames);
785 
786 	/**
787 	* Picks the next login nickname to be tried. If bForceDefaultIfPrimaryNicknamesEmpty is true then the algorithm
788 	* will return a default nickname in case the primary setting in the options is empty. If bForceDefaultIfPrimaryNicknamesEmpty
789 	* is false then the algorithm will try the alternative nicknames instead, then try some random options and finally
790 	* return an empty string signaling that no suitable choice could be made. bForceDefaultIfPrimaryNicknamesEmpty should
791 	* be set to true only in loginToIrcServer(), that is, the first time this function is called (otherwise there exists
792 	* a possibility of infinite nickname loop because of the repeated fallback choice). szBaseNickForRandomChoices will be
793 	* used for the random alternatives as the first left 7 characters. Upon return szChoiceDescriptionBuffer will contain
794 	* the textual description of the choice made (network specific, alternative, server specific, global etc...).
795 	*/
796 	QString pickNextLoginNickName(bool bForceDefaultIfPrimaryNicknamesEmpty, const QString & szBaseNickForRandomChoices, QString & szChoiceDescriptionBuffer);
797 
798 	//
799 	// KviIrcServerParser interface
800 	//
801 
802 	/**
803 	* \brief Called to start the notify lists when RPL_ENDOFMOTD is received
804 	* \return void
805 	*/
806 	void endOfMotdReceived();
807 
808 	/**
809 	* \brief Called when RPL_SERVINFO (004) is received and sets the info
810 	* \param szServerName The name of the server
811 	* \param szUserModes The user modes supported by the server
812 	* \param szChanModes The chan modes supported by the server
813 	* \return void
814 	*/
815 	void serverInfoReceived(const QString & szServerName, const QString & szUserModes, const QString & szChanModes);
816 
817 	/**
818 	* \brief Called when AUTHENTICATE answer is received
819 	* \return void
820 	*/
821 	void handleAuthenticate(KviCString & szResponse);
822 
823 	/**
824 	* \brief Called when CAP LS answer is received
825 	* \return void
826 	*/
827 	void handleInitialCapLs();
828 
829 	/**
830 	* \brief Called when CAP LS negotiation fails
831 	* \return void
832 	*/
833 	void handleFailedInitialCapLs();
834 
835 	/**
836 	* \brief Called when CAP ACK answer is received
837 	* \return void
838 	*/
839 	void handleInitialCapAck();
840 
841 	/**
842 	* \brief Called when CAP NAK answer is received
843 	* \return void
844 	*/
845 	void handleInitialCapNak();
846 
847 	/**
848 	* \brief Called when we want to end CAP negotiation and go on wi the login
849 	* \return void
850 	*/
851 	void endInitialCapNegotiation();
852 
853 	/**
854 	* \brief Called to update the away state
855 	* \param bAway Whether we enter the away mode
856 	* \return void
857 	*/
858 	void changeAwayState(bool bAway);
859 
860 	/**
861 	* \brief Called on each JOIN and sets the info
862 	*
863 	* It's called meaningful almost only on the first time
864 	* \param szUserName The username
865 	* \param szHostName The hostname
866 	* \return void
867 	* FIXME: call it also on other messages ?
868 	*/
869 	void userInfoReceived(const QString & szUserName, const QString & szHostName);
870 
871 	/**
872 	* \brief Called when NICK is received
873 	* \param szNewNick The new nickname for the user
874 	* \return void
875 	*/
876 	void nickChange(const QString & szNewNick);
877 
878 	/**
879 	* \brief Called when MODE is received for each mode character
880 	* \param cMode The mode flag :)
881 	* \param bSet Whether to set the mode
882 	* \return bool
883 	*/
884 	bool changeUserMode(char cMode, bool bSet);
885 
886 	/**
887 	* \brief Called on the first numeric received from server
888 	* \param szNickName The nickname to use
889 	* \return void
890 	*/
891 	void loginComplete(const QString & szNickName);
892 
893 	//
894 	// KviIrcContext interface
895 	//
896 
897 	/**
898 	* \brief This starts an asynchronous connection attempt
899 	*
900 	* You must return control to the Qt core for the connection operations to
901 	* be initiated
902 	* \return void
903 	*/
904 	void start();
905 
906 	/**
907 	* \brief Kills any running connection or attempt
908 	* \return void
909 	*/
910 	void abort();
911 
912 	/**
913 	* \brief Called once in a while (every 5 secs at the moment)
914 	* \param tNow The current time
915 	* \return void
916 	*/
917 	void heartbeat(kvi_time_t tNow);
918 
919 	//
920 	// KviIrcLink interface (down)
921 	//
922 
923 	/**
924 	* \brief This signals that the connection attempt has failed
925 	* \param iError The error code
926 	* \return void
927 	*/
928 	void linkAttemptFailed(int iError);
929 
930 	/**
931 	* \brief Called by KviIrcLink when the socket state changes to Connected
932 	* \return void
933 	*/
934 	void linkEstablished();
935 
936 	/**
937 	* \brief Called by KviIrcLink when the socket state changes to Ready
938 	* \return void
939 	*/
940 	void linkTerminated();
941 
942 private:
943 	/**
944 	* \brief Setups the codec for the text
945 	* \return void
946 	*/
947 	void setupTextCodec();
948 
949 	/**
950 	* \brief Setups the codec for the server
951 	* \return void
952 	*/
953 	void setupSrvCodec();
954 public slots:
955 	/**
956 	* \brief Called when we unhighlight all channels
957 	* \return void
958 	*/
959 	void unhighlightAllChannels();
960 
961 	/**
962 	* \brief Called when we unhighlight all queries
963 	* \return void
964 	*/
965 	void unhighlightAllQueries();
966 
967 	/**
968 	* \brief Called to restart the notify list
969 	* \return void
970 	*/
971 	void restartNotifyList();
972 private slots:
973 	/**
974 	* \brief Called when the hostname lookup is finished
975 	* \return void
976 	*/
977 	void hostNameLookupTerminated(KviDnsResolver * pDns);
978 signals:
979 	/**
980 	* \brief Emitted when the away state changes
981 	* \return void
982 	*/
983 	void awayStateChanged();
984 
985 	/**
986 	* \brief Emitted when the user modes change
987 	* \return void
988 	*/
989 	void userModeChanged();
990 
991 	/**
992 	* \brief Emitted when the nickname changes
993 	* \return void
994 	*/
995 	void nickNameChanged();
996 
997 	/**
998 	* \brief Emitted when we register a channel
999 	* \param pChan The channel :)
1000 	* \return void
1001 	*/
1002 	void channelRegistered(KviChannelWindow * pChan);
1003 
1004 	/**
1005 	* \brief Emitted when we unregister a channel
1006 	* \param pChan The channel :)
1007 	* \return void
1008 	*/
1009 	void channelUnregistered(KviChannelWindow * pChan);
1010 
1011 	/**
1012 	* \brief Emitted when the channels list change
1013 	* \return void
1014 	*/
1015 	void chanListChanged();
1016 };
1017 
1018 // TODO: KviIdentity
1019 
1020 #endif //_KVI_IRCCONNECTION_H_
1021