+ 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
+ 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;
+ 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;
+