+ // Almost always, all params are server-encoded. There's a few exceptions, let's catch them here!
+ // Possibly not the best option, we might want something more generic? Maybe yet another layer of
+ // unencoded events with event handlers for the exceptions...
+ // Also, PRIVMSG and NOTICE need some special handling, we put this in here as well, so we get out
+ // nice pre-parsed events that the CTCP handler can consume.
+
+ QStringList decParams;
+ bool defaultHandling = true; // whether to automatically copy the remaining params and send the event
+
+ switch (type) {
+ case EventManager::IrcEventPrivmsg:
+ defaultHandling = false; // this might create a list of events
+
+ if (checkParamCount(cmd, params, 1)) {
+ QString senderNick = nickFromMask(prefix);
+ net->updateNickFromMask(prefix);
+ // Check if the sender is our own nick. If so, treat message as if sent by ourself.
+ // See http://ircv3.net/specs/extensions/echo-message-3.2.html
+ // Cache the result to avoid multiple redundant comparisons
+ bool isSelfMessage = net->isMyNick(senderNick);
+
+ QByteArray msg = params.count() < 2 ? QByteArray() : params.at(1);
+
+ QStringList targets = net->serverDecode(params.at(0)).split(',', QString::SkipEmptyParts);
+ QStringList::const_iterator targetIter;
+ for (targetIter = targets.constBegin(); targetIter != targets.constEnd(); ++targetIter) {
+ // For self-messages, keep the target, don't set it to the senderNick
+ QString target = net->isChannelName(*targetIter) || net->isStatusMsg(*targetIter) || isSelfMessage ? *targetIter : senderNick;
+
+ // Note: self-messages could be encrypted with a different key. If issues arise,
+ // consider including this within an if (!isSelfMessage) block
+ msg = decrypt(net, target, msg);
+
+ IrcEventRawMessage* rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawPrivmsg,
+ net,
+ tags,
+ msg,
+ prefix,
+ target,
+ e->timestamp());
+ if (isSelfMessage) {
+ // Self-messages need processed differently, tag as such via flag.
+ rawMessage->setFlag(EventManager::Self);
+ }
+ events << rawMessage;
+ }
+ }
+ break;
+
+ case EventManager::IrcEventNotice:
+ defaultHandling = false;
+
+ if (checkParamCount(cmd, params, 2)) {
+ // Check if the sender is our own nick. If so, treat message as if sent by ourself.
+ // See http://ircv3.net/specs/extensions/echo-message-3.2.html
+ // Cache the result to avoid multiple redundant comparisons
+ bool isSelfMessage = net->isMyNick(nickFromMask(prefix));
+
+ QStringList targets = net->serverDecode(params.at(0)).split(',', QString::SkipEmptyParts);
+ QStringList::const_iterator targetIter;
+ for (targetIter = targets.constBegin(); targetIter != targets.constEnd(); ++targetIter) {
+ QString target = *targetIter;
+
+ // special treatment for welcome messages like:
+ // :ChanServ!ChanServ@services. NOTICE egst :[#apache] Welcome, this is #apache. Please read the in-channel topic message.
+ // This channel is being logged by IRSeekBot. If you have any question please see http://blog.freenode.net/?p=68
+ if (!net->isChannelName(target)) {
+ QString decMsg = net->serverDecode(params.at(1));
+ QRegExp welcomeRegExp(R"(^\[([^\]]+)\] )");
+ if (welcomeRegExp.indexIn(decMsg) != -1) {
+ QString channelname = welcomeRegExp.cap(1);
+ decMsg = decMsg.mid(welcomeRegExp.matchedLength());
+ // we only have CoreIrcChannels in the core, so this cast is safe
+ CoreIrcChannel* chan = static_cast<CoreIrcChannel*>(net->ircChannel(channelname)); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
+ if (chan && !chan->receivedWelcomeMsg()) {
+ chan->setReceivedWelcomeMsg();
+ events << new MessageEvent(Message::Notice, net, decMsg, prefix, channelname, Message::None, e->timestamp());
+ continue;
+ }
+ }
+ }
+
+ if (prefix.isEmpty() || target == "AUTH") {
+ target = QString();
+ }
+ else {
+ if (!target.isEmpty() && net->prefixes().contains(target.at(0)))
+ target = target.mid(1);
+
+ if (!net->isChannelName(target)) {
+ // For self-messages, keep the target, don't set it to the sender prefix
+ if (!isSelfMessage) {
+ target = nickFromMask(prefix);
+ }
+ net->updateNickFromMask(prefix);
+ }
+ }