From 0d6f14767816962dbf1cef2d3aa3784fac940141 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:22:42 -0400 Subject: [PATCH 1/6] Use AppStream metadata to construct KAboutData Which de-duplicates a lot of information! --- CMakeLists.txt | 3 ++- launcher/src/main.cpp | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7eaa05a..6a15044 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,9 +58,10 @@ if (BUILD_TESTING) add_subdirectory(autotests) endif() +install(FILES zone.xiv.astra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) + if (NOT WIN32) install(FILES zone.xiv.astra.desktop DESTINATION ${KDE_INSTALL_APPDIR}) - install(FILES zone.xiv.astra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES zone.xiv.astra.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) ecm_qt_install_logging_categories( diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp index 6e7b743..dfa3a69 100755 --- a/launcher/src/main.cpp +++ b/launcher/src/main.cpp @@ -6,6 +6,7 @@ #include #include #include // NOTE: do not remove this, if your IDE suggests to do so +#include #include #include #include @@ -46,13 +47,16 @@ int main(int argc, char *argv[]) } KLocalizedString::setApplicationDomain("astra"); + // This needs to be set before fromAppStreamForApplication can be used, so don't remove this! + QGuiApplication::setDesktopFileName(u"zone.xiv.astra"_s); - KAboutData about(QStringLiteral("astra"), - i18n("Astra"), - QStringLiteral(ASTRA_VERSION_STRING), - i18n("Play FFXIV"), - KAboutLicense::GPL_V3, - i18n("© 2021-2026 Joshua Goins")); + auto about = KAboutData::fromAppStreamForApplication(); + about.setVersion(QByteArrayLiteral(ASTRA_VERSION_STRING)); + // Works around bug fixed with https://invent.kde.org/frameworks/kcoreaddons/-/merge_requests/582 +#if KCOREADDONS_VERSION < QT_VERSION_CHECK(6, 28, 0) + about.setComponentName(QStringLiteral("astra")); +#endif + about.setCopyrightStatement(i18n("© 2021-2026 Joshua Goins")); about.setOtherText( i18n("This software requires that you have legitimate access to FINAL FANTASY XIV. By using this software, you may be in violation " "of your User Agreement.\n\nFINAL FANTASY, FINAL FANTASY XIV, FFXIV, SQUARE ENIX, and the SQUARE ENIX logo are registered trademarks or " @@ -62,7 +66,6 @@ int main(int argc, char *argv[]) QStringLiteral("josh@redstrate.com"), QStringLiteral("https://redstrate.com/"), QUrl(QStringLiteral("https://redstrate.com/rss-image.png"))); - about.setHomepage(QStringLiteral("https://xiv.zone/astra")); about.addComponent(QStringLiteral("physis"), i18n("Library for reading and writing FFXIV data."), QString::fromLatin1(physis_get_physis_version()), @@ -83,14 +86,9 @@ int main(int argc, char *argv[]) QStringLiteral("3.1.1"), QStringLiteral("https://github.com/paolostivanin/libcotp"), KAboutLicense::Unknown); - about.setDesktopFileName(QStringLiteral("zone.xiv.astra")); - about.setBugAddress(QByteArrayLiteral("https://github.com/redstrate/astra/issues")); - about.setComponentName(QStringLiteral("astra")); - about.setProgramLogo(QStringLiteral("zone.xiv.astra")); - about.setOrganizationDomain(QByteArrayLiteral("xiv.zone")); KAboutData::setApplicationData(about); - + QGuiApplication::setWindowIcon(QIcon::fromTheme(u"zone.xiv.astra"_s)); initializeLogging(); QCommandLineParser parser; From 944fdd23ed20b20e0b641236495fb6770956f397 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:23:09 -0400 Subject: [PATCH 2/6] AppStream metadata fix-ups --- zone.xiv.astra.appdata.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone.xiv.astra.appdata.xml b/zone.xiv.astra.appdata.xml index a0fdade..04dd77b 100644 --- a/zone.xiv.astra.appdata.xml +++ b/zone.xiv.astra.appdata.xml @@ -19,8 +19,8 @@ ffxiv ff14 - https://xiv.zone/astra - https://github.com/redstrate/astra/issues + https://xiv.zone/software/astra + https://github.com/redstrate/astra/issues/new https://redstrate.com/contact https://github.com/redstrate/astra zone.xiv.astra.desktop From 3973e162d2502d1698f3388b0c3311035518d62a Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:26:39 -0400 Subject: [PATCH 3/6] Stop hardcoding KDSingleApplication and libcotp version strings These keep drifting out-of-date, lets be a little bit smarter about this. --- launcher/CMakeLists.txt | 2 ++ launcher/src/main.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index f51eed9..7f31397 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -95,6 +95,8 @@ target_link_libraries(astra_static PUBLIC QCoro::Core QCoro::Network QCoro::Qml) +get_target_property(LIBCOTP_VERSION cotp VERSION) +target_compile_definitions(astra_static PUBLIC LIBCOTP_VERSION_STRING="${LIBCOTP_VERSION}") if (LINUX) target_link_libraries(astra_static PUBLIC KF6::FileMetaData) endif() diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp index dfa3a69..a0c9cc0 100755 --- a/launcher/src/main.cpp +++ b/launcher/src/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #ifdef Q_OS_WINDOWS @@ -78,12 +79,12 @@ int main(int argc, char *argv[]) KAboutLicense::GPL_V3); about.addComponent(QStringLiteral("KDSingleApplication"), i18n("Helper class for single-instance policy applications."), - QStringLiteral("1.2.0"), + QString::fromLatin1(KDSINGLEAPPLICATION_VERSION_STRING), QStringLiteral("https://github.com/KDAB/KDSingleApplication"), KAboutLicense::MIT); about.addComponent(QStringLiteral("libcotp"), - i18n(" C library that generates TOTP and HOTP."), - QStringLiteral("3.1.1"), + i18n("C library that generates TOTP and HOTP."), + QString::fromLatin1(LIBCOTP_VERSION_STRING), QStringLiteral("https://github.com/paolostivanin/libcotp"), KAboutLicense::Unknown); From 5b97a1fe88445d734c2a68fd4cd680534698f2a7 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:28:21 -0400 Subject: [PATCH 4/6] Fix icon not showing up inside application on Windows This mostly affects the Settings pages. --- CMakeLists.txt | 17 +++++++---------- launcher/CMakeLists.txt | 10 ---------- launcher/ui/Setup/SetupPage.qml | 6 ++++-- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a15044..dd2f49a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,17 +59,14 @@ if (BUILD_TESTING) endif() install(FILES zone.xiv.astra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) +install(FILES zone.xiv.astra.desktop DESTINATION ${KDE_INSTALL_APPDIR}) +install(FILES zone.xiv.astra.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) -if (NOT WIN32) - install(FILES zone.xiv.astra.desktop DESTINATION ${KDE_INSTALL_APPDIR}) - install(FILES zone.xiv.astra.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) - - ecm_qt_install_logging_categories( - EXPORT ASTRA - FILE astra.categories - SORT DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR} - ) -endif() +ecm_qt_install_logging_categories( + EXPORT ASTRA + FILE astra.categories + SORT DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR} +) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 7f31397..be054d7 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -147,16 +147,6 @@ qt_target_qml_sources(astra_static ui/Main.qml ) -set_source_files_properties(../zone.xiv.astra.svg PROPERTIES - QT_RESOURCE_ALIAS /zone.xiv.astra.svg -) - -qt_target_qml_sources(astra_static - PREFIX / - RESOURCES - ../zone.xiv.astra.svg -) - target_link_libraries(astra PRIVATE astra_static astra_staticplugin diff --git a/launcher/ui/Setup/SetupPage.qml b/launcher/ui/Setup/SetupPage.qml index e18a461..034459a 100644 --- a/launcher/ui/Setup/SetupPage.qml +++ b/launcher/ui/Setup/SetupPage.qml @@ -31,12 +31,14 @@ FormCard.FormCardPage { onAccepted: page.profile.config.gamePath = decodeURI(selectedFolder.toString().replace("file://", "").substr(Qt.platform.os === "windows" ? 1 : 0)) } - Image { - source: "qrc:/zone.xiv.astra.svg" + Kirigami.Icon { + source: "zone.xiv.astra" fillMode: Image.PreserveAspectFit visible: !LauncherCore.profileManager.hasAnyExistingInstallations() + Layout.preferredWidth: Math.round(Kirigami.Units.iconSizes.huge * 1.5) + Layout.preferredHeight: Math.round(Kirigami.Units.iconSizes.huge * 1.5) Layout.fillWidth: true Layout.fillHeight: true Layout.margins: Kirigami.Units.largeSpacing * 3 From 38527dff8308e24b8b9c7bd8b438cfcc3cda1246 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:30:52 -0400 Subject: [PATCH 5/6] Add an easy way to enable verbose logging and look at logs This is especially useful for Windows users where this is much harder to figure out how to set up. --- launcher/CMakeLists.txt | 1 + launcher/config.kcfg | 3 ++ launcher/src/launchercore.cpp | 4 ++ launcher/ui/Settings/SettingsPage.qml | 6 +++ launcher/ui/Settings/TroubleshootingPage.qml | 47 ++++++++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 launcher/ui/Settings/TroubleshootingPage.qml diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index be054d7..53db3c0 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -136,6 +136,7 @@ qt_target_qml_sources(astra_static ui/Settings/ProfileSettings.qml ui/Settings/ProfilesPage.qml ui/Settings/SettingsPage.qml + ui/Settings/TroubleshootingPage.qml ui/Setup/AccountSetup.qml ui/Setup/AddSquareEnix.qml ui/Setup/BenchmarkInstallProgress.qml diff --git a/launcher/config.kcfg b/launcher/config.kcfg index 72a77e0..565c090 100644 --- a/launcher/config.kcfg +++ b/launcher/config.kcfg @@ -23,6 +23,9 @@ SPDX-License-Identifier: CC0-1.0 QDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)).absoluteFilePath(QStringLiteral("FFXIV")) + + false + diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp index 3f7fc93..f72c636 100755 --- a/launcher/src/launchercore.cpp +++ b/launcher/src/launchercore.cpp @@ -35,6 +35,10 @@ LauncherCore::LauncherCore() : QObject() { m_config = new Config(KSharedConfig::openConfig(QStringLiteral("astrarc"), KConfig::SimpleConfig, QStandardPaths::AppConfigLocation), this); + if (config()->verboseLogging()) { + QLoggingCategory::setFilterRules(QStringLiteral("zone.xiv.astra*=true")); + } + m_mgr = new QNetworkAccessManager(this); m_squareEnixLogin = new SquareEnixLogin(*this, this); m_profileManager = new ProfileManager(this); diff --git a/launcher/ui/Settings/SettingsPage.qml b/launcher/ui/Settings/SettingsPage.qml index 29b1f42..7eb33d9 100644 --- a/launcher/ui/Settings/SettingsPage.qml +++ b/launcher/ui/Settings/SettingsPage.qml @@ -49,6 +49,12 @@ KirigamiSettings.ConfigurationView { page: () => Qt.createComponent("zone.xiv.astra", "DeveloperSettings") visible: LauncherCore.config.showDevTools }, + KirigamiSettings.ConfigurationModule { + moduleId: "troubleshooting" + text: i18n("Troubleshooting") + icon.name: "error-symbolic" + page: () => Qt.createComponent("zone.xiv.astra", "TroubleshootingPage") + }, KirigamiSettings.ConfigurationModule { moduleId: "about" text: i18n("About Astra") diff --git a/launcher/ui/Settings/TroubleshootingPage.qml b/launcher/ui/Settings/TroubleshootingPage.qml new file mode 100644 index 0000000..a91d778 --- /dev/null +++ b/launcher/ui/Settings/TroubleshootingPage.qml @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2026 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtCore +import QtQuick +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +import zone.xiv.astra + +import "../Components" + +FormCard.FormCardPage { + id: page + + title: i18nc("@title:window", "Troubleshooting") + + FormCard.FormCard { + Layout.topMargin: Kirigami.Units.largeSpacing * 4 + + FormCard.FormCheckDelegate { + id: verboseLoggingDelegate + + text: i18n("Enable Verbose Logging") + description: i18n("Requires a restart of Astra to take effect.") + checked: LauncherCore.config.verboseLogging + onCheckedChanged: { + LauncherCore.config.verboseLogging = checked; + LauncherCore.config.save(); + } + } + + FormCard.FormDelegateSeparator { + above: verboseLoggingDelegate + below: logsFolderDelegate + } + + FormCard.FormButtonDelegate { + id: logsFolderDelegate + + text: i18nc("@action:button", "Open Logs Folder") + onClicked: Qt.openUrlExternally(StandardPaths.writableLocation(StandardPaths.AppDataLocation) + "/log") + } + } +} From e890b934b04765e0395f92feda6655954a6b1c1c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 20 Jun 2026 14:32:34 -0400 Subject: [PATCH 6/6] Add debug logging when failing to find _STORED_ value A user is running into this edge case and hopefully this helps to figure out what's going on. --- launcher/src/squareenixlogin.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/launcher/src/squareenixlogin.cpp b/launcher/src/squareenixlogin.cpp index 9d47d67..dfdd5e2 100644 --- a/launcher/src/squareenixlogin.cpp +++ b/launcher/src/squareenixlogin.cpp @@ -271,11 +271,13 @@ QCoro::Task> SquareEnixLogin::getStor const QRegularExpressionMatch match = re.match(str); if (match.hasMatch()) { co_return StoredInfo{match.captured(1), url}; - } else { - Q_EMIT m_launcher.loginError( - i18n("Square Enix servers refused to confirm session information. The game may be under maintenance, try the official launcher.")); - co_return {}; } + + qCDebug(ASTRA_LOG) << "Failed to find _STORED_ in" << str; + Q_EMIT m_launcher.loginError( + i18n("Square Enix servers refused to confirm session information. The game may be under maintenance, try the official launcher.")); + + co_return {}; } QCoro::Task SquareEnixLogin::loginOAuth()