From f62cdd391a5e30ef2d2ffbcaa0718904b1652d4e Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Mon, 18 Feb 2008 18:37:11 +0000 Subject: [PATCH] - All CTCP messages are now using proper charset en/decodings - For non-Channel NOTICEs and RPL_NOSUCHNICK the redirection flag is set. This flag enables the client to show the message in the buffer it has been configured for (Status Buffer, Current Buffer, open Query) The latter one has no effect for the time beeing as Those Settings are stored in QtUiSettings which cannot be accessed by the Client. --- src/core/basichandler.cpp | 7 +++ src/core/basichandler.h | 1 + src/core/ctcphandler.cpp | 104 ++++++++++++++++++---------------- src/core/ctcphandler.h | 28 +++++---- src/core/ircserverhandler.cpp | 31 +++++----- 5 files changed, 92 insertions(+), 79 deletions(-) diff --git a/src/core/basichandler.cpp b/src/core/basichandler.cpp index 8288e10d..d93a8441 100644 --- a/src/core/basichandler.cpp +++ b/src/core/basichandler.cpp @@ -21,6 +21,7 @@ #include +#include "util.h" #include "networkconnection.h" BasicHandler::BasicHandler(NetworkConnection *parent) @@ -187,3 +188,9 @@ void BasicHandler::putCmd(const QString &cmd, const QList ¶ms, c foreach(QByteArray param, params) list << param; emit putCmd(cmd, list, prefix); } + +void BasicHandler::displayMsg(Message::Type msgType, QString target, QString text, QString sender, quint8 flags) { + if(target.startsWith('$') || target.startsWith('#')) + target = nickFromMask(sender); + emit displayMsg(msgType, typeByTarget(target), target, text, sender, flags); +} diff --git a/src/core/basichandler.h b/src/core/basichandler.h index 7af38942..757af6e8 100644 --- a/src/core/basichandler.h +++ b/src/core/basichandler.h @@ -60,6 +60,7 @@ signals: void putRawLine(const QByteArray &msg); protected: + void displayMsg(Message::Type, QString target, QString text, QString sender = "", quint8 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()); diff --git a/src/core/ctcphandler.cpp b/src/core/ctcphandler.cpp index 1e5254da..e6b53443 100644 --- a/src/core/ctcphandler.cpp +++ b/src/core/ctcphandler.cpp @@ -25,28 +25,29 @@ #include "network.h" CtcpHandler::CtcpHandler(NetworkConnection *parent) - : BasicHandler(parent) { - - QString MQUOTE = QString('\020'); - ctcpMDequoteHash[MQUOTE + '0'] = QString('\000'); - ctcpMDequoteHash[MQUOTE + 'n'] = QString('\n'); - ctcpMDequoteHash[MQUOTE + 'r'] = QString('\r'); + : BasicHandler(parent), + XDELIM("\001") +{ + + QByteArray MQUOTE = QByteArray("\020"); + ctcpMDequoteHash[MQUOTE + '0'] = QByteArray("\000"); + ctcpMDequoteHash[MQUOTE + 'n'] = QByteArray("\n"); + ctcpMDequoteHash[MQUOTE + 'r'] = QByteArray("\r"); ctcpMDequoteHash[MQUOTE + MQUOTE] = MQUOTE; - XDELIM = QString('\001'); - QString XQUOTE = QString('\134'); + QByteArray XQUOTE = QByteArray("\134"); ctcpXDelimDequoteHash[XQUOTE + XQUOTE] = XQUOTE; - ctcpXDelimDequoteHash[XQUOTE + QString('a')] = XDELIM; + ctcpXDelimDequoteHash[XQUOTE + QByteArray("a")] = XDELIM; } -QString CtcpHandler::dequote(QString message) { - QString dequotedMessage; - QString messagepart; - QHash::iterator ctcpquote; +QByteArray CtcpHandler::dequote(const QByteArray &message) { + QByteArray dequotedMessage; + QByteArray messagepart; + QHash::iterator ctcpquote; // copy dequote Message for(int i = 0; i < message.size(); i++) { - messagepart = message[i]; + messagepart = message.mid(i,1); if(i+1 < message.size()) { for(ctcpquote = ctcpMDequoteHash.begin(); ctcpquote != ctcpMDequoteHash.end(); ++ctcpquote) { if(message.mid(i,2) == ctcpquote.key()) { @@ -62,13 +63,13 @@ QString CtcpHandler::dequote(QString message) { } -QString CtcpHandler::XdelimDequote(QString message) { - QString dequotedMessage; - QString messagepart; - QHash::iterator xdelimquote; +QByteArray CtcpHandler::xdelimDequote(const QByteArray &message) { + QByteArray dequotedMessage; + QByteArray messagepart; + QHash::iterator xdelimquote; for(int i = 0; i < message.size(); i++) { - messagepart = message[i]; + messagepart = message.mid(i,1); if(i+1 < message.size()) { for(xdelimquote = ctcpXDelimDequoteHash.begin(); xdelimquote != ctcpXDelimDequoteHash.end(); ++xdelimquote) { if(message.mid(i,2) == xdelimquote.key()) { @@ -83,64 +84,71 @@ QString CtcpHandler::XdelimDequote(QString message) { return dequotedMessage; } -void CtcpHandler::parse(Message::Type messageType, QString prefix, QString target, QString message) { - QString ctcp; +void CtcpHandler::parse(Message::Type messageType, const QString &prefix, const QString &target, const QByteArray &message) { + QByteArray ctcp; //lowlevel message dequote - QString dequotedMessage = dequote(message); + QByteArray dequotedMessage = dequote(message); - CtcpType ctcptype = (messageType == Message::Notice) + CtcpType ctcptype = messageType == Message::Notice ? CtcpReply : CtcpQuery; + + quint8 flags = (messageType == Message::Notice && !network()->isChannelName(target)) + ? Message::Redirected + : Message::None; - BufferInfo::Type bufferType = typeByTarget(target); - // extract tagged / extended data - while(dequotedMessage.contains(XDELIM)) { - if(dequotedMessage.indexOf(XDELIM) > 0) - emit displayMsg(messageType, bufferType, target, dequotedMessage.section(XDELIM,0,0), prefix); - // messages << dequotedMessage.section(XDELIM,0,0), prefix); - ctcp = XdelimDequote(dequotedMessage.section(XDELIM,1,1)); - dequotedMessage = dequotedMessage.section(XDELIM,2,2); + int xdelimPos = -1; + int xdelimEndPos = -1; + int spacePos = -1; + while((xdelimPos = dequotedMessage.indexOf(XDELIM)) != -1) { + if(xdelimPos > 0) + displayMsg(messageType, target, userDecode(target, dequotedMessage.left(xdelimPos)), prefix, flags); + + xdelimEndPos = dequotedMessage.indexOf(XDELIM, xdelimPos + 1); + + ctcp = xdelimDequote(dequotedMessage.mid(xdelimPos + 1, xdelimEndPos - xdelimPos - 1)); + dequotedMessage = dequotedMessage.mid(xdelimEndPos + 1); //dispatch the ctcp command - QString ctcpcmd = ctcp.section(' ', 0, 0); - QString ctcpparam = ctcp.section(' ', 1); + spacePos = ctcp.indexOf(' '); + QString ctcpcmd = userDecode(target, ctcp.left(spacePos)); + QString ctcpparam = userDecode(target, ctcp.mid(spacePos + 1)); handle(ctcpcmd, Q_ARG(CtcpType, ctcptype), Q_ARG(QString, prefix), Q_ARG(QString, target), Q_ARG(QString, ctcpparam)); } if(!dequotedMessage.isEmpty()) - emit displayMsg(messageType, bufferType, target, dequotedMessage, prefix); - + displayMsg(messageType, target, userDecode(target, dequotedMessage), prefix, flags); } -QString CtcpHandler::pack(QString ctcpTag, QString message) { +QByteArray CtcpHandler::pack(const QByteArray &ctcpTag, const QByteArray &message) { return XDELIM + ctcpTag + ' ' + message + XDELIM; } // TODO handle encodings correctly! -void CtcpHandler::query(QString bufname, QString ctcpTag, QString message) { - QStringList params; - params << bufname << pack(ctcpTag, message); - emit putCmd("PRIVMSG", serverEncode(params)); +void CtcpHandler::query(const QString &bufname, const QString &ctcpTag, const QString &message) { + QList params; + params << serverEncode(bufname) << pack(serverEncode(ctcpTag), userEncode(bufname, message)); + emit putCmd("PRIVMSG", params); } -void CtcpHandler::reply(QString bufname, QString ctcpTag, QString message) { - QStringList params; - params << bufname << pack(ctcpTag, message); - emit putCmd("NOTICE", serverEncode(params)); +void CtcpHandler::reply(const QString &bufname, const QString &ctcpTag, const QString &message) { + QList params; + params << serverEncode(bufname) << pack(serverEncode(ctcpTag), userEncode(bufname, message)); + emit putCmd("NOTICE", params); } //******************************/ // CTCP HANDLER //******************************/ -void CtcpHandler::handleAction(CtcpType ctcptype, QString prefix, QString target, QString param) { +void CtcpHandler::handleAction(CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m) { Q_UNUSED(ctcptype) emit displayMsg(Message::Action, typeByTarget(target), target, param, prefix); } -void CtcpHandler::handlePing(CtcpType ctcptype, QString prefix, QString target, QString param) { +void CtcpHandler::handlePing(CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m) { Q_UNUSED(target) if(ctcptype == CtcpQuery) { reply(nickFromMask(prefix), "PING", param); @@ -153,7 +161,7 @@ void CtcpHandler::handlePing(CtcpType ctcptype, QString prefix, QString target, } } -void CtcpHandler::handleVersion(CtcpType ctcptype, QString prefix, QString target, QString param) { +void CtcpHandler::handleVersion(CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m) { Q_UNUSED(target) if(ctcptype == CtcpQuery) { // FIXME use real Info about quassel :) @@ -166,7 +174,7 @@ void CtcpHandler::handleVersion(CtcpType ctcptype, QString prefix, QString targe } } -void CtcpHandler::defaultHandler(QString cmd, CtcpType ctcptype, QString prefix, QString target, QString param) { +void CtcpHandler::defaultHandler(const QString &cmd, CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m) { Q_UNUSED(ctcptype); Q_UNUSED(target); Q_UNUSED(param); diff --git a/src/core/ctcphandler.h b/src/core/ctcphandler.h index 59db0767..aa42bf9c 100644 --- a/src/core/ctcphandler.h +++ b/src/core/ctcphandler.h @@ -34,28 +34,26 @@ public: enum CtcpType {CtcpQuery, CtcpReply}; - void parse(Message::Type, QString prefix, QString target, QString message); + void parse(Message::Type, const QString &prefix, const QString &target, const QByteArray &message); - QString dequote(QString); - QString XdelimDequote(QString); + QByteArray dequote(const QByteArray &); + QByteArray xdelimDequote(const QByteArray &); - QString pack(QString ctcpTag, QString message); - void query(QString bufname, QString ctcpTag, QString message); - void reply(QString bufname, QString ctcpTag, QString message); + QByteArray pack(const QByteArray &ctcpTag, const QByteArray &message); + void query(const QString &bufname, const QString &ctcpTag, const QString &message); + void reply(const QString &bufname, const QString &ctcpTag, const QString &message); public slots: - void handleAction(CtcpType, QString prefix, QString target, QString param); - void handlePing(CtcpType, QString prefix, QString target, QString param); - void handleVersion(CtcpType, QString prefix, QString target, QString param); + void handleAction(CtcpType, const QString &prefix, const QString &target, const QString ¶m); + void handlePing(CtcpType, const QString &prefix, const QString &target, const QString ¶m); + void handleVersion(CtcpType, const QString &prefix, const QString &target, const QString ¶m); - void defaultHandler(QString cmd, CtcpType ctcptype, QString prefix, QString target, QString param); + void defaultHandler(const QString &cmd, CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m); private: - QString XDELIM; - QHash ctcpMDequoteHash; - QHash ctcpXDelimDequoteHash; - - + QByteArray XDELIM; + QHash ctcpMDequoteHash; + QHash ctcpXDelimDequoteHash; }; diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 9318f825..f3e6680e 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -32,8 +32,10 @@ #include -IrcServerHandler::IrcServerHandler(NetworkConnection *parent) : BasicHandler(parent) { - _whois = false; +IrcServerHandler::IrcServerHandler(NetworkConnection *parent) + : BasicHandler(parent), + _whois(false) +{ } IrcServerHandler::~IrcServerHandler() { @@ -123,19 +125,13 @@ void IrcServerHandler::defaultHandler(QString cmd, const QString &prefix, const emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" "), prefix); break; // Server error messages, display them in red. First param will be appended. - case 401: - { - // FIXME needs proper redirection + case 401: { QString target = params.takeFirst(); - BufferInfo::Type bufferType = network()->isChannelName(target) - ? BufferInfo::ChannelBuffer - : BufferInfo::QueryBuffer; - emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" ") + " " + target, prefix); - emit displayMsg(Message::Error, bufferType, target, params.join(" ") + " " + target, prefix); - break; + displayMsg(Message::Error, target, params.join(" ") + " " + target, prefix, Message::Redirected); + break; } - case 402: case 403: case 404: case 406: case 408: case 415: case 421: case 442: - { QString channelName = params.takeFirst(); + case 402: case 403: case 404: case 406: case 408: case 415: case 421: case 442: { + QString channelName = params.takeFirst(); emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", params.join(" ") + " " + channelName, prefix); break; } @@ -257,13 +253,16 @@ void IrcServerHandler::handleNotice(const QString &prefix, const QListcurrentServer().isEmpty() || network()->currentServer() == prefix) { emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", serverDecode(params[1]), prefix); return; } - QString target = serverDecode(params[0]); + // kick notices to the server buffer if they are directly addressed to us if(network()->isMyNick(target)) @@ -273,7 +272,7 @@ void IrcServerHandler::handleNotice(const QString &prefix, const QListctcpHandler()->parse(Message::Notice, sender, target, userDecode(sender, params[1])); + networkConnection()->ctcpHandler()->parse(Message::Notice, sender, target, params[1]); } void IrcServerHandler::handlePart(const QString &prefix, const QList ¶ms) { @@ -316,7 +315,7 @@ void IrcServerHandler::handlePrivmsg(const QString &prefix, const QList we let the ctcpHandler do the work - networkConnection()->ctcpHandler()->parse(Message::Plain, prefix, target, userDecode(ircuser->nick(), msg)); + networkConnection()->ctcpHandler()->parse(Message::Plain, prefix, target, msg); } void IrcServerHandler::handleQuit(const QString &prefix, const QList ¶ms) { -- 2.20.1