From: Marcus Eggenberger Date: Mon, 23 Jun 2008 11:07:34 +0000 (+0200) Subject: Fixing BR #39 (splitting long messages) X-Git-Tag: 0.3.0~355 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=b2f26944f3b4109d22bb1571aed2a7e2e9efbb5a;hp=fe4b38e66592f11fdf4c4651863968983daecd2d Fixing BR #39 (splitting long messages) Conflicts: src/core/basichandler.cpp src/core/basichandler.h --- diff --git a/src/core/basichandler.cpp b/src/core/basichandler.cpp index adf9fa47..a6af5373 100644 --- a/src/core/basichandler.cpp +++ b/src/core/basichandler.cpp @@ -32,8 +32,8 @@ BasicHandler::BasicHandler(NetworkConnection *parent) connect(this, SIGNAL(displayMsg(Message::Type, BufferInfo::Type, QString, QString, QString, Message::Flags)), networkConnection(), SIGNAL(displayMsg(Message::Type, BufferInfo::Type, QString, QString, QString, Message::Flags))); - connect(this, SIGNAL(putCmd(QString, const QVariantList &, const QByteArray &)), - networkConnection(), SLOT(putCmd(QString, const QVariantList &, const QByteArray &))); + connect(this, SIGNAL(putCmd(QString, const QList &, const QByteArray &)), + networkConnection(), SLOT(putCmd(QString, const QList &, const QByteArray &))); connect(this, SIGNAL(putRawLine(const QByteArray &)), networkConnection(), SLOT(putRawLine(const QByteArray &))); @@ -168,17 +168,11 @@ BufferInfo::Type BasicHandler::typeByTarget(const QString &target) const { } void BasicHandler::putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix) { - QVariantList list; + QList list; list << param; emit putCmd(cmd, list, prefix); } -void BasicHandler::putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix) { - QVariantList list; - foreach(QByteArray param, params) list << param; - emit putCmd(cmd, list, prefix); -} - void BasicHandler::displayMsg(Message::Type msgType, QString target, QString text, QString sender, Message::Flags flags) { IrcChannel *channel = network()->ircChannel(target); if(!channel && (target.startsWith('$') || target.startsWith('#'))) diff --git a/src/core/basichandler.h b/src/core/basichandler.h index ebac6dd3..47003478 100644 --- a/src/core/basichandler.h +++ b/src/core/basichandler.h @@ -55,13 +55,12 @@ public: signals: void displayMsg(Message::Type, BufferInfo::Type, QString target, QString text, QString sender = "", Message::Flags flags = Message::None); - void putCmd(const QString &cmd, const QVariantList ¶ms, const QByteArray &prefix); + void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); void putRawLine(const QByteArray &msg); protected: void displayMsg(Message::Type, QString target, QString text, QString sender = "", Message::Flags flags = Message::None); void putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix = QByteArray()); - void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); virtual void handle(const QString &member, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), diff --git a/src/core/networkconnection.cpp b/src/core/networkconnection.cpp index 3d9fcc73..ab453114 100644 --- a/src/core/networkconnection.cpp +++ b/src/core/networkconnection.cpp @@ -433,17 +433,73 @@ void NetworkConnection::fillBucketAndProcessQueue() { } } -void NetworkConnection::putCmd(const QString &cmd, const QVariantList ¶ms, const QByteArray &prefix) { +// returns 0 if the message will not be chopped by the irc server or number of chopped bytes if message is too long +int NetworkConnection::lastParamOverrun(const QString &cmd, const QList ¶ms) { + //the server will pass our message that trunkated to 512 bytes including CRLF with the following format: + // ":prefix COMMAND param0 param1 :lastparam" + // where prefix = "nickname!user@host" + // that means that the last message can be as long as: + // 512 - nicklen - userlen - hostlen - commandlen - sum(param[0]..param[n-1])) - 2 (for CRLF) - 4 (":!@" + 1space between prefix and command) - max(paramcount - 1, 0) (space for simple params) - 2 (space and colon for last param) + IrcUser *me = network()->me(); + int maxLen = 512 - serverEncode(me->nick()).count() - serverEncode(me->user()).count() - serverEncode(me->host()).count() - cmd.toAscii().count() - 6; + + if(!params.isEmpty()) { + for(int i = 0; i < params.count() - 1; i++) { + maxLen -= (params[i].count() + 1); + } + maxLen -= 2; // " :" last param separator; + + if(params.last().count() > maxLen) { + return params.last().count() - maxLen; + } else { + return 0; + } + } else { + return 0; + } +} + +void NetworkConnection::putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix) { QByteArray msg; + if(cmd == "PRIVMSG" && params.count() > 1) { + int overrun = lastParamOverrun(cmd, params); + if(overrun) { + QList paramCopy1; + QList paramCopy2; + for(int i = 0; i < params.count() - 1; i++) { + paramCopy1 << params[i]; + paramCopy2 << params[i]; + } + + QByteArray lastPart = params.last(); + QByteArray splitter(" .,-"); + int maxSplitPos = params.last().count() - overrun; + int splitPos = -1; + for(int i = 0; i < splitter.size(); i++) { + splitPos = qMax(splitPos, lastPart.lastIndexOf(splitter[i], maxSplitPos)); + } + + if(splitPos == -1) { + splitPos = maxSplitPos; + } + + paramCopy1 << lastPart.left(splitPos); + paramCopy2 << lastPart.mid(splitPos); + putCmd(cmd, paramCopy1, prefix); + putCmd(cmd, paramCopy2, prefix); + return; + } + } + if(!prefix.isEmpty()) msg += ":" + prefix + " "; msg += cmd.toUpper().toAscii(); for(int i = 0; i < params.size() - 1; i++) { - msg += " " + params[i].toByteArray(); + msg += " " + params[i]; } if(!params.isEmpty()) - msg += " :" + params.last().toByteArray(); + msg += " :" + params.last(); if(cmd == "PRIVMSG" && params.count() > 1) { QByteArray msghead = "PRIVMSG " + params[0].toByteArray() + " :"; diff --git a/src/core/networkconnection.h b/src/core/networkconnection.h index 16bfccc4..cebf8379 100644 --- a/src/core/networkconnection.h +++ b/src/core/networkconnection.h @@ -95,7 +95,8 @@ public slots: void userInput(BufferInfo bufferInfo, QString msg); void putRawLine(QByteArray input); - void putCmd(const QString &cmd, const QVariantList ¶ms, const QByteArray &prefix = QByteArray()); + int lastParamOverrun(const QString &cmd, const QList ¶ms); + void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); void setChannelJoined(const QString &channel); void setChannelParted(const QString &channel);