Pressing enter in the topic line now sets the channel topic.
[quassel.git] / src / core / ircserverhandler.cpp
index 87bc7e5..0499c85 100644 (file)
 
 IrcServerHandler::IrcServerHandler(NetworkConnection *parent)
   : BasicHandler(parent),
-    networkConnection(parent) {
-      _whois = false;
+    _whois(false)
+{
 }
 
 IrcServerHandler::~IrcServerHandler() {
 
 }
 
-QString IrcServerHandler::serverDecode(const QByteArray &string) {
-  return networkConnection->serverDecode(string);
-}
-
-QStringList IrcServerHandler::serverDecode(const QList<QByteArray> &stringlist) {
-  QStringList list;
-  foreach(QByteArray s, stringlist) list << networkConnection->serverDecode(s);
-  return list;
-}
-
-QString IrcServerHandler::bufferDecode(const QString &bufferName, const QByteArray &string) {
-  return networkConnection->bufferDecode(bufferName, string);
-}
-
-QStringList IrcServerHandler::bufferDecode(const QString &bufferName, const QList<QByteArray> &stringlist) {
-  QStringList list;
-  foreach(QByteArray s, stringlist) list << networkConnection->bufferDecode(bufferName, s);
-  return list;
-}
-
-QString IrcServerHandler::userDecode(const QString &userNick, const QByteArray &string) {
-  return networkConnection->userDecode(userNick, string);
-}
-
-QStringList IrcServerHandler::userDecode(const QString &userNick, const QList<QByteArray> &stringlist) {
-  QStringList list;
-  foreach(QByteArray s, stringlist) list << networkConnection->userDecode(userNick, s);
-  return list;
-}
-
 /*! Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */
 void IrcServerHandler::handleServerMsg(QByteArray msg) {
   try {
@@ -135,7 +105,7 @@ void IrcServerHandler::handleServerMsg(QByteArray msg) {
 }
 
 
-void IrcServerHandler::defaultHandler(QString cmd, QString prefix, QList<QByteArray> rawparams) {
+void IrcServerHandler::defaultHandler(QString cmd, const QString &prefix, const QList<QByteArray> &rawparams) {
   // we assume that all this happens in server encoding
   QStringList params;
   foreach(QByteArray r, rawparams) params << serverDecode(r);
@@ -155,24 +125,18 @@ void IrcServerHandler::defaultHandler(QString cmd, QString prefix, QList<QByteAr
         emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" "), prefix);
         break;
       // Server error messages, display them in red. First param will be appended.
-      case 401: 
-      {
-       // FIXME needs proper redirection
+      case 401: {
        QString target = params.takeFirst();
-       BufferInfo::Type bufferType = network()->isChannelName(target)
-         ? BufferInfo::ChannelBuffer
-         : BufferInfo::QueryBuffer;
-        emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" ") + " " + target, prefix);
-        emit displayMsg(Message::Error, bufferType, target, params.join(" ") + " " + target, prefix);
-        break;
+       displayMsg(Message::Error, target, params.join(" ") + " " + target, prefix, Message::Redirected);
+       break;
       }
-      case 402: case 403: case 404: case 406: case 408: case 415: case 421: case 442:
-      { QString channelName = params.takeFirst();
+      case 402: case 403: case 404: case 406: case 408: case 415: case 421: case 442: {
+       QString channelName = params.takeFirst();
         emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" ") + " " + channelName, prefix);
         break;
       }
       // Server error messages which will be displayed with a colon between the first param and the rest
-      case 413: case 414: case 423: case 441: case 444: case 461:
+      case 413: case 414: case 423: case 441: case 444: case 461:  // FIXME see below for the 47x codes
       case 467: case 471: case 473: case 474: case 475: case 476: case 477: case 478: case 482:
       case 436: // ERR_NICKCOLLISION
       { QString p = params.takeFirst();
@@ -197,18 +161,19 @@ void IrcServerHandler::defaultHandler(QString cmd, QString prefix, QList<QByteAr
 //******************************/
 // IRC SERVER HANDLER
 //******************************/
-void IrcServerHandler::handleJoin(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleJoin(const QString &prefix, const QList<QByteArray> &params) {
   Q_ASSERT(params.count() == 1);
   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)) network()->addPersistentChannel(channel, networkConnection()->channelKey(channel));
 }
 
-void IrcServerHandler::handleKick(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleKick(const QString &prefix, const QList<QByteArray> &params) {
   network()->updateNickFromMask(prefix);
-  IrcUser *victim = network()->ircUser(serverDecode(params[1]));
+  IrcUser *victim = network()->ircUser(params[1]);
   QString channel = serverDecode(params[0]);
   Q_ASSERT(victim);
 
@@ -216,29 +181,30 @@ void IrcServerHandler::handleKick(QString prefix, QList<QByteArray> params) {
 
   QString msg;
   if(params.count() > 2) // someone got a reason!
-    msg = QString("%1 %2").arg(victim->nick()).arg(bufferDecode(channel, params[2]));
+    msg = QString("%1 %2").arg(victim->nick()).arg(channelDecode(channel, params[2]));
   else
     msg = victim->nick();
 
   emit displayMsg(Message::Kick, BufferInfo::ChannelBuffer, channel, msg, prefix);
+  //if(network()->isMe(victim)) networkConnection()->setKickedFromChannel(channel);
 }
 
-void IrcServerHandler::handleMode(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleMode(const QString &prefix, const QList<QByteArray> &params) {
   if(params.count() < 2) {
     emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Received invalid MODE from %s: %s").arg(prefix).arg(serverDecode(params).join(" ")));
     return;
   }
 
-  if(network()->isChannelName(params[0])) {
+  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.takeFirst());
+    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.takeFirst();
+    QString modes = params[1];
     bool add = true;
-    int modeIndex = 0;
+    int modeIndex = 2;
     for(int c = 0; c < modes.length(); c++) {
       if(modes[c] == '+') {
        add = true;
@@ -267,7 +233,7 @@ void IrcServerHandler::handleMode(QString prefix, QList<QByteArray> params) {
   }
 }
 
-void IrcServerHandler::handleNick(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleNick(const QString &prefix, const QList<QByteArray> &params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
   Q_ASSERT(ircuser);
   QString newnick = serverDecode(params[0]);
@@ -277,38 +243,30 @@ void IrcServerHandler::handleNick(QString prefix, QList<QByteArray> params) {
     ? newnick
     : prefix;
 
+
+  emit nickChanged(newnick, oldnick);
   foreach(QString channel, ircuser->channels())
     emit displayMsg(Message::Nick, BufferInfo::ChannelBuffer, channel, newnick, sender);
   
   ircuser->setNick(newnick);
 }
 
-void IrcServerHandler::handleNotice(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleNotice(const QString &prefix, const QList<QByteArray> &params) {
   if(params.count() < 2) {
-    qWarning() << "IrcServerHandler::handleNotice(): not enoug Parameters:" << prefix << serverDecode(params);
-    return;
-  }
-
-  // check if it's only a Server Message or if it's a regular Notice
-  if(network()->currentServer().isEmpty() || network()->currentServer() == prefix) {
-    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[1]), prefix);
+    qWarning() << "IrcServerHandler::handleNotice(): not enough Parameters:" << prefix << serverDecode(params);
     return;
   }
 
   QString target = serverDecode(params[0]);
+  if(prefix.isEmpty() || target == "AUTH")
+    target = "";
+  else if(!network()->isChannelName(target))
+    target = nickFromMask(prefix);
 
-  // kick notices to the server buffer if they are directly addressed to us
-  if(network()->isMyNick(target))
-    target = QString("");
-
-  QString sender = prefix.contains('!')
-    ? nickFromMask(prefix)
-    : prefix;
-
-  networkConnection->ctcpHandler()->parse(Message::Notice, sender, target, userDecode(prefix, params[1]));
+  networkConnection()->ctcpHandler()->parse(Message::Notice, prefix, target, params[1]);
 }
 
-void IrcServerHandler::handlePart(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handlePart(const QString &prefix, const QList<QByteArray> &params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
   QString channel = serverDecode(params[0]);
   Q_ASSERT(ircuser);
@@ -320,33 +278,41 @@ void IrcServerHandler::handlePart(QString prefix, QList<QByteArray> params) {
     msg = userDecode(ircuser->nick(), params[1]);
 
   emit displayMsg(Message::Part, BufferInfo::ChannelBuffer, channel, msg, prefix);
+  if(network()->isMe(ircuser)) network()->removePersistentChannel(channel);
 }
 
-void IrcServerHandler::handlePing(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handlePing(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
-  emit putCmd("PONG", serverDecode(params));
+  putCmd("PONG", params);
 }
 
-void IrcServerHandler::handlePrivmsg(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handlePrivmsg(const QString &prefix, const QList<QByteArray> &params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
   Q_ASSERT(ircuser);
-  if(params.count() < 2)
-    params << QByteArray("");
 
+  if(params.isEmpty()) {
+    qWarning() << "IrcServerHandler::handlePrivmsg(): received PRIVMSG without target or message from:" << prefix;
+    return;
+  }
+     
   QString target = serverDecode(params[0]);
 
+  QByteArray msg = params.count() < 2
+    ? QByteArray("")
+    : params[1];
+
   // are we the target?
   if(network()->isMyNick(target))
     target = nickFromMask(ircuser->nick());
 
   // it's possible to pack multiple privmsgs into one param using ctcp
   // - > we let the ctcpHandler do the work
-  networkConnection->ctcpHandler()->parse(Message::Plain, prefix, target, userDecode(ircuser->nick(), params[1]));
+  networkConnection()->ctcpHandler()->parse(Message::Plain, prefix, target, msg);
 }
 
-void IrcServerHandler::handleQuit(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleQuit(const QString &prefix, const QList<QByteArray> &params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
-  Q_ASSERT(ircuser);
+  if(!ircuser) return;
 
   QString msg;
   if(params.count())
@@ -358,11 +324,12 @@ void IrcServerHandler::handleQuit(QString prefix, QList<QByteArray> params) {
   network()->removeIrcUser(nickFromMask(prefix));
 }
 
-void IrcServerHandler::handleTopic(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handleTopic(const QString &prefix, const QList<QByteArray> &params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
+  if(!ircuser) return;
   QString channel = serverDecode(params[0]);
-  QString topic = bufferDecode(channel, params[1]);
-  Q_ASSERT(ircuser);
+  QString topic;
+  if(params.count() >= 2) topic = channelDecode(channel, params[1]);
 
   network()->ircChannel(channel)->setTopic(topic);
 
@@ -370,7 +337,7 @@ void IrcServerHandler::handleTopic(QString prefix, QList<QByteArray> params) {
 }
 
 /* RPL_WELCOME */
-void IrcServerHandler::handle001(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle001(const QString &prefix, const QList<QByteArray> &params) {
   // there should be only one param: "Welcome to the Internet Relay Network <nick>!<user>@<host>"
   QString param = serverDecode(params[0]);
   QString myhostmask = param.section(' ', -1, -1);
@@ -382,17 +349,26 @@ void IrcServerHandler::handle001(QString prefix, QList<QByteArray> params) {
 
 /* RPL_ISUPPORT */
 // TODO Complete 005 handling, also use sensible defaults for non-sent stuff
-void IrcServerHandler::handle005(QString prefix, QList<QByteArray> params) {
-  Q_UNUSED(prefix)
-  QString rpl_isupport_suffix = serverDecode(params.takeLast());
-  if(rpl_isupport_suffix.toLower() != QString("are supported by this server")) {
+void IrcServerHandler::handle005(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  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";
     return;
   }
-  
-  foreach(QString param, serverDecode(params)) {
-    QString key = param.section("=", 0, 0);
-    QString value = param.section("=", 1);
+
+  QString rawSupport;
+  QString key, value;
+  for(int i = 0; i < numParams - 1; i++) {
+    QString rawSupport = serverDecode(params[i]);
+    QString key = rawSupport.section("=", 0, 0);
+    QString value = rawSupport.section("=", 1);
     network()->addSupport(key, value);
   }
 }
@@ -413,10 +389,10 @@ WHOWAS-Message:
 
 
 /*   RPL_AWAY - "<nick> :<away message>" */
-void IrcServerHandler::handle301(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle301(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
   QString nickName = serverDecode(params[0]);
-  QString awayMessage = serverDecode(params.last());
+  QString awayMessage = userDecode(nickName, params.last());
 
   IrcUser *ircuser = network()->ircUser(nickName);
   if(ircuser) {
@@ -443,7 +419,7 @@ void IrcServerHandler::handle301(QString prefix, QList<QByteArray> params) {
 }
 
 /*  RPL_WHOISUSER - "<nick> <user> <host> * :<real name>" */
-void IrcServerHandler::handle311(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle311(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   _whois = true;
   IrcUser *ircuser = network()->ircUser(serverDecode(params[0]));
@@ -456,7 +432,7 @@ void IrcServerHandler::handle311(QString prefix, QList<QByteArray> params) {
 }
  
 /*  RPL_WHOISSERVER -  "<nick> <server> :<server info>" */
-void IrcServerHandler::handle312(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle312(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   IrcUser *ircuser = network()->ircUser(serverDecode(params[0]));
   if(ircuser) {
@@ -470,7 +446,7 @@ void IrcServerHandler::handle312(QString prefix, QList<QByteArray> params) {
 }
 
 /*  RPL_WHOISOPERATOR - "<nick> :is an IRC operator" */
-void IrcServerHandler::handle313(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle313(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   IrcUser *ircuser = network()->ircUser(serverDecode(params[0]));
   if(ircuser) {
@@ -480,23 +456,26 @@ void IrcServerHandler::handle313(QString prefix, QList<QByteArray> params) {
 }
 
 /*  RPL_WHOWASUSER - "<nick> <user> <host> * :<real name>" */
-void IrcServerHandler::handle314(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle314(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whowas] %1").arg(serverDecode(params).join(" ")));
 }
 
 /*  RPL_ENDOFWHO: "<name> :End of WHO list" */
-void IrcServerHandler::handle315(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle315(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
-  emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] %1").arg(serverDecode(params).join(" ")));
+  // FIXME temporarily made silent
+  Q_UNUSED(params)
+  // emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] %1").arg(serverDecode(params).join(" ")));
 }
 
 /*  RPL_WHOISIDLE - "<nick> <integer> :seconds idle" 
    (real life: "<nick> <integer> <integer> :seconds idle, signon time) */
    //TODO: parse real life message
-void IrcServerHandler::handle317(QString prefix, QList<QByteArray> params) {
-  Q_UNUSED(prefix)
-  IrcUser *ircuser = network()->ircUser(serverDecode(params[0]));
+void IrcServerHandler::handle317(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  QString nick = serverDecode(params[0]);
+  IrcUser *ircuser = network()->ircUser(nick);
   if(ircuser) {
     QDateTime now = QDateTime::currentDateTime();
     int idleSecs = serverDecode(params[1]).toInt();
@@ -504,25 +483,25 @@ void IrcServerHandler::handle317(QString prefix, QList<QByteArray> params) {
     ircuser->setIdleTime(now.addSecs(idleSecs));
     emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1 is idling for %2 seconds").arg(ircuser->nick()).arg(ircuser->idleTime().secsTo(now)));
   } else {
-    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] idle message: %1").arg(serverDecode(params).join(" ")));
+    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] idle message: %1").arg(userDecode(nick, params).join(" ")));
   }
 }
 
 /*  RPL_ENDOFWHOIS - "<nick> :End of WHOIS list" */
-void IrcServerHandler::handle318(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle318(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   _whois = false;
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(serverDecode(params).join(" ")));
 }
 
 /*  RPL_WHOISCHANNELS - "<nick> :*( ( "@" / "+" ) <channel> " " )" */
-void IrcServerHandler::handle319(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle319(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(serverDecode(params).join(" ")));
 }
 
 /* RPL_NOTOPIC */
-void IrcServerHandler::handle331(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle331(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
   QString channel = serverDecode(params[0]);
   network()->ircChannel(channel)->setTopic(QString());
@@ -530,24 +509,25 @@ void IrcServerHandler::handle331(QString prefix, QList<QByteArray> params) {
 }
 
 /* RPL_TOPIC */
-void IrcServerHandler::handle332(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle332(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
   QString channel = serverDecode(params[0]);
-  QString topic = bufferDecode(channel, params[1]);
+  QString topic = channelDecode(channel, params[1]);
   network()->ircChannel(channel)->setTopic(topic);
   emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic for %1 is \"%2\"").arg(channel, topic));
 }
 
 /* Topic set by... */
-void IrcServerHandler::handle333(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle333(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
   QString channel = serverDecode(params[0]);
-  emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic set by %1 on %2") .arg(bufferDecode(channel, params[1]), QDateTime::fromTime_t(bufferDecode(channel, params[2]).toUInt()).toString()));
+  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()));
 }
 
 /*  RPL_WHOREPLY: "<channel> <user> <host> <server> <nick> 
               ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] :<hopcount> <real name>" */
-void IrcServerHandler::handle352(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle352(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   QString channel = serverDecode(params[0]);
   IrcUser *ircuser = network()->ircUser(serverDecode(params[4]));
@@ -561,16 +541,24 @@ void IrcServerHandler::handle352(QString prefix, QList<QByteArray> params) {
     ircuser->setRealName(serverDecode(params.last()).section(" ", 1));
   }
 
-  emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] %1").arg(serverDecode(params).join(" ")));
+  // FIXME temporarily made silent
+  //emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Who] %1").arg(serverDecode(params).join(" ")));
 }
 
 /* RPL_NAMREPLY */
-void IrcServerHandler::handle353(QString prefix, QList<QByteArray> params) {
-  Q_UNUSED(prefix)
-  params.removeFirst(); // either "=", "*" or "@" indicating a public, private or secret channel
-  QString channelname = serverDecode(params.takeFirst());
+void IrcServerHandler::handle353(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  const int numParams = params.count();
+  if(numParams < 2) {
+    qWarning() << "IrcServerHandler::handler353() received not enough params:" << serverDecode(params);
+    return;
+  }
+    
+  // param[0] is either "=", "*" or "@" indicating a public, private or secret channel
+  // we don't use this information at the time beeing
+  QString channelname = serverDecode(params[1]);
 
-  foreach(QString nick, serverDecode(params.takeFirst()).split(' ')) {
+  foreach(QString nick, serverDecode(params[2]).split(' ')) {
     QString mode = QString();
 
     if(network()->prefixes().contains(nick[0])) {
@@ -587,13 +575,13 @@ void IrcServerHandler::handle353(QString prefix, QList<QByteArray> params) {
 }
 
 /*  RPL_ENDOFWHOWAS - "<nick> :End of WHOWAS" */
-void IrcServerHandler::handle369(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle369(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix)
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whowas] %1").arg(serverDecode(params).join(" ")));
 }
 
 /* ERR_ERRONEUSNICKNAME */
-void IrcServerHandler::handle432(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle432(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
 
   if(params.size() < 2) {
@@ -613,7 +601,7 @@ void IrcServerHandler::handle432(QString prefix, QList<QByteArray> params) {
 }
 
 /* ERR_NICKNAMEINUSE */
-void IrcServerHandler::handle433(QString prefix, QList<QByteArray> params) {
+void IrcServerHandler::handle433(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
 
   QString errnick = serverDecode(params[0]);
@@ -621,17 +609,24 @@ void IrcServerHandler::handle433(QString prefix, QList<QByteArray> params) {
 
   // if there is a problem while connecting to the server -> we handle it
   // but only if our connection has not been finished yet...
-  if(!networkConnection->network()->currentServer().isEmpty())
+  if(!network()->currentServer().isEmpty())
     return;
 
   tryNextNick(errnick);
 }
 
+/* */
+
+// FIXME networkConnection()->setChannelKey("") for all ERR replies indicating that a JOIN went wrong
+//       mostly, these are codes in the 47x range
+
+/* */
+
 void IrcServerHandler::tryNextNick(const QString &errnick) {
-  QStringList desiredNicks = networkConnection->coreSession()->identity(networkConnection->network()->identity())->nicks();
+  QStringList desiredNicks = networkConnection()->coreSession()->identity(network()->identity())->nicks();
   int nextNick = desiredNicks.indexOf(errnick) + 1;
   if(desiredNicks.size() > nextNick) {
-    putCmd("NICK", QStringList(desiredNicks[nextNick]));
+    putCmd("NICK", serverEncode(desiredNicks[nextNick]));
   } else {
     emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("No free and valid nicks in nicklist found. use: /nick <othernick> to continue"));
   }