/***************************************************************************
- * Copyright (C) 2005-2016 by the Quassel Project *
+ * Copyright (C) 2005-2018 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
void CoreSessionEventProcessor::processIrcEventPong(IrcEvent *e)
{
- // 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 (checkParamCount(e, 2)) {
- QString timestamp = e->params().at(1);
- QTime sendTime = QTime::fromString(timestamp, "hh:mm:ss.zzz");
- if (sendTime.isValid())
- e->network()->setLatency(sendTime.msecsTo(QTime::currentTime()) / 2);
+ // Ensure we get at least one parameter
+ if (!checkParamCount(e, 1))
+ return;
+
+ // Some IRC servers respond with only one parameter, others respond with two, with the latter
+ // being the text sent. Handle both situations.
+ QString timestamp;
+ if (e->params().count() < 2) {
+ // Only one parameter received
+ // :localhost PONG 02:43:49.565
+ timestamp = e->params().at(0);
+ } else {
+ // Two parameters received, pick the second
+ // :localhost PONG localhost :02:43:49.565
+ timestamp = e->params().at(1);
+ }
+
+ // The server is supposed to send back what we passed as parameter, and we send a timestamp.
+ // However, using quote and whatnot, one can send arbitrary pings, and IRC servers may decide to
+ // ignore our requests entirely and send whatever they want, so we have to do some sanity
+ // checks.
+ //
+ // Attempt to parse the timestamp
+ QTime sendTime = QTime::fromString(timestamp, "hh:mm:ss.zzz");
+ if (sendTime.isValid()) {
+ // Calculate latency from time difference, divided by 2 to account for round-trip time
+ e->network()->setLatency(sendTime.msecsTo(QTime::currentTime()) / 2);
+ } else {
+ // Just in case it's a wonky server, log a debug message to make this easier to track down
+ qDebug() << "Received valid PONG with invalid timestamp, parameters are" << e->params();
}
}
if (ircuser) {
ircuser->setAway(true);
ircuser->setAwayMessage(e->params().at(1));
- //ircuser->setLastAwayMessage(now);
+ // lastAwayMessageTime is set in EventStringifier::processIrcEvent301(), no need to set it
+ // here too
+ //ircuser->setLastAwayMessageTime(now);
}
}
int idleSecs = e->params()[1].toInt();
if (e->params().count() > 3) { // if we have more then 3 params we have the above mentioned "real life" situation
- int logintime = e->params()[2].toInt();
- loginTime = QDateTime::fromTime_t(logintime);
+ // Allow for 64-bit time
+ qint64 logintime = e->params()[2].toLongLong();
+ // Time in IRC protocol is defined as seconds. Convert from seconds instead.
+ // See https://doc.qt.io/qt-5/qdatetime.html#fromSecsSinceEpoch
+#if QT_VERSION >= 0x050800
+ loginTime = QDateTime::fromSecsSinceEpoch(logintime);
+#else
+ // fromSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for
+ // now.
+ // See https://doc.qt.io/qt-5/qdatetime.html#fromMSecsSinceEpoch
+ loginTime = QDateTime::fromMSecsSinceEpoch((qint64)(logintime * 1000));
+#endif
}
IrcUser *ircuser = e->network()->ircUser(e->params()[0]);
switch (e->params().count()) {
case 3:
topic = e->params()[2];
+ [[clang::fallthrough]];
case 2:
userCount = e->params()[1].toUInt();
+ [[clang::fallthrough]];
case 1:
channelName = e->params()[0];
+ [[clang::fallthrough]];
default:
break;
}
void CoreSessionEventProcessor::handleCtcpTime(CtcpEvent *e)
{
- e->setReply(QDateTime::currentDateTime().toString());
+ // Explicitly specify the Qt default DateTime format string to allow for modification
+ // Qt::TextDate default roughly corresponds to...
+ // > ddd MMM d yyyy HH:mm:ss
+ //
+ // See https://doc.qt.io/qt-5/qdatetime.html#toString
+ // And https://doc.qt.io/qt-5/qt.html#DateFormat-enum
+#if QT_VERSION > 0x050000
+ // Append the timezone identifier "t", so other other IRC users have a frame of reference for
+ // the current timezone. This could be figured out before by manually comparing to UTC, so this
+ // is just convenience.
+
+ // Alas, "t" was only added in Qt 5
+ e->setReply(QDateTime::currentDateTime().toString("ddd MMM d yyyy HH:mm:ss t"));
+#else
+ e->setReply(QDateTime::currentDateTime().toString("ddd MMM d yyyy HH:mm:ss"));
+#endif
}
void CoreSessionEventProcessor::handleCtcpVersion(CtcpEvent *e)
{
- e->setReply(QString("Quassel IRC %1 (built on %2) -- http://www.quassel-irc.org")
+ e->setReply(QString("Quassel IRC %1 (built on %2) -- https://www.quassel-irc.org")
.arg(Quassel::buildInfo().plainVersionString).arg(Quassel::buildInfo().commitDate));
}