[Client+Server] Deck version history with restore

This commit is contained in:
Lukas Brübach 2026-10-11 17:10:01 +02:00
parent 875e87d1bc
commit 44f57aa2b9
17 changed files with 437 additions and 0 deletions

View file

@ -89,6 +89,7 @@
#include <libcockatrice/protocol/pb/command_deck_del_dir.pb.h>
#include <libcockatrice/protocol/pb/command_deck_download.pb.h>
#include <libcockatrice/protocol/pb/command_deck_download_public.pb.h>
#include <libcockatrice/protocol/pb/command_deck_history_list.pb.h>
#include <libcockatrice/protocol/pb/command_deck_list.pb.h>
#include <libcockatrice/protocol/pb/command_deck_list_other_user.pb.h>
#include <libcockatrice/protocol/pb/command_deck_new_dir.pb.h>
@ -130,6 +131,7 @@
#include <libcockatrice/protocol/pb/response_card_art_rule_entry.pb.h>
#include <libcockatrice/protocol/pb/response_clear_blacklisted_banners.pb.h>
#include <libcockatrice/protocol/pb/response_deck_download.pb.h>
#include <libcockatrice/protocol/pb/response_deck_history_list.pb.h>
#include <libcockatrice/protocol/pb/response_deck_list.pb.h>
#include <libcockatrice/protocol/pb/response_deck_share_create.pb.h>
#include <libcockatrice/protocol/pb/response_deck_share_download.pb.h>
@ -375,6 +377,8 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedSessionComm
return cmdDeckDownload(cmd.GetExtension(Command_DeckDownload::ext), rc);
case SessionCommand::DECK_SYNC_CHECK:
return cmdDeckSyncCheck(cmd.GetExtension(Command_DeckSyncCheck::ext), rc);
case SessionCommand::DECK_HISTORY_LIST:
return cmdDeckHistoryList(cmd.GetExtension(Command_DeckHistoryList::ext), rc);
case SessionCommand::REPLAY_LIST:
return cmdReplayList(cmd.GetExtension(Command_ReplayList::ext), rc);
case SessionCommand::REPLAY_DOWNLOAD:
@ -953,6 +957,50 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckSyncCheck(const Com
return Response::RespOk;
}
Response::ResponseCode AbstractServerSocketInterface::cmdDeckHistoryList(const Command_DeckHistoryList &cmd,
ResponseContainer &rc)
{
if (authState != PasswordRight) {
return Response::RespFunctionNotAllowed;
}
sqlInterface->checkSql();
QSqlQuery *ownerQuery =
sqlInterface->prepareQuery("select 1 from {prefix}_decklist_files where id = :id and id_user = :id_user");
ownerQuery->bindValue(":id", cmd.deck_id());
ownerQuery->bindValue(":id_user", userInfo->id());
if (!sqlInterface->execSqlQuery(ownerQuery)) {
return Response::RespContextError;
}
if (!ownerQuery->next()) {
return Response::RespNameNotFound;
}
const int limit = qMin(cmd.has_limit() ? static_cast<int>(cmd.limit()) : 20, servatrice->getDeckSyncMaxVersions());
QSqlQuery *query =
sqlInterface->prepareQuery("select version_no, unix_timestamp(created_at), created_by_clientid, hash, "
"content from {prefix}_deck_versions where deck_id = :deck_id order by version_no "
"desc limit :limit");
query->bindValue(":deck_id", cmd.deck_id());
query->bindValue(":limit", qMax(1, limit));
if (!sqlInterface->execSqlQuery(query)) {
return Response::RespContextError;
}
Response_DeckHistoryList *re = new Response_DeckHistoryList;
while (query->next()) {
DeckVersionInfo *version = re->add_versions();
version->set_version_no(query->value(0).toUInt());
version->set_created_at(query->value(1).toULongLong());
version->set_created_by_clientid(query->value(2).toString().toStdString());
version->set_hash(query->value(3).toString().toStdString());
version->set_content(query->value(4).toString().toStdString());
}
rc.setResponseExtension(re);
return Response::RespOk;
}
Response::ResponseCode AbstractServerSocketInterface::cmdDeckDownloadPublic(const Command_DeckDownloadPublic &cmd,
ResponseContainer &rc)
{

View file

@ -56,6 +56,7 @@ class Command_DeckShareList;
class Command_DeckShareListMine;
class Command_DeckShareRemove;
class Command_DeckShareDownload;
class Command_DeckHistoryList;
class Command_DeckSyncCheck;
class Command_ReplayList;
class Command_ReplayDownload;
@ -112,6 +113,7 @@ class Command_ViewLogHistory;
class Command_WarnUser;
class QObject;
class ResponseContainer;
class Response_DeckHistoryList;
class Response_DeckSyncStatus;
class AbstractServerSocketInterface : public Server_ProtocolHandler
@ -167,6 +169,7 @@ private:
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc);
bool syncCheckHelper(int userId, qint64 sinceSecs, Response_DeckSyncStatus *status);
Response::ResponseCode cmdDeckSyncCheck(const Command_DeckSyncCheck &cmd, ResponseContainer &rc);
Response::ResponseCode cmdDeckHistoryList(const Command_DeckHistoryList &cmd, ResponseContainer &rc);
Response::ResponseCode cmdDeckDownloadPublic(const Command_DeckDownloadPublic &cmd, ResponseContainer &rc);
Response::ResponseCode cmdDeckShareCreate(const Command_DeckShareCreate &cmd, ResponseContainer &rc);
Response::ResponseCode cmdDeckShareList(const Command_DeckShareList &cmd, ResponseContainer &rc);