diff options
Diffstat (limited to '')
-rw-r--r-- | server/ircnetwork.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/server/ircnetwork.cpp b/server/ircnetwork.cpp new file mode 100644 index 0000000..e50a309 --- /dev/null +++ b/server/ircnetwork.cpp @@ -0,0 +1,158 @@ +#include "ircnetwork.h" +#include "bouncer.h" +#include <QTcpSocket> +#include <QSslSocket> + +IRCNetwork::IRCNetwork(IRCNetworkConfig &config, QObject *parent) : + QObject(parent) +{ + m_config = config; + m_loggedIn = false; + m_socket = NULL; + + qDebug("[%p] IRCNetwork::IRCNetwork()", this); +} + + + + +void IRCNetwork::startConnection() { + unlinkSocket(); + qDebug("[%p] IRCNetwork::startConnection()", this); + + m_readBuffer.clear(); + + if (m_config.useSSL) { + QSslSocket *ssl = new QSslSocket(this); + m_socket = ssl; + + connect(ssl, SIGNAL(encrypted()), this, SLOT(socketConnected())); + connect(ssl, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(socketSslErrors(QList<QSslError>))); + + ssl->ignoreSslErrors(); + ssl->connectToHostEncrypted(m_config.hostname, m_config.port); + } else { + m_socket = new QTcpSocket(this); + connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected())); + m_socket->connectToHost(m_config.hostname, m_config.port); + } + + connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReceived())); + connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); + connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); + + qDebug("[%p] Going...", this); +} + +void IRCNetwork::unlinkSocket() { + markAsDisconnected(); + + if (m_socket != NULL) { + QObject::disconnect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected())); + QObject::disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReceived())); + QObject::disconnect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); + QObject::disconnect(m_socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); + + QSslSocket *ssl = qobject_cast<QSslSocket *>(m_socket); + if (ssl) { + QObject::disconnect(ssl, SIGNAL(encrypted()), this, SLOT(socketConnected())); + } + + m_socket->close(); + m_socket->deleteLater(); + m_socket = NULL; + } +} + + +void IRCNetwork::sendLine(const QString &line) { + if (m_socket == NULL) { + qWarning("Sending line while m_socket is null!!"); + return; + } + + m_socket->write(line.toUtf8()); + m_socket->write("\r\n"); +} + +void IRCNetwork::socketConnected() { + qDebug("Connected to network socket!"); + sendLine(QString("PASS ") + m_config.password); + sendLine("USER username 0 * :realname"); + sendLine("NICK Ninjifox"); +} + +void IRCNetwork::socketDisconnected() { + qDebug("Socket disconnected!"); + unlinkSocket(); +} + +void IRCNetwork::socketError(QAbstractSocket::SocketError error) { + qDebug("Socket error!"); + unlinkSocket(); +} + +void IRCNetwork::socketSslErrors(const QList<QSslError> &errors) { + qDebug("Socket SSL errors!"); + foreach (const QSslError &error, errors) { + qDebug("- %s", error.errorString().toLatin1().data()); + } + + qobject_cast<QSslSocket *>(m_socket)->ignoreSslErrors(); + //unlinkSocket(); +} + +void IRCNetwork::socketReceived() { + qDebug("Data arrived!"); + + m_readBuffer.append(m_socket->readAll()); + + // Try to process as many lines as we can + char *buf = m_readBuffer.data(); + int bufSize = m_readBuffer.size(); + int lineBegin = 0; + int pos = 0; + + while (pos < bufSize) { + if (buf[pos] == '\r' || buf[pos] == '\n') { + if (pos > lineBegin) { + QString line = QString::fromUtf8(&buf[lineBegin], pos - lineBegin); + parseLine(line); + } + + lineBegin = pos + 1; + } + + pos++; + } + + // If we managed to handle anything, lop it off the buffer + if (pos > 0) { + if (pos >= bufSize) { + m_readBuffer.clear(); + } else { + memmove(buf, &buf[pos], bufSize - pos); + m_readBuffer.resize(bufSize - pos); + } + } +} + + +void IRCNetwork::parseLine(const QString &line) { + Message message; + message.timestamp = QDateTime::currentDateTime(); + message.text = line; + + m_statusBuffer.messages.append(message); + Bouncer::instance()->broadcast(message); +} + + +void IRCNetwork::markAsDisconnected() { + if (!m_loggedIn) + return; + + m_loggedIn = false; + // boop + // have to part user from channels here +} |