Merge pull request #1 from sandsmark/master
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 19 Feb 2013 22:29:33 +0000 (14:29 -0800)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 19 Feb 2013 22:29:33 +0000 (14:29 -0800)
Support for * as a mode target

1  2 
src/core/coreuserinputhandler.cpp
src/core/coreuserinputhandler.h

@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
 - *   Copyright (C) 2005-2012 by the Quassel Project                        *
 + *   Copyright (C) 2005-2013 by the Quassel Project                        *
   *   devel@quassel-irc.org                                                 *
   *                                                                         *
   *   This program is free software; you can redistribute it and/or modify  *
@@@ -207,6 -207,14 +207,6 @@@ void CoreUserInputHandler::handleDelkey
      }
  
      network()->setCipherKey(target, QByteArray());
 -
 -    if (network()->isChannelName(target) && network()->channels().contains(target)) {
 -        qobject_cast<CoreIrcChannel *>(network()->ircChannel(target))->setEncrypted(false);
 -    }
 -    else if (network()->nicks().contains(target)) {
 -        qobject_cast<CoreIrcUser *>(network()->ircUser(target))->setEncrypted(false);
 -    }
 -
      emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("The key for %1 has been deleted.").arg(target));
  
  #else
  #endif
  }
  
+ void CoreUserInputHandler::doMode(const BufferInfo &bufferInfo, const QChar& addOrRemove, const QChar& mode, const QString &nicks)
+ {
+     QString m;
+     bool isNumber;
+     int maxModes = network()->support("MODES").toInt(&isNumber);
+     if (!isNumber || maxModes == 0) maxModes = 1;
+     
+     QStringList nickList;
+     if (nicks == "*") { // All users in channel
+         const QList<IrcUser*> users = network()->ircChannel(bufferInfo.bufferName())->ircUsers();
+         foreach(IrcUser *user, users) {
+             if ((addOrRemove == '+' && !network()->ircChannel(bufferInfo.bufferName())->userModes(user).contains(mode))
+                 || (addOrRemove == '-' && network()->ircChannel(bufferInfo.bufferName())->userModes(user).contains(mode)))
+                 nickList.append(user->nick());
+         }
+     } else { 
+         nickList = nicks.split(' ', QString::SkipEmptyParts);
+     }
+     
+     if (nickList.count() == 0) return;
+     
+     while (!nickList.isEmpty()) {
+         int amount = qMin(nickList.count(), maxModes);
+         QString m = addOrRemove; for(int i = 0; i < amount; i++) m += mode;
+         QStringList params;
+         params << bufferInfo.bufferName() << m;
+         for(int i = 0; i < amount; i++) params << nickList.takeFirst();
+         emit putCmd("MODE", serverEncode(params));
+     }
+ }
  
- void CoreUserInputHandler::handleDeop(const BufferInfo &bufferInfo, const QString &msg)
+ void CoreUserInputHandler::handleDeop(const BufferInfo &bufferInfo, const QString &nicks)
  {
-     QStringList nicks = msg.split(' ', QString::SkipEmptyParts);
-     QString m = "-"; for (int i = 0; i < nicks.count(); i++) m += 'o';
-     QStringList params;
-     params << bufferInfo.bufferName() << m << nicks;
-     emit putCmd("MODE", serverEncode(params));
+     doMode(bufferInfo, '-', 'o', nicks);
  }
  
  
- void CoreUserInputHandler::handleDehalfop(const BufferInfo &bufferInfo, const QString &msg)
+ void CoreUserInputHandler::handleDehalfop(const BufferInfo &bufferInfo, const QString &nicks)
  {
-     QStringList nicks = msg.split(' ', QString::SkipEmptyParts);
-     QString m = "-"; for (int i = 0; i < nicks.count(); i++) m += 'h';
-     QStringList params;
-     params << bufferInfo.bufferName() << m << nicks;
-     emit putCmd("MODE", serverEncode(params));
+     doMode(bufferInfo, '-', 'h', nicks);
  }
  
  
- void CoreUserInputHandler::handleDevoice(const BufferInfo &bufferInfo, const QString &msg)
+ void CoreUserInputHandler::handleDevoice(const BufferInfo &bufferInfo, const QString &nicks)
  {
-     QStringList nicks = msg.split(' ', QString::SkipEmptyParts);
-     QString m = "-"; for (int i = 0; i < nicks.count(); i++) m += 'v';
-     QStringList params;
-     params << bufferInfo.bufferName() << m << nicks;
-     emit putCmd("MODE", serverEncode(params));
+     doMode(bufferInfo, '-', 'v', nicks);
+ }
+ void CoreUserInputHandler::handleHalfop(const BufferInfo &bufferInfo, const QString &nicks)
+ {
+     doMode(bufferInfo, '+', 'h', nicks);
+ }
+ void CoreUserInputHandler::handleOp(const BufferInfo &bufferInfo, const QString &nicks) {
+   doMode(bufferInfo, '+', 'o', nicks);
  }
  
  
@@@ -319,50 -355,6 +347,50 @@@ void CoreUserInputHandler::handleJoin(c
  }
  
  
 +void CoreUserInputHandler::handleKeyx(const BufferInfo &bufferInfo, const QString &msg)
 +{
 +#ifdef HAVE_QCA2
 +    if (!bufferInfo.isValid())
 +        return;
 +
 +    if (!Cipher::neededFeaturesAvailable())
 +        return;
 +
 +    QStringList parms = msg.split(' ', QString::SkipEmptyParts);
 +
 +    if (parms.count() == 0 && !bufferInfo.bufferName().isEmpty())
 +        parms.prepend(bufferInfo.bufferName());
 +    else if (parms.count() != 1) {
 +        emit displayMsg(Message::Info, bufferInfo.bufferName(),
 +            tr("[usage] /keyx [<nick|channel>] Initiates a DH1080 key exchange with the target."));
 +        return;
 +    }
 +
 +    QString target = parms.at(0);
 +
 +    Cipher *cipher = network()->cipher(target);
 +    if (!cipher) // happens when there is no CoreIrcChannel for the target
 +        return;
 +
 +    QByteArray pubKey = cipher->initKeyExchange();
 +    if (pubKey.isEmpty())
 +        emit displayMsg(Message::Error, bufferInfo.bufferName(), tr("Failed to initiate key exchange with %1.").arg(target));
 +    else {
 +        QList<QByteArray> params;
 +        params << serverEncode(target) << serverEncode("DH1080_INIT ") + pubKey;
 +        emit putCmd("NOTICE", params);
 +        emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("Initiated key exchange with %1.").arg(target));
 +    }
 +#else
 +    Q_UNUSED(msg)
 +    emit displayMsg(Message::Error, bufferInfo.bufferName(), tr("Error: Setting an encryption key requires Quassel to have been built "
 +                                                                "with support for the Qt Cryptographic Architecture (QCA) library. "
 +                                                                "Contact your distributor about a Quassel package with QCA "
 +                                                                "support, or rebuild Quassel with QCA present."));
 +#endif
 +}
 +
 +
  void CoreUserInputHandler::handleKick(const BufferInfo &bufferInfo, const QString &msg)
  {
      QString nick = msg.section(' ', 0, 0, QString::SectionSkipEmpty);
@@@ -463,25 -455,6 +491,6 @@@ void CoreUserInputHandler::handleNotice
  }
  
  
- void CoreUserInputHandler::handleHalfop(const BufferInfo &bufferInfo, const QString &msg)
- {
-     QStringList nicks = msg.split(' ', QString::SkipEmptyParts);
-     QString m = "+"; for (int i = 0; i < nicks.count(); i++) m += 'h';
-     QStringList params;
-     params << bufferInfo.bufferName() << m << nicks;
-     emit putCmd("MODE", serverEncode(params));
- }
- void CoreUserInputHandler::handleOp(const BufferInfo &bufferInfo, const QString &msg)
- {
-     QStringList nicks = msg.split(' ', QString::SkipEmptyParts);
-     QString m = "+"; for (int i = 0; i < nicks.count(); i++) m += 'o';
-     QStringList params;
-     params << bufferInfo.bufferName() << m << nicks;
-     emit putCmd("MODE", serverEncode(params));
- }
  
  void CoreUserInputHandler::handleOper(const BufferInfo &bufferInfo, const QString &msg)
  {
@@@ -596,8 -569,14 +605,8 @@@ void CoreUserInputHandler::handleSetkey
  
      QString target = parms.at(0);
      QByteArray key = parms.at(1).toLocal8Bit();
 -
      network()->setCipherKey(target, key);
  
 -    if (network()->isChannelName(target) && network()->channels().contains(target))
 -        qobject_cast<CoreIrcChannel *>(network()->ircChannel(target))->setEncrypted(true);
 -    else if (network()->nicks().contains(target))
 -        qobject_cast<CoreIrcUser *>(network()->ircUser(target))->setEncrypted(true);
 -
      emit displayMsg(Message::Info, bufferInfo.bufferName(), tr("The key for %1 has been set.").arg(target));
  #else
      Q_UNUSED(msg)
@@@ -746,7 -725,7 +755,7 @@@ void CoreUserInputHandler::putPrivmsg(c
          QByteArray crypted = message.left(splitPos);
          bool isEncrypted = false;
  #ifdef HAVE_QCA2
 -        if (cipher && !message.isEmpty()) {
 +        if (cipher && !cipher->key().isEmpty() && !message.isEmpty()) {
              isEncrypted = cipher->encrypt(crypted);
          }
  #endif
@@@ -827,7 -806,7 +836,7 @@@ QByteArray CoreUserInputHandler::encryp
          return message_;
  
      Cipher *cipher = network()->cipher(target);
 -    if (!cipher)
 +    if (!cipher || cipher->key().isEmpty())
          return message_;
  
      QByteArray message = message_;
@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
 - *   Copyright (C) 2005-2012 by the Quassel Project                        *
 + *   Copyright (C) 2005-2013 by the Quassel Project                        *
   *   devel@quassel-irc.org                                                 *
   *                                                                         *
   *   This program is free software; you can redistribute it and/or modify  *
@@@ -43,12 -43,11 +43,12 @@@ public slots
      void handleUnban(const BufferInfo &bufferInfo, const QString &text);
      void handleCtcp(const BufferInfo &bufferInfo, const QString &text);
      void handleDelkey(const BufferInfo &bufferInfo, const QString &text);
-     void handleDeop(const BufferInfo &bufferInfo, const QString &text);
-     void handleDehalfop(const BufferInfo &bufferInfo, const QString &text);
-     void handleDevoice(const BufferInfo &bufferInfo, const QString &text);
+     void handleDeop(const BufferInfo& bufferInfo, const QString &nicks);
+     void handleDehalfop(const BufferInfo& bufferInfo, const QString &nicks);
+     void handleDevoice(const BufferInfo& bufferInfo, const QString &nicks);
      void handleInvite(const BufferInfo &bufferInfo, const QString &text);
      void handleJoin(const BufferInfo &bufferInfo, const QString &text);
 +    void handleKeyx(const BufferInfo &bufferInfo, const QString &text);
      void handleKick(const BufferInfo &bufferInfo, const QString &text);
      void handleKill(const BufferInfo &bufferInfo, const QString &text);
      void handleList(const BufferInfo &bufferInfo, const QString &text);
@@@ -58,8 -57,8 +58,8 @@@
      void handleNick(const BufferInfo &bufferInfo, const QString &text);
      void handleNotice(const BufferInfo &bufferInfo, const QString &text);
      void handleOper(const BufferInfo &bufferInfo, const QString &text);
-     void handleOp(const BufferInfo &bufferInfo, const QString &text);
-     void handleHalfop(const BufferInfo &bufferInfo, const QString &text);
+     void handleOp(const BufferInfo& bufferInfo, const QString &nicks);
+     void handleHalfop(const BufferInfo& bufferInfo, const QString &nicks);
      void handlePart(const BufferInfo &bufferInfo, const QString &text);
      void handlePing(const BufferInfo &bufferInfo, const QString &text);
      void handleQuery(const BufferInfo &bufferInfo, const QString &text);
@@@ -84,6 -83,7 +84,7 @@@ protected
      void timerEvent(QTimerEvent *event);
  
  private:
+     void doMode(const BufferInfo& bufferInfo, const QChar &addOrRemove, const QChar &mode, const QString &nickList);
      void banOrUnban(const BufferInfo &bufferInfo, const QString &text, bool ban);
      void putPrivmsg(const QByteArray &target, const QByteArray &message, Cipher *cipher = 0);
      int lastParamOverrun(const QString &cmd, const QList<QByteArray> &params);