X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fircparser.cpp;h=3bd8691324dedf43c1cd6fe7526b828aa4d41af1;hb=1dc525a6f105f8db449bf04b127147f24de3d421;hp=8a6a7eb4ad5a3002fc99020bd45af3dbce445f34;hpb=fad08c0bc53514b43fdf44e5a792a019b1414367;p=quassel.git diff --git a/src/core/ircparser.cpp b/src/core/ircparser.cpp index 8a6a7eb4..3bd86913 100644 --- a/src/core/ircparser.cpp +++ b/src/core/ircparser.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2019 by the Quassel Project * + * Copyright (C) 2005-2020 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -119,6 +119,16 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) qDebug() << "IRC net" << net->networkId() << "<<" << tags << prefix << cmd << params; } + if (tags.contains(IrcTags::SERVER_TIME)) { + QDateTime serverTime = QDateTime::fromString(tags[IrcTags::SERVER_TIME], "yyyy-MM-ddThh:mm:ss.zzzZ"); + serverTime.setTimeSpec(Qt::UTC); + if (serverTime.isValid()) { + e->setTimestamp(serverTime); + } else { + qDebug() << "Invalid timestamp from server-time tag:" << tags[IrcTags::SERVER_TIME]; + } + } + QList events; EventManager::EventType type = EventManager::Invalid; @@ -179,6 +189,7 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) IrcEventRawMessage* rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawPrivmsg, net, + tags, msg, prefix, target, @@ -246,16 +257,17 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) // Don't allow key exchange in channels, and don't allow it for self-messages. bool keyExchangeAllowed = (!net->isChannelName(target) && !isSelfMessage); if (params[1].startsWith("DH1080_INIT") && keyExchangeAllowed) { - events << new KeyEvent(EventManager::KeyEvent, net, prefix, target, KeyEvent::Init, params[1].mid(12)); + events << new KeyEvent(EventManager::KeyEvent, net, tags, prefix, target, KeyEvent::Init, params[1].mid(12)); } else if (params[1].startsWith("DH1080_FINISH") && keyExchangeAllowed) { - events << new KeyEvent(EventManager::KeyEvent, net, prefix, target, KeyEvent::Finish, params[1].mid(14)); + events << new KeyEvent(EventManager::KeyEvent, net, tags, prefix, target, KeyEvent::Finish, params[1].mid(14)); } else #endif { IrcEventRawMessage* rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawNotice, net, + tags, params[1], prefix, target, @@ -270,7 +282,7 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) } break; - // the following events need only special casing for param decoding + // the following events need only special casing for param decoding case EventManager::IrcEventKick: if (params.count() >= 3) { // we have a reason decParams << net->serverDecode(params.at(0)) << net->serverDecode(params.at(1)); @@ -294,6 +306,34 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) } break; + case EventManager::IrcEventTagmsg: + defaultHandling = false; // this might create a list of events + + if (checkParamCount(cmd, params, 1)) { + QString senderNick = nickFromMask(prefix); + net->updateNickFromMask(prefix); + // Check if the sender is our own nick. If so, treat message as if sent by ourself. + // See http://ircv3.net/specs/extensions/echo-message-3.2.html + // Cache the result to avoid multiple redundant comparisons + bool isSelfMessage = net->isMyNick(senderNick); + + QStringList targets = net->serverDecode(params.at(0)).split(',', QString::SkipEmptyParts); + QStringList::const_iterator targetIter; + for (targetIter = targets.constBegin(); targetIter != targets.constEnd(); ++targetIter) { + // For self-messages, keep the target, don't set it to the senderNick + QString target = net->isChannelName(*targetIter) || net->isStatusMsg(*targetIter) || isSelfMessage ? *targetIter : senderNick; + + IrcEvent* tagMsg = new IrcEvent(EventManager::IrcEventTagmsg, net, tags, prefix, {target}); + if (isSelfMessage) { + // Self-messages need processed differently, tag as such via flag. + tagMsg->setFlag(EventManager::Self); + } + tagMsg->setTimestamp(e->timestamp()); + events << tagMsg; + } + } + break; + case EventManager::IrcEventTopic: if (params.count() >= 1) { QString channel = net->serverDecode(params.at(0)); @@ -302,15 +342,17 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) } break; - case EventManager::IrcEventAway: { - // Update hostmask info first. This will create the nick if it doesn't exist, e.g. - // away-notify data being sent before JOIN messages. - net->updateNickFromMask(prefix); - // Separate nick in order to separate server and user decoding - QString nick = nickFromMask(prefix); - decParams << nick; - decParams << (params.count() >= 1 ? net->userDecode(nick, params.at(0)) : QString()); - } break; + case EventManager::IrcEventAway: + { + // Update hostmask info first. This will create the nick if it doesn't exist, e.g. + // away-notify data being sent before JOIN messages. + net->updateNickFromMask(prefix); + // Separate nick in order to separate server and user decoding + QString nick = nickFromMask(prefix); + decParams << nick; + decParams << (params.count() >= 1 ? net->userDecode(nick, params.at(0)) : QString()); + } + break; case EventManager::IrcEventNumeric: switch (num) { @@ -369,15 +411,15 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) IrcEvent* event; if (type == EventManager::IrcEventNumeric) - event = new IrcEventNumeric(num, net, prefix, messageTarget); + event = new IrcEventNumeric(num, net, tags, prefix, messageTarget); else - event = new IrcEvent(type, net, prefix); + event = new IrcEvent(type, net, tags, prefix); event->setParams(decParams); event->setTimestamp(e->timestamp()); events << event; } - foreach (Event* event, events) { + for (Event* event : events) { emit newEvent(event); } }