X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fnetworkconnection.h;h=d9474557f5c06c633b4296c6368740696136e210;hp=a7d6eba65152cbe97f6c71cd3c0a62565e067f64;hb=f7379184b7c0ae4e53d7470809f84e2ad3239ec1;hpb=fd7c2c4a41b5bb9cffcfe7a8f86a28ab7f38ac27 diff --git a/src/core/networkconnection.h b/src/core/networkconnection.h index a7d6eba6..d9474557 100644 --- a/src/core/networkconnection.h +++ b/src/core/networkconnection.h @@ -24,122 +24,183 @@ #include #include #include -#include -#include #include +#ifdef HAVE_SSL +# include +# include +#else +# include +#endif + +#include "coresession.h" +#include "identity.h" #include "message.h" +#include "network.h" #include "signalproxy.h" -class Network; - class IrcServerHandler; class UserInputHandler; class CtcpHandler; -class CoreSession; - -/*! - * This is a server object, managing a single connection to an IRC server, handling the associated channels and so on. - * We have this running in its own thread mainly to not block other server objects or the core if something goes wrong, - * e.g. if some scripts starts running wild... - */ -class NetworkConnection : public QThread { +class NetworkConnection : public QObject { Q_OBJECT public: - NetworkConnection(UserId uid, NetworkId networkId, QString network, const QVariant &previousState = QVariant()); + NetworkConnection(Network *network, CoreSession *session); ~NetworkConnection(); - UserId userId() const { return _userId; } + inline NetworkId networkId() const { return network()->networkId(); } + inline QString networkName() const { return network()->networkName(); } + inline Network *network() const { return _network; } + inline Identity *identity() const { return coreSession()->identity(network()->identity()); } + inline CoreSession *coreSession() const { return _coreSession; } - // networkState state(); - bool isConnected() const { return socket.state() == QAbstractSocket::ConnectedState; } + inline bool isConnected() const { return connectionState() == Network::Initialized; } + inline Network::ConnectionState connectionState() const { return _connectionState; } - NetworkId networkId() const; - QString networkName() const; // hasbeen getNetwork() - - Network *network() const { return _network; } - IrcServerHandler *ircServerHandler() const { return _ircServerHandler; } - UserInputHandler *userInputHandler() const { return _userInputHandler; } - CtcpHandler *ctcpHandler() const { return _ctcpHandler; } - - QVariant state(); ///< Return data necessary to restore the server's state upon core restart + inline IrcServerHandler *ircServerHandler() const { return _ircServerHandler; } + inline UserInputHandler *userInputHandler() const { return _userInputHandler; } + inline CtcpHandler *ctcpHandler() const { return _ctcpHandler; } //! Decode a string using the server (network) decoding. QString serverDecode(const QByteArray &string) const; - //! Decode a string using a buffer-specific encoding if one is set (and use the server encoding else). - QString bufferDecode(const QString &bufferName, const QByteArray &string) const; + //! Decode a string using a channel-specific encoding if one is set (and use the standard encoding else). + QString channelDecode(const QString &channelName, const QByteArray &string) const; - //! Decode a string using a IrcUser specific encoding, if one exists (using the server encoding else). + //! Decode a string using an IrcUser-specific encoding, if one exists (using the standaed encoding else). QString userDecode(const QString &userNick, const QByteArray &string) const; //! Encode a string using the server (network) encoding. QByteArray serverEncode(const QString &string) const; - //! Encode a string using the buffer-specific encoding, if set, and use the server encoding else. - QByteArray bufferEncode(const QString &bufferName, const QString &string) const; + //! Encode a string using the channel-specific encoding, if set, and use the standard encoding else. + QByteArray channelEncode(const QString &channelName, const QString &string) const; - //! Encode a string using the user-specific encoding, if set, and use the server encoding else. + //! Encode a string using the user-specific encoding, if set, and use the standard encoding else. QByteArray userEncode(const QString &userNick, const QString &string) const; + inline QString channelKey(const QString &channel) const { return _channelKeys.value(channel.toLower(), QString()); } + inline QStringList persistentChannels() const { return _channelKeys.keys(); } + + inline bool isAutoWhoInProgress(const QString &channel) const { return _autoWhoInProgress.value(channel.toLower(), 0); } + public slots: // void setServerOptions(); - void connectToIrc(QString net); - void disconnectFromIrc(QString net); - void userInput(uint netid, QString buffer, QString msg); + void connectToIrc(bool reconnecting = false); + void disconnectFromIrc(bool requested = true, const QString &reason = QString()); + void userInput(BufferInfo bufferInfo, QString msg); - void putRawLine(QString input); - void putCmd(QString cmd, QStringList params, QString prefix = 0); + void putRawLine(QByteArray input); + int lastParamOverrun(const QString &cmd, const QList ¶ms); + void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); + void setChannelJoined(const QString &channel); + void setChannelParted(const QString &channel); + void addChannelKey(const QString &channel, const QString &key); + void removeChannelKey(const QString &channel); -private slots: - void threadFinished(); - void sendPerform(); + bool setAutoWhoDone(const QString &channel); signals: - void networkState(QString net, QVariantMap data); + // #void networkState(QString net, QVariantMap data); void recvRawServerMsg(QString); void displayStatusMsg(QString); //void displayMsg(Message msg); - void displayMsg(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None); - void connected(uint networkId); - void disconnected(uint networkId); - + void displayMsg(Message::Type, BufferInfo::Type, QString target, QString text, QString sender = "", Message::Flags flags = Message::None); + void connected(NetworkId networkId); ///< Emitted after receipt of 001 to indicate that we can now send data to the IRC server + void disconnected(NetworkId networkId); + void connectionStateChanged(Network::ConnectionState); void connectionInitialized(); ///< Emitted after receipt of 001 to indicate that we can now send data to the IRC server + void connectionError(const QString &errorMsg); - void synchronizeClients(); - - void queryRequested(QString network, QString nick); + void quitRequested(NetworkId networkId); + + //void queryRequested(QString network, QString nick); + void nickChanged(const NetworkId &networkId, const QString &newNick, const QString &oldNick); // this signal is inteded to rename query buffers in the storage backend + void channelJoined(NetworkId, const QString &channel, const QString &key = QString()); + void channelParted(NetworkId, const QString &channel); + void sslErrors(const QVariant &errorData); private slots: - void run(); void socketHasData(); void socketError(QAbstractSocket::SocketError); void socketConnected(); + void socketInitialized(); + void socketCloseTimeout(); + void socketDisconnected(); void socketStateChanged(QAbstractSocket::SocketState); + void setConnectionState(Network::ConnectionState); + void networkInitialized(const QString ¤tServer); -private: - UserId _userId; - NetworkId _networkId; + void sendPerform(); + void autoReconnectSettingsChanged(); + void doAutoReconnect(); + void sendPing(); + void sendAutoWho(); + void startAutoWhoCycle(); + void nickChanged(const QString &newNick, const QString &oldNick); // this signal is inteded to rename query buffers in the storage backend + +#ifdef HAVE_SSL + void socketEncrypted(); + void sslErrors(const QList &errors); +#endif + void fillBucketAndProcessQueue(); + +private: +#ifdef HAVE_SSL + QSslSocket socket; +#else QTcpSocket socket; +#endif + + Network::ConnectionState _connectionState; + + Network *_network; + CoreSession *_coreSession; + BufferInfo _statusBufferInfo; IrcServerHandler *_ircServerHandler; UserInputHandler *_userInputHandler; CtcpHandler *_ctcpHandler; - Network *_network; + QHash _channelKeys; // stores persistent channels and their passwords, if any + + QTimer _autoReconnectTimer; + + int _autoReconnectCount; + + QTimer _socketCloseTimer; - QVariantMap networkSettings; - QVariantMap identity; + /* this flag triggers quitRequested() once the socket is closed + * it is needed to determine whether or not the connection needs to be + *in the automatic session restore. */ + bool _quitRequested; - QVariant _previousState; + bool _previousConnectionAttemptFailed; + int _lastUsedServerlistIndex; - CoreSession *coreSession() const; + QTimer _pingTimer; + bool _autoWhoEnabled; + QStringList _autoWhoQueue; + QHash _autoWhoInProgress; + int _autoWhoInterval; + int _autoWhoNickLimit; + int _autoWhoDelay; + QTimer _autoWhoTimer, _autoWhoCycleTimer; + + QTimer _tokenBucketTimer; + int _messagesPerSecond; // token refill speed + int _burstSize; // size of the token bucket + int _tokenBucket; // the virtual bucket that holds the tokens + QList _msgQueue; + + void writeToSocket(QByteArray s); + class ParseError : public Exception { public: ParseError(QString cmd, QString prefix, QStringList params); @@ -149,7 +210,6 @@ private: public: UnknownCmdError(QString cmd, QString prefix, QStringList params); }; - }; #endif