From 4441c552aa27b241c92b5b448ac3b01dfb83ad69 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Sep 2020 00:39:20 -0400 Subject: [PATCH 1/5] Adding GlobalDecks Feature --- servatrice/servatrice.ini.example | 3 +++ servatrice/src/servatrice.cpp | 5 +++++ servatrice/src/servatrice.h | 1 + servatrice/src/serversocketinterface.cpp | 27 +++++++++++++++++------- servatrice/src/serversocketinterface.h | 2 +- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index 9da88779c..ec42a1f32 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -85,6 +85,9 @@ officialwarnings="Flamming,Spamming,Causing Drama,Abusive Language" ; Clients will be notified at the 90% time period of pending disconnection if they do not take action. idleclienttimeout=3600 +; You can define one user whose decks will be available to all users. This is useful for hosting events and distributing preconstructed decks to all users. By default this is unset. This will be matched against the id field in cockatrice_users. +; globaldecksid=1 + [authentication] ; Servatrice can authenticate users connecting. It currently supports 3 different authentication methods: diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index d3bb488bb..f1913ec03 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -808,6 +808,11 @@ bool Servatrice::getClientIDRequiredEnabled() const return settingsCache->value("server/requireclientid", 0).toBool(); } +int Servatrice::getGlobalDecksID() const +{ + return settingsCache->value("server/globaldecksid", -1).toInt(); +} + bool Servatrice::getRegOnlyServerEnabled() const { return settingsCache->value("authentication/regonly", 0).toBool(); diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 67053590d..0310eb305 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -259,6 +259,7 @@ public: int getMinPasswordLength() const; int getIdleClientTimeout() const override; int getServerID() const override; + int getGlobalDecksID() const; int getMaxGameInactivityTime() const override; int getMaxPlayerInactivityTime() const override; int getClientKeepAlive() const override; diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 5c59bdd49..895f1213f 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -74,6 +74,7 @@ #include static const int protocolVersion = 14; +static const int globalDeckOffset = 10000000; AbstractServerSocketInterface::AbstractServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, @@ -342,12 +343,14 @@ int AbstractServerSocketInterface::getDeckPathId(const QString &path) return getDeckPathId(0, path.split("/")); } -bool AbstractServerSocketInterface::deckListHelper(int folderId, ServerInfo_DeckStorage_Folder *folder) +bool AbstractServerSocketInterface::deckListHelper(int folderId, int userId, ServerInfo_DeckStorage_Folder *folder) { + int offset = (servatrice->getGlobalDecksID() == userId) ? globalDeckOffset : 0; + QSqlQuery *query = sqlInterface->prepareQuery( "select id, name from {prefix}_decklist_folders where id_parent = :id_parent and id_user = :id_user"); query->bindValue(":id_parent", folderId); - query->bindValue(":id_user", userInfo->id()); + query->bindValue(":id_user", userId); if (!sqlInterface->execSqlQuery(query)) return false; @@ -357,23 +360,23 @@ bool AbstractServerSocketInterface::deckListHelper(int folderId, ServerInfo_Deck foreach (int key, results.keys()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(key); + newItem->set_id(key+offset); newItem->set_name(results.value(key).toStdString()); - if (!deckListHelper(newItem->id(), newItem->mutable_folder())) + if (!deckListHelper(key, userId, newItem->mutable_folder())) return false; } query = sqlInterface->prepareQuery("select id, name, upload_time from {prefix}_decklist_files where id_folder = " ":id_folder and id_user = :id_user"); query->bindValue(":id_folder", folderId); - query->bindValue(":id_user", userInfo->id()); + query->bindValue(":id_user", userId); if (!sqlInterface->execSqlQuery(query)) return false; while (query->next()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(query->value(0).toInt()); + newItem->set_id(query->value(0).toInt()+offset); newItem->set_name(query->value(1).toString().toStdString()); ServerInfo_DeckStorage_File *newFile = newItem->mutable_file(); @@ -397,7 +400,12 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckList(const Command_ Response_DeckList *re = new Response_DeckList; ServerInfo_DeckStorage_Folder *root = re->mutable_root(); - if (!deckListHelper(0, root)) + int globalID = servatrice->getGlobalDecksID(); + if((globalID != -1) && ((globalID != userInfo->id()))) + if (!deckListHelper(0, globalID, root)) + return Response::RespContextError; + + if (!deckListHelper(0, userInfo->id(), root)) return Response::RespContextError; rc.setResponseExtension(re); @@ -568,7 +576,10 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckDownload(const Comm DeckList *deck; try { - deck = sqlInterface->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); + if((servatrice->getGlobalDecksID() != -1) && (cmd.deck_id()>globalDeckOffset)) + deck = sqlInterface->getDeckFromDatabase(cmd.deck_id()-globalDeckOffset, servatrice->getGlobalDecksID()); + else + deck = sqlInterface->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); } catch (Response::ResponseCode &r) { return r; } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 722e1e0be..e85d174f8 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -82,7 +82,7 @@ private: Response::ResponseCode cmdRemoveFromList(const Command_RemoveFromList &cmd, ResponseContainer &rc); int getDeckPathId(int basePathId, QStringList path); int getDeckPathId(const QString &path); - bool deckListHelper(int folderId, ServerInfo_DeckStorage_Folder *folder); + bool deckListHelper(int folderId, int userId, ServerInfo_DeckStorage_Folder *folder); Response::ResponseCode cmdDeckList(const Command_DeckList &cmd, ResponseContainer &rc); Response::ResponseCode cmdDeckNewDir(const Command_DeckNewDir &cmd, ResponseContainer &rc); void deckDelDirHelper(int basePathId); From acacbaa7a14400cedb00dabef9d90a5bd4790be7 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Sep 2020 01:29:09 -0400 Subject: [PATCH 2/5] Correct style --- servatrice/src/serversocketinterface.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 895f1213f..a15445b25 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -360,7 +360,7 @@ bool AbstractServerSocketInterface::deckListHelper(int folderId, int userId, Ser foreach (int key, results.keys()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(key+offset); + newItem->set_id(key + offset); newItem->set_name(results.value(key).toStdString()); if (!deckListHelper(key, userId, newItem->mutable_folder())) @@ -376,7 +376,7 @@ bool AbstractServerSocketInterface::deckListHelper(int folderId, int userId, Ser while (query->next()) { ServerInfo_DeckStorage_TreeItem *newItem = folder->add_items(); - newItem->set_id(query->value(0).toInt()+offset); + newItem->set_id(query->value(0).toInt() + offset); newItem->set_name(query->value(1).toString().toStdString()); ServerInfo_DeckStorage_File *newFile = newItem->mutable_file(); @@ -401,7 +401,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckList(const Command_ ServerInfo_DeckStorage_Folder *root = re->mutable_root(); int globalID = servatrice->getGlobalDecksID(); - if((globalID != -1) && ((globalID != userInfo->id()))) + if ((globalID != -1) && ((globalID != userInfo->id()))) if (!deckListHelper(0, globalID, root)) return Response::RespContextError; @@ -576,8 +576,8 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckDownload(const Comm DeckList *deck; try { - if((servatrice->getGlobalDecksID() != -1) && (cmd.deck_id()>globalDeckOffset)) - deck = sqlInterface->getDeckFromDatabase(cmd.deck_id()-globalDeckOffset, servatrice->getGlobalDecksID()); + if ((servatrice->getGlobalDecksID() != -1) && (cmd.deck_id() > globalDeckOffset)) + deck = sqlInterface->getDeckFromDatabase(cmd.deck_id() - globalDeckOffset, servatrice->getGlobalDecksID()); else deck = sqlInterface->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); } catch (Response::ResponseCode &r) { From 7b01874459a98442819d675060287c3e2734e992 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Sep 2020 10:37:18 -0400 Subject: [PATCH 3/5] Correct logic so that the global user can modify their decks. --- servatrice/src/serversocketinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index a15445b25..fbcf5accb 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -345,7 +345,7 @@ int AbstractServerSocketInterface::getDeckPathId(const QString &path) bool AbstractServerSocketInterface::deckListHelper(int folderId, int userId, ServerInfo_DeckStorage_Folder *folder) { - int offset = (servatrice->getGlobalDecksID() == userId) ? globalDeckOffset : 0; + int offset = (userInfo->id() != userId) ? globalDeckOffset : 0; QSqlQuery *query = sqlInterface->prepareQuery( "select id, name from {prefix}_decklist_folders where id_parent = :id_parent and id_user = :id_user"); From 642ce68496534b1f0f69e3dfaa2feaf6b659f18c Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Sep 2020 17:49:57 -0400 Subject: [PATCH 4/5] Move the offset logic one layer deeper for it to work with Command_DeckDownload AND Command_DeckSelect --- servatrice/src/servatrice_database_interface.cpp | 6 ++++++ servatrice/src/serversocketinterface.cpp | 6 +----- servatrice/src/serversocketinterface.h | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index fcb43bf95..1b3fc2bf6 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -868,6 +868,12 @@ DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int user { checkSql(); + if ((server->getGlobalDecksID() != -1) && (deckId > globalDeckOffset)) + { + deckId = deckId - globalDeckOffset; + userId = server->getGlobalDecksID(); + } + QSqlQuery *query = prepareQuery("select content from {prefix}_decklist_files where id = :id and id_user = :id_user"); query->bindValue(":id", deckId); diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index fbcf5accb..14b1a680b 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -74,7 +74,6 @@ #include static const int protocolVersion = 14; -static const int globalDeckOffset = 10000000; AbstractServerSocketInterface::AbstractServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, @@ -576,10 +575,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckDownload(const Comm DeckList *deck; try { - if ((servatrice->getGlobalDecksID() != -1) && (cmd.deck_id() > globalDeckOffset)) - deck = sqlInterface->getDeckFromDatabase(cmd.deck_id() - globalDeckOffset, servatrice->getGlobalDecksID()); - else - deck = sqlInterface->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); + deck = sqlInterface->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); } catch (Response::ResponseCode &r) { return r; } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index e85d174f8..ab4517883 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -27,6 +27,8 @@ #include #include +static const int globalDeckOffset = 10000000; + class Servatrice; class Servatrice_DatabaseInterface; class DeckList; From 18ec1d37531f62a43eef835ea6b3e5522cc61cfa Mon Sep 17 00:00:00 2001 From: Donald Haase Date: Mon, 28 Sep 2020 22:38:17 -0400 Subject: [PATCH 5/5] Style fix for travis --- servatrice/src/servatrice_database_interface.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index 1b3fc2bf6..f1d639ff4 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -868,8 +868,7 @@ DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int user { checkSql(); - if ((server->getGlobalDecksID() != -1) && (deckId > globalDeckOffset)) - { + if ((server->getGlobalDecksID() != -1) && (deckId > globalDeckOffset)) { deckId = deckId - globalDeckOffset; userId = server->getGlobalDecksID(); }