/***************************************************************************
- * Copyright (C) 2005-2015 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 (!_userModes.contains(ircuser)) {
- qWarning() << "Channel" << name() << "received data for unknown User" << ircuser->nick();
+ // This can happen e.g. when disconnecting from a network, so don't log a warning
return false;
}
return;
}
+ // Sort user modes first
+ const QStringList sortedModes = network()->sortPrefixModes(modes);
+
QStringList newNicks;
QStringList newModes;
QList<IrcUser *> newUsers;
IrcUser *ircuser;
for (int i = 0; i < users.count(); i++) {
ircuser = users[i];
- if (!ircuser || _userModes.contains(ircuser)) {
- if (modes[i].count() > 1) {
+ if (!ircuser)
+ continue;
+ if (_userModes.contains(ircuser)) {
+ if (sortedModes[i].count() > 1) {
// Multiple modes received, do it one at a time
// TODO Better way of syncing this without breaking protocol?
- for (int i_m = 0; i_m < modes[i].count(); ++i_m) {
- addUserMode(ircuser, modes[i][i_m]);
+ for (int i_m = 0; i_m < sortedModes[i].count(); ++i_m) {
+ addUserMode(ircuser, sortedModes[i][i_m]);
}
} else {
- addUserMode(ircuser, modes[i]);
+ addUserMode(ircuser, sortedModes[i]);
}
continue;
}
- _userModes[ircuser] = modes[i];
+ _userModes[ircuser] = sortedModes[i];
ircuser->joinChannel(this, true);
connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString)));
// the joins are propagated by the ircuser. The signal ircUserJoined is only for convenience
newNicks << ircuser->nick();
- newModes << modes[i];
+ newModes << sortedModes[i];
newUsers << ircuser;
}
void IrcChannel::setUserModes(IrcUser *ircuser, const QString &modes)
{
if (isKnownUser(ircuser)) {
- _userModes[ircuser] = modes;
+ // Keep user modes sorted
+ _userModes[ircuser] = network()->sortPrefixModes(modes);
QString nick = ircuser->nick();
SYNC_OTHER(setUserModes, ARG(nick), ARG(modes))
emit ircUserModesSet(ircuser, modes);
return;
if (!_userModes[ircuser].contains(mode)) {
- _userModes[ircuser] += mode;
+ // Keep user modes sorted
+ _userModes[ircuser] = network()->sortPrefixModes(_userModes[ircuser] + mode);
QString nick = ircuser->nick();
SYNC_OTHER(addUserMode, ARG(nick), ARG(mode))
emit ircUserModeAdded(ircuser, mode);
return;
if (_userModes[ircuser].contains(mode)) {
+ // Removing modes shouldn't mess up ordering
_userModes[ircuser].remove(mode);
QString nick = ircuser->nick();
SYNC_OTHER(removeUserMode, ARG(nick), ARG(mode));
modes << iter.value().toString();
++iter;
}
+ // joinIrcUsers handles sorting modes
joinIrcUsers(users, modes);
}
return _C_channelModes.contains(mode);
case Network::D_CHANMODE:
return _D_channelModes.contains(mode);
- default:
- return false;
}
+ return false;
}
case Network::A_CHANMODE:
if (_A_channelModes.contains(mode))
return _A_channelModes[mode];
+ break;
default:
- return QStringList();
+ ;
}
+ return {};
}