From: Bas Pape Date: Tue, 25 Sep 2012 18:57:14 +0000 (+0200) Subject: Simplify CTCP parsing by default X-Git-Tag: 0.9-beta1~31 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=a272baf28f926a9e66be767936dd38b6b4aa94da Simplify CTCP parsing by default Rather than adhering to the CTCP 'specification', reply only to single CTCP messages without text around them. All messages not fitting the requirements are simply displayed in the buffer. The old behaviour can still be enabled in the settings dialog. Fixes #1130 --- diff --git a/src/common/networkconfig.cpp b/src/common/networkconfig.cpp index 17a37b42..066988f8 100644 --- a/src/common/networkconfig.cpp +++ b/src/common/networkconfig.cpp @@ -29,7 +29,8 @@ NetworkConfig::NetworkConfig(const QString &objectName, QObject *parent) _autoWhoEnabled(true), _autoWhoInterval(90), _autoWhoNickLimit(200), - _autoWhoDelay(5) + _autoWhoDelay(5), + _standardCtcp(false) { } @@ -107,3 +108,14 @@ void NetworkConfig::setAutoWhoDelay(int delay) SYNC(ARG(delay)) emit autoWhoDelaySet(delay); } + + +void NetworkConfig::setStandardCtcp(bool enabled) +{ + if (_standardCtcp == enabled) + return; + + _standardCtcp = enabled; + SYNC(ARG(enabled)) + emit standardCtcpSet(enabled); +} diff --git a/src/common/networkconfig.h b/src/common/networkconfig.h index 3d18077b..ae121aa5 100644 --- a/src/common/networkconfig.h +++ b/src/common/networkconfig.h @@ -35,6 +35,7 @@ class NetworkConfig : public SyncableObject Q_PROPERTY(int autoWhoInterval READ autoWhoInterval WRITE setAutoWhoInterval) Q_PROPERTY(int autoWhoNickLimit READ autoWhoNickLimit WRITE setAutoWhoNickLimit) Q_PROPERTY(int autoWhoDelay READ autoWhoDelay WRITE setAutoWhoDelay) + Q_PROPERTY(bool standardCtcp READ standardCtcp WRITE setStandardCtcp) public : NetworkConfig(const QString &objectName = "GlobalNetworkConfig", QObject *parent = 0); @@ -70,6 +71,10 @@ public slots: void setAutoWhoDelay(int); virtual inline void requestSetAutoWhoDelay(int i) { REQUEST(ARG(i)) } + inline bool standardCtcp() const { return _standardCtcp; } + void setStandardCtcp(bool); + virtual inline void requestSetStandardCtcp(bool b) { REQUEST(ARG(b)) } + signals: void pingTimeoutEnabledSet(bool); void pingIntervalSet(int); @@ -78,6 +83,7 @@ signals: void autoWhoIntervalSet(int); // void autoWhoNickLimitSet(int); void autoWhoDelaySet(int); + void standardCtcpSet(bool); // void setPingTimeoutEnabledRequested(bool); // void setPingIntervalRequested(int); @@ -96,6 +102,8 @@ private: int _autoWhoInterval; int _autoWhoNickLimit; int _autoWhoDelay; + + bool _standardCtcp; }; diff --git a/src/core/corenetworkconfig.h b/src/core/corenetworkconfig.h index d906dcb3..e045697c 100644 --- a/src/core/corenetworkconfig.h +++ b/src/core/corenetworkconfig.h @@ -45,6 +45,7 @@ public slots: virtual inline void requestSetAutoWhoInterval(int interval) { setAutoWhoInterval(interval); } virtual inline void requestSetAutoWhoNickLimit(int nickLimit) { setAutoWhoNickLimit(nickLimit); } virtual inline void requestSetAutoWhoDelay(int delay) { setAutoWhoDelay(delay); } + virtual inline void requestSetStandardCtcp(bool enabled) { setStandardCtcp(enabled); } }; diff --git a/src/core/ctcpparser.cpp b/src/core/ctcpparser.cpp index cddb6e18..ee300df8 100644 --- a/src/core/ctcpparser.cpp +++ b/src/core/ctcpparser.cpp @@ -20,6 +20,7 @@ #include "ctcpparser.h" +#include "corenetworkconfig.h" #include "coresession.h" #include "ctcpevent.h" #include "messageevent.h" @@ -148,8 +149,6 @@ void CtcpParser::processIrcEventRawPrivmsg(IrcEventRawMessage *event) void CtcpParser::parse(IrcEventRawMessage *e, Message::Type messagetype) { - QByteArray ctcp; - //lowlevel message dequote QByteArray dequotedMessage = lowLevelDequote(e->rawMessage()); @@ -161,6 +160,53 @@ void CtcpParser::parse(IrcEventRawMessage *e, Message::Type messagetype) ? Message::Redirected : Message::None; + if (coreSession()->networkConfig()->standardCtcp()) + parseStandard(e, messagetype, dequotedMessage, ctcptype, flags); + else + parseSimple(e, messagetype, dequotedMessage, ctcptype, flags); +} + + +// 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) +{ + if (dequotedMessage.count(XDELIM) != 2 || dequotedMessage[0] != '\001' || dequotedMessage[dequotedMessage.count() -1] != '\001') { + displayMsg(e, messagetype, targetDecode(e, dequotedMessage), e->prefix(), e->target(), flags); + } else { + int spacePos = -1; + QString ctcpcmd, ctcpparam; + + QByteArray ctcp = xdelimDequote(dequotedMessage.mid(1, dequotedMessage.count() - 2)); + spacePos = ctcp.indexOf(' '); + if (spacePos != -1) { + ctcpcmd = targetDecode(e, ctcp.left(spacePos)); + ctcpparam = targetDecode(e, ctcp.mid(spacePos + 1)); + } else { + ctcpcmd = targetDecode(e, ctcp); + ctcpparam = QString(); + } + ctcpcmd = ctcpcmd.toUpper(); + + // we don't want to block /me messages by the CTCP ignore list + if (ctcpcmd == QLatin1String("ACTION") || !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(), e->prefix(), e->target(), + ctcptype, ctcpcmd, ctcpparam, e->timestamp(), uuid); + emit newEvent(event); + CtcpEvent *flushEvent = new CtcpEvent(EventManager::CtcpEventFlush, e->network(), e->prefix(), e->target(), + ctcptype, "INVALID", QString(), e->timestamp(), uuid); + emit newEvent(flushEvent); + } + } +} + + +void CtcpParser::parseStandard(IrcEventRawMessage *e, Message::Type messagetype, QByteArray dequotedMessage, CtcpEvent::CtcpType ctcptype, Message::Flags flags) +{ + QByteArray ctcp; + QList ctcpEvents; QUuid uuid; // needed to group all replies together diff --git a/src/core/ctcpparser.h b/src/core/ctcpparser.h index 255539e1..d3f50c9b 100644 --- a/src/core/ctcpparser.h +++ b/src/core/ctcpparser.h @@ -26,6 +26,7 @@ #include "corenetwork.h" #include "eventmanager.h" #include "ircevent.h" +#include "ctcpevent.h" class CoreSession; class CtcpEvent; @@ -63,6 +64,8 @@ protected: 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); QByteArray lowLevelQuote(const QByteArray &); QByteArray lowLevelDequote(const QByteArray &); diff --git a/src/qtui/settingspages/connectionsettingspage.cpp b/src/qtui/settingspages/connectionsettingspage.cpp index 3d4ac7a3..4fcc70a6 100644 --- a/src/qtui/settingspages/connectionsettingspage.cpp +++ b/src/qtui/settingspages/connectionsettingspage.cpp @@ -85,6 +85,8 @@ QVariant ConnectionSettingsPage::loadAutoWidgetValue(const QString &widgetName) return config->autoWhoNickLimit(); if (widgetName == "autoWhoDelay") return config->autoWhoDelay(); + if (widgetName == "standardCtcp") + return config->standardCtcp(); return SettingsPage::loadAutoWidgetValue(widgetName); } @@ -109,6 +111,8 @@ void ConnectionSettingsPage::saveAutoWidgetValue(const QString &widgetName, cons config->requestSetAutoWhoNickLimit(value.toInt()); else if (widgetName == "autoWhoDelay") config->requestSetAutoWhoDelay(value.toInt()); + else if (widgetName == "standardCtcp") + config->requestSetStandardCtcp(value.toBool()); else SettingsPage::saveAutoWidgetValue(widgetName, value); diff --git a/src/qtui/settingspages/connectionsettingspage.ui b/src/qtui/settingspages/connectionsettingspage.ui index 484454c3..e1ca2480 100644 --- a/src/qtui/settingspages/connectionsettingspage.ui +++ b/src/qtui/settingspages/connectionsettingspage.ui @@ -244,6 +244,16 @@ + + + + Enable standard-compliant CTCP behavior + + + + + +