adding server lag indicator to the network tooltip
[quassel.git] / src / core / ircserverhandler.cpp
index 3d7596d..ae7736d 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 
 #include "coresession.h"
+#include "coreirclisthelper.h"
 #include "networkconnection.h"
 #include "network.h"
 #include "identity.h"
@@ -107,8 +108,7 @@ void IrcServerHandler::handleServerMsg(QByteArray msg) {
 
 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);
+  QStringList params = serverDecode(rawparams);
   uint num = cmd.toUInt();
   if(num) {
     // A lot of server messages don't really need their own handler because they don't do much.
@@ -144,12 +144,17 @@ void IrcServerHandler::defaultHandler(QString cmd, const QString &prefix, const
         break;
       }
       // Ignore these commands.
-      case 366: case 376:
+      case 321: case 366: case 376:
         break;
 
       // Everything else will be marked in red, so we can add them somewhere.
       default:
-        emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", cmd + " " + params.join(" "), prefix);
+       if(_whois) {
+         // many nets define their own WHOIS fields. we fetch those not in need of special attention here:
+         emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", "[Whois] " + params.join(" "), prefix);
+       } else {
+         emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", cmd + " " + params.join(" "), prefix);
+       }
     }
     //qDebug() << prefix <<":"<<cmd<<params;
   } else {
@@ -345,6 +350,23 @@ void IrcServerHandler::handlePing(const QString &prefix, const QList<QByteArray>
   putCmd("PONG", params);
 }
 
+void IrcServerHandler::handlePong(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  // the server is supposed to send back what we passed as param. and we send a timestamp
+  // but using quote and whatnought one can send arbitrary pings, so we have to do some sanity checks
+  if(params.count() < 2)
+    return;
+
+  QString timestamp = serverDecode(params[1]);
+  QTime sendTime = QTime::fromString(timestamp, "hh:mm:ss.zzz");
+  if(!sendTime.isValid()) {
+    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", "PONG " + serverDecode(params).join(" "), prefix);
+    return;
+  }
+
+  network()->setLatency(sendTime.msecsTo(QTime::currentTime()) / 2);
+}
+
 void IrcServerHandler::handlePrivmsg(const QString &prefix, const QList<QByteArray> &params) {
   if(!checkParamCount("IrcServerHandler::handlePrivmsg()", params, 1))
     return;
@@ -431,14 +453,16 @@ void IrcServerHandler::handle001(const QString &prefix, const QList<QByteArray>
 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);
+  if(numParams == 0) {
+    emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Received RPL_ISUPPORT (005) without parameters!"), prefix);
+    return;
   }
 
+  emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params).join(" "), prefix);
+
   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;
+  if(!rpl_isupport_suffix.toLower().contains("are supported by this server")) {
+    emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Received non RFC compliant RPL_ISUPPORT: this can lead to unexpected behavior!"), prefix);
   }
 
   QString rawSupport;
@@ -722,6 +746,37 @@ void IrcServerHandler::handle320(const QString &prefix, const QList<QByteArray>
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(serverDecode(params).join(" ")));
 }
 
+/* RPL_LIST -  "<channel> <# visible> :<topic>" */
+void IrcServerHandler::handle322(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix)
+  QString channelName;
+  quint32 userCount = 0;
+  QString topic;
+  
+  int paramCount = params.count();
+  switch(paramCount) {
+  case 3:
+    topic = serverDecode(params[2]);
+  case 2:
+    userCount = serverDecode(params[1]).toUInt();
+  case 1:
+    channelName = serverDecode(params[0]);
+  default:
+    break;
+  }
+  if(!networkConnection()->coreSession()->ircListHelper()->addChannel(network()->networkId(), channelName, userCount, topic))
+    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Channel %1 has %2 users. Topic is: %3").arg(channelName).arg(userCount).arg(topic));
+}
+
+/* RPL_LISTEND ":End of LIST" */
+void IrcServerHandler::handle323(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix)
+  Q_UNUSED(params)
+
+  if(!networkConnection()->coreSession()->ircListHelper()->endOfChannelList(network()->networkId()))
+    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("End of channel list"));
+}
+       
 /* RPL_CHANNELMODEIS - "<channel> <mode> <mode params>" */
 void IrcServerHandler::handle324(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);