X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fircserverhandler.cpp;h=6dfb838372811baaf7bef7064868246d0ef4d833;hp=3a3d4f01a9a30c458d371dada4d312b0c475c774;hb=c8467bd28cb62ffbc4d3f6c7b459ce75ef580238;hpb=299bc5da644f9325b4116fd186f7de7e24955c78 diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 3a3d4f01..6dfb8383 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -39,6 +39,8 @@ IrcServerHandler::IrcServerHandler(CoreNetwork *parent) } IrcServerHandler::~IrcServerHandler() { + if(!_netsplits.empty()) + qDeleteAll(_netsplits); } /*! Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */ @@ -186,9 +188,23 @@ void IrcServerHandler::handleJoin(const QString &prefix, const QList QString channel = serverDecode(params[0]); IrcUser *ircuser = network()->updateNickFromMask(prefix); - emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, prefix); + + bool handledByNetsplit = false; + if(!_netsplits.empty()) { + foreach(Netsplit* n, _netsplits) { + handledByNetsplit = n->userJoined(prefix, channel); + if(handledByNetsplit) + break; + } + } + + // normal join + if(!handledByNetsplit) { + emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, prefix); + ircuser->joinChannel(channel); + } //qDebug() << "IrcServerHandler::handleJoin()" << prefix << params; - ircuser->joinChannel(channel); + if(network()->isMe(ircuser)) { network()->setChannelJoined(channel); putCmd("MODE", params[0]); // we want to know the modes of the channel we just joined, so we ask politely @@ -249,8 +265,20 @@ void IrcServerHandler::handleMode(const QString &prefix, const QList // user channel modes (op, voice, etc...) if(paramOffset < params.count()) { IrcUser *ircUser = network()->ircUser(params[paramOffset]); - if(add) - channel->addUserMode(ircUser, QString(modes[c])); + if(add) { + bool handledByNetsplit = false; + if(!_netsplits.empty()) { + foreach(Netsplit* n, _netsplits) { + handledByNetsplit = n->userAlreadyJoined(ircUser->hostmask(), channel->name()); + if(handledByNetsplit) { + n->addMode(ircUser->hostmask(), channel->name(), QString(modes[c])); + break; + } + } + } + if(!handledByNetsplit) + channel->addUserMode(ircUser, QString(modes[c])); + } else channel->removeUserMode(ircUser, QString(modes[c])); } else { @@ -461,10 +489,32 @@ void IrcServerHandler::handleQuit(const QString &prefix, const QList if(params.count() > 0) msg = userDecode(ircuser->nick(), params[0]); - foreach(QString channel, ircuser->channels()) - emit displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, msg, prefix); - - ircuser->quit(); + // check if netsplit + if(Netsplit::isNetsplit(msg)) { + Netsplit *n; + if(!_netsplits.contains(msg)) { + n = new Netsplit(); + connect(n, SIGNAL(finished()), this, SLOT(handleNetsplitFinished())); + connect(n, SIGNAL(netsplitJoin(const QString&, const QStringList&, const QStringList&, const QString&)), + this, SLOT(handleNetsplitJoin(const QString&, const QStringList&, const QStringList&, const QString&))); + connect(n, SIGNAL(netsplitQuit(const QString&, const QStringList&, const QString&)), + this, SLOT(handleNetsplitQuit(const QString&, const QStringList&, const QString&))); + connect(n, SIGNAL(earlyJoin(const QString&, const QStringList&, const QStringList&)), + this, SLOT(handleEarlyNetsplitJoin(const QString&, const QStringList&, const QStringList&))); + _netsplits.insert(msg, n); + } + else { + n = _netsplits[msg]; + } + // add this user to the netsplit + n->userQuit(prefix, ircuser->channels(),msg); + } + // normal quit + else { + foreach(QString channel, ircuser->channels()) + emit displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, msg, prefix); + ircuser->quit(); + } } void IrcServerHandler::handleTopic(const QString &prefix, const QList ¶ms) { @@ -485,7 +535,7 @@ void IrcServerHandler::handleTopic(const QString &prefix, const QListsetTopic(topic); - emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel->name(), tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel->name()).arg(topic)); + emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel->name(), tr("%1 has changed topic for %2 to: \"%3\"").arg(ircuser->nick()).arg(channel->name()).arg(topic)); } /* RPL_WELCOME */ @@ -884,7 +934,7 @@ void IrcServerHandler::handle331(const QString &prefix, const QList if(chan) chan->setTopic(QString()); - emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("No topic is set for %1.").arg(channel)); + emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel, tr("No topic is set for %1.").arg(channel)); } /* RPL_TOPIC */ @@ -899,7 +949,7 @@ void IrcServerHandler::handle332(const QString &prefix, const QList if(chan) chan->setTopic(topic); - emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic for %1 is \"%2\"").arg(channel, topic)); + emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel, tr("Topic for %1 is \"%2\"").arg(channel, topic)); } /* Topic set by... */ @@ -909,7 +959,7 @@ void IrcServerHandler::handle333(const QString &prefix, const QList return; QString channel = serverDecode(params[0]); - emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, + emit displayMsg(Message::Topic, BufferInfo::ChannelBuffer, channel, tr("Topic set by %1 on %2") .arg(serverDecode(params[1]), QDateTime::fromTime_t(channelDecode(channel, params[2]).toUInt()).toString())); } @@ -1013,6 +1063,70 @@ void IrcServerHandler::handle433(const QString &prefix, const QList tryNextNick(errnick); } +/* Handle signals from Netsplit objects */ + +void IrcServerHandler::handleNetsplitJoin(const QString &channel, const QStringList &users, const QStringList &modes, const QString& quitMessage) +{ + IrcChannel *ircChannel = network()->ircChannel(channel); + if(!ircChannel) { + return; + } + QList ircUsers; + QStringList newModes = modes; + + foreach(QString user, users) { + IrcUser *iu = network()->updateNickFromMask(user); + if(iu) + ircUsers.append(iu); + else { + newModes.removeAt(users.indexOf(user)); + } + } + + QString msg = users.join("#:#").append("#:#").append(quitMessage); + emit displayMsg(Message::NetsplitJoin, BufferInfo::ChannelBuffer, channel, msg); + ircChannel->joinIrcUsers(ircUsers, newModes); +} + +void IrcServerHandler::handleNetsplitQuit(const QString &channel, const QStringList &users, const QString& quitMessage) +{ + QString msg = users.join("#:#").append("#:#").append(quitMessage); + emit displayMsg(Message::NetsplitQuit, BufferInfo::ChannelBuffer, channel, msg); + foreach(QString user, users) { + IrcUser *iu = network()->ircUser(nickFromMask(user)); + if(iu) + iu->quit(); + } +} + +void IrcServerHandler::handleEarlyNetsplitJoin(const QString &channel, const QStringList &users, const QStringList &modes) { + IrcChannel *ircChannel = network()->ircChannel(channel); + if(!ircChannel) { + qDebug() << "handleEarlyNetsplitJoin(): channel " << channel << " invalid"; + return; + } + QList ircUsers; + QStringList newModes = modes; + + foreach(QString user, users) { + IrcUser *iu = network()->updateNickFromMask(user); + if(iu) { + ircUsers.append(iu); + emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, user); + } + else { + newModes.removeAt(users.indexOf(user)); + } + } + ircChannel->joinIrcUsers(ircUsers, newModes); +} +void IrcServerHandler::handleNetsplitFinished() +{ + Netsplit* n = qobject_cast(sender()); + _netsplits.remove(_netsplits.key(n)); + n->deleteLater(); +} + /* */ // FIXME networkConnection()->setChannelKey("") for all ERR replies indicating that a JOIN went wrong