void CtcpHandler::parse(Message::Type messageType, const QString &prefix, const QString &target, const QByteArray &message) { QByteArray ctcp; //lowlevel message dequote QByteArray dequotedMessage = lowLevelDequote(message); CtcpType ctcptype = messageType == Message::Notice ? CtcpReply : CtcpQuery; Message::Flags flags = (messageType == Message::Notice && !network()->isChannelName(target)) ? Message::Redirected : Message::None; // extract tagged / extended data int xdelimPos = -1; int xdelimEndPos = -1; int spacePos = -1; while((xdelimPos = dequotedMessage.indexOf(XDELIM)) != -1) { if(xdelimPos > 0) displayMsg(messageType, target, userDecode(target, dequotedMessage.left(xdelimPos)), prefix, flags); xdelimEndPos = dequotedMessage.indexOf(XDELIM, xdelimPos + 1); if(xdelimEndPos == -1) { // no matching end delimiter found... treat rest of the message as ctcp xdelimEndPos = dequotedMessage.count(); } ctcp = xdelimDequote(dequotedMessage.mid(xdelimPos + 1, xdelimEndPos - xdelimPos - 1)); dequotedMessage = dequotedMessage.mid(xdelimEndPos + 1); //dispatch the ctcp command QString ctcpcmd = userDecode(target, ctcp.left(spacePos)); QString ctcpparam = userDecode(target, ctcp.mid(spacePos + 1)); spacePos = ctcp.indexOf(' '); if(spacePos != -1) { ctcpcmd = userDecode(target, ctcp.left(spacePos)); ctcpparam = userDecode(target, ctcp.mid(spacePos + 1)); } else { ctcpcmd = userDecode(target, ctcp); ctcpparam = QString(); } handle(ctcpcmd, Q_ARG(CtcpType, ctcptype), Q_ARG(QString, prefix), Q_ARG(QString, target), Q_ARG(QString, ctcpparam)); } if(!dequotedMessage.isEmpty()) displayMsg(messageType, target, userDecode(target, dequotedMessage), prefix, flags); }
void CtcpParser::parse(IrcEventRawMessage *e, Message::Type messagetype) { //lowlevel message dequote QByteArray dequotedMessage = lowLevelDequote(e->rawMessage()); CtcpEvent::CtcpType ctcptype = e->type() == EventManager::IrcEventRawNotice ? CtcpEvent::Reply : CtcpEvent::Query; Message::Flags flags = (ctcptype == CtcpEvent::Reply && !e->network()->isChannelName(e->target())) ? Message::Redirected : Message::None; if (coreSession()->networkConfig()->standardCtcp()) parseStandard(e, messagetype, dequotedMessage, ctcptype, flags); else parseSimple(e, messagetype, dequotedMessage, ctcptype, flags); }
void CtcpParser::parse(IrcEventRawMessage *e, Message::Type messagetype) { //lowlevel message dequote QByteArray dequotedMessage = lowLevelDequote(e->rawMessage()); CtcpEvent::CtcpType ctcptype = e->type() == EventManager::IrcEventRawNotice ? CtcpEvent::Reply : CtcpEvent::Query; Message::Flags flags = (ctcptype == CtcpEvent::Reply && !e->network()->isChannelName(e->target())) ? 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 parseSimple(e, messagetype, dequotedMessage, ctcptype, flags); }