X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fircserverhandler.cpp;h=3d7596dfb46dc97cb467f0f0dce73979096fe36e;hp=74192f17c541aed92c69d2c8571f7ce543a4ba5f;hb=c8cb4218c158e9a4419520804e6972f2321684a1;hpb=464a20552a20ff976ef4d696f69bc73b389886ad diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 74192f17..3d7596df 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -162,21 +162,30 @@ void IrcServerHandler::defaultHandler(QString cmd, const QString &prefix, const // IRC SERVER HANDLER //******************************/ void IrcServerHandler::handleJoin(const QString &prefix, const QList ¶ms) { - if(params.count() < 1) return; + if(!checkParamCount("IrcServerHandler::handleJoin()", params, 1)) + return; + QString channel = serverDecode(params[0]); IrcUser *ircuser = network()->updateNickFromMask(prefix); emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, prefix); //qDebug() << "IrcServerHandler::handleJoin()" << prefix << params; ircuser->joinChannel(channel); - if(network()->isMe(ircuser)) networkConnection()->setChannelJoined(channel); + if(network()->isMe(ircuser)) { + networkConnection()->setChannelJoined(channel); + putCmd("MODE", params[0]); // we want to know the modes of the channel we just joined, so we ask politely + } } void IrcServerHandler::handleKick(const QString &prefix, const QList ¶ms) { + if(!checkParamCount("IrcServerHandler::handleKick()", params, 2)) + return; + network()->updateNickFromMask(prefix); IrcUser *victim = network()->ircUser(params[1]); - if(!victim) return; + if(!victim) + return; + QString channel = serverDecode(params[0]); - victim->partChannel(channel); QString msg; @@ -190,21 +199,17 @@ void IrcServerHandler::handleKick(const QString &prefix, const QList } void IrcServerHandler::handleMode(const QString &prefix, const QList ¶ms) { - if(params.count() < 2) { - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Received invalid MODE from %s: %s").arg(prefix).arg(serverDecode(params).join(" "))); + if(!checkParamCount("IrcServerHandler::handleMode()", params, 2)) return; - } if(network()->isChannelName(serverDecode(params[0]))) { // Channel Modes emit displayMsg(Message::Mode, BufferInfo::ChannelBuffer, serverDecode(params[0]), serverDecode(params).join(" "), prefix); IrcChannel *channel = network()->ircChannel(params[0]); - // FIXME: currently the IrcChannels only support PREFIX-Modes for users - // This cannot be fixed unless the SignalProxy() doesn't rely on methodIds anymore QString modes = params[1]; bool add = true; - int modeIndex = 2; + int paramOffset = 2; for(int c = 0; c < modes.length(); c++) { if(modes[c] == '+') { add = true; @@ -215,15 +220,36 @@ void IrcServerHandler::handleMode(const QString &prefix, const QList continue; } - // this is the part where we restrict the mode changes to PREFIXES: - if(network()->prefixModes().contains(modes[c]) && modeIndex < params.count()) { - IrcUser *ircUser = network()->ircUser(params[modeIndex]); + if(network()->prefixModes().contains(modes[c])) { + // user channel modes (op, voice, etc...) + if(paramOffset < params.count()) { + IrcUser *ircUser = network()->ircUser(params[paramOffset]); + if(add) + channel->addUserMode(ircUser, QString(modes[c])); + else + channel->removeUserMode(ircUser, QString(modes[c])); + } else { + qWarning() << "Received MODE with too few parameters:" << serverDecode(params); + } + paramOffset++; + } else { + // regular channel modes + QString value; + Network::ChannelModeType modeType = network()->channelModeType(modes[c]); + if(modeType == Network::A_CHANMODE || modeType == Network::B_CHANMODE || (modeType == Network::C_CHANMODE && add)) { + if(paramOffset < params.count()) { + value = params[paramOffset]; + } else { + qWarning() << "Received MODE with too few parameters:" << serverDecode(params); + } + paramOffset++; + } + if(add) - channel->addUserMode(ircUser, QString(modes[c])); + channel->addChannelMode(modes[c], value); else - channel->removeUserMode(ircUser, QString(modes[c])); + channel->removeChannelMode(modes[c], value); } - modeIndex++; } } else { @@ -258,6 +284,9 @@ void IrcServerHandler::handleMode(const QString &prefix, const QList } void IrcServerHandler::handleNick(const QString &prefix, const QList ¶ms) { + if(!checkParamCount("IrcServerHandler::handleNick()", params, 1)) + return; + IrcUser *ircuser = network()->updateNickFromMask(prefix); if(!ircuser) { qWarning() << "IrcServerHandler::handleNick(): Unknown IrcUser!"; @@ -270,7 +299,6 @@ void IrcServerHandler::handleNick(const QString &prefix, const QList ? newnick : prefix; - emit nickChanged(newnick, oldnick); foreach(QString channel, ircuser->channels()) emit displayMsg(Message::Nick, BufferInfo::ChannelBuffer, channel, newnick, sender); @@ -279,10 +307,8 @@ void IrcServerHandler::handleNick(const QString &prefix, const QList } void IrcServerHandler::handleNotice(const QString &prefix, const QList ¶ms) { - if(params.count() < 2) { - qWarning() << "IrcServerHandler::handleNotice(): not enough Parameters:" << prefix << serverDecode(params); + if(!checkParamCount("IrcServerHandler::handleNotice()", params, 2)) return; - } QString target = serverDecode(params[0]); if(prefix.isEmpty() || target == "AUTH") @@ -294,6 +320,9 @@ void IrcServerHandler::handleNotice(const QString &prefix, const QList ¶ms) { + if(!checkParamCount("IrcServerHandler::handlePart()", params, 1)) + return; + IrcUser *ircuser = network()->updateNickFromMask(prefix); QString channel = serverDecode(params[0]); if(!ircuser) { @@ -317,6 +346,9 @@ void IrcServerHandler::handlePing(const QString &prefix, const QList } void IrcServerHandler::handlePrivmsg(const QString &prefix, const QList ¶ms) { + if(!checkParamCount("IrcServerHandler::handlePrivmsg()", params, 1)) + return; + IrcUser *ircuser = network()->updateNickFromMask(prefix); if(!ircuser) { qWarning() << "IrcServerHandler::handlePrivmsg(): Unknown IrcUser!"; @@ -348,7 +380,7 @@ void IrcServerHandler::handleQuit(const QString &prefix, const QList if(!ircuser) return; QString msg; - if(params.count()) + if(params.count() > 0) msg = userDecode(ircuser->nick(), params[0]); foreach(QString channel, ircuser->channels()) @@ -358,23 +390,37 @@ void IrcServerHandler::handleQuit(const QString &prefix, const QList } void IrcServerHandler::handleTopic(const QString &prefix, const QList ¶ms) { + if(!checkParamCount("IrcServerHandler::handleTopic()", params, 1)) + return; + IrcUser *ircuser = network()->updateNickFromMask(prefix); - if(!ircuser) return; - QString channel = serverDecode(params[0]); + if(!ircuser) + return; + + IrcChannel *channel = network()->ircChannel(serverDecode(params[0])); + if(!channel) + return; + QString topic; - if(params.count() >= 2) topic = channelDecode(channel, params[1]); + if(params.count() > 1) + topic = channelDecode(channel->name(), params[1]); - network()->ircChannel(channel)->setTopic(topic); + channel->setTopic(topic); - emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel).arg(topic)); + emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel->name(), tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel->name()).arg(topic)); } /* RPL_WELCOME */ void IrcServerHandler::handle001(const QString &prefix, const QList ¶ms) { + network()->setCurrentServer(prefix); + + if(params.isEmpty()) { + emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", QString("%1 didn't supply a valid welcome message... expect some serious issues...")); + } // there should be only one param: "Welcome to the Internet Relay Network !@" QString param = serverDecode(params[0]); QString myhostmask = param.section(' ', -1, -1); - network()->setCurrentServer(prefix); + network()->setMyNick(nickFromMask(myhostmask)); emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", param, prefix); @@ -387,9 +433,8 @@ void IrcServerHandler::handle005(const QString &prefix, const QList const int numParams = params.size(); if(numParams < 1) { qWarning() << "IrcServerHandler::handle005(): received RPL_ISUPPORT (005) with too few parameters:" << serverDecode(params); - return; } - + QString rpl_isupport_suffix = serverDecode(params.last()); if(!rpl_isupport_suffix.toLower().contains("supported")) { qWarning() << "Received invalid RPL_ISUPPORT! Suffix is:" << rpl_isupport_suffix << "Excpected: are supported by this server"; @@ -406,6 +451,33 @@ void IrcServerHandler::handle005(const QString &prefix, const QList } } +/* RPL_UMODEIS - " []" */ +void IrcServerHandler::handle221(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + //TODO: save information in network object + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("%1").arg(serverDecode(params).join(" "))); +} + +/* RPL_STATSCONN - "Highest connection cout: 8000 (7999 clients)" */ +void IrcServerHandler::handle250(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + //TODO: save information in network object + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("%1").arg(serverDecode(params).join(" "))); +} + +/* RPL_LOCALUSERS - "Current local user: 5024 Max: 7999 */ +void IrcServerHandler::handle265(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + //TODO: save information in network object + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("%1").arg(serverDecode(params).join(" "))); +} + +/* RPL_GLOBALUSERS - "Current global users: 46093 Max: 47650" */ +void IrcServerHandler::handle266(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + //TODO: save information in network object + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("%1").arg(serverDecode(params).join(" "))); +} /* WHOIS-Message: @@ -424,8 +496,12 @@ WHOWAS-Message: /* RPL_AWAY - " :" */ void IrcServerHandler::handle301(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle301()", params, 2)) + return; + + QString nickName = serverDecode(params[0]); - QString awayMessage = userDecode(nickName, params.last()); + QString awayMessage = userDecode(nickName, params[1]); IrcUser *ircuser = network()->ircUser(nickName); if(ircuser) { @@ -451,9 +527,64 @@ void IrcServerHandler::handle301(const QString &prefix, const QList } } +// 305 RPL_UNAWAY +// ":You are no longer marked as being away" +void IrcServerHandler::handle305(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix); + IrcUser *me = network()->me(); + if(me) + me->setAway(false); + + if(!params.isEmpty()) + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[0])); +} + +// 306 RPL_NOWAWAY +// ":You have been marked as being away" +void IrcServerHandler::handle306(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix); + IrcUser *me = network()->me(); + if(me) + me->setAway(true); + + if(!params.isEmpty()) + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[0])); +} + +/* RPL_WHOISSERVICE - " is registered nick" */ +void IrcServerHandler::handle307(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle307()", params, 1)) + return; + + QString whoisServiceReply = serverDecode(params).join(" "); + IrcUser *ircuser = network()->ircUser(serverDecode(params[0])); + if(ircuser) { + ircuser->setWhoisServiceReply(whoisServiceReply); + } + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(whoisServiceReply)); +} + +/* RPL_SUSERHOST - " is available for help." */ +void IrcServerHandler::handle310(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle310()", params, 1)) + return; + + QString suserHost = serverDecode(params).join(" "); + IrcUser *ircuser = network()->ircUser(serverDecode(params[0])); + if(ircuser) { + ircuser->setSuserHost(suserHost); + } + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(suserHost)); +} + /* RPL_WHOISUSER - " * :" */ void IrcServerHandler::handle311(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle311()", params, 3)) + return; + _whois = true; IrcUser *ircuser = network()->ircUser(serverDecode(params[0])); if(ircuser) { @@ -469,6 +600,9 @@ void IrcServerHandler::handle311(const QString &prefix, const QList /* RPL_WHOISSERVER - " :" */ void IrcServerHandler::handle312(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle312()", params, 2)) + return; + IrcUser *ircuser = network()->ircUser(serverDecode(params[0])); if(ircuser) { ircuser->setServer(serverDecode(params[1])); @@ -485,6 +619,9 @@ void IrcServerHandler::handle312(const QString &prefix, const QList /* RPL_WHOISOPERATOR - " :is an IRC operator" */ void IrcServerHandler::handle313(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle313()", params, 1)) + return; + IrcUser *ircuser = network()->ircUser(serverDecode(params[0])); if(ircuser) { ircuser->setIrcOperator(params.last()); @@ -495,6 +632,9 @@ void IrcServerHandler::handle313(const QString &prefix, const QList /* RPL_WHOWASUSER - " * :" */ void IrcServerHandler::handle314(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle314()", params, 3)) + return; + QString nick = serverDecode(params[0]); QString hostmask = QString("%1@%2").arg(serverDecode(params[1])).arg(serverDecode(params[2])); QString realName = serverDecode(params.last()); @@ -504,20 +644,24 @@ void IrcServerHandler::handle314(const QString &prefix, const QList /* RPL_ENDOFWHO: " :End of WHO list" */ void IrcServerHandler::handle315(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle315()", params, 1)) + return; + QStringList p = serverDecode(params); - if(p.count()) { - if(networkConnection()->setAutoWhoDone(p[0])) { - return; // stay silent - } - p.takeLast(); // should be "End of WHO list" - emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] End of /WHO list for %1").arg(p.join(" "))); + if(networkConnection()->setAutoWhoDone(p[0])) { + return; // stay silent } + p.takeLast(); // should be "End of WHO list" + emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] End of /WHO list for %1").arg(p.join(" "))); } /* RPL_WHOISIDLE - " :seconds idle" (real life: " :seconds idle, signon time) */ void IrcServerHandler::handle317(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle317()", params, 2)) + return; + QString nick = serverDecode(params[0]); IrcUser *ircuser = network()->ircUser(nick); if(ircuser) { @@ -525,7 +669,7 @@ void IrcServerHandler::handle317(const QString &prefix, const QList int idleSecs = serverDecode(params[1]).toInt(); idleSecs *= -1; ircuser->setIdleTime(now.addSecs(idleSecs)); - if(params.size()>3) { + if(params.size() > 3) { // if we have more then 3 params we have the obove mentioned "real life" situation int loginTime = serverDecode(params[2]).toInt(); ircuser->setLoginTime(QDateTime::fromTime_t(loginTime)); emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1 is logged in since %2").arg(ircuser->nick()).arg(ircuser->loginTime().toString())); @@ -549,6 +693,9 @@ void IrcServerHandler::handle318(const QString &prefix, const QList /* RPL_WHOISCHANNELS - " :*( ( "@" / "+" ) " " )" */ void IrcServerHandler::handle319(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle319()", params, 2)) + return; + QString nick = serverDecode(params.first()); QStringList op; QStringList voice; @@ -575,9 +722,24 @@ void IrcServerHandler::handle320(const QString &prefix, const QList emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(serverDecode(params).join(" "))); } +/* RPL_CHANNELMODEIS - " " */ +void IrcServerHandler::handle324(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix); + handleMode(prefix, params); +} + +/* RPL_??? - " " */ +void IrcServerHandler::handle329(const QString &prefix, const QList ¶ms) { + Q_UNUSED(prefix); + // FIXME implement this... +} + /* RPL_NOTOPIC */ void IrcServerHandler::handle331(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle331()", params, 1)) + return; + QString channel = serverDecode(params[0]); network()->ircChannel(channel)->setTopic(QString()); emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("No topic is set for %1.").arg(channel)); @@ -586,6 +748,9 @@ void IrcServerHandler::handle331(const QString &prefix, const QList /* RPL_TOPIC */ void IrcServerHandler::handle332(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle332()", params, 2)) + return; + QString channel = serverDecode(params[0]); QString topic = channelDecode(channel, params[1]); network()->ircChannel(channel)->setTopic(topic); @@ -595,6 +760,9 @@ void IrcServerHandler::handle332(const QString &prefix, const QList /* Topic set by... */ void IrcServerHandler::handle333(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); + if(!checkParamCount("IrcServerHandler::handle333()", params, 3)) + return; + QString channel = serverDecode(params[0]); emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic set by %1 on %2") .arg(serverDecode(params[1]), QDateTime::fromTime_t(channelDecode(channel, params[2]).toUInt()).toString())); @@ -604,6 +772,9 @@ void IrcServerHandler::handle333(const QString &prefix, const QList ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] : " */ void IrcServerHandler::handle352(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix) + if(!checkParamCount("IrcServerHandler::handle352()", params, 6)) + return; + QString channel = serverDecode(params[0]); IrcUser *ircuser = network()->ircUser(serverDecode(params[4])); if(ircuser) { @@ -624,11 +795,8 @@ void IrcServerHandler::handle352(const QString &prefix, const QList /* RPL_NAMREPLY */ void IrcServerHandler::handle353(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); - const int numParams = params.count(); - if(numParams < 2) { - qWarning() << "IrcServerHandler::handler353() received not enough params:" << serverDecode(params); + if(!checkParamCount("IrcServerHandler::handle353()", params, 2)) return; - } // param[0] is either "=", "*" or "@" indicating a public, private or secret channel // we don't use this information at the time beeing @@ -687,7 +855,9 @@ void IrcServerHandler::handle432(const QString &prefix, const QList /* ERR_NICKNAMEINUSE */ void IrcServerHandler::handle433(const QString &prefix, const QList ¶ms) { Q_UNUSED(prefix); - + if(!checkParamCount("IrcServerHandler::handle433()", params, 1)) + return; + QString errnick = serverDecode(params[0]); emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Nick already in use: %1").arg(errnick)); @@ -716,6 +886,15 @@ void IrcServerHandler::tryNextNick(const QString &errnick) { } } +bool IrcServerHandler::checkParamCount(const QString &methodName, const QList ¶ms, int minParams) { + if(params.count() < minParams) { + qWarning() << qPrintable(methodName) << "requieres" << minParams << "parameters but received only" << params.count() << serverDecode(params); + return false; + } else { + return true; + } +} + /***********************************************************************************/