X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fircserverhandler.cpp;h=14b35075da17ce86ed9a6b1095f4d1f8ec41ab63;hb=6f69d56e0725945e38f9bcfb30573417bbc01b62;hp=4d706d69805a6601efb417aa20cea8b4dff0b604;hpb=44a6109557eafd29cc6079dd6521ad3cf80c15b3;p=quassel.git diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 4d706d69..14b35075 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-08 by the Quassel Project * + * Copyright (C) 2005-09 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -57,11 +57,23 @@ void IrcServerHandler::handleServerMsg(QByteArray msg) { // NOTE: This assumes that this is true in raw encoding, but well, hopefully there are no servers running in japanese on protocol level... int idx = msg.indexOf(" :"); if(idx >= 0) { - if(msg.length() > idx + 2) trailing = msg.mid(idx + 2); + if(msg.length() > idx + 2) + trailing = msg.mid(idx + 2); msg = msg.left(idx); } // OK, now it is safe to split... QList params = msg.split(' '); + + // This could still contain empty elements due to (faulty?) ircds sending multiple spaces in a row + // Also, QByteArray is not nearly as convenient to work with as QString for such things :) + QList::iterator iter = params.begin(); + while(iter != params.end()) { + if(iter->isEmpty()) + iter = params.erase(iter); + else + ++iter; + } + if(!trailing.isEmpty()) params << trailing; if(params.count() < 1) { qWarning() << "Received invalid string from server!"; @@ -88,12 +100,17 @@ void IrcServerHandler::handleServerMsg(QByteArray msg) { uint num = cmd.toUInt(); if(num > 0) { if(params.count() == 0) { - qWarning() << "Message received from server violates RFC and is ignored!"; + qWarning() << "Message received from server violates RFC and is ignored!" << msg; return; } - params.removeFirst(); + _target = serverDecode(params.takeFirst()); + } else { + _target = QString(); } + // note that the IRC server is still alive + network()->resetPingTimeout(); + // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-) handle(cmd, Q_ARG(QString, prefix), Q_ARG(QList, params)); } @@ -306,11 +323,15 @@ void IrcServerHandler::handleNick(const QString &prefix, const QList ? newnick : prefix; + + // the order is cruicial + // otherwise the client would rename the buffer, see that the assigned ircuser doesn't match anymore + // and remove the ircuser from the querybuffer leading to a wrong on/offline state + ircuser->setNick(newnick); coreSession()->renameBuffer(network()->networkId(), newnick, oldnick); + foreach(QString channel, ircuser->channels()) emit displayMsg(Message::Nick, BufferInfo::ChannelBuffer, channel, newnick, sender); - - ircuser->setNick(newnick); } void IrcServerHandler::handleNotice(const QString &prefix, const QList ¶ms) { @@ -810,14 +831,34 @@ void IrcServerHandler::handle324(const QString &prefix, const QList handleMode(prefix, params); } +/* RPL_??? - " */ +void IrcServerHandler::handle328(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle328()", params, 2)) + return; + + QString channel = serverDecode(params[0]); + QString homepage = serverDecode(params[1]); + + emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Homepage for %1 is %2").arg(channel, homepage)); +} + + /* RPL_??? - " " */ void IrcServerHandler::handle329(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); - Q_UNUSED(params) -#ifdef __GNUC__ -# warning "Implement handle329 (Channel creation time)" -#endif - // FIXME implement this... + if(!checkParamCount("IrcServerHandler::handle329()", params, 2)) + return; + + QString channel = serverDecode(params[0]); + uint unixtime = params[1].toUInt(); + if(!unixtime) { + qWarning() << Q_FUNC_INFO << "received invalid timestamp:" << params[1]; + return; + } + QDateTime time = QDateTime::fromTime_t(unixtime); + + emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Channel %1 created on %2").arg(channel, time.toString())); } /* RPL_NOTOPIC */ @@ -928,20 +969,19 @@ void IrcServerHandler::handle369(const QString &prefix, const QList void IrcServerHandler::handle432(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + QString errnick; if(params.size() < 2) { // handle unreal-ircd bug, where unreal ircd doesnt supply a TARGET in ERR_ERRONEUSNICKNAME during registration phase: // nick @@@ // :irc.scortum.moep.net 432 @@@ :Erroneous Nickname: Illegal characters // correct server reply: // :irc.scortum.moep.net 432 * @@@ :Erroneous Nickname: Illegal characters - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("There is a nickname in your identity's nicklist which contains illegal characters")); - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Due to a bug in Unreal IRCd (and maybe other irc-servers too) we're unable to determine the erroneous nick")); - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Please use: /nick to continue or clean up your nicklist")); + errnick = target(); } else { - QString errnick = params[0]; - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Nick %1 contains illegal characters").arg(errnick)); - tryNextNick(errnick); + errnick = params[0]; } + emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Nick %1 contains illegal characters").arg(errnick)); + tryNextNick(errnick, true /* erroneus */); } /* ERR_NICKNAMEINUSE */ @@ -968,14 +1008,21 @@ void IrcServerHandler::handle433(const QString &prefix, const QList /* */ -void IrcServerHandler::tryNextNick(const QString &errnick) { +void IrcServerHandler::tryNextNick(const QString &errnick, bool erroneus) { QStringList desiredNicks = coreSession()->identity(network()->identity())->nicks(); - int nextNick = desiredNicks.indexOf(errnick) + 1; - if(desiredNicks.size() > nextNick) { - putCmd("NICK", serverEncode(desiredNicks[nextNick])); + int nextNickIdx = desiredNicks.indexOf(errnick) + 1; + QString nextNick; + if(nextNickIdx > 0 && desiredNicks.size() > nextNickIdx) { + nextNick = desiredNicks[nextNickIdx]; } else { - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("No free and valid nicks in nicklist found. use: /nick to continue")); + if(erroneus) { + emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("No free and valid nicks in nicklist found. use: /nick to continue")); + return; + } else { + nextNick = errnick + "_"; + } } + putCmd("NICK", serverEncode(nextNick)); } bool IrcServerHandler::checkParamCount(const QString &methodName, const QList ¶ms, int minParams) {