X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=network%2Fserver.cpp;h=e4d37a6aa3b28214cfcd5dd9a9ff9e0589b6edec;hp=7f8b705f478537e3be424f85a7cc92d9af891002;hb=057883f768f86257c9dbefeb5ef12403b207b773;hpb=bcd7397f34626cf64f263f8779036b3c5d0767e9 diff --git a/network/server.cpp b/network/server.cpp index 7f8b705f..e4d37a6a 100644 --- a/network/server.cpp +++ b/network/server.cpp @@ -21,10 +21,12 @@ #include "global.h" #include "server.h" #include "cmdcodes.h" +#include "message.h" #include +#include -Server::Server() { +Server::Server(QString net) : network(net) { } @@ -32,10 +34,6 @@ Server::~Server() { } -void Server::init() { - //Message::init(&dispatchServerMsg, &dispatchUserMsg); -} - void Server::run() { connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected())); connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); @@ -46,12 +44,19 @@ void Server::run() { exec(); } -void Server::connectToIrc( const QString & host, quint16 port ) { - qDebug() << "Connecting..."; +void Server::connectToIrc(QString net) { + if(net != network) return; // not me! + networkSettings = global->getData("Networks").toMap()[net].toMap(); + identity = global->getData("Identities").toMap()[networkSettings["Identity"].toString()].toMap(); + QList servers = networkSettings["Servers"].toList(); + QString host = servers[0].toMap()["Address"].toString(); + quint16 port = servers[0].toMap()["Port"].toUInt(); + displayStatusMsg(QString("Connecting to %1:%2...").arg(host).arg(port)); socket.connectToHost(host, port); } -void Server::disconnectFromIrc( ) { +void Server::disconnectFromIrc(QString net) { + if(net != network) return; // not me! socket.disconnectFromHost(); } @@ -66,23 +71,48 @@ void Server::socketHasData() { } void Server::socketError( QAbstractSocket::SocketError err ) { - qDebug() << "Socket Error!"; + //qDebug() << "Socket Error!"; //emit error(err); } void Server::socketConnected( ) { - qDebug() << "Socket connected!"; - putRawLine("NICK :QuasselDev"); - putRawLine("USER Sputnick 8 * :Using Quassel IRC (WiP Version)"); + putRawLine(QString("NICK :%1").arg(identity["NickList"].toStringList()[0])); + putRawLine(QString("USER %1 8 * :%2").arg(identity["Ident"].toString()).arg(identity["RealName"].toString())); } void Server::socketDisconnected( ) { - qDebug() << "Socket disconnected!"; - //emit disconnected(); + //qDebug() << "Socket disconnected!"; + emit disconnected(); } void Server::socketStateChanged(QAbstractSocket::SocketState state) { - qDebug() << "Socket state changed: " << state; + //qDebug() << "Socket state changed: " << state; +} + +QString Server::nickFromMask(QString mask) { + return mask.section('!', 0, 0); +} + +QString Server::userFromMask(QString mask) { + QString userhost = mask.section('!', 1); + if(userhost.isEmpty()) return QString(); + return userhost.section('@', 0, 0); +} + +QString Server::hostFromMask(QString mask) { + QString userhost = mask.section('!', 1); + if(userhost.isEmpty()) return QString(); + return userhost.section('@', 1); +} + +void Server::userInput(QString net, QString buf, QString msg) { + if(net != network) return; // not me! + msg = msg.trimmed(); // remove whitespace from start and end + if(msg.isEmpty()) return; + if(!msg.startsWith('/')) { + msg = QString("/SAY ") + msg; + } + handleUserMsg(buf, msg); } void Server::putRawLine(QString s) { @@ -130,72 +160,209 @@ void Server::handleServerMsg(QString msg) { if(!trailing.isEmpty()) { params << trailing; } + // numeric replies usually have our own nick as first param. Remove this! + // BTW, this behavior is not in the RFC. + uint num = cmd.toUInt(); + if(num > 1 && params.count() > 0) { // 001 sets our nick, so we shouldn't remove anything + if(params[0] == currentNick) params.removeFirst(); + else qWarning((QString("First param NOT nick: %1:%2 %3").arg(prefix).arg(cmd).arg(params.join(" "))).toAscii()); + } // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-) QString hname = cmd.toLower(); hname[0] = hname[0].toUpper(); - hname = "handle" + hname + "FromServer"; + hname = "handleServer" + hname; if(!QMetaObject::invokeMethod(this, hname.toAscii(), Q_ARG(QString, prefix), Q_ARG(QStringList, params))) { // Ok. Default handler it is. - defaultHandlerForServer(cmd, prefix, params); + defaultServerHandler(cmd, prefix, params); } } catch(Exception e) { - emit recvLine(e.msg()); + emit displayMsg("", Message(e.msg(), "", Message::Error)); } } -void Server::defaultHandlerForServer(QString cmd, QString prefix, QStringList params) { +void Server::defaultServerHandler(QString cmd, QString prefix, QStringList params) { uint num = cmd.toUInt(); if(num) { - recvLine(cmd + " " + params.join(" ")); + // A lot of server messages don't really need their own handler because they don't do much. + // Catch and handle these here. + switch(num) { + // Welcome, status, info messages. Just display these. + case 2: case 3: case 4: case 5: case 251: case 252: case 253: case 254: case 255: case 372: case 375: + emit displayMsg("", Message(params.join(" "), prefix, Message::Server)); + break; + // Ignore these commands. + case 366: case 376: + break; + + // Everything else will be marked in red, so we can add them somewhere. + default: + emit displayMsg("", Message(cmd + " " + params.join(" "), prefix, Message::Error)); + } + //qDebug() << prefix <<":"<getCmdCode(); - QString prefix = msg->getPrefix(); - QStringList params = msg->getParams(); - if(cmdCode < 0) { - switch(-cmdCode) { - case CMD_PING: - // PING [] - if(params.size() < 1 || params.size() > 2) throw ParseError(msg); - putCmd("PONG", params); - break; +void Server::handleUser(QString msg, Buffer *buf) { - default: - throw Exception(QString("No handler installed for command: ") + msg->getCmd() + " " + msg->getParams().join(" ")); - } - } else if(msg->getCmdCode() > 0) { - switch(msg->getCmdCode()) { - default: - // - throw Exception(msg->getCmd() + " " + msg->getParams().join(" ")); - } +} +*/ +void Server::handleUserJoin(QString msg, Buffer *buf) { + putCmd("JOIN", QStringList(msg)); + +} + +void Server::handleUserQuote(QString msg, Buffer *buf) { + putRawLine(msg); +} + +void Server::handleUserSay(QString msg, Buffer *buf) { + if(!buf) return; // server buffer + QStringList params; + params << buf->name() << msg; + putCmd("PRIVMSG", params); + emit displayMsg(params[0], Message(msg, currentNick, Message::Msg, Message::Self)); +} + +/**********************************************************************************/ + +void Server::handleServerJoin(QString prefix, QStringList params) { + Q_ASSERT(params.count() == 1); + QString nick = nickFromMask(prefix); + if(nick == currentNick) { + Q_ASSERT(!buffers.contains(params[0])); // cannot join a buffer twice! + Buffer *buf = new Buffer(params[0]); + buffers[params[0]] = buf; } else { - throw UnknownCmdError(msg); + VarMap n; + if(nicks.contains(nick)) { + n = nicks[nick].toMap(); + VarMap chans = n["Channels"].toMap(); + // Q_ASSERT(!chans.keys().contains(params[0])); TODO uncomment + chans[params[0]] = VarMap(); + n["Channels"] = chans; + nicks[nick] = n; + emit nickUpdated(network, nick, n); + } else { + VarMap chans; + chans[params[0]] = VarMap(); + n["Channels"] = chans; + n["Nick"] = nick; + n["User"] = userFromMask(prefix); + n["Host"] = hostFromMask(prefix); + nicks[nick] = n; + emit nickAdded(network, nick, n); + } + QString user = n["User"].toString(); QString host = n["Host"].toString(); + if(user.isEmpty() || host.isEmpty()) emit displayMsg(params[0], Message(tr("%1 has joined %2").arg(nick).arg(params[0]), "", Message::Join)); + else emit displayMsg(params[0], Message(tr("%1 (%2@%3) has joined %4").arg(nick).arg(user).arg(host).arg(params[0]), "", Message::Join)); } } -*/ -void Server::handleNoticeFromServer(QString prefix, QStringList params) { - recvLine(params.join(" ")); +void Server::handleServerNotice(QString prefix, QStringList params) { + Message msg(params[1], prefix, Message::Notice); + if(prefix == currentServer) emit displayMsg("", Message(params[1], prefix, Message::Server)); + else emit displayMsg("", Message(params[1], prefix, Message::Notice)); } -void Server::handlePingFromServer(QString prefix, QStringList params) { +void Server::handleServerPing(QString prefix, QStringList params) { putCmd("PONG", params); } +void Server::handleServerPrivmsg(QString prefix, QStringList params) { + emit displayMsg(params[0], Message(params[1], nickFromMask(prefix), Message::Msg)); + +} + +/* RPL_WELCOME */ +void Server::handleServer001(QString prefix, QStringList params) { + currentServer = prefix; + currentNick = params[0]; + emit ownNickSet(network, currentNick); + emit displayMsg("", Message(params[1], prefix, Message::Server)); +} + +/* RPL_NOTOPIC */ +void Server::handleServer331(QString prefix, QStringList params) { + emit topicSet(network, params[0], ""); +} + +/* RPL_TOPIC */ +void Server::handleServer332(QString prefix, QStringList params) { + emit topicSet(network, params[0], params[1]); + emit displayMsg(params[0], Message(tr("Topic for %1 is \"%2\"").arg(params[0]).arg(params[1]), "", Message::Server)); +} + +/* Topic set by... */ +void Server::handleServer333(QString prefix, QStringList params) { + emit displayMsg(params[0], Message(tr("Topic set by %1 on %2").arg(params[1]).arg(QDateTime::fromTime_t(params[2].toUInt()).toString()), "", Message::Server)); +} + +/* RPL_NAMREPLY */ +void Server::handleServer353(QString prefix, QStringList params) { + params.removeFirst(); // = or * + QString buf = params.takeFirst(); + foreach(QString nick, params[0].split(' ')) { + // TODO: parse more prefix characters! use 005? + QString mode = ""; + if(nick.startsWith('@')) { mode = "o"; nick.remove(0,1); } + else if(nick.startsWith('+')) { mode = "v"; nick.remove(0,1); } + VarMap c; c["Mode"] = mode; + if(nicks.contains(nick)) { + VarMap n = nicks[nick].toMap(); + VarMap chans = n["Channels"].toMap(); + chans[buf] = c; + n["Channels"] = chans; + nicks[nick] = n; + emit nickUpdated(network, nick, n); + } else { + VarMap n; VarMap c; VarMap chans; + c["Mode"] = mode; + chans[buf] = c; + n["Channels"] = chans; + n["Nick"] = nick; + nicks[nick] = n; + emit nickAdded(network, nick, n); + } + } +} +/***********************************************************************************/ + /* Exception classes for message handling */ Server::ParseError::ParseError(QString cmd, QString prefix, QStringList params) { _msg = QString("Command Parse Error: ") + cmd + params.join(" ");