From: Michael Marley Date: Wed, 23 Mar 2016 20:47:02 +0000 (-0400) Subject: Handle STATUSMSG messages X-Git-Tag: travis-deploy-test~498^2~1 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=4259bc3c5b11164245535e011a69efa6937bb6a6 Handle STATUSMSG messages Previously PRIVMSGs to channels prefixed with certain characters (usually "+" or "@") (example "@#quassel") would appear in new query buffers instead of in the channel buffer. People were using that problem to broadcast query SPAM in active channels such as This patch fixes the issue by detecting the condition, first in ircparser.cpp where it will use the channel name instead of the sender's nick as the target. ctcpparser.cpp then sees the prefixed channel name and reacts by truncating the prefix(es) and setting a new flag so that the client can tell the message was a STATUSMSG. A look-ahead system is used to ensure that the channel prefix character is not stripped even when the channel prefix characters and STATUSMSG prefix characters overlap. The server-provided STATUSMSG prefixes are used if available, otherwise "@" and "+" are used. This patch doesn't make the client display the STATUSMSGs any differently than regular messages. I omitted this because there was some discussion on the channel about the best way to display these messages, but no conclusion was ever reached. This patch will at least stop the query SPAM and also provides the infrastructure necessary to change the display format later. --- diff --git a/src/common/message.h b/src/common/message.h index 402faeaa..a7fb4938 100644 --- a/src/common/message.h +++ b/src/common/message.h @@ -61,6 +61,7 @@ public: Highlight = 0x02, Redirected = 0x04, ServerMsg = 0x08, + StatusMsg = 0x10, Backlog = 0x80 }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/common/network.cpp b/src/common/network.cpp index 24ce1259..54d0366f 100644 --- a/src/common/network.cpp +++ b/src/common/network.cpp @@ -77,6 +77,18 @@ bool Network::isChannelName(const QString &channelname) const } +bool Network::isStatusMsg(const QString &target) const +{ + if (target.isEmpty()) + return false; + + if (supports("STATUSMSG")) + return support("STATUSMSG").contains(target[0]); + else + return QString("@+").contains(target[0]); +} + + NetworkInfo Network::networkInfo() const { NetworkInfo info; diff --git a/src/common/network.h b/src/common/network.h index 190c62c0..c6f8f670 100644 --- a/src/common/network.h +++ b/src/common/network.h @@ -131,6 +131,7 @@ public : inline bool isMe(IrcUser *ircuser) const { return (ircuser->nick().toLower() == myNick().toLower()); } bool isChannelName(const QString &channelname) const; + bool isStatusMsg(const QString &target) const; inline bool isConnected() const { return _connected; } //Network::ConnectionState connectionState() const; diff --git a/src/core/ctcpparser.cpp b/src/core/ctcpparser.cpp index d2da8413..f5257bb1 100644 --- a/src/core/ctcpparser.cpp +++ b/src/core/ctcpparser.cpp @@ -171,6 +171,27 @@ void CtcpParser::parse(IrcEventRawMessage *e, Message::Type messagetype) ? Message::Redirected : Message::None; + bool isStatusMsg = false; + + // First remove all statusmsg prefix characters that are not also channel prefix characters. + while (e->network()->isStatusMsg(e->target()) && !e->network()->isChannelName(e->target())) { + isStatusMsg = true; + e->setTarget(e->target().remove(0, 1)); + } + + // Then continue removing statusmsg characters as long as removing the character will still result in a + // valid channel name. This prevents removing the channel prefix character if said character is in the + // overlap between the statusmsg characters and the channel prefix characters. + while (e->network()->isStatusMsg(e->target()) && e->network()->isChannelName(e->target().remove(0, 1))) { + isStatusMsg = true; + e->setTarget(e->target().remove(0, 1)); + } + + // If any statusmsg characters were removed, Flag the message as a StatusMsg. + if (isStatusMsg) { + flags |= Message::StatusMsg; + } + if (coreSession()->networkConfig()->standardCtcp()) parseStandard(e, messagetype, dequotedMessage, ctcptype, flags); else diff --git a/src/core/ircparser.cpp b/src/core/ircparser.cpp index 681346c1..dec7b788 100644 --- a/src/core/ircparser.cpp +++ b/src/core/ircparser.cpp @@ -186,7 +186,7 @@ void IrcParser::processNetworkIncoming(NetworkDataEvent *e) QStringList targets = net->serverDecode(params.at(0)).split(',', QString::SkipEmptyParts); QStringList::const_iterator targetIter; for (targetIter = targets.constBegin(); targetIter != targets.constEnd(); ++targetIter) { - QString target = net->isChannelName(*targetIter) ? *targetIter : senderNick; + QString target = net->isChannelName(*targetIter) || net->isStatusMsg(*targetIter) ? *targetIter : senderNick; msg = decrypt(net, target, msg);