mirror of
https://github.com/redstrate/Astra.git
synced 2025-04-20 03:37:47 +00:00
Improve character sync error handling, and the sync itself
Ported from libQuotient's invokeLogin to our own custom one, so we can avoid the initial sync until login. Then, make sure we find the room *after* the sync, not before it. Also since I wiped the media cache from my server, I hit a crash since it tried to open an invalid ZIP file. Now we can handle that.
This commit is contained in:
parent
b5b9cdfdc0
commit
807cf0e062
4 changed files with 68 additions and 33 deletions
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
private:
|
||||
QCoro::Task<void> uploadCharacterData(const QDir &dir, const QString &id);
|
||||
QCoro::Task<void> downloadCharacterData(const QDir &dir, const QString &id, const QString &contentUri);
|
||||
QCoro::Task<bool> downloadCharacterData(const QDir &dir, const QString &id, const QString &contentUri);
|
||||
|
||||
LauncherCore &launcher;
|
||||
Account &m_account;
|
||||
|
|
|
@ -105,10 +105,10 @@ Q_SIGNALS:
|
|||
void loginError(const QString &message);
|
||||
|
||||
private:
|
||||
void invokeLogin();
|
||||
QString roomId() const;
|
||||
void setRoomId(const QString &roomId);
|
||||
QCoro::Task<> findRoom();
|
||||
QCoro::Task<> beginInitialSync();
|
||||
|
||||
Quotient::AccountRegistry m_accountRegistry;
|
||||
|
||||
|
|
|
@ -33,6 +33,9 @@ QCoro::Task<bool> CharacterSync::sync(const bool initialSync)
|
|||
co_return false;
|
||||
}
|
||||
|
||||
// Perform a manual sync just in case
|
||||
co_await syncManager->sync();
|
||||
|
||||
if (!syncManager->isReady()) {
|
||||
Q_EMIT launcher.stageChanged(i18n("Waiting for sync connection..."));
|
||||
|
||||
|
@ -42,9 +45,6 @@ QCoro::Task<bool> 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()) {
|
||||
|
@ -110,10 +110,15 @@ QCoro::Task<bool> CharacterSync::sync(const bool initialSync)
|
|||
const bool needsDownload = areFilesDifferent;
|
||||
|
||||
if (needsUpload) {
|
||||
qCDebug(ASTRA_LOG) << id << "uploading character data";
|
||||
// if we didn't upload character data yet, upload it now
|
||||
co_await uploadCharacterData(dir.absoluteFilePath(), id);
|
||||
} else if (needsDownload) {
|
||||
co_await downloadCharacterData(dir.absoluteFilePath(), id, previousData->mxcUri);
|
||||
qCDebug(ASTRA_LOG) << id << "downloading character data";
|
||||
if (!co_await downloadCharacterData(dir.absoluteFilePath(), id, previousData->mxcUri)) {
|
||||
Q_EMIT launcher.loginError(i18n("Failed to sync character data from the server. Please do another initial sync under Settings and try again."));
|
||||
co_return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +154,7 @@ QCoro::Task<void> CharacterSync::uploadCharacterData(const QDir &dir, const QStr
|
|||
co_return;
|
||||
}
|
||||
|
||||
QCoro::Task<void> CharacterSync::downloadCharacterData(const QDir &dir, const QString &id, const QString &contentUri)
|
||||
QCoro::Task<bool> CharacterSync::downloadCharacterData(const QDir &dir, const QString &id, const QString &contentUri)
|
||||
{
|
||||
const QTemporaryDir tempDir;
|
||||
|
||||
|
@ -160,17 +165,27 @@ QCoro::Task<void> CharacterSync::downloadCharacterData(const QDir &dir, const QS
|
|||
auto zip = new KZip(tempZipPath);
|
||||
zip->setCompression(KZip::DeflateCompression);
|
||||
zip->open(QIODevice::ReadOnly);
|
||||
|
||||
if (zip->isOpen()) {
|
||||
qCDebug(ASTRA_LOG) << "contents:" << zip->directory()->entries();
|
||||
|
||||
Q_UNUSED(zip->directory()->file(gearsetFilename)->copyTo(dir.absolutePath()))
|
||||
if (auto file = zip->directory()->file(gearsetFilename); file != nullptr) {
|
||||
Q_UNUSED(file->copyTo(dir.absolutePath()))
|
||||
|
||||
qCDebug(ASTRA_LOG) << "Extracted character data!";
|
||||
|
||||
zip->close();
|
||||
delete zip;
|
||||
|
||||
co_return;
|
||||
co_return true;
|
||||
}
|
||||
}
|
||||
|
||||
zip->close();
|
||||
delete zip;
|
||||
|
||||
qCDebug(ASTRA_LOG) << "Failed to read character ZIP!";
|
||||
|
||||
co_return false;
|
||||
}
|
||||
|
||||
#include "moc_charactersync.cpp"
|
||||
|
|
|
@ -33,7 +33,7 @@ using namespace Quotient;
|
|||
SyncManager::SyncManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_accountRegistry.invokeLogin(); // TODO: port from invokeLogin
|
||||
invokeLogin();
|
||||
connect(&m_accountRegistry, &AccountRegistry::rowsInserted, this, [this]() {
|
||||
connection()->setCacheState(false);
|
||||
connection()->setLazyLoading(false);
|
||||
|
@ -43,8 +43,6 @@ SyncManager::SyncManager(QObject *parent)
|
|||
Q_EMIT connectedChanged();
|
||||
Q_EMIT userIdChanged();
|
||||
Q_EMIT connectionChanged();
|
||||
|
||||
beginInitialSync();
|
||||
});
|
||||
connect(&m_accountRegistry, &AccountRegistry::rowsRemoved, this, [this]() {
|
||||
Q_EMIT connectedChanged();
|
||||
|
@ -117,7 +115,11 @@ QCoro::Task<> SyncManager::sync()
|
|||
auto connection = m_accountRegistry.accounts().first();
|
||||
connection->sync();
|
||||
co_await qCoro(connection, &Connection::syncDone);
|
||||
m_accountRegistry.accounts().first()->stopSync();
|
||||
|
||||
if (!m_currentRoom) {
|
||||
co_await findRoom();
|
||||
}
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
|
@ -132,6 +134,18 @@ QCoro::Task<void> SyncManager::findRoom()
|
|||
// If we have no room id set, we need to find the correct room type
|
||||
const bool needsFirstTimeRoom = roomId.isEmpty();
|
||||
|
||||
if (!needsFirstTimeRoom) {
|
||||
auto room = m_accountRegistry.accounts().first()->room(roomId);
|
||||
if (room) {
|
||||
qCDebug(ASTRA_LOG) << "Found pre-existing room!";
|
||||
|
||||
m_currentRoom = room;
|
||||
Q_EMIT isReadyChanged();
|
||||
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find our room
|
||||
auto rooms = m_accountRegistry.accounts().first()->rooms(Quotient::JoinState::Join);
|
||||
for (auto room : rooms) {
|
||||
|
@ -151,15 +165,6 @@ QCoro::Task<void> SyncManager::findRoom()
|
|||
Q_EMIT isReadyChanged();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (room->id() == roomId) {
|
||||
qCDebug(ASTRA_LOG) << "Found pre-existing room!";
|
||||
|
||||
m_currentRoom = room;
|
||||
Q_EMIT isReadyChanged();
|
||||
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +195,28 @@ QCoro::Task<void> SyncManager::findRoom()
|
|||
co_return;
|
||||
}
|
||||
|
||||
void SyncManager::invokeLogin()
|
||||
{
|
||||
// Simplified from libQuotient, but this can be simplified even more
|
||||
const auto accounts = SettingsGroup("Accounts"_L1).childGroups();
|
||||
for (const auto &accountId : accounts) {
|
||||
AccountSettings account{accountId};
|
||||
|
||||
if (account.homeserver().isEmpty())
|
||||
continue;
|
||||
|
||||
auto accessTokenLoadingJob = new QKeychain::ReadPasswordJob(qAppName(), this);
|
||||
accessTokenLoadingJob->setKey(accountId);
|
||||
connect(accessTokenLoadingJob, &QKeychain::Job::finished, this, [accountId, this, accessTokenLoadingJob]() {
|
||||
AccountSettings account{accountId};
|
||||
auto connection = new Connection(account.homeserver());
|
||||
connection->assumeIdentity(account.userId(), account.deviceId(), QString::fromUtf8(accessTokenLoadingJob->binaryData()));
|
||||
m_accountRegistry.add(connection);
|
||||
});
|
||||
accessTokenLoadingJob->start();
|
||||
}
|
||||
}
|
||||
|
||||
QString SyncManager::roomId() const
|
||||
{
|
||||
return KSharedConfig::openStateConfig()->group(QStringLiteral("Sync")).readEntry(QStringLiteral("RoomId"));
|
||||
|
@ -204,6 +231,7 @@ void SyncManager::setRoomId(const QString &roomId)
|
|||
|
||||
bool SyncManager::isReady() const
|
||||
{
|
||||
qInfo() << connected() << m_currentRoom;
|
||||
return connected() && m_currentRoom;
|
||||
}
|
||||
|
||||
|
@ -294,12 +322,4 @@ 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"
|
||||
|
|
Loading…
Add table
Reference in a new issue