diff --git a/common/common.pro b/common/common.pro new file mode 100644 index 00000000..b4256651 --- /dev/null +++ b/common/common.pro @@ -0,0 +1,14 @@ +###################################################################### +# Automatically generated by qmake (2.01a) So. Okt 25 12:02:12 2009 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += protocol.h widget.h +SOURCES += main.cpp protocol.cpp widget.cpp + +CONFIG += qt debug diff --git a/common/main.cpp b/common/main.cpp new file mode 100644 index 00000000..866537ff --- /dev/null +++ b/common/main.cpp @@ -0,0 +1,17 @@ +#include +#include +#include "widget.h" + +int main(int argc, char *argv[]) +{ +// qInstallMsgHandler(myMessageOutput); + QApplication app(argc, argv); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + + Widget *widget = new Widget; + widget->show(); + + return app.exec(); +} + + diff --git a/common/protocol.cpp b/common/protocol.cpp new file mode 100644 index 00000000..43186ef0 --- /dev/null +++ b/common/protocol.cpp @@ -0,0 +1,55 @@ +#include "protocol.h" +#include +#include +#include + +Command::Command(const QString &_cmdName) + : cmdName(_cmdName) +{ + +} + +void Command::validateParameters() +{ +} + +bool Command::read(QXmlStreamReader &xml) +{ + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + qDebug() << "startElement: " << xml.name().toString(); + } else if (xml.isEndElement()) { + qDebug() << "endElement: " << xml.name().toString(); + if (xml.name() == cmdName) { + validateParameters(); + qDebug() << "FERTIG"; + deleteLater(); + return true; + } else { + QString tagName = xml.name().toString(); + if (!parameters.contains(tagName)) + qDebug() << "unrecognized attribute"; + else + parameters[tagName] = currentElementText; + } + } else if (xml.isCharacters() && !xml.isWhitespace()) { + currentElementText = xml.text().toString(); + qDebug() << "text: " << currentElementText; + } + } + return false; +} + +void Command::write(QXmlStreamWriter &xml) +{ + xml.writeStartElement(cmdName); + + QMapIterator i(parameters); + while (i.hasNext()) { + i.next(); + xml.writeTextElement(i.key(), i.value()); + } + + xml.writeEndElement(); +} diff --git a/common/protocol.h b/common/protocol.h new file mode 100644 index 00000000..4c92c3ba --- /dev/null +++ b/common/protocol.h @@ -0,0 +1,64 @@ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include +#include +#include + +class QXmlStreamReader; +class QXmlStreamWriter; + +class Command : public QObject { + Q_OBJECT +protected: + QString cmdName; + QMap parameters; + QString currentElementText; +public: + Command(const QString &_cmdName); + virtual bool read(QXmlStreamReader &xml); + virtual void write(QXmlStreamWriter &xml); + void validateParameters(); +}; + +class Command_Ping : public Command { +public: + Command_Ping() : Command("ping") { } +}; +class Command_ChatListChannels : public Command { +public: + Command_ChatListChannels() : Command("chat_list_channels") { } +}; +class Command_ChatJoinChannel : public Command { +private: + QString channel; +public: + Command_ChatJoinChannel(const QString &_channel = QString()) : Command("chat_join_channel"), channel(_channel) + { + parameters.insert("channel", channel); + } +}; +class Command_ChatLeaveChannel : public Command { +private: + QString channel; +public: + Command_ChatLeaveChannel(const QString &_channel = QString()) : Command("chat_leave_channel"), channel(_channel) + { + parameters.insert("channel", channel); + } +}; +class Command_ChatSay : public Command { +private: + QString channel; + QString message; +public: + Command_ChatSay(const QString &_channel = QString(), const QString &_message = QString()) : Command("chat_say"), channel(_channel), message(_message) + { + parameters.insert("channel", channel); + parameters.insert("message", message); + } +}; + + + +#endif diff --git a/common/protocol_info.dat b/common/protocol_info.dat new file mode 100644 index 00000000..7eb44b98 --- /dev/null +++ b/common/protocol_info.dat @@ -0,0 +1,29 @@ +0:login:Login:s,username:s,password +0:chat_list_channels:ChatListChannels +0:chat_join_channel:ChatJoinChannel:s,channel +1:chat_leave_channel:ChatLeaveChannel +1:chat_say:ChatSay:s,message +0:list_games:ListGames +0:create_game:CreateGame:s,description:s,password:i,max_players:b,spectators_allowed +0:join_game:JoinGame:i,game_id:s,password:b,spectator +2:leave_game:LeaveGame +2:say:Say:s,message +2:shuffle:Shuffle +2:roll_die:RollDie:i,sides +2:draw_cards:DrawCards:i,number +2:move_card:MoveCard:s,start_zone:i,card_id:s,target_zone:i,x:i,y:b,faceDown +2:create_token:CreateToken:s,zone:s,name:s,pt:i,x:i,y +2:create_arrow:CreateArrow:i,start_player_id:s,start_zone:i,start_card_id:i,target_player_id:s,target_player_zone:i,target_card_id:i,color +2:delete_arrow:DeleteArrow:i,arrow_id +2:set_card_attr:SetCardAttr:s,zone:i,card_id:s,attr_name:s,attr_value +2:ready_start:ReadyStart +2:inc_counter:IncCounter:i,counter_id:i,delta +2:add_counter:AddCounter:s,counter_name:i,color:i,radius:i,value +2:set_counter:SetCounter:i,counter_id:i,value +2:del_counter:DelCounter:i,counter_id +2:next_turn:NextTurn +2:set_active_phase:SetActivePhase:i,phase +2:dump_zone:DumpZone:i,player_id:s,zone_name:i,number_cards +2:stop_dump_zone:StopDumpZone:i,player_id:s,zone_name +2:dump_all:DumpAll +2:submit_deck:SubmitDeck \ No newline at end of file diff --git a/common/protocol_info.pl b/common/protocol_info.pl new file mode 100755 index 00000000..fd022a0f --- /dev/null +++ b/common/protocol_info.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl + +open(file, "protocol_info.dat"); +while () { + s/\s+$//; + @line = split(/:/); + $type = shift(@line); + if ($type == 0) { + $baseClass = 'Command'; + } elsif ($type == 1) { + $baseClass = 'ChatCommand'; + } else { + $baseClass = 'GameCommand'; + } + + $name1 = shift(@line); + $className = 'Command_' . shift(@line); + print "class $className : public $baseClass {\n" + . "private:\n"; + $paramStr1 = ''; + $paramStr2 = ''; + $paramStr3 = ''; + $paramStr4 = ''; + while ($param = shift(@line)) { + ($key, $value) = split(/,/, $param); + $prettyVarName = $value; + if (!($paramStr1 eq '')) { + $paramStr1 .= ', '; + } + $paramStr2 .= ", $prettyVarName(_$prettyVarName)"; + $paramStr3 .= "\t\tparameters.insert(\"$value\", $prettyVarName);\n"; + if ($key == 'b') { + $dataType = 'bool'; + $paramStr1 .= "bool _$prettyVarName = false"; + } elsif ($key == 's') { + $dataType = 'QString'; + $paramStr1 .= "const QString &_$prettyVarName = QString()"; + } elsif ($key == 'i') { + $dataType = 'int'; + $paramStr1 .= "int _$prettyVarName = -1"; + } + $first = substr($prettyVarName, 0, 1); + $first =~ tr/a-z/A-Z/; + $prettyVarName2 = $first . substr($prettyVarName, 1, length($prettyVarName)); + $paramStr4 .= "\t$dataType get$prettyVarName2() const { return $prettyVarName; }\n"; + print "\t$dataType $value;\n"; + } + print "public:\n"; + print "\t$className($paramStr1)\n\t\t: $baseClass(\"$name1\")$paramStr2\n" + . "\t{\n"; + print $paramStr3; + print "\t}\n"; + print $paramStr4; + print "};\n"; +} +close(file); diff --git a/common/widget.cpp b/common/widget.cpp new file mode 100644 index 00000000..07c938b5 --- /dev/null +++ b/common/widget.cpp @@ -0,0 +1,96 @@ +#include +#include +#include "widget.h" +#include "protocol.h" + +Widget::Widget() + : QMainWindow(), currentCommand(0) +{ + edit1 = new QTextEdit; + start = new QPushButton; + connect(start, SIGNAL(clicked()), this, SLOT(startClicked())); + + buffer = new QBuffer; + buffer->open(QIODevice::ReadWrite); + connect(buffer, SIGNAL(readyRead()), this, SLOT(updateEdit())); + + xmlWriter.setDevice(buffer); + xmlWriter.setAutoFormatting(true); + + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(edit1); + vbox->addWidget(start); + + QWidget *central = new QWidget; + central->setLayout(vbox); + setCentralWidget(central); +} + +void Widget::startClicked() +{ + currentCommand = 0; + xmlWriter.writeStartDocument(); + xmlWriter.writeStartElement("cockatrice_communication"); + + Command *test = new Command_Ping; + test->write(xmlWriter); + + Command *test2 = new Command_ChatLeaveChannel("foobar"); + test2->write(xmlWriter); + + Command *test3 = new Command_ChatSay("foobar", "Hallo, dies ist ein Test"); + test3->write(xmlWriter); +} + +bool Widget::readCurrentCommand() +{ + if (!currentCommand) + return false; + if (currentCommand->read(xmlReader)) { + qDebug() << "setting to 0"; + currentCommand = 0; + } + return true; +} + +void Widget::parseXml() +{ + if (readCurrentCommand()) + return; + + while (!xmlReader.atEnd()) { + xmlReader.readNext(); + if (xmlReader.isStartElement()) { + QString cmdStr = xmlReader.name().toString(); + qDebug() << "parseXml: startElement: " << cmdStr; + if (cmdStr == "ping") + currentCommand = new Command_Ping; + else if (cmdStr == "chat_leave_channel") + currentCommand = new Command_ChatLeaveChannel; + else if (cmdStr == "chat_say") + currentCommand = new Command_ChatSay; + else + qDebug() << "unrecognized command"; + readCurrentCommand(); + } + } +} + +void Widget::parseBuffer() +{ + xmlReader.clear(); + buffer->seek(0); + while (!buffer->atEnd()) { + QByteArray oneByte = buffer->read(1); + xmlReader.addData(oneByte); + parseXml(); + } +} + +void Widget::updateEdit() +{ + buffer->seek(0); + edit1->setText(buffer->readAll()); + + parseBuffer(); +} diff --git a/common/widget.h b/common/widget.h new file mode 100644 index 00000000..f6c22778 --- /dev/null +++ b/common/widget.h @@ -0,0 +1,33 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include +#include + +class QTextEdit; +class QPushButton; +class QBuffer; +class Command; + +class Widget : public QMainWindow { + Q_OBJECT +private: + QTextEdit *edit1; + QPushButton *start; + QBuffer *buffer; + QXmlStreamReader xmlReader; + QXmlStreamWriter xmlWriter; + + Command *currentCommand; + bool readCurrentCommand(); + void parseBuffer(); + void parseXml(); +private slots: + void startClicked(); + void updateEdit(); +public: + Widget(); +}; + +#endif