X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Feventstringifier.cpp;h=a852be1b8facedc6b69b2a87b1a64865978ba45a;hp=c7da8d78b5279beecdfdf69bfec90977d3ff14d2;hb=HEAD;hpb=dcc541413235e39cc505061950d4aafa89367f98 diff --git a/src/core/eventstringifier.cpp b/src/core/eventstringifier.cpp index c7da8d78..a9c68c80 100644 --- a/src/core/eventstringifier.cpp +++ b/src/core/eventstringifier.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2018 by the Quassel Project * + * Copyright (C) 2005-2022 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -22,45 +22,52 @@ #include "coresession.h" #include "ctcpevent.h" +#include "irctags.h" #include "messageevent.h" -EventStringifier::EventStringifier(CoreSession *parent) : BasicHandler("handleCtcp", parent), - _coreSession(parent), - _whois(false) +EventStringifier::EventStringifier(CoreSession* parent) + : BasicHandler("handleCtcp", parent) + , _coreSession(parent) + , _whois(false) { - connect(this, SIGNAL(newMessageEvent(Event *)), coreSession()->eventManager(), SLOT(postEvent(Event *))); + connect(this, &EventStringifier::newMessageEvent, coreSession()->eventManager(), &EventManager::postEvent); } - -void EventStringifier::displayMsg(NetworkEvent *event, Message::Type msgType, const QString &msg, const QString &sender, - const QString &target, Message::Flags msgFlags) +void EventStringifier::displayMsg(NetworkEvent* event, + Message::Type msgType, + QString msg, + QString sender, + QString target, + Message::Flags msgFlags) { if (event->flags().testFlag(EventManager::Silent)) return; - MessageEvent *msgEvent = createMessageEvent(event, msgType, msg, sender, target, msgFlags); - //sendMessageEvent(msgEvent); + MessageEvent* msgEvent = createMessageEvent(event, msgType, std::move(msg), std::move(sender), std::move(target), msgFlags); + // sendMessageEvent(msgEvent); emit newMessageEvent(msgEvent); } - -MessageEvent *EventStringifier::createMessageEvent(NetworkEvent *event, Message::Type msgType, const QString &msg, const QString &sender, - const QString &target, Message::Flags msgFlags) +MessageEvent* EventStringifier::createMessageEvent(NetworkEvent* event, + Message::Type msgType, + QString msg, + QString sender, + QString target, + Message::Flags msgFlags) { - MessageEvent *msgEvent = new MessageEvent(msgType, event->network(), msg, sender, target, msgFlags); - msgEvent->setTimestamp(event->timestamp()); + MessageEvent* msgEvent = new MessageEvent(msgType, event->network(), std::move(msg), std::move(sender), std::move(target), msgFlags, event->timestamp()); return msgEvent; } - -bool EventStringifier::checkParamCount(IrcEvent *e, int minParams) +bool EventStringifier::checkParamCount(IrcEvent* e, int minParams) { if (e->params().count() < minParams) { if (e->type() == EventManager::IrcEventNumeric) { - qWarning() << "Command " << static_cast(e)->number() << " requires " << minParams << "params, got: " << e->params(); + qWarning() << "Command " << static_cast(e)->number() << " requires " << minParams + << "params, got: " << e->params(); } else { - QString name = coreSession()->eventManager()->enumName(e->type()); + QString name = EventManager::enumName(e->type()); qWarning() << qPrintable(name) << "requires" << minParams << "params, got:" << e->params(); } e->stop(); @@ -69,27 +76,24 @@ bool EventStringifier::checkParamCount(IrcEvent *e, int minParams) return true; } - /* These are only for legacy reasons; remove as soon as we handle NetworkSplitEvents properly */ -void EventStringifier::processNetworkSplitJoin(NetworkSplitEvent *e) +void EventStringifier::processNetworkSplitJoin(NetworkSplitEvent* e) { QString msg = e->users().join("#:#") + "#:#" + e->quitMessage(); displayMsg(e, Message::NetsplitJoin, msg, QString(), e->channel()); } - -void EventStringifier::processNetworkSplitQuit(NetworkSplitEvent *e) +void EventStringifier::processNetworkSplitQuit(NetworkSplitEvent* e) { QString msg = e->users().join("#:#") + "#:#" + e->quitMessage(); displayMsg(e, Message::NetsplitQuit, msg, QString(), e->channel()); } - /* End legacy */ -void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) +void EventStringifier::processIrcEventNumeric(IrcEventNumeric* e) { - //qDebug() << e->number(); + // qDebug() << e->number(); switch (e->number()) { // Welcome, status, info messages. Just display these. case 1: @@ -137,13 +141,12 @@ void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) case 491: case 501: case 502: - case 431: // ERR_NONICKNAMEGIVEN + case 431: // ERR_NONICKNAMEGIVEN displayMsg(e, Message::Error, e->params().join(" "), e->prefix()); break; // Server error messages, display them in red. Colon between first param and rest. - case 401: - { + case 401: { if (!checkParamCount(e, 1)) return; @@ -160,8 +163,7 @@ void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) case 408: case 415: case 421: - case 442: - { + case 442: { if (!checkParamCount(e, 1)) return; @@ -177,7 +179,7 @@ void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) case 423: case 441: case 444: - case 461: // FIXME see below for the 47x codes + case 461: // FIXME see below for the 47x codes case 467: case 471: case 473: @@ -187,7 +189,7 @@ void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) case 477: case 478: case 482: - case 436: // ERR_NICKCOLLISION + case 436: // ERR_NICKCOLLISION { if (!checkParamCount(e, 1)) return; @@ -239,22 +241,31 @@ void EventStringifier::processIrcEventNumeric(IrcEventNumeric *e) } else { // FIXME figure out how/where to do this in the future - //if(coreSession()->ircListHelper()->requestInProgress(network()->networkId())) + // if(coreSession()->ircListHelper()->requestInProgress(network()->networkId())) // coreSession()->ircListHelper()->reportError(params.join(" ")); - //else + // else displayMsg(e, Message::Error, QString("%1 %2").arg(e->number(), 3, 10, QLatin1Char('0')).arg(e->params().join(" ")), e->prefix()); } } } - -void EventStringifier::processIrcEventInvite(IrcEvent *e) +void EventStringifier::processIrcEventInvite(IrcEvent* e) { - displayMsg(e, Message::Invite, tr("%1 invited you to channel %2").arg(e->nick(), e->params().at(1))); -} + if (!checkParamCount(e, 2)) + return; + // TODO: provide a nicer UI for invite notifications + QString target = e->params().at(0); + QString channel = e->params().at(1); + if (e->network()->isMyNick(target)) { + displayMsg(e, Message::Invite, tr("%1 invited you to channel %2").arg(e->nick(), channel)); + } + else { + displayMsg(e, Message::Invite, tr("%1 invited %2 to channel %3").arg(e->nick(), target, channel)); + } +} -void EventStringifier::processIrcEventJoin(IrcEvent *e) +void EventStringifier::processIrcEventJoin(IrcEvent* e) { if (e->testFlag(EventManager::Netsplit)) return; @@ -268,13 +279,12 @@ void EventStringifier::processIrcEventJoin(IrcEvent *e) displayMsg(e, Message::Join, e->params()[0], e->prefix(), e->params()[0], msgFlags); } - -void EventStringifier::processIrcEventKick(IrcEvent *e) +void EventStringifier::processIrcEventKick(IrcEvent* e) { if (!checkParamCount(e, 2)) return; - IrcUser *victim = e->network()->ircUser(e->params().at(1)); + IrcUser* victim = e->network()->ircUser(e->params().at(1)); if (victim) { QString channel = e->params().at(0); QString msg = victim->nick(); @@ -291,8 +301,7 @@ void EventStringifier::processIrcEventKick(IrcEvent *e) } } - -void EventStringifier::processIrcEventMode(IrcEvent *e) +void EventStringifier::processIrcEventMode(IrcEvent* e) { if (e->network()->isChannelName(e->params().first())) { // Channel Modes @@ -311,14 +320,13 @@ void EventStringifier::processIrcEventMode(IrcEvent *e) } } - // this needs to be called before the ircuser is renamed! -void EventStringifier::processIrcEventNick(IrcEvent *e) +void EventStringifier::processIrcEventNick(IrcEvent* e) { if (!checkParamCount(e, 1)) return; - IrcUser *ircuser = e->network()->updateNickFromMask(e->prefix()); + IrcUser* ircuser = e->network()->updateNickFromMask(e->prefix()); if (!ircuser) { qWarning() << Q_FUNC_INFO << "Unknown IrcUser!"; return; @@ -332,19 +340,19 @@ void EventStringifier::processIrcEventNick(IrcEvent *e) // Treat the sender as the new nickname, mark the message as Self sender = newnick; msgFlags = Message::Self; - } else { + } + else { // Take the sender from the event prefix, don't mark the message sender = e->prefix(); } // Announce to all channels the IrcUser is in - foreach(const QString &channel, ircuser->channels()) { + for (const QString& channel : ircuser->channels()) { displayMsg(e, Message::Nick, newnick, sender, channel, msgFlags); } } - -void EventStringifier::processIrcEventPart(IrcEvent *e) +void EventStringifier::processIrcEventPart(IrcEvent* e) { if (!checkParamCount(e, 1)) return; @@ -352,7 +360,6 @@ void EventStringifier::processIrcEventPart(IrcEvent *e) QString channel = e->params().at(0); QString msg = e->params().count() > 1 ? e->params().at(1) : QString(); - Message::Flag msgFlags = Message::Flag::None; if (e->testFlag(EventManager::Self)) { // Mark the message as Self @@ -362,8 +369,7 @@ void EventStringifier::processIrcEventPart(IrcEvent *e) displayMsg(e, Message::Part, msg, e->prefix(), channel, msgFlags); } - -void EventStringifier::processIrcEventPong(IrcEvent *e) +void EventStringifier::processIrcEventPong(IrcEvent* e) { // CoreSessionEventProcessor will flag automated PONG replies as EventManager::Silent. There's // no need to handle that specially here. @@ -372,17 +378,15 @@ void EventStringifier::processIrcEventPong(IrcEvent *e) displayMsg(e, Message::Server, "PONG " + e->params().join(" "), e->prefix()); } - -void EventStringifier::processIrcEventQuit(IrcEvent *e) +void EventStringifier::processIrcEventQuit(IrcEvent* e) { if (e->testFlag(EventManager::Netsplit)) return; - IrcUser *ircuser = e->network()->updateNickFromMask(e->prefix()); + IrcUser* ircuser = e->network()->updateNickFromMask(e->prefix()); if (!ircuser) return; - Message::Flag msgFlags = Message::Flag::None; if (e->testFlag(EventManager::Self)) { // Mark the message as Self @@ -390,14 +394,12 @@ void EventStringifier::processIrcEventQuit(IrcEvent *e) } // Announce to all channels the IrcUser is in - foreach(const QString &channel, ircuser->channels()) { - displayMsg(e, Message::Quit, e->params().count() ? e->params().first() : QString(), - e->prefix(), channel, msgFlags); + for (const QString& channel : ircuser->channels()) { + displayMsg(e, Message::Quit, e->params().count() ? e->params().first() : QString(), e->prefix(), channel, msgFlags); } } - -void EventStringifier::processIrcEventTopic(IrcEvent *e) +void EventStringifier::processIrcEventTopic(IrcEvent* e) { Message::Flag msgFlags = Message::Flag::None; if (e->testFlag(EventManager::Self)) { @@ -405,12 +407,15 @@ void EventStringifier::processIrcEventTopic(IrcEvent *e) msgFlags = Message::Self; } - displayMsg(e, Message::Topic, tr("%1 has changed topic for %2 to: \"%3\"") - .arg(e->nick(), e->params().at(0), e->params().at(1)), QString(), e->params().at(0), + displayMsg(e, + Message::Topic, + tr("%1 has changed topic for %2 to: \"%3\"").arg(e->nick(), e->params().at(0), e->params().at(1)), + QString(), + e->params().at(0), msgFlags); } -void EventStringifier::processIrcEventError(IrcEvent *e) +void EventStringifier::processIrcEventError(IrcEvent* e) { // Need an error reason if (!checkParamCount(e, 1)) @@ -419,23 +424,21 @@ void EventStringifier::processIrcEventError(IrcEvent *e) displayMsg(e, Message::Server, tr("Error from server: ") + e->params().join("")); } -void EventStringifier::processIrcEventWallops(IrcEvent *e) +void EventStringifier::processIrcEventWallops(IrcEvent* e) { displayMsg(e, Message::Server, tr("[Operwall] %1: %2").arg(e->nick(), e->params().join(" "))); } - /* RPL_ISUPPORT */ -void EventStringifier::processIrcEvent005(IrcEvent *e) +void EventStringifier::processIrcEvent005(IrcEvent* e) { if (!e->params().last().contains(QRegExp("are supported (by|on) this server"))) displayMsg(e, Message::Error, tr("Received non-RFC-compliant RPL_ISUPPORT: this can lead to unexpected behavior!"), e->prefix()); displayMsg(e, Message::Server, e->params().join(" "), e->prefix()); } - /* RPL_AWAY - " :" */ -void EventStringifier::processIrcEvent301(IrcEvent *e) +void EventStringifier::processIrcEvent301(IrcEvent* e) { QString nick = e->params().at(0); QString awayMsg = e->params().at(1); @@ -448,37 +451,41 @@ void EventStringifier::processIrcEvent301(IrcEvent *e) } else { target = nick; - IrcUser *ircuser = e->network()->ircUser(nick); + IrcUser* ircuser = e->network()->ircUser(nick); if (ircuser) { QDateTime now = QDateTime::currentDateTime(); now.setTimeSpec(Qt::UTC); // Don't print "user is away" messages more often than this - const int silenceTime = 60; - if (ircuser->lastAwayMessageTime().addSecs(silenceTime) >= now) + // 1 hour = 60 min * 60 sec + const int silenceTime = 60 * 60; + // Check if away state has NOT changed and silence time hasn't yet elapsed + if (!ircuser->hasAwayChanged() && ircuser->lastAwayMessageTime().addSecs(silenceTime) >= now) { + // Away message hasn't changed and we're still within the period of silence; don't + // repeat the message send = false; + } ircuser->setLastAwayMessageTime(now); + // Mark any changes in away as acknowledged + ircuser->acknowledgeAwayChanged(); } } if (send) displayMsg(e, Message::Server, msg + tr("%1 is away: \"%2\"").arg(nick, awayMsg), QString(), target); } - /* RPL_UNAWAY - ":You are no longer marked as being away" */ -void EventStringifier::processIrcEvent305(IrcEvent *e) +void EventStringifier::processIrcEvent305(IrcEvent* e) { displayMsg(e, Message::Server, tr("You are no longer marked as being away")); } - /* RPL_NOWAWAY - ":You have been marked as being away" */ -void EventStringifier::processIrcEvent306(IrcEvent *e) +void EventStringifier::processIrcEvent306(IrcEvent* e) { if (!e->network()->autoAwayActive()) displayMsg(e, Message::Server, tr("You have been marked as being away")); } - /* WHOIS-Message: Replies 311 - 313, 317 - 319 are all replies generated in response to a WHOIS message. @@ -493,13 +500,13 @@ WHOWAS-Message: */ /* RPL_WHOISUSER - " * :" */ -void EventStringifier::processIrcEvent311(IrcEvent *e) +void EventStringifier::processIrcEvent311(IrcEvent* e) { _whois = true; const QString whoisUserString = tr("[Whois] %1 is %2 (%3)"); - IrcUser *ircuser = e->network()->ircUser(e->params().at(0)); + IrcUser* ircuser = e->network()->ircUser(e->params().at(0)); if (ircuser) displayMsg(e, Message::Server, whoisUserString.arg(ircuser->nick(), ircuser->hostmask(), ircuser->realName())); else { @@ -508,9 +515,8 @@ void EventStringifier::processIrcEvent311(IrcEvent *e) } } - /* RPL_WHOISSERVER - " :" */ -void EventStringifier::processIrcEvent312(IrcEvent *e) +void EventStringifier::processIrcEvent312(IrcEvent* e) { if (_whois) displayMsg(e, Message::Server, tr("[Whois] %1 is online via %2 (%3)").arg(e->params().at(0), e->params().at(1), e->params().last())); @@ -518,9 +524,8 @@ void EventStringifier::processIrcEvent312(IrcEvent *e) displayMsg(e, Message::Server, tr("[Whowas] %1 was online via %2 (%3)").arg(e->params().at(0), e->params().at(1), e->params().last())); } - /* RPL_WHOWASUSER - " * :" */ -void EventStringifier::processIrcEvent314(IrcEvent *e) +void EventStringifier::processIrcEvent314(IrcEvent* e) { if (!checkParamCount(e, 3)) return; @@ -528,23 +533,22 @@ void EventStringifier::processIrcEvent314(IrcEvent *e) displayMsg(e, Message::Server, tr("[Whowas] %1 was %2@%3 (%4)").arg(e->params()[0], e->params()[1], e->params()[2], e->params().last())); } - /* RPL_ENDOFWHO: " :End of WHO list" */ -void EventStringifier::processIrcEvent315(IrcEvent *e) +void EventStringifier::processIrcEvent315(IrcEvent* e) { QStringList p = e->params(); - p.takeLast(); // should be "End of WHO list" + p.takeLast(); // should be "End of WHO list" displayMsg(e, Message::Server, tr("[Who] End of /WHO list for %1").arg(p.join(" "))); } - /* RPL_WHOISIDLE - " :seconds idle" (real life: " :seconds idle, signon time) */ -void EventStringifier::processIrcEvent317(IrcEvent *e) +void EventStringifier::processIrcEvent317(IrcEvent* e) { 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 + if (e->params().count() > 3) { + // if we have more then 3 params we have the above mentioned "real life" situation // 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 @@ -552,29 +556,28 @@ void EventStringifier::processIrcEvent317(IrcEvent *e) #else // fromSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now. // See https://doc.qt.io/qt-5/qdatetime.html#fromMSecsSinceEpoch - QDateTime loginTime = QDateTime::fromMSecsSinceEpoch( - (qint64)(e->params()[2].toLongLong() * 1000)).toUTC(); + QDateTime loginTime = QDateTime::fromMSecsSinceEpoch((qint64)(e->params()[2].toLongLong() * 1000)).toUTC(); #endif - displayMsg(e, Message::Server, tr("[Whois] %1 is logged in since %2") - .arg(e->params()[0], loginTime.toString("yyyy-MM-dd hh:mm:ss UTC"))); + displayMsg(e, + Message::Server, + tr("[Whois] %1 is logged in since %2").arg(e->params()[0], loginTime.toString("yyyy-MM-dd hh:mm:ss UTC"))); } QDateTime idlingSince = e->timestamp().toLocalTime().addSecs(-idleSecs).toUTC(); - displayMsg(e, Message::Server, tr("[Whois] %1 is idling for %2 (since %3)") - .arg(e->params()[0], secondsToString(idleSecs), - idlingSince.toString("yyyy-MM-dd hh:mm:ss UTC"))); + displayMsg(e, + Message::Server, + tr("[Whois] %1 is idling for %2 (since %3)") + .arg(e->params()[0], secondsToString(idleSecs), idlingSince.toString("yyyy-MM-dd hh:mm:ss UTC"))); } - /* RPL_ENDOFWHOIS - " :End of WHOIS list" */ -void EventStringifier::processIrcEvent318(IrcEvent *e) +void EventStringifier::processIrcEvent318(IrcEvent* e) { _whois = false; displayMsg(e, Message::Server, tr("[Whois] End of /WHOIS list")); } - /* RPL_WHOISCHANNELS - " :*( ( "@" / "+" ) " " )" */ -void EventStringifier::processIrcEvent319(IrcEvent *e) +void EventStringifier::processIrcEvent319(IrcEvent* e) { if (!checkParamCount(e, 2)) return; @@ -583,7 +586,7 @@ void EventStringifier::processIrcEvent319(IrcEvent *e) QStringList op; QStringList voice; QStringList user; - foreach(QString channel, e->params().last().split(" ")) { + for (QString channel : e->params().last().split(" ")) { if (channel.startsWith("@")) op.append(channel.remove(0, 1)); else if (channel.startsWith("+")) @@ -599,9 +602,8 @@ void EventStringifier::processIrcEvent319(IrcEvent *e) displayMsg(e, Message::Server, tr("[Whois] %1 is an operator on channels: %2").arg(nick, op.join(" "))); } - /* RPL_LIST - " <# visible> :" */ -void EventStringifier::processIrcEvent322(IrcEvent *e) +void EventStringifier::processIrcEvent322(IrcEvent* e) { QString channelName; quint32 userCount = 0; @@ -610,37 +612,33 @@ void EventStringifier::processIrcEvent322(IrcEvent *e) switch (e->params().count()) { case 3: topic = e->params()[2]; - [[clang::fallthrough]]; + // fallthrough case 2: userCount = e->params()[1].toUInt(); - [[clang::fallthrough]]; + /* fallthrough */ case 1: channelName = e->params()[0]; - [[clang::fallthrough]]; + // blubb default: break; } - displayMsg(e, Message::Server, tr("Channel %1 has %2 users. Topic is: \"%3\"") - .arg(channelName).arg(userCount).arg(topic)); + displayMsg(e, Message::Server, tr("Channel %1 has %2 users. Topic is: \"%3\"").arg(channelName).arg(userCount).arg(topic)); } - /* RPL_LISTEND ":End of LIST" */ -void EventStringifier::processIrcEvent323(IrcEvent *e) +void EventStringifier::processIrcEvent323(IrcEvent* e) { displayMsg(e, Message::Server, tr("End of channel list")); } - /* RPL_CHANNELMODEIS - " " */ -void EventStringifier::processIrcEvent324(IrcEvent *e) +void EventStringifier::processIrcEvent324(IrcEvent* e) { processIrcEventMode(e); } - /* RPL_??? - " */ -void EventStringifier::processIrcEvent328(IrcEvent *e) +void EventStringifier::processIrcEvent328(IrcEvent* e) { if (!checkParamCount(e, 2)) return; @@ -649,9 +647,8 @@ void EventStringifier::processIrcEvent328(IrcEvent *e) displayMsg(e, Message::Topic, tr("Homepage for %1 is %2").arg(channel, e->params()[1]), QString(), channel); } - /* RPL_??? - " " */ -void EventStringifier::processIrcEvent329(IrcEvent *e) +void EventStringifier::processIrcEvent329(IrcEvent* e) { if (!checkParamCount(e, 2)) return; @@ -672,14 +669,11 @@ void EventStringifier::processIrcEvent329(IrcEvent *e) // See https://doc.qt.io/qt-5/qdatetime.html#fromMSecsSinceEpoch QDateTime time = QDateTime::fromMSecsSinceEpoch((qint64)(unixtime * 1000)).toUTC(); #endif - displayMsg(e, Message::Topic, tr("Channel %1 created on %2") - .arg(channel, time.toString("yyyy-MM-dd hh:mm:ss UTC")), - QString(), channel); + displayMsg(e, Message::Topic, tr("Channel %1 created on %2").arg(channel, time.toString("yyyy-MM-dd hh:mm:ss UTC")), QString(), channel); } - /* RPL_WHOISACCOUNT: " :is authed as */ -void EventStringifier::processIrcEvent330(IrcEvent *e) +void EventStringifier::processIrcEvent330(IrcEvent* e) { if (e->params().count() < 3) return; @@ -693,25 +687,22 @@ void EventStringifier::processIrcEvent330(IrcEvent *e) } } - /* RPL_NOTOPIC */ -void EventStringifier::processIrcEvent331(IrcEvent *e) +void EventStringifier::processIrcEvent331(IrcEvent* e) { QString channel = e->params().first(); displayMsg(e, Message::Topic, tr("No topic is set for %1.").arg(channel), QString(), channel); } - /* RPL_TOPIC */ -void EventStringifier::processIrcEvent332(IrcEvent *e) +void EventStringifier::processIrcEvent332(IrcEvent* e) { QString channel = e->params().first(); displayMsg(e, Message::Topic, tr("Topic for %1 is \"%2\"").arg(channel, e->params()[1]), QString(), channel); } - /* Topic set by... */ -void EventStringifier::processIrcEvent333(IrcEvent *e) +void EventStringifier::processIrcEvent333(IrcEvent* e) { if (!checkParamCount(e, 3)) return; @@ -724,17 +715,17 @@ void EventStringifier::processIrcEvent333(IrcEvent *e) #else // fromSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now. // See https://doc.qt.io/qt-5/qdatetime.html#fromMSecsSinceEpoch - QDateTime topicSetTime = QDateTime::fromMSecsSinceEpoch( - (qint64)(e->params()[2].toLongLong() * 1000)).toUTC(); + QDateTime topicSetTime = QDateTime::fromMSecsSinceEpoch((qint64)(e->params()[2].toLongLong() * 1000)).toUTC(); #endif - displayMsg(e, Message::Topic, tr("Topic set by %1 on %2") - .arg(e->params()[1], - topicSetTime.toString("yyyy-MM-dd hh:mm:ss UTC")), QString(), channel); + displayMsg(e, + Message::Topic, + tr("Topic set by %1 on %2").arg(e->params()[1], topicSetTime.toString("yyyy-MM-dd hh:mm:ss UTC")), + QString(), + channel); } - /* RPL_INVITING - " */ -void EventStringifier::processIrcEvent341(IrcEvent *e) +void EventStringifier::processIrcEvent341(IrcEvent* e) { if (!checkParamCount(e, 2)) return; @@ -743,34 +734,30 @@ void EventStringifier::processIrcEvent341(IrcEvent *e) displayMsg(e, Message::Server, tr("%1 has been invited to %2").arg(e->params().first(), channel), QString(), channel); } - /* RPL_WHOREPLY: " ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] : " */ -void EventStringifier::processIrcEvent352(IrcEvent *e) +void EventStringifier::processIrcEvent352(IrcEvent* e) { displayMsg(e, Message::Server, tr("[Who] %1").arg(e->params().join(" "))); } - /* RPL_WHOSPCRPL: " # ~ ("H"/ "G") :" Could be anything else, though. User-specified fields. See http://faerion.sourceforge.net/doc/irc/whox.var */ -void EventStringifier::processIrcEvent354(IrcEvent *e) +void EventStringifier::processIrcEvent354(IrcEvent* e) { displayMsg(e, Message::Server, tr("[WhoX] %1").arg(e->params().join(" "))); } - /* RPL_ENDOFWHOWAS - " :End of WHOWAS" */ -void EventStringifier::processIrcEvent369(IrcEvent *e) +void EventStringifier::processIrcEvent369(IrcEvent* e) { displayMsg(e, Message::Server, tr("End of /WHOWAS")); } - /* ERR_ERRONEUSNICKNAME */ -void EventStringifier::processIrcEvent432(IrcEvent *e) +void EventStringifier::processIrcEvent432(IrcEvent* e) { if (!checkParamCount(e, 1)) return; @@ -778,9 +765,8 @@ void EventStringifier::processIrcEvent432(IrcEvent *e) displayMsg(e, Message::Error, tr("Nick %1 contains illegal characters").arg(e->params()[0])); } - /* ERR_NICKNAMEINUSE */ -void EventStringifier::processIrcEvent433(IrcEvent *e) +void EventStringifier::processIrcEvent433(IrcEvent* e) { if (!checkParamCount(e, 1)) return; @@ -788,9 +774,8 @@ void EventStringifier::processIrcEvent433(IrcEvent *e) displayMsg(e, Message::Error, tr("Nick already in use: %1").arg(e->params()[0])); } - /* ERR_UNAVAILRESOURCE */ -void EventStringifier::processIrcEvent437(IrcEvent *e) +void EventStringifier::processIrcEvent437(IrcEvent* e) { if (!checkParamCount(e, 1)) return; @@ -798,7 +783,6 @@ void EventStringifier::processIrcEvent437(IrcEvent *e) displayMsg(e, Message::Error, tr("Nick/channel is temporarily unavailable: %1").arg(e->params()[0])); } - // template /* @@ -812,49 +796,67 @@ void EventStringifier::processIrcEvent(IrcEvent *e) { /******** CTCP HANDLING ********/ /*******************************/ -void EventStringifier::processCtcpEvent(CtcpEvent *e) +void EventStringifier::processCtcpEvent(CtcpEvent* e) { if (e->type() != EventManager::CtcpEvent) return; - if (e->testFlag(EventManager::Self)) { - displayMsg(e, Message::Action, + // Only stringify outgoing CTCP messages this way + if (e->testFlag(EventManager::Self) && + // Only stringify CTCP queries this way + e->ctcpType() == CtcpEvent::CtcpType::Query && + // Always handle ACTIONs as if they were sent from network, to properly handle echo-message + e->ctcpCmd() != "ACTION") { + displayMsg(e, + Message::Action, tr("sending CTCP-%1 request to %2").arg(e->ctcpCmd(), e->target()), - e->network()->myNick(), QString(), Message::Flag::Self); + e->network()->myNick(), + QString(), + Message::Flag::Self); return; } - handle(e->ctcpCmd(), Q_ARG(CtcpEvent *, e)); + handle(e->ctcpCmd(), Q_ARG(CtcpEvent*, e)); } - -void EventStringifier::defaultHandler(const QString &ctcpCmd, CtcpEvent *e) +void EventStringifier::defaultHandler(const QString& ctcpCmd, CtcpEvent* e) { Q_UNUSED(ctcpCmd); if (e->ctcpType() == CtcpEvent::Query) { QString unknown; - if (e->reply().isNull()) // all known core-side handlers (except for ACTION) set a reply! + if (e->reply().isNull()) // all known core-side handlers (except for ACTION) set a reply! //: Optional "unknown" in "Received unknown CTCP-FOO request by bar" unknown = tr("unknown") + ' '; displayMsg(e, Message::Server, tr("Received %1CTCP-%2 request by %3").arg(unknown, e->ctcpCmd(), e->prefix())); - return; + } else { + // Ignore echo messages for our own answers + if (!e->testFlag(EventManager::Self)) { + displayMsg(e, Message::Server, + tr("Received CTCP-%1 answer from %2: %3").arg(e->ctcpCmd(), nickFromMask(e->prefix()),e->param())); + } } - displayMsg(e, Message::Server, tr("Received CTCP-%1 answer from %2: %3").arg(e->ctcpCmd(), nickFromMask(e->prefix()), e->param())); } - -void EventStringifier::handleCtcpAction(CtcpEvent *e) +void EventStringifier::handleCtcpAction(CtcpEvent* e) { - displayMsg(e, Message::Action, e->param(), e->prefix(), e->target()); -} + Message::Flag msgFlags = Message::Flag::None; + if (e->testFlag(EventManager::Self)) { + // Mark the message as Self + msgFlags = Message::Self; + } + displayMsg(e, Message::Action, e->param(), e->prefix(), e->target(), msgFlags); +} -void EventStringifier::handleCtcpPing(CtcpEvent *e) +void EventStringifier::handleCtcpPing(CtcpEvent* e) { if (e->ctcpType() == CtcpEvent::Query) defaultHandler(e->ctcpCmd(), e); else { - displayMsg(e, Message::Server, tr("Received CTCP-PING answer from %1 with %2 milliseconds round trip time") - .arg(nickFromMask(e->prefix())).arg(QDateTime::fromMSecsSinceEpoch(e->param().toULongLong()).msecsTo(e->timestamp()))); + displayMsg(e, + Message::Server, + tr("Received CTCP-PING answer from %1 with %2 milliseconds round trip time") + .arg(nickFromMask(e->prefix())) + .arg(QDateTime::fromMSecsSinceEpoch(e->param().toULongLong()).msecsTo(e->timestamp()))); } }