X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcoresessioneventprocessor.cpp;h=e0fa8921389a22c3cfdc8423a589a0dda5a5fc93;hp=2a3dfc2e29ad133729e00949028e1dc2de4f77e6;hb=714b39660fe19e7f092880019429c8da76ee2bd5;hpb=d1aa795013aaebe5ca57353d6077b0007b489832 diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index 2a3dfc2e..e0fa8921 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -402,11 +402,16 @@ void CoreSessionEventProcessor::processIrcEventJoin(IrcEvent *e) break; } - // If using away-notify, check new users. Works around buggy IRC servers - // forgetting to send :away messages for users who join channels when away. - if (net->capEnabled(IrcCap::AWAY_NOTIFY)) { - net->queueAutoWhoOneshot(ircuser->nick()); - } + // With "away-notify" enabled, some IRC servers forget to send :away messages for users who join + // channels while away. Unfortunately, working around this involves WHO'ng every single user as + // they join, which is not very efficient. If at all possible, it's better to get the issue + // fixed in the IRC server instead. + // + // If pursuing a workaround instead, this is where you'd do it. Check the version control + // history for the commit that added this comment to see how to implement it - there's some + // unexpected situations to watch out for! + // + // See https://ircv3.net/specs/extensions/away-notify-3.1.html if (!handledByNetsplit) ircuser->joinChannel(channel); @@ -454,17 +459,17 @@ void CoreSessionEventProcessor::processIrcEventMode(IrcEvent *e) QString modes = e->params()[1]; bool add = true; int paramOffset = 2; - for (int c = 0; c < modes.length(); c++) { - if (modes[c] == '+') { + for (auto mode : modes) { + if (mode == '+') { add = true; continue; } - if (modes[c] == '-') { + if (mode == '-') { add = false; continue; } - if (e->network()->prefixModes().contains(modes[c])) { + if (e->network()->prefixModes().contains(mode)) { // user channel modes (op, voice, etc...) if (paramOffset < e->params().count()) { IrcUser *ircUser = e->network()->ircUser(e->params()[paramOffset]); @@ -478,15 +483,15 @@ void CoreSessionEventProcessor::processIrcEventMode(IrcEvent *e) foreach(Netsplit* n, _netsplits.value(e->network())) { handledByNetsplit = n->userAlreadyJoined(ircUser->hostmask(), channel->name()); if (handledByNetsplit) { - n->addMode(ircUser->hostmask(), channel->name(), QString(modes[c])); + n->addMode(ircUser->hostmask(), channel->name(), QString(mode)); break; } } if (!handledByNetsplit) - channel->addUserMode(ircUser, QString(modes[c])); + channel->addUserMode(ircUser, QString(mode)); } else - channel->removeUserMode(ircUser, QString(modes[c])); + channel->removeUserMode(ircUser, QString(mode)); } } else { @@ -497,7 +502,7 @@ void CoreSessionEventProcessor::processIrcEventMode(IrcEvent *e) else { // regular channel modes QString value; - Network::ChannelModeType modeType = e->network()->channelModeType(modes[c]); + Network::ChannelModeType modeType = e->network()->channelModeType(mode); if (modeType == Network::A_CHANMODE || modeType == Network::B_CHANMODE || (modeType == Network::C_CHANMODE && add)) { if (paramOffset < e->params().count()) { value = e->params()[paramOffset]; @@ -509,9 +514,9 @@ void CoreSessionEventProcessor::processIrcEventMode(IrcEvent *e) } if (add) - channel->addChannelMode(modes[c], value); + channel->addChannelMode(mode, value); else - channel->removeChannelMode(modes[c], value); + channel->removeChannelMode(mode, value); } } } @@ -796,7 +801,7 @@ void CoreSessionEventProcessor::processKeyEvent(KeyEvent *e) emit newEvent(new MessageEvent(Message::Error, e->network(), tr("Unable to perform key exchange, missing qca-ossl plugin."), e->prefix(), e->target(), Message::None, e->timestamp())); return; } - CoreNetwork *net = qobject_cast(e->network()); + auto *net = qobject_cast(e->network()); Cipher *c = net->cipher(e->target()); if (!c) // happens when there is no CoreIrcChannel for the target (i.e. never?) return; @@ -1134,9 +1139,7 @@ void CoreSessionEventProcessor::processIrcEvent352(IrcEvent *e) return; QString channel = e->params()[0]; - // Store the nick separate from ircuser for AutoWho check below - QString nick = e->params()[4]; - IrcUser *ircuser = e->network()->ircUser(nick); + IrcUser *ircuser = e->network()->ircUser(e->params()[4]); if (ircuser) { // Only process the WHO information if an IRC user exists. Don't create an IRC user here; // there's no way to track when the user quits, which would leave a phantom IrcUser lying @@ -1148,10 +1151,7 @@ void CoreSessionEventProcessor::processIrcEvent352(IrcEvent *e) } // Check if channel name has a who in progress. - // If not, then check if user nickname has a who in progress. Use nick directly; don't use - // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received). - if (coreNetwork(e)->isAutoWhoInProgress(channel) || - (coreNetwork(e)->isAutoWhoInProgress(nick))) { + if (coreNetwork(e)->isAutoWhoInProgress(channel)) { e->setFlag(EventManager::Silent); } } @@ -1238,8 +1238,7 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e) return; QString channel = e->params()[1]; - QString nick = e->params()[5]; - IrcUser *ircuser = e->network()->ircUser(nick); + IrcUser *ircuser = e->network()->ircUser(e->params()[5]); if (ircuser) { // Only process the WHO information if an IRC user exists. Don't create an IRC user here; // there's no way to track when the user quits, which would leave a phantom IrcUser lying @@ -1263,10 +1262,7 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e) } // Check if channel name has a who in progress. - // If not, then check if user nickname has a who in progress. Use nick directly; don't use - // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received). - if (coreNetwork(e)->isAutoWhoInProgress(channel) || - (coreNetwork(e)->isAutoWhoInProgress(nick))) { + if (coreNetwork(e)->isAutoWhoInProgress(channel)) { e->setFlag(EventManager::Silent); } } @@ -1482,7 +1478,7 @@ void CoreSessionEventProcessor::handleEarlyNetsplitJoin(Network *net, const QStr void CoreSessionEventProcessor::handleNetsplitFinished() { - Netsplit *n = qobject_cast(sender()); + auto *n = qobject_cast(sender()); Q_ASSERT(n); QHash splithash = _netsplits.take(n->network()); splithash.remove(splithash.key(n)); @@ -1613,30 +1609,22 @@ void CoreSessionEventProcessor::handleCtcpPing(CtcpEvent *e) void CoreSessionEventProcessor::handleCtcpTime(CtcpEvent *e) { - // 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 + // Use the ISO standard to avoid locale-specific translated names + // Include timezone offset data to show which timezone a user's in, otherwise we're providing + // NTP-over-IRC with terrible accuracy. + e->setReply(formatDateTimeToOffsetISO(QDateTime::currentDateTime())); } void CoreSessionEventProcessor::handleCtcpVersion(CtcpEvent *e) { // Deliberately do not translate project name + // Use the ISO standard to avoid locale-specific translated names + // Use UTC time to provide a consistent string regardless of timezone + // (Statistics tracking tools usually only group client versions by exact string matching) 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))); + "unknown" : tryFormatUnixEpoch(Quassel::buildInfo().commitDate, + Qt::DateFormat::ISODate, true))); }