#include "ircnetwork.h" #include "bouncer.h" #include #include 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)), this, SLOT(socketSslErrors(QList))); 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(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 &errors) { qDebug("Socket SSL errors!"); foreach (const QSslError &error, errors) { qDebug("- %s", error.errorString().toLatin1().data()); } qobject_cast(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 }