mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
[Client+Server] Auto deck sync with change polling
This commit is contained in:
parent
dcccb0f332
commit
e73fcd602c
18 changed files with 448 additions and 18 deletions
|
|
@ -98,6 +98,7 @@
|
|||
#include <libcockatrice/protocol/pb/command_deck_share_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_share_list_mine.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_share_remove.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_sync_check.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_get_server_stats.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_replay_delete_match.pb.h>
|
||||
|
|
@ -134,6 +135,7 @@
|
|||
#include <libcockatrice/protocol/pb/response_deck_share_download.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_share_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_share_list_mine.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_sync_status.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_forgotpasswordrequest.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_admin_notes.pb.h>
|
||||
|
|
@ -371,6 +373,8 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedSessionComm
|
|||
return cmdDeckUpload(cmd.GetExtension(Command_DeckUpload::ext), rc);
|
||||
case SessionCommand::DECK_DOWNLOAD:
|
||||
return cmdDeckDownload(cmd.GetExtension(Command_DeckDownload::ext), rc);
|
||||
case SessionCommand::DECK_SYNC_CHECK:
|
||||
return cmdDeckSyncCheck(cmd.GetExtension(Command_DeckSyncCheck::ext), rc);
|
||||
case SessionCommand::REPLAY_LIST:
|
||||
return cmdReplayList(cmd.GetExtension(Command_ReplayList::ext), rc);
|
||||
case SessionCommand::REPLAY_DOWNLOAD:
|
||||
|
|
@ -894,6 +898,80 @@ Response::ResponseCode AbstractServerSocketInterface::cmdDeckSetVisibility(const
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
bool AbstractServerSocketInterface::syncCheckHelper(int folderId,
|
||||
const QString &prefix,
|
||||
int userId,
|
||||
qint64 sinceSecs,
|
||||
Response_DeckSyncStatus *status)
|
||||
{
|
||||
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", userId);
|
||||
if (!sqlInterface->execSqlQuery(query)) {
|
||||
return false;
|
||||
}
|
||||
QList<std::pair<int, QString>> subfolders;
|
||||
while (query->next()) {
|
||||
subfolders.append({query->value(0).toInt(), query->value(1).toString()});
|
||||
}
|
||||
for (const auto &[subfolderId, subfolderName] : subfolders) {
|
||||
const QString path = prefix.isEmpty() ? subfolderName : prefix + "/" + subfolderName;
|
||||
if (!syncCheckHelper(subfolderId, path, userId, sinceSecs, status)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
query = sqlInterface->prepareQuery("select id, name, guid, hash, last_modified, deleted from "
|
||||
"{prefix}_decklist_files where id_folder = :id_folder and id_user = :id_user "
|
||||
"and (last_modified is null or last_modified > FROM_UNIXTIME(:since))");
|
||||
query->bindValue(":id_folder", folderId);
|
||||
query->bindValue(":id_user", userId);
|
||||
query->bindValue(":since", sinceSecs);
|
||||
if (!sqlInterface->execSqlQuery(query)) {
|
||||
return false;
|
||||
}
|
||||
while (query->next()) {
|
||||
const QString name = query->value(1).toString();
|
||||
DeckSyncChangedFile *changed = status->add_changed_files();
|
||||
changed->set_path((prefix.isEmpty() ? name : prefix + "/" + name).toStdString());
|
||||
changed->set_deck_id(query->value(0).toUInt());
|
||||
changed->set_guid(query->value(2).toString().toStdString());
|
||||
changed->set_hash(query->value(3).toString().toStdString());
|
||||
const QDateTime lastModified = query->value(4).toDateTime();
|
||||
if (lastModified.isValid()) {
|
||||
changed->set_last_modified(lastModified.toSecsSinceEpoch());
|
||||
}
|
||||
changed->set_deleted(query->value(5).toBool());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdDeckSyncCheck(const Command_DeckSyncCheck &cmd,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
if (authState != PasswordRight) {
|
||||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
|
||||
sqlInterface->checkSql();
|
||||
|
||||
Response_DeckSyncStatus *re = new Response_DeckSyncStatus;
|
||||
if (!syncCheckHelper(0, QString(), userInfo->id(), static_cast<qint64>(cmd.last_sync_time()), re)) {
|
||||
delete re;
|
||||
return Response::RespContextError;
|
||||
}
|
||||
|
||||
QSqlQuery *clockQuery = sqlInterface->prepareQuery("select unix_timestamp(now())");
|
||||
if (!sqlInterface->execSqlQuery(clockQuery) || !clockQuery->next()) {
|
||||
delete re;
|
||||
return Response::RespContextError;
|
||||
}
|
||||
re->set_server_time(clockQuery->value(0).toULongLong());
|
||||
rc.setResponseExtension(re);
|
||||
return Response::RespOk;
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdDeckDownloadPublic(const Command_DeckDownloadPublic &cmd,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue