From: Janne Koschinski Date: Fri, 15 Feb 2019 13:32:31 +0000 (+0100) Subject: Cleanup allowing for tags to be available at later points, adds TAGMSG X-Git-Tag: test-travis-01~58 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=edc55b1f86cf613a332eeeb5d85537a54120dfa5 Cleanup allowing for tags to be available at later points, adds TAGMSG --- diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 417e5ff3..000b772a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -28,6 +28,7 @@ target_sources(${TARGET} PRIVATE ircdecoder.cpp ircencoder.cpp irctag.cpp + irctags.h ircuser.cpp logger.cpp message.cpp diff --git a/src/common/ctcpevent.h b/src/common/ctcpevent.h index a6c5462d..dec8ba35 100644 --- a/src/common/ctcpevent.h +++ b/src/common/ctcpevent.h @@ -39,14 +39,15 @@ public: explicit CtcpEvent(EventManager::EventType type, Network* network, - const QString& prefix, + QHash tags, + QString prefix, QString target, CtcpType ctcpType, QString ctcpCmd, QString param, const QDateTime& timestamp = QDateTime(), const QUuid& uuid = QUuid()) - : IrcEvent(type, network, prefix) + : IrcEvent(type, network, std::move(tags), std::move(prefix)) , _ctcpType(ctcpType) , _ctcpCmd(std::move(ctcpCmd)) , _target(std::move(target)) @@ -84,9 +85,12 @@ protected: inline void debugInfo(QDebug& dbg) const override { NetworkEvent::debugInfo(dbg); - dbg << ", prefix = " << qPrintable(prefix()) << ", target = " << qPrintable(target()) - << ", ctcptype = " << (ctcpType() == Query ? "query" : "reply") << ", cmd = " << qPrintable(ctcpCmd()) - << ", param = " << qPrintable(param()) << ", reply = " << qPrintable(reply()); + dbg << ", prefix = " << qPrintable(prefix()) + << ", target = " << qPrintable(target()) + << ", ctcptype = " << (ctcpType() == Query ? "query" : "reply") + << ", cmd = " << qPrintable(ctcpCmd()) + << ", param = " << qPrintable(param()) + << ", reply = " << qPrintable(reply()); } private: diff --git a/src/common/eventmanager.h b/src/common/eventmanager.h index d1059cf2..e4ddb3b0 100644 --- a/src/common/eventmanager.h +++ b/src/common/eventmanager.h @@ -107,6 +107,7 @@ public: IrcEventPong, IrcEventPrivmsg, IrcEventQuit, + IrcEventTagmsg, IrcEventTopic, IrcEventError, /// ERROR message from server IrcEventWallops, diff --git a/src/common/ircevent.h b/src/common/ircevent.h index 7988437a..90dc3846 100644 --- a/src/common/ircevent.h +++ b/src/common/ircevent.h @@ -24,14 +24,17 @@ #include +#include "irctag.h" #include "networkevent.h" #include "util.h" class COMMON_EXPORT IrcEvent : public NetworkEvent { public: - explicit IrcEvent(EventManager::EventType type, Network* network, QString prefix, QStringList params = QStringList()) + explicit IrcEvent( + EventManager::EventType type, Network* network, QHash tags, QString prefix, QStringList params = {}) : NetworkEvent(type, network) + , _tags(std::move(tags)) , _prefix(std::move(prefix)) , _params(std::move(params)) {} @@ -39,6 +42,9 @@ public: inline QString prefix() const { return _prefix; } inline void setPrefix(const QString& prefix) { _prefix = prefix; } + inline QHash tags() const { return _tags; } + inline void setTags(const QHash& tags) { _tags = tags; } + inline QString nick() const { return nickFromMask(prefix()); } inline QStringList params() const { return _params; } @@ -58,6 +64,7 @@ protected: } private: + QHash _tags; QString _prefix; QStringList _params; }; @@ -65,8 +72,13 @@ private: class COMMON_EXPORT IrcEventNumeric : public IrcEvent { public: - explicit IrcEventNumeric(uint number, Network* network, const QString& prefix, QString target, const QStringList& params = QStringList()) - : IrcEvent(EventManager::IrcEventNumeric, network, prefix, params) + explicit IrcEventNumeric(uint number, + Network* network, + QHash tags, + QString prefix, + QString target, + QStringList params = {}) + : IrcEvent(EventManager::IrcEventNumeric, network, std::move(tags), std::move(prefix), std::move(params)) , _number(number) , _target(std::move(target)) {} @@ -85,7 +97,9 @@ protected: { dbg << ", num = " << number(); NetworkEvent::debugInfo(dbg); - dbg << ", target = " << qPrintable(target()) << ", prefix = " << qPrintable(prefix()) << ", params = " << params(); + dbg << ", target = " << qPrintable(target()) + << ", prefix = " << qPrintable(prefix()) + << ", params = " << params(); } private: @@ -98,13 +112,14 @@ private: class COMMON_EXPORT IrcEventRawMessage : public IrcEvent { public: - explicit inline IrcEventRawMessage(EventManager::EventType type, - Network* network, - QByteArray rawMessage, - const QString& prefix, - const QString& target, - const QDateTime& timestamp = QDateTime()) - : IrcEvent(type, network, prefix, QStringList() << target) + explicit IrcEventRawMessage(EventManager::EventType type, + Network* network, + QHash tags, + QByteArray rawMessage, + QString prefix, + QString target, + const QDateTime& timestamp = QDateTime()) + : IrcEvent(type, network, std::move(tags), std::move(prefix), QStringList() << target) , _rawMessage(std::move(rawMessage)) { setTimestamp(timestamp); @@ -124,7 +139,9 @@ protected: inline void debugInfo(QDebug& dbg) const override { NetworkEvent::debugInfo(dbg); - dbg << ", target = " << qPrintable(target()) << ", prefix = " << qPrintable(prefix()) << ", msg = " << rawMessage(); + dbg << ", target = " << qPrintable(target()) + << ", prefix = " << qPrintable(prefix()) + << ", msg = " << rawMessage(); } private: diff --git a/src/core/irctags.h b/src/common/irctags.h similarity index 100% rename from src/core/irctags.h rename to src/common/irctags.h diff --git a/src/common/message.cpp b/src/common/message.cpp index 2aa3e302..1367b40c 100644 --- a/src/common/message.cpp +++ b/src/common/message.cpp @@ -18,18 +18,23 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#include "message.h" - #include #include +#include "message.h" #include "peer.h" #include "signalproxy.h" #include "util.h" -Message::Message( - BufferInfo bufferInfo, Type type, QString contents, QString sender, QString senderPrefixes, QString realName, QString avatarUrl, Flags flags) +Message::Message(BufferInfo bufferInfo, + Type type, + QString contents, + QString sender, + QString senderPrefixes, + QString realName, + QString avatarUrl, + Flags flags) : _timestamp(QDateTime::currentDateTime().toUTC()) , _bufferInfo(std::move(bufferInfo)) , _contents(std::move(contents)) @@ -71,13 +76,16 @@ QDataStream& operator<<(QDataStream& out, const Message& msg) if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::LongTime)) { // toMSecs returns a qint64, signed rather than unsigned - out << (qint64)msg.timestamp().toMSecsSinceEpoch(); + out << (qint64) msg.timestamp().toMSecsSinceEpoch(); } else { - out << (quint32)msg.timestamp().toTime_t(); + out << (quint32) msg.timestamp().toTime_t(); } - out << (quint32)msg.type() << (quint8)msg.flags() << msg.bufferInfo() << msg.sender().toUtf8(); + out << (quint32) msg.type() + << (quint8) msg.flags() + << msg.bufferInfo() + << msg.sender().toUtf8(); if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::SenderPrefixes)) out << msg.senderPrefixes().toUtf8(); @@ -147,9 +155,14 @@ QDataStream& operator>>(QDataStream& in, Message& msg) QDebug operator<<(QDebug dbg, const Message& msg) { - dbg.nospace() << qPrintable(QString("Message(MsgId:")) << msg.msgId() << qPrintable(QString(",")) << msg.timestamp() - << qPrintable(QString(", Type:")) << msg.type() << qPrintable(QString(", RealName:")) << msg.realName() - << qPrintable(QString(", AvatarURL:")) << msg.avatarUrl() << qPrintable(QString(", Flags:")) << msg.flags() - << qPrintable(QString(")")) << msg.senderPrefixes() << msg.sender() << ":" << msg.contents(); + dbg.nospace() << qPrintable(QString("Message(MsgId:")) << msg.msgId() + << qPrintable(QString(",")) << msg.timestamp() + << qPrintable(QString(", Type:")) << msg.type() + << qPrintable(QString(", RealName:")) << msg.realName() + << qPrintable(QString(", AvatarURL:")) << msg.avatarUrl() + << qPrintable(QString(", Flags:")) << msg.flags() + << qPrintable(QString(")")) + << msg.senderPrefixes() << msg.sender() << ":" + << msg.contents(); return dbg; } diff --git a/src/common/messageevent.cpp b/src/common/messageevent.cpp index 193e4897..1b86070f 100644 --- a/src/common/messageevent.cpp +++ b/src/common/messageevent.cpp @@ -30,12 +30,17 @@ Event* MessageEvent::create(EventManager::EventType type, QVariantMap& map, Netw return nullptr; } -MessageEvent::MessageEvent( - Message::Type msgType, Network* net, QString msg, const QString& sender, QString target, Message::Flags flags, const QDateTime& timestamp) +MessageEvent::MessageEvent(Message::Type msgType, + Network* net, + QString msg, + QString sender, + QString target, + Message::Flags flags, + const QDateTime& timestamp) : NetworkEvent(EventManager::MessageEvent, net) , _msgType(msgType) , _text(std::move(msg)) - , _sender(sender) + , _sender(std::move(sender)) , _target(std::move(target)) , _msgFlags(flags) { @@ -45,7 +50,7 @@ MessageEvent::MessageEvent( _target = _target.mid(1); if (_target.startsWith('$') || _target.startsWith('#')) - _target = nickFromMask(sender); + _target = nickFromMask(_sender); } _bufferType = bufferTypeByTarget(_target); @@ -71,7 +76,7 @@ void MessageEvent::toVariantMap(QVariantMap& map) const { NetworkEvent::toVariantMap(map); map["messageType"] = msgType(); - map["messageFlags"] = (int)msgFlags(); + map["messageFlags"] = (int) msgFlags(); map["bufferType"] = bufferType(); map["text"] = text(); map["sender"] = sender(); diff --git a/src/common/messageevent.h b/src/common/messageevent.h index 8ac668d6..f8d636fd 100644 --- a/src/common/messageevent.h +++ b/src/common/messageevent.h @@ -34,10 +34,10 @@ public: explicit MessageEvent(Message::Type msgType, Network* network, QString msg, - const QString& sender = QString(), - QString target = QString(), + QString sender = {}, + QString target = {}, Message::Flags msgFlags = Message::None, - const QDateTime& timestamp = QDateTime()); + const QDateTime& timestamp = {}); inline Message::Type msgType() const { return _msgType; } inline void setMsgType(Message::Type type) { _msgType = type; } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2e9199a3..a4cc8099 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -32,7 +32,6 @@ target_sources(${TARGET} PRIVATE eventstringifier.cpp identserver.cpp ircparser.cpp - irctags.h netsplit.cpp oidentdconfiggenerator.cpp postgresqlstorage.cpp diff --git a/src/core/coresession.h b/src/core/coresession.h index 5a05f024..d44a9c49 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -289,7 +289,12 @@ struct NetworkInternalMessage QString text; QString sender; Message::Flags flags; - NetworkInternalMessage(Message::Type type, BufferInfo::Type bufferType, QString target, QString text, QString sender = "", Message::Flags flags = Message::None) + NetworkInternalMessage(Message::Type type, + BufferInfo::Type bufferType, + QString target, + QString text, + QString sender = "", + Message::Flags flags = Message::None) : type(type) , bufferType(bufferType) , target(std::move(target)) @@ -308,8 +313,14 @@ struct RawMessage QString text; QString sender; Message::Flags flags; - RawMessage( - NetworkId networkId, Message::Type type, BufferInfo::Type bufferType, QString target, QString text, QString sender, Message::Flags flags) + + RawMessage(NetworkId networkId, + Message::Type type, + BufferInfo::Type bufferType, + QString target, + QString text, + QString sender, + Message::Flags flags) : networkId(networkId) , type(type) , bufferType(bufferType) @@ -319,7 +330,8 @@ struct RawMessage , flags(flags) {} - RawMessage(NetworkId networkId, const NetworkInternalMessage& msg) + RawMessage(NetworkId networkId, + const NetworkInternalMessage& msg) : networkId(networkId) , type(msg.type) , bufferType(msg.bufferType) diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index c1807ab8..af30bfb7 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -1469,7 +1469,7 @@ void CoreSessionEventProcessor::handleEarlyNetsplitJoin(Network* net, const QStr if (ircUser) { ircUsers.append(ircUser); // fake event for scripts that consume join events - events << new IrcEvent(EventManager::IrcEventJoin, net, ircUser->hostmask(), QStringList() << channel); + events << new IrcEvent(EventManager::IrcEventJoin, net, {}, ircUser->hostmask(), QStringList() << channel); } else { newModes.removeAt(users.indexOf(user)); diff --git a/src/core/ctcpparser.cpp b/src/core/ctcpparser.cpp index 8f2384d9..dc8ceff0 100644 --- a/src/core/ctcpparser.cpp +++ b/src/core/ctcpparser.cpp @@ -24,6 +24,7 @@ #include "coresession.h" #include "coreuserinputhandler.h" #include "ctcpevent.h" +#include "irctags.h" #include "messageevent.h" const QByteArray XDELIM = "\001"; @@ -54,15 +55,17 @@ void CtcpParser::setStandardCtcp(bool enabled) _ctcpXDelimDequoteHash[XQUOTE + QByteArray("a")] = XDELIM; } -void CtcpParser::displayMsg( - NetworkEvent* event, Message::Type msgType, const QString& msg, const QString& sender, const QString& target, Message::Flags msgFlags) +void CtcpParser::displayMsg(NetworkEvent* event, + Message::Type msgType, + QString msg, + QString sender, + QString target, + Message::Flags msgFlags) { if (event->testFlag(EventManager::Silent)) return; - 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()); emit newEvent(msgEvent); } @@ -192,8 +195,11 @@ void CtcpParser::parse(IrcEventRawMessage* e, Message::Type messagetype) // only accept CTCPs in their simplest form, i.e. one ctcp, from start to // end, no text around it; not as per the 'specs', but makes people happier -void CtcpParser::parseSimple( - IrcEventRawMessage* e, Message::Type messagetype, QByteArray dequotedMessage, CtcpEvent::CtcpType ctcptype, Message::Flags flags) +void CtcpParser::parseSimple(IrcEventRawMessage* e, + Message::Type messagetype, + const QByteArray& dequotedMessage, + CtcpEvent::CtcpType ctcptype, + Message::Flags flags) { if (dequotedMessage.count(XDELIM) != 2 || dequotedMessage[0] != '\001' || dequotedMessage[dequotedMessage.count() - 1] != '\001') { displayMsg(e, messagetype, targetDecode(e, dequotedMessage), e->prefix(), e->target(), flags); @@ -214,13 +220,15 @@ void CtcpParser::parseSimple( } ctcpcmd = ctcpcmd.toUpper(); + bool isAction = ctcpcmd == QLatin1String("ACTION"); // we don't want to block /me messages by the CTCP ignore list - if (ctcpcmd == QLatin1String("ACTION") + if (isAction || !coreSession()->ignoreListManager()->ctcpMatch(e->prefix(), e->network()->networkName(), ctcpcmd)) { QUuid uuid = QUuid::createUuid(); _replies.insert(uuid, CtcpReply(coreNetwork(e), nickFromMask(e->prefix()))); CtcpEvent* event = new CtcpEvent(EventManager::CtcpEvent, e->network(), + isAction ? QHash() : e->tags(), e->prefix(), e->target(), ctcptype, @@ -231,6 +239,7 @@ void CtcpParser::parseSimple( emit newEvent(event); CtcpEvent* flushEvent = new CtcpEvent(EventManager::CtcpEventFlush, e->network(), + {}, e->prefix(), e->target(), ctcptype, @@ -243,9 +252,13 @@ void CtcpParser::parseSimple( } } -void CtcpParser::parseStandard( - IrcEventRawMessage* e, Message::Type messagetype, QByteArray dequotedMessage, CtcpEvent::CtcpType ctcptype, Message::Flags flags) +void CtcpParser::parseStandard(IrcEventRawMessage* e, + Message::Type messagetype, + const QByteArray& dequotedMessage_, + CtcpEvent::CtcpType ctcptype, + Message::Flags flags) { + auto dequotedMessage = dequotedMessage_; QByteArray ctcp; QList ctcpEvents; @@ -283,14 +296,16 @@ void CtcpParser::parseStandard( ctcpcmd = ctcpcmd.toUpper(); + bool isAction = ctcpcmd == QLatin1String("ACTION"); // we don't want to block /me messages by the CTCP ignore list - if (ctcpcmd == QLatin1String("ACTION") + if (isAction || !coreSession()->ignoreListManager()->ctcpMatch(e->prefix(), e->network()->networkName(), ctcpcmd)) { if (uuid.isNull()) uuid = QUuid::createUuid(); CtcpEvent* event = new CtcpEvent(EventManager::CtcpEvent, e->network(), + isAction ? QHash() : e->tags(), e->prefix(), e->target(), ctcptype, @@ -305,6 +320,7 @@ void CtcpParser::parseStandard( _replies.insert(uuid, CtcpReply(coreNetwork(e), nickFromMask(e->prefix()))); CtcpEvent* flushEvent = new CtcpEvent(EventManager::CtcpEventFlush, e->network(), + {}, e->prefix(), e->target(), ctcptype, @@ -313,7 +329,7 @@ void CtcpParser::parseStandard( e->timestamp(), uuid); ctcpEvents << flushEvent; - foreach (CtcpEvent* event, ctcpEvents) { + for (CtcpEvent* event : ctcpEvents) { emit newEvent(event); } } diff --git a/src/core/ctcpparser.h b/src/core/ctcpparser.h index 81f18860..0eac1b79 100644 --- a/src/core/ctcpparser.h +++ b/src/core/ctcpparser.h @@ -60,16 +60,22 @@ protected: //! Creates and sends a MessageEvent void displayMsg(NetworkEvent* event, Message::Type msgType, - const QString& msg, - const QString& sender = QString(), - const QString& target = QString(), + QString msg, + QString sender = {}, + QString target = {}, Message::Flags msgFlags = Message::None); void parse(IrcEventRawMessage* event, Message::Type msgType); - void parseSimple( - IrcEventRawMessage* e, Message::Type messagetype, QByteArray dequotedMessage, CtcpEvent::CtcpType ctcptype, Message::Flags flags); - void parseStandard( - IrcEventRawMessage* e, Message::Type messagetype, QByteArray dequotedMessage, CtcpEvent::CtcpType ctcptype, Message::Flags flags); + void parseSimple(IrcEventRawMessage* e, + Message::Type messagetype, + const QByteArray& dequotedMessage, + CtcpEvent::CtcpType ctcptype, + Message::Flags flags); + void parseStandard(IrcEventRawMessage* e, + Message::Type messagetype, + const QByteArray& dequotedMessage, + CtcpEvent::CtcpType ctcptype, + Message::Flags flags); QByteArray lowLevelQuote(const QByteArray&); QByteArray lowLevelDequote(const QByteArray&); diff --git a/src/core/eventstringifier.cpp b/src/core/eventstringifier.cpp index b5753224..d4c268ce 100644 --- a/src/core/eventstringifier.cpp +++ b/src/core/eventstringifier.cpp @@ -22,6 +22,7 @@ #include "coresession.h" #include "ctcpevent.h" +#include "irctags.h" #include "messageevent.h" EventStringifier::EventStringifier(CoreSession* parent) @@ -32,22 +33,29 @@ EventStringifier::EventStringifier(CoreSession* parent) 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); + 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; } @@ -59,7 +67,7 @@ bool EventStringifier::checkParamCount(IrcEvent* e, int 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(); @@ -328,7 +336,7 @@ void EventStringifier::processIrcEventNick(IrcEvent* e) } // 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); } } @@ -375,7 +383,7 @@ void EventStringifier::processIrcEventQuit(IrcEvent* e) } // Announce to all channels the IrcUser is in - foreach (const QString& channel, ircuser->channels()) { + for (const QString& channel : ircuser->channels()) { displayMsg(e, Message::Quit, e->params().count() ? e->params().first() : QString(), e->prefix(), channel, msgFlags); } } @@ -528,9 +536,10 @@ 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 - // Time in IRC protocol is defined as seconds. Convert from seconds instead. - // See https://doc.qt.io/qt-5/qdatetime.html#fromSecsSinceEpoch + 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 QDateTime loginTime = QDateTime::fromSecsSinceEpoch(e->params()[2].toLongLong()).toUTC(); #else @@ -566,7 +575,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("+")) diff --git a/src/core/eventstringifier.h b/src/core/eventstringifier.h index 504ff139..d1274ed0 100644 --- a/src/core/eventstringifier.h +++ b/src/core/eventstringifier.h @@ -43,9 +43,9 @@ public: MessageEvent* createMessageEvent(NetworkEvent* event, Message::Type msgType, - const QString& msg, - const QString& sender = QString(), - const QString& target = QString(), + QString msg, + QString sender = {}, + QString target = {}, Message::Flags msgFlags = Message::None); // legacy handlers @@ -108,9 +108,9 @@ public slots: //! Creates and sends a MessageEvent void displayMsg(NetworkEvent* event, Message::Type msgType, - const QString& msg, - const QString& sender = QString(), - const QString& target = QString(), + QString msg, + QString sender = {}, + QString target = {}, Message::Flags msgFlags = Message::None); signals: diff --git a/src/core/ircparser.cpp b/src/core/ircparser.cpp index 8a6a7eb4..2add78d7 100644 --- a/src/core/ircparser.cpp +++ b/src/core/ircparser.cpp @@ -179,6 +179,7 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent* e) IrcEventRawMessage* rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawPrivmsg, net, + tags, msg, prefix, target, @@ -246,16 +247,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 +272,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 +296,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 +332,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 +401,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); } } diff --git a/src/core/keyevent.h b/src/core/keyevent.h index 393f4d22..c1c6cc20 100644 --- a/src/core/keyevent.h +++ b/src/core/keyevent.h @@ -36,12 +36,13 @@ public: explicit KeyEvent(EventManager::EventType type, Network* network, - const QString& prefix, + QHash tags, + QString prefix, QString target, ExchangeType exchangeType, QByteArray key, const QDateTime& timestamp = QDateTime()) - : IrcEvent(type, network, prefix) + : IrcEvent(type, network, std::move(tags), std::move(prefix)) , _exchangeType(exchangeType) , _target(std::move(target)) , _key(std::move(key))