/***************************************************************************
- * Copyright (C) 2005-2016 by the Quassel Project *
+ * Copyright (C) 2005-2018 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
if (net->isMe(ircuser)) {
net->setChannelJoined(channel);
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
// FIXME use event
net->putRawLine(net->serverEncode("MODE " + channel)); // we want to know the modes of the channel we just joined, so we ask politely
}
ircUser->removeUserModes(removeModes);
if (e->network()->isMe(ircUser)) {
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
coreNetwork(e)->updatePersistentModes(addModes, removeModes);
}
}
}
+void CoreSessionEventProcessor::processIrcEventNick(IrcEvent *e)
+{
+ if (checkParamCount(e, 1)) {
+ IrcUser *ircuser = e->network()->updateNickFromMask(e->prefix());
+ if (!ircuser) {
+ qWarning() << Q_FUNC_INFO << "Unknown IrcUser!";
+ return;
+ }
+
+ if (e->network()->isMe(ircuser)) {
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
+ }
+
+ // Actual processing is handled in lateProcessIrcEventNick(), this just sets the event flag
+ }
+}
+
+
void CoreSessionEventProcessor::lateProcessIrcEventNick(IrcEvent *e)
{
if (checkParamCount(e, 1)) {
}
+void CoreSessionEventProcessor::processIrcEventPart(IrcEvent *e)
+{
+ if (checkParamCount(e, 1)) {
+ IrcUser *ircuser = e->network()->updateNickFromMask(e->prefix());
+ if (!ircuser) {
+ qWarning() << Q_FUNC_INFO<< "Unknown IrcUser!";
+ return;
+ }
+
+ if (e->network()->isMe(ircuser)) {
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
+ }
+
+ // Actual processing is handled in lateProcessIrcEventNick(), this just sets the event flag
+ }
+}
+
+
void CoreSessionEventProcessor::lateProcessIrcEventPart(IrcEvent *e)
{
if (checkParamCount(e, 1)) {
}
QString channel = e->params().at(0);
ircuser->partChannel(channel);
- if (e->network()->isMe(ircuser))
+ if (e->network()->isMe(ircuser)) {
qobject_cast<CoreNetwork *>(e->network())->setChannelParted(channel);
+ }
}
}
if (!ircuser)
return;
+ if (e->network()->isMe(ircuser)) {
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
+ }
+
QString msg;
if (e->params().count() > 0)
msg = e->params()[0];
void CoreSessionEventProcessor::processIrcEventTopic(IrcEvent *e)
{
if (checkParamCount(e, 2)) {
- e->network()->updateNickFromMask(e->prefix());
+ IrcUser *ircuser = e->network()->updateNickFromMask(e->prefix());
+
+ if (e->network()->isMe(ircuser)) {
+ // Mark the message as Self
+ e->setFlag(EventManager::Self);
+ }
+
IrcChannel *channel = e->network()->ircChannel(e->params().at(0));
if (channel)
channel->setTopic(e->params().at(1));
if (ircuser) {
ircuser->setAway(true);
ircuser->setAwayMessage(e->params().at(1));
- //ircuser->setLastAwayMessage(now);
+ // lastAwayMessageTime is set in EventStringifier::processIrcEvent301(), no need to set it
+ // here too
+ //ircuser->setLastAwayMessageTime(now);
}
}
int idleSecs = e->params()[1].toInt();
if (e->params().count() > 3) { // if we have more then 3 params we have the above mentioned "real life" situation
- int logintime = e->params()[2].toInt();
- loginTime = QDateTime::fromTime_t(logintime);
+ // Allow for 64-bit time
+ qint64 logintime = e->params()[2].toLongLong();
+ // Time in IRC protocol is defined as seconds. Convert from seconds instead.
+ // See https://doc.qt.io/qt-5/qdatetime.html#fromSecsSinceEpoch
+#if QT_VERSION >= 0x050800
+ loginTime = QDateTime::fromSecsSinceEpoch(logintime);
+#else
+ // fromSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for
+ // now.
+ // See https://doc.qt.io/qt-5/qdatetime.html#fromMSecsSinceEpoch
+ loginTime = QDateTime::fromMSecsSinceEpoch((qint64)(logintime * 1000));
+#endif
}
IrcUser *ircuser = e->network()->ircUser(e->params()[0]);
switch (e->params().count()) {
case 3:
topic = e->params()[2];
+ [[clang::fallthrough]];
case 2:
userCount = e->params()[1].toUInt();
+ [[clang::fallthrough]];
case 1:
channelName = e->params()[0];
+ [[clang::fallthrough]];
default:
break;
}
return;
QString channel = e->params()[0];
- IrcUser *ircuser = e->network()->ircUser(e->params()[4]);
+ // Store the nick separate from ircuser for AutoWho check below
+ QString nick = e->params()[4];
+ IrcUser *ircuser = e->network()->ircUser(nick);
if (ircuser) {
+ // Only process the WHO information if an IRC user exists. Don't create an IRC user here;
+ // there's no way to track when the user quits, which would leave a phantom IrcUser lying
+ // around.
+ // NOTE: Whenever MONITOR support is introduced, the IrcUser will be created by an
+ // RPL_MONONLINE numeric before any WHO commands are run.
processWhoInformation(e->network(), channel, ircuser, e->params()[3], e->params()[1],
e->params()[2], e->params()[5], e->params().last().section(" ", 1));
}
// Check if channel name has a who in progress.
- // If not, then check if user nick exists and has a who in progress.
+ // If not, then check if user nickname has a who in progress. Use nick directly; don't use
+ // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received).
if (coreNetwork(e)->isAutoWhoInProgress(channel) ||
- (ircuser && coreNetwork(e)->isAutoWhoInProgress(ircuser->nick()))) {
+ (coreNetwork(e)->isAutoWhoInProgress(nick))) {
e->setFlag(EventManager::Silent);
}
}
return;
QString channel = e->params()[1];
- IrcUser *ircuser = e->network()->ircUser(e->params()[5]);
+ QString nick = e->params()[5];
+ IrcUser *ircuser = e->network()->ircUser(nick);
if (ircuser) {
+ // Only process the WHO information if an IRC user exists. Don't create an IRC user here;
+ // there's no way to track when the user quits, which would leave a phantom IrcUser lying
+ // around.
+ // NOTE: Whenever MONITOR support is introduced, the IrcUser will be created by an
+ // RPL_MONONLINE numeric before any WHO commands are run.
processWhoInformation(e->network(), channel, ircuser, e->params()[4], e->params()[2],
e->params()[3], e->params()[6], e->params().last());
// Don't use .section(" ", 1) with WHOX replies, for there's no hopcount to trim out
}
// Check if channel name has a who in progress.
- // If not, then check if user nick exists and has a who in progress.
+ // If not, then check if user nickname has a who in progress. Use nick directly; don't use
+ // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received).
if (coreNetwork(e)->isAutoWhoInProgress(channel) ||
- (ircuser && coreNetwork(e)->isAutoWhoInProgress(ircuser->nick()))) {
+ (coreNetwork(e)->isAutoWhoInProgress(nick))) {
e->setFlag(EventManager::Silent);
}
}
void CoreSessionEventProcessor::handleCtcpTime(CtcpEvent *e)
{
- e->setReply(QDateTime::currentDateTime().toString());
+ // Explicitly specify the Qt default DateTime format string to allow for modification
+ // Qt::TextDate default roughly corresponds to...
+ // > ddd MMM d yyyy HH:mm:ss
+ //
+ // See https://doc.qt.io/qt-5/qdatetime.html#toString
+ // And https://doc.qt.io/qt-5/qt.html#DateFormat-enum
+#if QT_VERSION > 0x050000
+ // Append the timezone identifier "t", so other other IRC users have a frame of reference for
+ // the current timezone. This could be figured out before by manually comparing to UTC, so this
+ // is just convenience.
+
+ // Alas, "t" was only added in Qt 5
+ e->setReply(QDateTime::currentDateTime().toString("ddd MMM d yyyy HH:mm:ss t"));
+#else
+ e->setReply(QDateTime::currentDateTime().toString("ddd MMM d yyyy HH:mm:ss"));
+#endif
}
void CoreSessionEventProcessor::handleCtcpVersion(CtcpEvent *e)
{
- e->setReply(QString("Quassel IRC %1 (built on %2) -- http://www.quassel-irc.org")
+ e->setReply(QString("Quassel IRC %1 (built on %2) -- https://www.quassel-irc.org")
.arg(Quassel::buildInfo().plainVersionString).arg(Quassel::buildInfo().commitDate));
}