1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-05-13 21:07:46 +00:00

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.
This commit is contained in:
Joshua Goins 2025-05-07 20:18:38 -04:00
parent b38032c3b5
commit 8c2a591279
3 changed files with 77 additions and 13 deletions

View file

@ -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;

View file

@ -9,6 +9,7 @@
#include <KLocalizedString>
#include <KTar>
#include <KZip>
#include <QCoroSignal>
#include <QFile>
#include <QJsonDocument>
#include <QNetworkReply>
@ -86,8 +87,10 @@ QCoro::Task<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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);

View file

@ -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();
}
}
}