QVariantList CoreBacklogManager::requestBacklogAll(MsgId first, MsgId last, int limit, int additional) { QVariantList backlog; QList<Message> msgList; msgList = Core::requestAllMsgs(coreSession()->user(), first, last, limit); QList<Message>::const_iterator msgIter = msgList.constBegin(); QList<Message>::const_iterator msgListEnd = msgList.constEnd(); while(msgIter != msgListEnd) { backlog << qVariantFromValue(*msgIter); msgIter++; } if(additional) { if(first != -1) { last = first; } else { last = -1; if(!msgList.isEmpty()) { if(msgList.first().msgId() < msgList.last().msgId()) last = msgList.first().msgId(); else last = msgList.last().msgId(); } } msgList = Core::requestAllMsgs(coreSession()->user(), -1, last, additional); msgIter = msgList.constBegin(); msgListEnd = msgList.constEnd(); while(msgIter != msgListEnd) { backlog << qVariantFromValue(*msgIter); msgIter++; } } return backlog; }
// 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<CtcpEvent *> ctcpEvents; QUuid uuid; // needed to group all replies together // extract tagged / extended data int xdelimPos = -1; int xdelimEndPos = -1; int spacePos = -1; while ((xdelimPos = dequotedMessage.indexOf(XDELIM)) != -1) { if (xdelimPos > 0) displayMsg(e, messagetype, targetDecode(e, dequotedMessage.left(xdelimPos)), e->prefix(), e->target(), 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 = targetDecode(e, ctcp.left(spacePos)); QString ctcpparam = targetDecode(e, ctcp.mid(spacePos + 1)); 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)) { if (uuid.isNull()) uuid = QUuid::createUuid(); CtcpEvent *event = new CtcpEvent(EventManager::CtcpEvent, e->network(), e->prefix(), e->target(), ctcptype, ctcpcmd, ctcpparam, e->timestamp(), uuid); ctcpEvents << event; } } if (!ctcpEvents.isEmpty()) { _replies.insert(uuid, CtcpReply(coreNetwork(e), nickFromMask(e->prefix()))); CtcpEvent *flushEvent = new CtcpEvent(EventManager::CtcpEventFlush, e->network(), e->prefix(), e->target(), ctcptype, "INVALID", QString(), e->timestamp(), uuid); ctcpEvents << flushEvent; foreach(CtcpEvent *event, ctcpEvents) { emit newEvent(event); }
QVariantList CoreBacklogManager::requestBacklog(BufferId bufferId, MsgId first, MsgId last, int limit, int additional) { QVariantList backlog; QList<Message> msgList; msgList = Core::requestMsgs(coreSession()->user(), bufferId, first, last, limit); QList<Message>::const_iterator msgIter = msgList.constBegin(); QList<Message>::const_iterator msgListEnd = msgList.constEnd(); while(msgIter != msgListEnd) { backlog << qVariantFromValue(*msgIter); msgIter++; } if(additional && limit != 0) { MsgId oldestMessage = first; if(!msgList.isEmpty()) { if(msgList.first().msgId() < msgList.last().msgId()) oldestMessage = msgList.first().msgId(); else oldestMessage = msgList.last().msgId(); } if(first != -1) { last = first; } else { last = oldestMessage; } // only fetch additional messages if they continue seemlessly // that is, if the list of messages is not truncated by the limit if(last == oldestMessage) { msgList = Core::requestMsgs(coreSession()->user(), bufferId, -1, last, additional); msgIter = msgList.constBegin(); msgListEnd = msgList.constEnd(); while(msgIter != msgListEnd) { backlog << qVariantFromValue(*msgIter); msgIter++; } } } return backlog; }
bool CoreIrcListHelper::dispatchQuery(const NetworkId &netId, const QString &query) { CoreNetwork *network = coreSession()->network(netId); if(network) { _channelLists[netId] = QList<ChannelDescription>(); network->userInputHandler()->handleList(BufferInfo(), query); _queryTimeout[startTimer(10000)] = netId; return true; } else { return false; } }
void CoreUserInputHandler::handleUserInput(const BufferInfo &bufferInfo, const QString &msg) { if (msg.isEmpty()) return; AliasManager::CommandList list = coreSession()->aliasManager().processInput(bufferInfo, msg); for (int i = 0; i < list.count(); i++) { QString cmd = list.at(i).second.section(' ', 0, 0).remove(0, 1).toUpper(); QString payload = list.at(i).second.section(' ', 1); handle(cmd, Q_ARG(BufferInfo, list.at(i).first), Q_ARG(QString, payload)); } }
bool CoreIrcListHelper::dispatchQuery(const NetworkId &netId, const QString &query) { CoreNetwork *network = coreSession()->network(netId); if (network) { _channelLists[netId] = QList<ChannelDescription>(); network->userInputHandler()->handleList(BufferInfo(), query); auto timer = std::make_shared<QBasicTimer>(); timer->start(kTimeoutMs, this); _queryTimeoutByNetId[netId] = timer; _queryTimeoutByTimerId[timer->timerId()] = netId; return true; } else { return false; } }
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); }