From 8c2a591279b234ec6cfc8e8d02f5b42c2877cbcc Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Wed, 7 May 2025 20:18:38 -0400 Subject: [PATCH] Make Astra more useful when offline When you're offline, all of the asset update checks fail (of course) and thus can prevent you from logging in. While it's possible to work around this already by toggling certain things off such as Dalamud, the built-in Wine etc - we should still be able to play if we have all of that downloaded. Now there is buttons in the network fail prompts that allow you to continue if you understand the risks. This would also make Astra more resilient to issues like GitHub being temporarily unavailable. --- launcher/include/launchercore.h | 3 ++ launcher/src/assetupdater.cpp | 36 ++++++++++++++++------ launcher/ui/Pages/StatusPage.qml | 51 +++++++++++++++++++++++++++++--- 3 files changed, 77 insertions(+), 13 deletions(-) diff --git a/launcher/include/launchercore.h b/launcher/include/launchercore.h index cb70283..2d57a6a 100755 --- a/launcher/include/launchercore.h +++ b/launcher/include/launchercore.h @@ -155,6 +155,7 @@ Q_SIGNALS: void loginError(QString message); void dalamudError(QString message); void miscError(QString message); + void assetError(QString message); void stageChanged(QString message, QString explanation = {}); void stageIndeterminate(); void stageDeterminate(int min, int max, int value); @@ -165,6 +166,8 @@ Q_SIGNALS: void showWindow(); void requiresUpdate(QString message); void updateDecided(bool allowUpdate); + void assetDecided(bool shouldContinue); + void dalamudDecided(bool shouldContinue); protected: friend class Patcher; diff --git a/launcher/src/assetupdater.cpp b/launcher/src/assetupdater.cpp index c259b02..d0206a1 100644 --- a/launcher/src/assetupdater.cpp +++ b/launcher/src/assetupdater.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -86,8 +87,10 @@ QCoro::Task AssetUpdater::checkRemoteCompatibilityToolVersion() const auto reply = co_await launcher.mgr()->get(request); if (reply->error() != QNetworkReply::NetworkError::NoError) { - Q_EMIT launcher.miscError(i18n("Could not check for the latest compatibility tool version.\n\n%1", reply->errorString())); - co_return false; + Q_EMIT launcher.assetError(i18n("Could not check for the latest compatibility tool version.\n\n%1", reply->errorString())); + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::assetDecided); + co_return shouldContinue; } const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); @@ -132,8 +135,10 @@ QCoro::Task AssetUpdater::checkRemoteDxvkVersion() const auto reply = co_await launcher.mgr()->get(request); if (reply->error() != QNetworkReply::NetworkError::NoError) { - Q_EMIT launcher.miscError(i18n("Could not check for the latest DXVK version.\n\n%1", reply->errorString())); - co_return false; + Q_EMIT launcher.assetError(i18n("Could not check for the latest DXVK version.\n\n%1", reply->errorString())); + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::assetDecided); + co_return shouldContinue; } const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); @@ -179,7 +184,9 @@ QCoro::Task AssetUpdater::checkRemoteDalamudAssetVersion() if (reply->error() != QNetworkReply::NetworkError::NoError) { Q_EMIT launcher.dalamudError(i18n("Could not check for Dalamud asset updates.\n\n%1", reply->errorString())); - co_return false; + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::dalamudDecided); + co_return shouldContinue; } const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); @@ -221,7 +228,13 @@ QCoro::Task AssetUpdater::checkRemoteDalamudVersion() if (reply->error() != QNetworkReply::NetworkError::NoError) { Q_EMIT launcher.dalamudError(i18n("Could not check for Dalamud updates.\n\n%1", reply->errorString())); - co_return false; + + // Always assume Dalamud is applicable for this version when we can't contact the server! + // The user is prompted to turn off Dalamud anyway, if they wish. + m_profile.setDalamudApplicable(true); + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::dalamudDecided); + co_return shouldContinue; } const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); @@ -349,7 +362,9 @@ QCoro::Task AssetUpdater::installDalamudAssets() if (!extractZip(m_tempDir.filePath(QStringLiteral("dalamud-assets.zip")), m_dalamudAssetDir.absolutePath())) { qCritical(ASTRA_LOG) << "Failed to install Dalamud assets"; Q_EMIT launcher.dalamudError(i18n("Failed to install Dalamud assets.")); - co_return false; + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::dalamudDecided); + co_return shouldContinue; } // TODO: check for file hashes @@ -381,7 +396,9 @@ QCoro::Task AssetUpdater::installDalamud() if (!extractZip(m_tempDir.filePath(QStringLiteral("latest.zip")), m_dalamudDir.absoluteFilePath(m_profile.dalamudChannelName()))) { qCritical(ASTRA_LOG) << "Failed to install Dalamud"; Q_EMIT launcher.dalamudError(i18n("Failed to install Dalamud.")); - co_return false; + + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::dalamudDecided); + co_return shouldContinue; } m_profile.setDalamudVersion(m_remoteDalamudVersion); @@ -432,7 +449,8 @@ QCoro::Task AssetUpdater::installRuntime() qCritical(ASTRA_LOG) << "Failed to install dotnet"; Q_EMIT launcher.dalamudError(i18n("Failed to install .NET runtime.")); - co_return false; + const bool shouldContinue = co_await qCoro(&launcher, &LauncherCore::dalamudDecided); + co_return shouldContinue; } else { Utility::writeVersion(m_dalamudRuntimeDir.absoluteFilePath(QStringLiteral("runtime.ver")), m_remoteRuntimeVersion); diff --git a/launcher/ui/Pages/StatusPage.qml b/launcher/ui/Pages/StatusPage.qml index 56efedc..1d132b0 100644 --- a/launcher/ui/Pages/StatusPage.qml +++ b/launcher/ui/Pages/StatusPage.qml @@ -46,13 +46,29 @@ Kirigami.Page { title: i18n("Dalamud Error") showCloseButton: false - standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.Cancel + standardButtons: Kirigami.Dialog.Cancel - onAccepted: { - LauncherCore.currentProfile.config.dalamudEnabled = false; + customFooterActions: [ + Kirigami.Action { + icon.name: "edit-none-symbolic" + text: i18n("Disable Dalamud") + onTriggered: { + LauncherCore.currentProfile.config.dalamudEnabled = false; + dalamudErrorDialog.accept(); + } + }, + Kirigami.Action { + icon.name: "checkmark-symbolic" + text: i18n("Continue Anyway") + onTriggered: dalamudErrorDialog.accept() + } + ] + + onAccepted: LauncherCore.dalamudDecided(true) + onRejected: { + LauncherCore.dalamudDecided(false); applicationWindow().checkSetup(); } - onRejected: applicationWindow().checkSetup() } Kirigami.PromptDialog { @@ -68,6 +84,27 @@ Kirigami.Page { } } + Kirigami.PromptDialog { + id: assetDialog + + showCloseButton: false + standardButtons: Kirigami.Dialog.Cancel + + customFooterActions: [ + Kirigami.Action { + icon.name: "checkmark-symbolic" + text: i18n("Continue Anyway") + onTriggered: assetDialog.accept() + } + ] + + onAccepted: LauncherCore.assetDecided(true) + onRejected: { + LauncherCore.assetDecided(false); + applicationWindow().checkSetup(); + } + } + Connections { target: LauncherCore @@ -109,5 +146,11 @@ Kirigami.Page { updateDialog.subtitle = message; updateDialog.open(); } + + function onAssetError(message: string): void { + assetDialog.title = i18n("Error"); + assetDialog.subtitle = message; + assetDialog.open(); + } } }