We have a working message parser now, and a framework for handler functions!
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 17 Oct 2006 08:17:20 +0000 (08:17 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 17 Oct 2006 08:17:20 +0000 (08:17 +0000)
14 files changed:
core/core.cpp
core/proxy.cpp
core/quassel.cpp
core/quassel.h
gui/channelwidget.cpp
main/main_core.cpp
main/main_mono.cpp
network/CMakeLists.txt
network/builtin_cmds.cpp
network/cmdcodes.h [moved from network/msgcodes.h with 67% similarity]
network/message.cpp
network/message.h
network/server.cpp
network/server.h

index 10c9d3d..f5c06fd 100644 (file)
 #include <QSettings>
 
 void Core::init() {
 #include <QSettings>
 
 void Core::init() {
-
+  Server::init();
 
 }
 
 void Core::run() {
 
 
 }
 
 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();
   connect(&server, SIGNAL(recvLine(const QString &)), this, SIGNAL(outputLine(const QString &)));
   //connect(
   server.start();
-  qDebug() << "Core running...";
-
   exec();
 }
 
   exec();
 }
 
index acf0f78..4e97362 100644 (file)
@@ -51,4 +51,4 @@ QVariant proxyConnect(uint func, QVariant arg) {
   }
   return 0;
 }
   }
   return 0;
 }
-*/
\ No newline at end of file
+*/
index f7fe6b3..b650b21 100644 (file)
 #include "quassel.h"
 #include "logger.h"
 #include "proxy.h"
 #include "quassel.h"
 #include "logger.h"
 #include "proxy.h"
-#include "messages.h"
 
 #include <QString>
 #include <QDomDocument>
 
 void Quassel::init() {
 
 #include <QString>
 #include <QDomDocument>
 
 void Quassel::init() {
+  Core::init();
+
   //initIconMap();
   //initIconMap();
-  Message::init();
 }
 
 void Quassel::setLogger(Logger *) {
 }
 
 void Quassel::setLogger(Logger *) {
index 08a72d5..3b7b5f7 100644 (file)
@@ -22,9 +22,9 @@
 #define _QUASSEL_H_
 
 class Logger;
 #define _QUASSEL_H_
 
 class Logger;
-class QString;
 
 #include <QHash>
 
 #include <QHash>
+#include <QString>
 
 
 /**
 
 
 /**
@@ -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
 #endif
index bde11c7..320cef3 100644 (file)
@@ -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();
   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();
 }
 }
 
 void ChannelWidget::enterPressed() {
   emit inputLine(ui.lineEdit->text());
   ui.lineEdit->clear();
 }
-
-  
\ No newline at end of file
index f8e6630..2526485 100644 (file)
@@ -27,7 +27,6 @@
 
 int main(int argc, char **argv) {
 
 
 int main(int argc, char **argv) {
 
-  Core::init();
   Quassel::init();
   Logger *logger = new Logger();
   Quassel::setLogger(logger);
   Quassel::init();
   Logger *logger = new Logger();
   Quassel::setLogger(logger);
index f3f4ab9..b935a12 100644 (file)
@@ -28,8 +28,6 @@
 #include "proxy.h"
 
 #include "mainwin.h"
 #include "proxy.h"
 
 #include "mainwin.h"
-#include "messages.h"
-#include "server.h"
 
 int main(int argc, char **argv) {
 
 
 int main(int argc, char **argv) {
 
@@ -37,10 +35,6 @@ int main(int argc, char **argv) {
   Logger *logger = new Logger();
   Quassel::setLogger(logger);
 
   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");
   QApplication app(argc, argv);
 
   QApplication::setOrganizationDomain("quassel-irc.org");
index 6130d18..4dbbcfb 100644 (file)
@@ -1,5 +1,5 @@
 SET(network_SRCS message.cpp builtin_cmds.cpp builtin_handlers.cpp server.cpp)
 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})
 SET(network_MOCS server.h)
 
 QT4_WRAP_CPP(_MOC ${network_MOCS})
index 5bc3a8d..7bbe48c 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <QtGlobal>
 #include "message.h"
 
 #include <QtGlobal>
 #include "message.h"
-
+#include "cmdcodes.h"
 
 /** This macro marks strings as translateable for Qt's linguist tools */
 #define _(str) QT_TR_NOOP(str)
 
 /** This macro marks strings as translateable for Qt's linguist tools */
 #define _(str) QT_TR_NOOP(str)
 /** Set handler addresses to 0 to use the default (server) handler. */
 
 BuiltinCmd builtins[] = {
 /** 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 }
 };
 
 
 };
 
 
similarity index 67%
rename from network/msgcodes.h
rename to network/cmdcodes.h
index e494da2..787a673 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
  *   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 {
 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
 };
 
 
 };
 
 
index d99e5eb..2bfd915 100644 (file)
@@ -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);
     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) {
   } else {
     int t = cmd.toInt();
     if(t) {
-      type = t;
+      cmdCode = t;
       recvHandler = defaultRecvHandler;
       sendHandler = defaultSendHandler;
     } else {
       // Unknown cmd!
       qWarning() << "Unknown command: " << cmd;
       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;
   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;
     c.cmd = builtins[i].cmd.toUpper();
     c.cmdDescr = builtins[i].cmdDescr;
     c.args = builtins[i].args;
index 2620d7c..83c24b3 100644 (file)
@@ -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 {
  * 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;
   QString cmd;
   QString cmdDescr;
   QString args;
@@ -64,7 +64,7 @@ class Message {
 
     inline Server * getServer() { return server; }
     inline Buffer * getBuffer() { return buffer; }
 
     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; }
     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;
   protected:
     Server *server;
     Buffer *buffer;
-    int type;
+    int cmdCode;
     QString prefix;
     QString cmd;
     QStringList params;
     QString prefix;
     QString cmd;
     QStringList params;
@@ -92,6 +92,7 @@ class Message {
  *  command hash.
  */
 struct BuiltinCmd {
  *  command hash.
  */
 struct BuiltinCmd {
+  int cmdCode;
   QString cmd;
   QString cmdDescr;
   QString args;
   QString cmd;
   QString cmdDescr;
   QString args;
index c253ab1..d55a9a7 100644 (file)
@@ -18,7 +18,9 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include "quassel.h"
 #include "server.h"
 #include "server.h"
+#include "cmdcodes.h"
 
 Server::Server() {
   socket = new QTcpSocket();
 
 Server::Server() {
   socket = new QTcpSocket();
@@ -61,7 +63,7 @@ void Server::disconnectFromIrc( ) {
 }
 
 void Server::putRawLine( const QString &s ) {
 }
 
 void Server::putRawLine( const QString &s ) {
-  qDebug() << "Raw line: " << s;
+  qDebug() << "Sent: " << s;
   stream << s << "\r\n" << flush;
   //Message::createFromServerString(this, 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);
     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;
   }
 }
     delete msg;
   }
 }
@@ -96,13 +102,50 @@ void Server::socketStateChanged(QAbstractSocket::SocketState state) {
   qDebug() << "Socket state changed: " << 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) {
 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 <server1> [<server2>]
+        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();
+
+}
index b213111..5eecb31 100644 (file)
@@ -24,6 +24,7 @@
 #include <QtCore>
 #include <QtNetwork>
 
 #include <QtCore>
 #include <QtNetwork>
 
+#include "quassel.h"
 #include "message.h"
 
 #define DEFAULT_PORT 6667
 #include "message.h"
 
 #define DEFAULT_PORT 6667
@@ -71,10 +72,19 @@ class Server : public QThread {
     QTextStream stream;
 
     void handleServerMsg(Message *);
     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); }
 
     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 {};
 };
 
 class Buffer {};