diff --git a/launcher/include/syncmanager.h b/launcher/include/syncmanager.h index a58e813..be63d14 100644 --- a/launcher/include/syncmanager.h +++ b/launcher/include/syncmanager.h @@ -11,7 +11,7 @@ /** * @brief Handles setting up the connection to Matrix and all of the fun things needed to do for that. - * Does NOT handle the actual synchronization process, see @c CharacterSync. That handles determining the files to sync and whatnot. + * Does NOT handle the actual synchronization process, see @c CharacterSync. */ class SyncManager : public QObject { @@ -24,27 +24,40 @@ public: explicit SyncManager(QObject *parent = nullptr); /** - * Log in to a connection + * @brief Log in to a connection * @param matrixId user id in the form @user:server.tld * @param password */ Q_INVOKABLE void login(const QString &matrixId, const QString &password); /** - * Log out of the connection + * @brief Log out of the connection */ Q_INVOKABLE void logout(); /** - * Run a single sync. We're not syncing constantly, since we typically don't need it and it consumes a lot of data + * @brief Run a single sync. We're not syncing constantly, since we typically don't need it and it consumes a lot of data. */ - Q_INVOKABLE void sync(); + Q_INVOKABLE QCoro::Task<> sync(); + /** + * @return Whether there is a connection to the server. + */ bool connected() const; + + /** + * @return The currently logged in user. + */ QString userId() const; + + /** + * @return The LibQuotient connection. + */ Quotient::Connection *connection() const; - /// If we're ready to begin downloading or uploading data + /** + * @return If we're ready to begin downloading or uploading data + */ bool isReady() const; struct PreviousCharacterData { @@ -52,22 +65,35 @@ public: QString hostname; }; - /// Returns a content repo URI, or nullopt if there's existing character data or not respectively + /** + * @return The currently uploaded character data, or nullopt if there's none for @p id. + */ QCoro::Task> getUploadedCharacterData(const QString &id); - /// Uploads character data for @p id from @p path (a file) + /** + * @brief Uploads character data for @p id from @p path. + * @return True if uploaded successfuly, false otherwise. + */ QCoro::Task uploadedCharacterData(const QString &id, const QString &path); - /// Downloads character data + /** + * @brief Downloads the character data archive from @p mxcUri and extracts it in @p destPath. + */ QCoro::Task downloadCharacterData(const QString &mxcUri, const QString &destPath); - /// Checks the lock on the sync + /** + * @brief Checks if there's a lock. + */ QCoro::Task> checkLock(); - /// Sets the sync lock to the device's hostname + /** + * @brief Sets the sync to the device's hostname. + */ QCoro::Task<> setLock(); - /// Breaks the sync lock + /** + * @brief Breaks the current sync lock. + */ QCoro::Task<> breakLock(); Q_SIGNALS: @@ -80,7 +106,8 @@ Q_SIGNALS: private: QString roomId() const; void setRoomId(const QString &roomId); - QCoro::Task findRoom(); + QCoro::Task<> findRoom(); + QCoro::Task<> beginInitialSync(); Quotient::AccountRegistry m_accountRegistry; diff --git a/launcher/src/charactersync.cpp b/launcher/src/charactersync.cpp index 8813848..abf56fb 100644 --- a/launcher/src/charactersync.cpp +++ b/launcher/src/charactersync.cpp @@ -39,6 +39,9 @@ QCoro::Task CharacterSync::sync(const bool initialSync) Q_EMIT launcher.stageChanged(i18n("Synchronizing character data...")); + // Perform a manual sync just in case + co_await syncManager->sync(); + // On game boot, check if we need the lock. Otherwise break it when we clean up. if (initialSync) { if (const auto hostname = co_await syncManager->checkLock(); hostname.has_value()) { diff --git a/launcher/src/syncmanager.cpp b/launcher/src/syncmanager.cpp index a3ea977..1e41b2a 100644 --- a/launcher/src/syncmanager.cpp +++ b/launcher/src/syncmanager.cpp @@ -19,9 +19,9 @@ #include #include -const QString roomType = QStringLiteral("zone.xiv.astra-sync"); -const QString syncEventType = QStringLiteral("zone.xiv.astra.sync"); -const QString lockEventType = QStringLiteral("zone.xiv.astra.lock"); +const auto roomType = QStringLiteral("zone.xiv.astra-sync"); +const auto syncEventType = QStringLiteral("zone.xiv.astra.sync"); +const auto lockEventType = QStringLiteral("zone.xiv.astra.lock"); using namespace Quotient; @@ -32,13 +32,14 @@ SyncManager::SyncManager(QObject *parent) connect(&m_accountRegistry, &AccountRegistry::rowsInserted, this, [this]() { connection()->setCacheState(false); connection()->setLazyLoading(false); - connection()->setDirectChatEncryptionDefault(false); - connection()->setEncryptionDefault(false); + Connection::setDirectChatEncryptionDefault(false); + Connection::setEncryptionDefault(false); Q_EMIT connectedChanged(); Q_EMIT userIdChanged(); Q_EMIT connectionChanged(); - sync(); + + beginInitialSync(); }); connect(&m_accountRegistry, &AccountRegistry::rowsRemoved, this, [this]() { Q_EMIT connectedChanged(); @@ -61,7 +62,7 @@ void SyncManager::login(const QString &matrixId, const QString &password) Qt::SingleShotConnection); connect(connection, &Connection::connected, this, [this, connection] { - qCDebug(ASTRA_LOG) << "Connected!"; + qCDebug(ASTRA_LOG) << "Connected to the sync server!"; // TODO: store somewhere else, not their QSettings AccountSettings account(connection->userId()); @@ -101,23 +102,15 @@ Quotient::Connection *SyncManager::connection() const return nullptr; } -void SyncManager::sync() +QCoro::Task<> SyncManager::sync() { + // TODO: de-duplicate sync() calls. otherwise if they happen in quick succession, they wait on each other which is useless for our use case + auto connection = m_accountRegistry.accounts().first(); connection->sync(); - connect( - connection, - &Connection::syncDone, - this, - [this]() { - m_accountRegistry.accounts().first()->stopSync(); - - qCDebug(ASTRA_LOG) << "Done with sync."; - - // Find the room we need to sync with - findRoom(); - }, - Qt::SingleShotConnection); + co_await qCoro(connection, &Connection::syncDone); + m_accountRegistry.accounts().first()->stopSync(); + co_return; } QCoro::Task SyncManager::findRoom() @@ -282,4 +275,12 @@ QCoro::Task<> SyncManager::breakLock() co_return; } +QCoro::Task<> SyncManager::beginInitialSync() +{ + co_await sync(); + + // Find the room we need to sync with + findRoom(); +} + #include "moc_syncmanager.cpp"