From d3114fafbf413618e2f2006114431714c5199da3 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Wed, 18 Nov 2009 19:59:03 +0100 Subject: [PATCH] decklist transfer code --- cockatrice/cockatrice.pro | 4 +- common/decklist.cpp | 40 +++++---- common/decklist.h | 1 + common/protocol.cpp | 108 ++++++++++++++++++++++- common/protocol.h | 48 +++++++++- common/protocol_datastructures.h | 2 +- servatrice/servatrice.pro | 2 + servatrice/src/serversocketinterface.cpp | 77 ++++++++++++++-- servatrice/src/serversocketinterface.h | 2 +- 9 files changed, 248 insertions(+), 36 deletions(-) diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 38e8bd78..c2533b8e 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -33,7 +33,6 @@ HEADERS += src/counter.h \ src/zoneviewlayout.h \ src/carddatabasemodel.h \ src/window_deckeditor.h \ - src/decklist.h \ src/setsmodel.h \ src/window_sets.h \ src/abstractgraphicsitem.h \ @@ -45,6 +44,7 @@ HEADERS += src/counter.h \ src/tab_chatchannel.h \ src/tab_game.h \ src/tab_supervisor.h \ + ../common/decklist.h \ ../common/protocol.h \ ../common/protocol_items.h \ ../common/protocol_datastructures.h @@ -76,7 +76,6 @@ SOURCES += src/counter.cpp \ src/zoneviewlayout.cpp \ src/carddatabasemodel.cpp \ src/window_deckeditor.cpp \ - src/decklist.cpp \ src/setsmodel.cpp \ src/window_sets.cpp \ src/abstractgraphicsitem.cpp \ @@ -88,6 +87,7 @@ SOURCES += src/counter.cpp \ src/tab_chatchannel.cpp \ src/tab_game.cpp \ src/tab_supervisor.cpp \ + ../common/decklist.cpp \ ../common/protocol.cpp \ ../common/protocol_items.cpp diff --git a/common/decklist.cpp b/common/decklist.cpp index 9512871e..c7c57207 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -4,8 +4,8 @@ #include #include #include +#include #include "decklist.h" -#include "carddatabase.h" AbstractDecklistNode::AbstractDecklistNode(InnerDecklistNode *_parent) : parent(_parent), currentItem(0) @@ -185,7 +185,7 @@ bool DeckList::readElement(QXmlStreamReader *xml) if (currentZone) { if (currentZone->readElement(xml)) currentZone = 0; - return true; + return false; } if (xml->isEndElement()) { @@ -193,17 +193,17 @@ bool DeckList::readElement(QXmlStreamReader *xml) name = currentElementText; else if (xml->name() == "comments") comments = currentElementText; - else - return false; + else if (xml->name() == "cockatrice_deck") { + qDebug() << "deck finished!"; + return true; + } currentElementText.clear(); } else if (xml->isStartElement() && (xml->name() == "zone")) currentZone = new InnerDecklistNode(xml->attributes().value("name").toString(), root); else if (xml->isCharacters() && !xml->isWhitespace()) currentElementText = xml->text().toString(); - else - return false; - return true; + return false; } void DeckList::writeElement(QXmlStreamWriter *xml) @@ -219,25 +219,29 @@ void DeckList::writeElement(QXmlStreamWriter *xml) xml->writeEndElement(); // cockatrice_deck } -bool DeckList::loadFromFile_Native(QIODevice *device) +bool DeckList::loadFromXml(QXmlStreamReader *xml) { - QXmlStreamReader xml(device); - while (!xml.atEnd()) { - xml.readNext(); - if (xml.isStartElement()) { - if (xml.name() != "cockatrice_deck") + while (!xml->atEnd()) { + xml->readNext(); + if (xml->isStartElement()) { + if (xml->name() != "cockatrice_deck") return false; - while (!xml.atEnd()) { - xml.readNext(); - if (!readElement(&xml)) - if (xml.isEndElement() && (xml.name() == "cockatrice_deck")) - return true; + while (!xml->atEnd()) { + xml->readNext(); + if (readElement(xml)) + return true; } } } return false; } +bool DeckList::loadFromFile_Native(QIODevice *device) +{ + QXmlStreamReader xml(device); + return loadFromXml(&xml); +} + bool DeckList::saveToFile_Native(QIODevice *device) { QXmlStreamWriter xml(device); diff --git a/common/decklist.h b/common/decklist.h index 5e7765a0..cabade83 100644 --- a/common/decklist.h +++ b/common/decklist.h @@ -103,6 +103,7 @@ public: bool readElement(QXmlStreamReader *xml); void writeElement(QXmlStreamWriter *xml); + bool loadFromXml(QXmlStreamReader *xml); bool loadFromFile_Native(QIODevice *device); bool saveToFile_Native(QIODevice *device); diff --git a/common/protocol.cpp b/common/protocol.cpp index 0ed78649..70b81cb2 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -3,6 +3,7 @@ #include #include "protocol.h" #include "protocol_items.h" +#include "decklist.h" QHash ProtocolItem::itemNameHash; @@ -69,6 +70,7 @@ void ProtocolItem::initializeHash() itemNameHash.insert("resp", ProtocolResponse::newItem); ProtocolResponse::initializeHash(); itemNameHash.insert("respdeck_list", Response_DeckList::newItem); + itemNameHash.insert("respdeck_download", Response_DeckDownload::newItem); itemNameHash.insert("generic_eventlist_games", Event_ListGames::newItem); itemNameHash.insert("generic_eventlist_chat_channels", Event_ListChatChannels::newItem); @@ -99,6 +101,49 @@ void Command::processResponse(ProtocolResponse *response) emit finished(response->getResponseCode()); } +Command_DeckUpload::Command_DeckUpload(int _cmdId, DeckList *_deck, const QString &_path) + : Command("deck_upload", _cmdId), deck(_deck), path(_path), readFinished(false) +{ + setParameter("path", path); +} + +Command_DeckUpload::~Command_DeckUpload() +{ + delete deck; +} + +void Command_DeckUpload::extractParameters() +{ + Command::extractParameters(); + + path = parameters["path"]; +} + +bool Command_DeckUpload::readElement(QXmlStreamReader *xml) +{ + if (readFinished) + return false; + + if (!deck) { + if (xml->isStartElement() && (xml->name() == "cockatrice_deck")) { + deck = new DeckList; + return true; + } + return false; + } + + if (deck->readElement(xml)) + readFinished = true; + return true; +} + +void Command_DeckUpload::writeElement(QXmlStreamWriter *xml) +{ + if (deck) + deck->writeElement(xml); +} + + QHash ProtocolResponse::responseHash; ProtocolResponse::ProtocolResponse(int _cmdId, ResponseCode _responseCode, const QString &_itemName) @@ -180,7 +225,7 @@ void Response_DeckList::Directory::writeElement(QXmlStreamWriter *xml) } Response_DeckList::Response_DeckList(int _cmdId, ResponseCode _responseCode, Directory *_root) - : ProtocolResponse(_cmdId, _responseCode, "deck_list"), root(_root) + : ProtocolResponse(_cmdId, _responseCode, "deck_list"), root(_root), readFinished(false) { } @@ -191,13 +236,20 @@ Response_DeckList::~Response_DeckList() bool Response_DeckList::readElement(QXmlStreamReader *xml) { + if (readFinished) + return false; + if (!root) { - if (xml->isStartElement() && (xml->name() == "directory")) + if (xml->isStartElement() && (xml->name() == "directory")) { root = new Directory; + return true; + } return false; } - return !root->readElement(xml); + if (root->readElement(xml)) + readFinished = true; + return true; } void Response_DeckList::writeElement(QXmlStreamWriter *xml) @@ -205,6 +257,56 @@ void Response_DeckList::writeElement(QXmlStreamWriter *xml) root->writeElement(xml); } +Response_DeckDownload::Response_DeckDownload(int _cmdId, ResponseCode _responseCode, DeckList *_deck) + : ProtocolResponse(_cmdId, _responseCode, "deck_download"), deck(_deck), readFinished(false) +{ +} + +Response_DeckDownload::~Response_DeckDownload() +{ + delete deck; +} + +bool Response_DeckDownload::readElement(QXmlStreamReader *xml) +{ + if (readFinished) + return false; + + if (!deck) { + if (xml->isStartElement() && (xml->name() == "cockatrice_deck")) { + deck = new DeckList; + return true; + } + return false; + } + + if (deck->readElement(xml)) + readFinished = true; + return true; +} + +void Response_DeckDownload::writeElement(QXmlStreamWriter *xml) +{ + if (deck) + deck->writeElement(xml); +} + +Response_DeckUpload::Response_DeckUpload(int _cmdId, ResponseCode _responseCode, int _deckId) + : ProtocolResponse(_cmdId, _responseCode, "deck_upload"), deckId(_deckId) +{ + setParameter("deck_id", deckId); +} + +void Response_DeckUpload::extractParameters() +{ + ProtocolResponse::extractParameters(); + + bool ok; + deckId = parameters["deck_id"].toInt(&ok); + if (!ok) + deckId = -1; +} + GenericEvent::GenericEvent(const QString &_eventName) : ProtocolItem(_eventName) { diff --git a/common/protocol.h b/common/protocol.h index 8b43f943..238d4ba9 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -14,13 +14,16 @@ class QXmlStreamWriter; class QXmlStreamAttributes; class ProtocolResponse; +class DeckList; enum ItemId { ItemId_Command_DeckUpload = ItemId_Other + 1, ItemId_Event_ListChatChannels = ItemId_Other + 2, ItemId_Event_ChatListPlayers = ItemId_Other + 3, ItemId_Event_ListGames = ItemId_Other + 4, - ItemId_Response_DeckList = ItemId_Other + 5 + ItemId_Response_DeckList = ItemId_Other + 5, + ItemId_Response_DeckDownload = ItemId_Other + 6, + ItemId_Response_DeckUpload = ItemId_Other + 7 }; class ProtocolItem : public QObject { @@ -123,10 +126,21 @@ public: class Command_DeckUpload : public Command { Q_OBJECT +private: + DeckList *deck; + QString path; + bool readFinished; +protected: + void extractParameters(); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); public: - Command_DeckUpload(int _cmdId = -1) : Command("deck_upload", _cmdId) { } + Command_DeckUpload(int _cmdId = -1, DeckList *_deck = 0, const QString &_path = QString()); + ~Command_DeckUpload(); static ProtocolItem *newItem() { return new Command_DeckUpload; } int getItemId() const { return ItemId_Command_DeckUpload; } + DeckList *getDeck() const { return deck; } + QString getPath() const { return path; } }; // ----------------- @@ -182,6 +196,7 @@ public: }; private: Directory *root; + bool readFinished; protected: bool readElement(QXmlStreamReader *xml); void writeElement(QXmlStreamWriter *xml); @@ -193,6 +208,35 @@ public: Directory *getRoot() const { return root; } }; +class Response_DeckDownload : public ProtocolResponse { + Q_OBJECT +private: + DeckList *deck; + bool readFinished; +protected: + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); +public: + Response_DeckDownload(int _cmdId = -1, ResponseCode _responseCode = RespOk, DeckList *_deck = 0); + ~Response_DeckDownload(); + int getItemId() const { return ItemId_Response_DeckDownload; } + static ProtocolItem *newItem() { return new Response_DeckDownload; } + DeckList *getDeck() const { return deck; } +}; + +class Response_DeckUpload : public ProtocolResponse { + Q_OBJECT +private: + int deckId; +protected: + void extractParameters(); +public: + Response_DeckUpload(int _cmdId = -1, ResponseCode _responseCode = RespOk, int _deckId = -1); + int getItemId() const { return ItemId_Response_DeckUpload; } + static ProtocolItem *newItem() { return new Response_DeckUpload; } + int getDeckId() const { return deckId; } +}; + // -------------- // --- EVENTS --- // -------------- diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 69f7e74f..3dc1dcaf 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -4,7 +4,7 @@ #include #include -enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespNameNotFound, RespLoginNeeded, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed }; +enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed }; class ServerChatChannelInfo { private: diff --git a/servatrice/servatrice.pro b/servatrice/servatrice.pro index 5d6a77d4..58e5f034 100755 --- a/servatrice/servatrice.pro +++ b/servatrice/servatrice.pro @@ -14,6 +14,7 @@ QT += network sql HEADERS += src/servatrice.h \ src/serversocketinterface.h \ + ../common/decklist.h \ ../common/protocol.h \ ../common/protocol_items.h \ ../common/protocol_datastructures.h \ @@ -32,6 +33,7 @@ HEADERS += src/servatrice.h \ SOURCES += src/main.cpp \ src/servatrice.cpp \ src/serversocketinterface.cpp \ + ../common/decklist.cpp \ ../common/protocol.cpp \ ../common/protocol_items.cpp \ ../common/rng_abstract.cpp \ diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 79c4a4a0..676956a2 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -25,6 +25,7 @@ #include "servatrice.h" #include "protocol.h" #include "protocol_items.h" +#include "decklist.h" ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent) : Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), currentItem(0) @@ -113,8 +114,6 @@ int ServerSocketInterface::getDeckPathId(int basePathId, QStringList path) if (path[0].isEmpty()) return 0; - servatrice->checkSql(); - QSqlQuery query; query.prepare("select id from decklist_folders where id_parent = :id_parent and name = :name and user = :user"); query.bindValue(":id_parent", basePathId); @@ -136,28 +135,33 @@ int ServerSocketInterface::getDeckPathId(const QString &path) return getDeckPathId(0, path.split("/")); } -void ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) +bool ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) { QSqlQuery query; query.prepare("select id, name from decklist_folders where id_parent = :id_parent and user = :user"); query.bindValue(":id_parent", folder->getId()); query.bindValue(":user", playerName); - servatrice->execSqlQuery(query); + if (!servatrice->execSqlQuery(query)) + return false; while (query.next()) { Response_DeckList::Directory *newFolder = new Response_DeckList::Directory(query.value(1).toString(), query.value(0).toInt()); folder->append(newFolder); - deckListHelper(newFolder); + if (!deckListHelper(newFolder)) + return false; } query.prepare("select id, name from decklist_files where id_folder = :id_folder"); query.bindValue(":id_folder", folder->getId()); - servatrice->execSqlQuery(query); + if (!servatrice->execSqlQuery(query)) + return false; while (query.next()) { Response_DeckList::File *newFile = new Response_DeckList::File(query.value(1).toString(), query.value(0).toInt()); folder->append(newFile); } + + return true; } // CHECK AUTHENTICATION! @@ -165,11 +169,12 @@ void ServerSocketInterface::deckListHelper(Response_DeckList::Directory *folder) ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList *cmd) { - Response_DeckList::Directory *root = new Response_DeckList::Directory(QString()); - servatrice->checkSql(); + + Response_DeckList::Directory *root = new Response_DeckList::Directory(QString()); QSqlQuery query; - deckListHelper(root); + if (!deckListHelper(root)) + return RespContextError; sendProtocolItem(new Response_DeckList(cmd->getCmdId(), RespOk, root)); @@ -178,6 +183,8 @@ ResponseCode ServerSocketInterface::cmdDeckList(Command_DeckList *cmd) ResponseCode ServerSocketInterface::cmdDeckNewDir(Command_DeckNewDir *cmd) { + servatrice->checkSql(); + int folderId = getDeckPathId(cmd->getPath()); if (folderId == -1) return RespNameNotFound; @@ -194,6 +201,8 @@ ResponseCode ServerSocketInterface::cmdDeckNewDir(Command_DeckNewDir *cmd) void ServerSocketInterface::deckDelDirHelper(int basePathId) { + servatrice->checkSql(); + QSqlQuery query; query.prepare("select id from decklist_folders where id_parent = :id_parent"); @@ -213,14 +222,19 @@ void ServerSocketInterface::deckDelDirHelper(int basePathId) ResponseCode ServerSocketInterface::cmdDeckDelDir(Command_DeckDelDir *cmd) { + servatrice->checkSql(); + int basePathId = getDeckPathId(cmd->getPath()); if (basePathId == -1) return RespNameNotFound; deckDelDirHelper(basePathId); + return RespOk; } ResponseCode ServerSocketInterface::cmdDeckDel(Command_DeckDel *cmd) { + servatrice->checkSql(); + QSqlQuery query; query.prepare("select id from decklist_files where id = :id and user = :user"); @@ -239,8 +253,53 @@ ResponseCode ServerSocketInterface::cmdDeckDel(Command_DeckDel *cmd) ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd) { + servatrice->checkSql(); + + if (!cmd->getDeck()) + return RespInvalidData; + int folderId = getDeckPathId(cmd->getPath()); + if (folderId == -1) + return RespNameNotFound; + + QString deckContents; + QXmlStreamWriter deckWriter(&deckContents); + deckWriter.writeStartDocument(); + cmd->getDeck()->writeElement(&deckWriter); + deckWriter.writeEndDocument(); + + QSqlQuery query; + query.prepare("insert into decklist_files (id_folder, user, name, content) value(:id_folder, :user, :name, :content)"); + query.bindValue(":id_folder", folderId); + query.bindValue(":user", playerName); + query.bindValue(":name", cmd->getDeck()->getName()); + query.bindValue(":content", deckContents); + servatrice->execSqlQuery(query); + + sendProtocolItem(new Response_DeckUpload(cmd->getCmdId(), RespOk, query.lastInsertId().toInt())); + return RespNothing; } ResponseCode ServerSocketInterface::cmdDeckDownload(Command_DeckDownload *cmd) { + servatrice->checkSql(); + + QSqlQuery query; + + query.prepare("select content from decklist_files where id = :id and user = :user"); + query.bindValue(":id", cmd->getDeckId()); + query.bindValue(":user", playerName); + servatrice->execSqlQuery(query); + if (!query.next()) + return RespNameNotFound; + + QXmlStreamReader deckReader(query.value(0).toString()); + DeckList *deck = new DeckList; + if (!deck->loadFromXml(&deckReader)) { + delete deck; + deck = 0; + return RespInvalidData; + } + + sendProtocolItem(new Response_DeckDownload(cmd->getCmdId(), RespOk, deck)); + return RespNothing; } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 6342bffd..95eee7a1 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -43,7 +43,7 @@ private: int getDeckPathId(int basePathId, QStringList path); int getDeckPathId(const QString &path); - void deckListHelper(Response_DeckList::Directory *folder); + bool deckListHelper(Response_DeckList::Directory *folder); ResponseCode cmdDeckList(Command_DeckList *cmd); ResponseCode cmdDeckNewDir(Command_DeckNewDir *cmd); void deckDelDirHelper(int basePathId);