X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fcoresessioneventprocessor.cpp;h=8fa70157a100649a210d21a37a235b9bab3bc637;hb=4cf9c160f318a71400b032ea6d3031b9e6628a56;hp=57d836d9f13fe47d77036a6d1cea337e446284ad;hpb=d272e4719d2770a018f9a2856b61d9847eb24201;p=quassel.git diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index 57d836d9..8fa70157 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -28,7 +28,7 @@ #include "ctcpevent.h" #include "ircevent.h" #include "ircuser.h" -#include "logger.h" +#include "logmessage.h" #include "messageevent.h" #include "netsplit.h" #include "quassel.h" @@ -636,14 +636,71 @@ void CoreSessionEventProcessor::processIrcEventPing(IrcEvent *e) 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()) { + // Mark IRC server as sending valid ping replies + if (!coreNetwork(e)->isPongTimestampValid()) { + coreNetwork(e)->setPongTimestampValid(true); + // Add a message the first time it happens + qDebug().nospace() << "Received PONG with valid timestamp, marking pong replies on " + "network " + << "\"" << qPrintable(e->network()->networkName()) << "\" (ID: " + << qPrintable(QString::number(e->network()->networkId().toInt())) + << ") as usable for latency measurement"; + } + // Remove pending flag + coreNetwork(e)->resetPongReplyPending(); + + // Don't show this in the UI + e->setFlag(EventManager::Silent); + // TODO: To allow for a user-sent /ping (without arguments, so default timestamp is used), + // this could track how many automated PINGs have been sent by the core and subtract one + // each time, only marking the PING as silent if there's pending automated pong replies. + // However, that's a behavior change which warrants further testing. For now, take the + // simpler, previous approach that errs on the side of silencing too much. + + // Calculate latency from time difference, divided by 2 to account for round-trip time + e->network()->setLatency(sendTime.msecsTo(QTime::currentTime()) / 2); + } else if (coreNetwork(e)->isPongReplyPending() && !coreNetwork(e)->isPongTimestampValid()) { + // There's an auto-PING reply pending and we've not yet received a PONG reply with a valid + // timestamp. It's possible this server will never respond with a valid timestamp, and thus + // any automated PINGs will result in unwanted spamming of the server buffer. + + // Don't show this in the UI + e->setFlag(EventManager::Silent); + // Remove pending flag + coreNetwork(e)->resetPongReplyPending(); + + // Log a message + qDebug().nospace() << "Received PONG with invalid timestamp from network " + << "\"" << qPrintable(e->network()->networkName()) << "\" (ID: " + << qPrintable(QString::number(e->network()->networkId().toInt())) + << "), silencing, parameters are " << e->params(); } + // else: We're not expecting a PONG reply and timestamp is not valid, assume it's from the user } @@ -1556,12 +1613,30 @@ void CoreSessionEventProcessor::handleCtcpPing(CtcpEvent *e) 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) -- https://www.quassel-irc.org") - .arg(Quassel::buildInfo().plainVersionString).arg(Quassel::buildInfo().commitDate)); + // Deliberately do not translate project name + e->setReply(QString("Quassel IRC %1 (version date %2) -- https://www.quassel-irc.org") + .arg(Quassel::buildInfo().plainVersionString) + .arg(Quassel::buildInfo().commitDate.isEmpty() ? + "unknown" : tryFormatUnixEpoch(Quassel::buildInfo().commitDate))); }