/***************************************************************************
- * Copyright (C) 2005-2015 by the Quassel Project *
+ * Copyright (C) 2005-2016 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
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) {
- QString target = net->isChannelName(*targetIter) ? *targetIter : senderNick;
+ // 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);
- events << new IrcEventRawMessage(EventManager::IrcEventRawPrivmsg, net, msg, prefix, target, e->timestamp());
+ IrcEventRawMessage *rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawPrivmsg, net, msg, prefix, target, e->timestamp());
+ if (isSelfMessage) {
+ // Self-messages need processed differently, tag as such via flag.
+ rawMessage->setFlag(EventManager::Self);
+ }
+ events << rawMessage;
}
}
break;
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) {
else {
if (!target.isEmpty() && net->prefixes().contains(target.at(0)))
target = target.mid(1);
- if (!net->isChannelName(target))
- target = nickFromMask(prefix);
+
+ 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);
+ }
}
#ifdef HAVE_QCA2
// Handle DH1080 key exchange
- if (params[1].startsWith("DH1080_INIT") && !net->isChannelName(target)) {
+ // Don't allow key exchange in channels, and don't allow it for self-messages.
+ bool keyExchangeAllowed = (!net->isChannelName(target) && !isSelfMessage);
+ if (params[1].startsWith("DH1080_INIT") && keyExchangeAllowed) {
events << new KeyEvent(EventManager::KeyEvent, net, prefix, target, KeyEvent::Init, params[1].mid(12));
- } else if (params[1].startsWith("DH1080_FINISH") && !net->isChannelName(target)) {
+ } else if (params[1].startsWith("DH1080_FINISH") && keyExchangeAllowed) {
events << new KeyEvent(EventManager::KeyEvent, net, prefix, target, KeyEvent::Finish, params[1].mid(14));
} else
#endif
- events << new IrcEventRawMessage(EventManager::IrcEventRawNotice, net, params[1], prefix, target, e->timestamp());
+ {
+ IrcEventRawMessage *rawMessage = new IrcEventRawMessage(EventManager::IrcEventRawNotice, net, params[1], prefix, target, e->timestamp());
+ if (isSelfMessage) {
+ // Self-messages need processed differently, tag as such via flag.
+ rawMessage->setFlag(EventManager::Self);
+ }
+ events << rawMessage;
+ }
}
}
break;
QString channel = net->serverDecode(params.at(0));
decParams << channel;
decParams << net->userDecode(nickFromMask(prefix), params.at(1));
+ net->updateNickFromMask(prefix);
}
break;
case EventManager::IrcEventQuit:
if (params.count() >= 1) {
decParams << net->userDecode(nickFromMask(prefix), params.at(0));
+ net->updateNickFromMask(prefix);
}
break;
}
break;
+ case EventManager::IrcEventAway:
+ {
+ // Update hostmask info first. This will create the nick if it doesn't exist, e.g.
+ // away-notify data being sent before JOIN messages.
+ net->updateNickFromMask(prefix);
+ // Separate nick in order to separate server and user decoding
+ QString nick = nickFromMask(prefix);
+ decParams << nick;
+ decParams << (params.count() >= 1 ? net->userDecode(nick, params.at(0)) : QString());
+ }
+ break;
+
case EventManager::IrcEventNumeric:
switch (num) {
case 301: /* RPL_AWAY */