From 84516825d33a1b448a894eaf2e804cabb032f5f1 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 17 Oct 2006 08:17:20 +0000 Subject: [PATCH] We have a working message parser now, and a framework for handler functions! --- core/core.cpp | 5 +- core/proxy.cpp | 2 +- core/quassel.cpp | 4 +- core/quassel.h | 12 ++++- gui/channelwidget.cpp | 4 +- main/main_core.cpp | 1 - main/main_mono.cpp | 6 --- network/CMakeLists.txt | 2 +- network/builtin_cmds.cpp | 79 +++++++++++++++++++++++++++--- network/{msgcodes.h => cmdcodes.h} | 18 ++++--- network/message.cpp | 7 +-- network/message.h | 7 +-- network/server.cpp | 53 ++++++++++++++++++-- network/server.h | 12 ++++- 14 files changed, 167 insertions(+), 45 deletions(-) rename network/{msgcodes.h => cmdcodes.h} (67%) diff --git a/core/core.cpp b/core/core.cpp index 10c9d3d6..f5c06fd6 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -24,18 +24,15 @@ #include void Core::init() { - + Server::init(); } void Core::run() { - connect(this, SIGNAL(connectToIrc( const QString&, quint16 )), &server, SLOT(connectToIrc( const QString&, quint16 ))); connect(&server, SIGNAL(recvLine(const QString &)), this, SIGNAL(outputLine(const QString &))); //connect( server.start(); - qDebug() << "Core running..."; - exec(); } diff --git a/core/proxy.cpp b/core/proxy.cpp index acf0f78c..4e97362f 100644 --- a/core/proxy.cpp +++ b/core/proxy.cpp @@ -51,4 +51,4 @@ QVariant proxyConnect(uint func, QVariant arg) { } return 0; } -*/ \ No newline at end of file +*/ diff --git a/core/quassel.cpp b/core/quassel.cpp index f7fe6b36..b650b210 100644 --- a/core/quassel.cpp +++ b/core/quassel.cpp @@ -21,14 +21,14 @@ #include "quassel.h" #include "logger.h" #include "proxy.h" -#include "messages.h" #include #include void Quassel::init() { + Core::init(); + //initIconMap(); - Message::init(); } void Quassel::setLogger(Logger *) { diff --git a/core/quassel.h b/core/quassel.h index 08a72d50..3b7b5f7e 100644 --- a/core/quassel.h +++ b/core/quassel.h @@ -22,9 +22,9 @@ #define _QUASSEL_H_ class Logger; -class QString; #include +#include /** @@ -49,4 +49,14 @@ class Quassel { }; +class Exception { + public: + Exception(QString msg = "Unknown Exception") : _msg(msg) {}; + virtual inline QString msg() { return _msg; } + + protected: + QString _msg; + +}; + #endif diff --git a/gui/channelwidget.cpp b/gui/channelwidget.cpp index bde11c72..320cef34 100644 --- a/gui/channelwidget.cpp +++ b/gui/channelwidget.cpp @@ -44,12 +44,10 @@ ChannelWidget::ChannelWidget(QWidget *parent) : QWidget(parent) { connect(ui.lineEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed())); connect(this, SIGNAL(inputLine( const QString& )), &core, SLOT(inputLine( const QString& ))); core.start(); - core.connectToIrc("irc.quakenet.org"); + core.connectToIrc("irc.quakenet.org", 6668); } void ChannelWidget::enterPressed() { emit inputLine(ui.lineEdit->text()); ui.lineEdit->clear(); } - - \ No newline at end of file diff --git a/main/main_core.cpp b/main/main_core.cpp index f8e6630b..25264857 100644 --- a/main/main_core.cpp +++ b/main/main_core.cpp @@ -27,7 +27,6 @@ int main(int argc, char **argv) { - Core::init(); Quassel::init(); Logger *logger = new Logger(); Quassel::setLogger(logger); diff --git a/main/main_mono.cpp b/main/main_mono.cpp index f3f4ab98..b935a128 100644 --- a/main/main_mono.cpp +++ b/main/main_mono.cpp @@ -28,8 +28,6 @@ #include "proxy.h" #include "mainwin.h" -#include "messages.h" -#include "server.h" int main(int argc, char **argv) { @@ -37,10 +35,6 @@ int main(int argc, char **argv) { Logger *logger = new Logger(); Quassel::setLogger(logger); - //Message *m = new Message("admin"); - //m->*(m->getCmdHandler())(QStringList("")); - //(m->*(m->getCmdHandler()))(QStringList()); - QApplication app(argc, argv); QApplication::setOrganizationDomain("quassel-irc.org"); diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt index 6130d186..4dbbcfb1 100644 --- a/network/CMakeLists.txt +++ b/network/CMakeLists.txt @@ -1,5 +1,5 @@ SET(network_SRCS message.cpp builtin_cmds.cpp builtin_handlers.cpp server.cpp) -SET(network_HDRS message.h msgcodes.h) +SET(network_HDRS message.h cmdcodes.h) SET(network_MOCS server.h) QT4_WRAP_CPP(_MOC ${network_MOCS}) diff --git a/network/builtin_cmds.cpp b/network/builtin_cmds.cpp index 5bc3a8d3..7bbe48c4 100644 --- a/network/builtin_cmds.cpp +++ b/network/builtin_cmds.cpp @@ -20,7 +20,7 @@ #include #include "message.h" - +#include "cmdcodes.h" /** This macro marks strings as translateable for Qt's linguist tools */ #define _(str) QT_TR_NOOP(str) @@ -35,12 +35,79 @@ /** Set handler addresses to 0 to use the default (server) handler. */ BuiltinCmd builtins[] = { - { _("admin"), _("Get information about the administrator of a server."), - _("[server]"), _("server: Server"), - 0, 0 }, - + { CMD_ADMIN, "admin", _("Get information about the administrator of a server."), + _("[server]"), _("server: Server"), 0, 0 }, + { CMD_AME, "ame", "", "", "", 0, 0 }, + { CMD_AMSG, "amsg", _("Send message to all channels of all connected servers."), + _("message"), _("message: Message to send"), 0, 0 }, + { CMD_AWAY, "away", _("Toggle away status."), + _("[-all] [message]"), _(" -all: Toggle status on all connected servers\n" + "message: Away message (away status is removed if no message is given)"), 0, 0 }, + { CMD_BAN, "ban", _("Ban a nickname or hostmask."), + _("[channel] [nick [nick ...]]"), _("channel: Channel for ban (current of empty)\n" + " nick: Nickname or hostmask. If no nicknames are given, /ban displays the current banlist."), 0, 0 }, + { CMD_CTCP, "ctcp", _("Send a CTCP message (Client-To-Client Protocol)"), + _("target type [args]"), _("target: Nick or channel to send CTCP to\n" + " type: CTCP Type (e.g. VERSION, PING, CHAT...)\n" + " args: Arguments for CTCP"), 0, 0 }, + { CMD_CYCLE, "cycle", "", "", "", 0, 0 }, + { CMD_DEHALFOP, "dehalfop", "", "", "", 0, 0 }, + { CMD_DEOP, "deop", "", "", "", 0, 0 }, + { CMD_DEVOICE, "devoice", "", "", "", 0, 0 }, + { CMD_DIE, "die", "", "", "", 0, 0 }, + { CMD_ERROR, "error", "", "", "", 0, 0 }, + { CMD_HALFOP, "halfop", "", "", "", 0, 0 }, + { CMD_INFO, "info", "", "", "", 0, 0 }, + { CMD_INVITE, "invite", "", "", "", 0, 0 }, + { CMD_ISON, "ison", "", "", "", 0, 0 }, + { CMD_JOIN, "join", "", "", "", 0, 0 }, + { CMD_KICK, "kick", "", "", "", 0, 0 }, + { CMD_KICKBAN, "kickban", "", "", "", 0, 0 }, + { CMD_KILL, "kill", "", "", "", 0, 0 }, + { CMD_LINKS, "links", "", "", "", 0, 0 }, + { CMD_LIST, "list", "", "", "", 0, 0 }, + { CMD_LUSERS, "lusers", "", "", "", 0, 0 }, + { CMD_ME, "me", "", "", "", 0, 0 }, + { CMD_MODE, "mode", "", "", "", 0, 0 }, + { CMD_MOTD, "motd", "", "", "", 0, 0 }, + { CMD_MSG, "msg", "", "", "", 0, 0 }, + { CMD_NAMES, "names", "", "", "", 0, 0 }, + { CMD_NICK, "nick", "", "", "", 0, 0 }, + { CMD_NOTICE, "notice", _("Send notice message to user."), + _("nick message"), _(" nick: user to send notice to\n" + "message: text to send"), 0, 0 }, + { CMD_OP, "op", "", "", "", 0, 0 }, + { CMD_OPER, "oper", "", "", "", 0, 0 }, + { CMD_PART, "part", "", "", "", 0, 0 }, + { CMD_PING, "ping", _("Ping a server."), + _("server1 [server2]"), _("server1: Server to ping\nserver2: Forward ping to this server"), 0, 0 }, + { CMD_PONG, "pong", "", "", "", 0, 0 }, + { CMD_PRIVMSG, "privmsg", "", "", "", 0, 0 }, + { CMD_QUERY, "query", "", "", "", 0, 0 }, + { CMD_QUIT, "quit", "", "", "", 0, 0 }, + { CMD_QUOTE, "quote", "", "", "", 0, 0 }, + { CMD_REHASH, "rehash", "", "", "", 0, 0 }, + { CMD_RESTART, "restart", "", "", "", 0, 0 }, + { CMD_SERVICE, "service", "", "", "", 0, 0 }, + { CMD_SERVLIST, "servlist", "", "", "", 0, 0 }, + { CMD_SQUERY, "squery", "", "", "", 0, 0 }, + { CMD_SQUIT, "squit", "", "", "", 0, 0 }, + { CMD_STATS, "stats", "", "", "", 0, 0 }, + { CMD_SUMMON, "summon", "", "", "", 0, 0 }, + { CMD_TIME, "time", "", "", "", 0, 0 }, + { CMD_TOPIC, "topic", "", "", "", 0, 0 }, + { CMD_TRACE, "trace", "", "", "", 0, 0 }, + { CMD_UNBAN, "unban", "", "", "", 0, 0 }, + { CMD_USERHOST, "userhost", "", "", "", 0, 0 }, + { CMD_USERS, "users", "", "", "", 0, 0 }, + { CMD_VERSION, "version", "", "", "", 0, 0 }, + { CMD_VOICE, "voice", "", "", "", 0, 0 }, + { CMD_WALLOPS, "wallops", "", "", "", 0, 0 }, + { CMD_WHO, "who", "", "", "", 0, 0 }, + { CMD_WHOIS, "whois", "", "", "", 0, 0 }, + { CMD_WHOWAS, "whowas", "", "", "", 0, 0 }, - { 0, 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, 0, 0, 0 } }; diff --git a/network/msgcodes.h b/network/cmdcodes.h similarity index 67% rename from network/msgcodes.h rename to network/cmdcodes.h index e494da25..787a6735 100644 --- a/network/msgcodes.h +++ b/network/cmdcodes.h @@ -18,16 +18,18 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _MSGCODES_H_ -#define _MSGCODES_H_ +#ifndef _CMDCODES_H_ +#define _CMDCODES_H_ -/** Contains numeric codes for the named commands. */ +/** Contains numeric codes for the named commands. These are _negative_ in the message object. */ enum CmdCodes { - CMD_ADMIN = 1, CMD_AMSG, CMD_AWAY, CMD_BAN, CMD_CTCP, CMD_CYCLE, CMD_DEHALFOP, CMD_DEOP, CMD_DEVOICE, - CMD_HALFOP, CMD_INFO, CMD_INVITE, CMD_JOIN, CMD_KICK, CMD_KICKBAN, CMD_LIST, CMD_LUSERS, CMD_ME, - CMD_MODE, CMD_MOTD, CMD_MSG, CMD_NAMES, CMD_NICK, CMD_NOTICE, CMD_OP, CMD_PART, CMD_PING, CMD_PONG, - CMD_PRIVMSG, CMD_QUERY, CMD_QUIT, CMD_QUOTE, CMD_STATS, CMD_TIME, CMD_TOPIC, CMD_UNBAN, CMD_USERHOST, - CMD_USERS, CMD_VERSION, CMD_VOICE, CMD_WALLOPS, CMD_WHO, CMD_WHOIS, CMD_WHOWAS + CMD_ADMIN = 1, CMD_AME, CMD_AMSG, CMD_AWAY, CMD_BAN, CMD_CTCP, CMD_CYCLE, CMD_DEHALFOP, CMD_DEOP, CMD_DEVOICE, + CMD_DIE, CMD_ERROR, CMD_HALFOP, CMD_INFO, CMD_INVITE, CMD_ISON, CMD_JOIN, CMD_KICK, CMD_KICKBAN, CMD_KILL, CMD_LINKS, + CMD_LIST, CMD_LUSERS, CMD_ME, CMD_MODE, CMD_MOTD, CMD_MSG, CMD_NAMES, CMD_NICK, CMD_NOTICE, CMD_OP, CMD_OPER, + CMD_PART, CMD_PING, CMD_PONG, CMD_PRIVMSG, CMD_QUERY, CMD_QUIT, CMD_QUOTE, CMD_REHASH, CMD_RESTART, CMD_SERVICE, + CMD_SERVLIST, CMD_SQUERY, CMD_SQUIT, CMD_STATS, CMD_SUMMON, CMD_TIME, CMD_TOPIC, CMD_TRACE, CMD_UNBAN, CMD_USERHOST, + CMD_USERS, CMD_VERSION, CMD_VOICE, CMD_WALLOPS, CMD_WHO, CMD_WHOIS, CMD_WHOWAS, + CMD_USERDEFINED }; diff --git a/network/message.cpp b/network/message.cpp index d99e5ebc..2bfd915d 100644 --- a/network/message.cpp +++ b/network/message.cpp @@ -35,17 +35,17 @@ Message::Message(Server *srv, Buffer *buf, QString _cmd, QString _prefix, QStrin CmdType c = cmdTypes[cmd]; recvHandler = ( c.recvHandler ? c.recvHandler : defaultRecvHandler); sendHandler = ( c.sendHandler ? c.sendHandler : defaultSendHandler); - type = - c.type; + cmdCode = - c.cmdCode; // named commands have a _negative_ code! } else { int t = cmd.toInt(); if(t) { - type = t; + cmdCode = t; recvHandler = defaultRecvHandler; sendHandler = defaultSendHandler; } else { // Unknown cmd! qWarning() << "Unknown command: " << cmd; - type = 0; + cmdCode = 0; } } } @@ -58,6 +58,7 @@ void Message::init(recvHandlerType _r, sendHandlerType _s) { for(int i = 0; ; i++) { if(builtins[i].cmd.isEmpty()) break; CmdType c; + c.cmdCode = builtins[i].cmdCode; c.cmd = builtins[i].cmd.toUpper(); c.cmdDescr = builtins[i].cmdDescr; c.args = builtins[i].args; diff --git a/network/message.h b/network/message.h index 2620d7ce..83c24b3b 100644 --- a/network/message.h +++ b/network/message.h @@ -37,7 +37,7 @@ typedef void (*recvHandlerType)(Message *); // handler for incoming * Most of these are defined at compile time, but more may be added at runtime. */ struct CmdType { - int type; + int cmdCode; QString cmd; QString cmdDescr; QString args; @@ -64,7 +64,7 @@ class Message { inline Server * getServer() { return server; } inline Buffer * getBuffer() { return buffer; } - inline int getType() { return type; } + inline int getCmdCode() { return cmdCode; } inline QString getPrefix() { return prefix; } inline QString getCmd() { return cmd; } inline QStringList getParams() { return params; } @@ -74,7 +74,7 @@ class Message { protected: Server *server; Buffer *buffer; - int type; + int cmdCode; QString prefix; QString cmd; QStringList params; @@ -92,6 +92,7 @@ class Message { * command hash. */ struct BuiltinCmd { + int cmdCode; QString cmd; QString cmdDescr; QString args; diff --git a/network/server.cpp b/network/server.cpp index c253ab1a..d55a9a71 100644 --- a/network/server.cpp +++ b/network/server.cpp @@ -18,7 +18,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include "quassel.h" #include "server.h" +#include "cmdcodes.h" Server::Server() { socket = new QTcpSocket(); @@ -61,7 +63,7 @@ void Server::disconnectFromIrc( ) { } void Server::putRawLine( const QString &s ) { - qDebug() << "Raw line: " << s; + qDebug() << "Sent: " << s; stream << s << "\r\n" << flush; //Message::createFromServerString(this, s); } @@ -72,7 +74,11 @@ void Server::socketHasData( ) { qDebug() << "Read: " << s; emit recvRawServerMsg(s); Message *msg = Message::createFromServerString(this, s); - if(msg) handleServerMsg(msg); + if(msg) { + try { handleServerMsg(msg); } catch(Exception e) { + emit recvLine(e.msg() + "\n"); + } + } delete msg; } } @@ -96,13 +102,50 @@ void Server::socketStateChanged(QAbstractSocket::SocketState state) { qDebug() << "Socket state changed: " << state; } +/** Handle a message sent by the IRC server that does not have a custom handler. */ void Server::handleServerMsg(Message *msg) { - - + int cmdCode = msg->getCmdCode(); + QString prefix = msg->getPrefix(); + QStringList params = msg->getParams(); + if(cmdCode < 0) { + switch(-cmdCode) { + case CMD_PING: + // PING [] + if(params.size() == 1) { + putRawLine(QString("PONG :") + params[0]); + } else if(params.size() == 2) { + putRawLine(QString("PONG ") + params[0] + " :" + params[1]); + } else throw ParseError(msg); + break; + + default: + throw Exception(QString("No handler installed for command: ") + msg->getCmd() + " " + msg->getParams().join(" ")); + } + } else if(msg->getCmdCode() > 0) { + switch(msg->getCmdCode()) { + + default: + // + throw Exception(msg->getCmd() + " " + msg->getParams().join(" ")); + } + + } else { + throw UnknownCmdError(msg); + } } -void Server::handleUserMsg(Message *msg) { +QString Server::handleUserMsg(Message *msg) { + + return ""; +} +/* Exception classes for message handling */ +Server::ParseError::ParseError(Message *msg) { + _msg = QString("Command Parse Error: ") + msg->getCmd() + msg->getParams().join(" "); } +Server::UnknownCmdError::UnknownCmdError(Message *msg) { + _msg = QString("Unknown Command: ") + msg->getCmd(); + +} diff --git a/network/server.h b/network/server.h index b2131112..5eecb31b 100644 --- a/network/server.h +++ b/network/server.h @@ -24,6 +24,7 @@ #include #include +#include "quassel.h" #include "message.h" #define DEFAULT_PORT 6667 @@ -71,10 +72,19 @@ class Server : public QThread { QTextStream stream; void handleServerMsg(Message *); - void handleUserMsg(Message *); + QString handleUserMsg(Message *); static inline void dispatchServerMsg(Message *msg) { msg->getServer()->handleServerMsg(msg); } static inline void dispatchUserMsg(Message *msg) { msg->getServer()->handleUserMsg(msg); } + class ParseError : public Exception { + public: + ParseError(Message *msg); + }; + + class UnknownCmdError : public Exception { + public: + UnknownCmdError(Message *msg); + }; }; class Buffer {}; -- 2.20.1