1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-23 04:57:44 +00:00

Add graphical Steam compatibility tool installer

This commit is contained in:
Joshua Goins 2023-08-18 23:27:29 -04:00
parent 564aef5ecf
commit a502d57c8f
12 changed files with 227 additions and 20 deletions

View file

@ -3,7 +3,7 @@ Upstream-Name: Astra
Upstream-Contact: Joshua Goins <josh@redstrate.com>
Source: https://git.sr.ht/~redstrate/astra
Files: README.md .build.yml .editorconfig zone.xiv.astra.yml zone.xiv.astra.desktop build-flatpak.sh compatibilitytool/* misc/*
Files: README.md .build.yml .editorconfig zone.xiv.astra.yml zone.xiv.astra.desktop build-flatpak.sh misc/*
Copyright: Joshua Goins <josh@redstrate.com>
License: CC0-1.0

View file

@ -1,14 +0,0 @@
"compatibilitytools"
{
"compat_tools"
{
"Proton-Astra" // Internal name of this tool
{
"install_path" "."
"display_name" "Astra"
"from_oslist" "windows"
"to_oslist" "linux"
}
}
}

View file

@ -1,5 +0,0 @@
"manifest"
{
"version" "2"
"commandline" "/astra --steam %verb%"
}

View file

@ -6,6 +6,7 @@ target_sources(astra PRIVATE
include/account.h
include/accountmanager.h
include/assetupdater.h
include/compatibilitytoolinstaller.h
include/encryptedarg.h
include/gameinstaller.h
include/headline.h
@ -22,6 +23,7 @@ target_sources(astra PRIVATE
src/account.cpp
src/accountmanager.cpp
src/assetupdater.cpp
src/compatibilitytoolinstaller.cpp
src/encryptedarg.cpp
src/gameinstaller.cpp
src/launchercore.cpp

View file

@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QObject>
#include <QString>
class LauncherCore;
class CompatibilityToolInstaller : public QObject
{
Q_OBJECT
public:
CompatibilityToolInstaller(LauncherCore &launcher, QObject *parent = nullptr);
Q_INVOKABLE void installCompatibilityTool();
Q_INVOKABLE void removeCompatibilityTool();
Q_SIGNALS:
void installFinished();
void error(QString message);
private:
LauncherCore &m_launcher;
};

View file

@ -20,6 +20,7 @@ class SquareLauncher;
class AssetUpdater;
class Watchdog;
class GameInstaller;
class CompatibilityToolInstaller;
class LoginInformation : public QObject
{
@ -141,6 +142,7 @@ public:
bool m_isSteam = false;
Q_INVOKABLE GameInstaller *createInstaller(Profile *profile);
Q_INVOKABLE CompatibilityToolInstaller *createCompatInstaller();
bool isLoadingFinished() const;
bool hasAccount() const;

View file

@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<file>ui/Pages/NewsPage.qml</file>
<file>ui/Pages/StatusPage.qml</file>
<file>ui/Settings/AccountSettings.qml</file>
<file>ui/Settings/CompatibilityToolSetup.qml</file>
<file>ui/Settings/DeveloperSettings.qml</file>
<file>ui/Settings/GeneralSettings.qml</file>
<file>ui/Settings/ProfileSettings.qml</file>

View file

@ -0,0 +1,91 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "compatibilitytoolinstaller.h"
#include "launchercore.h"
CompatibilityToolInstaller::CompatibilityToolInstaller(LauncherCore &launcher, QObject *parent)
: QObject(parent)
, m_launcher(launcher)
{
}
void CompatibilityToolInstaller::installCompatibilityTool()
{
const QDir appDataDir = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::GenericDataLocation)[0];
const QDir steamDir = appDataDir.absoluteFilePath("Steam");
if (!steamDir.exists()) {
Q_EMIT error("Could not find a Steam installation.");
return;
}
const QDir compatToolDir = steamDir.absoluteFilePath("compatibilitytools.d");
const QDir astraToolDir = compatToolDir.absoluteFilePath("astra");
if (astraToolDir.exists()) {
Q_EMIT error("The compatibility tool is already installed.");
return;
} else {
QDir().mkpath(astraToolDir.absolutePath());
}
const QString appPath = QCoreApplication::applicationFilePath();
QFile appFile(appPath);
appFile.link(astraToolDir.absoluteFilePath("astra"));
const QString toolManifestContents = QStringLiteral(
"\"manifest\"\n"
"{\n"
" \"version\" \"2\"\n"
" \"commandline\" \"/astra --steam %verb%\"\n"
"}");
QFile toolManifestFile(astraToolDir.absoluteFilePath("toolmanifest.vdf"));
toolManifestFile.open(QIODevice::WriteOnly);
toolManifestFile.write(toolManifestContents.toUtf8());
toolManifestFile.close();
const QString compatibilityToolContents = QStringLiteral(
"\"compatibilitytools\"\n"
"{\n"
" \"compat_tools\"\n"
" {\n"
"\t\"Proton-Astra\" // Internal name of this tool\n"
"\t{\n"
"\t \"install_path\" \".\"\n"
"\t \"display_name\" \"Astra\"\n"
"\n"
"\t \"from_oslist\" \"windows\"\n"
"\t \"to_oslist\" \"linux\"\n"
"\t}\n"
" }\n"
"}");
QFile compatibilityToolFile(astraToolDir.absoluteFilePath("compatibilitytool.vdf"));
compatibilityToolFile.open(QIODevice::WriteOnly);
compatibilityToolFile.write(compatibilityToolContents.toUtf8());
compatibilityToolFile.close();
Q_EMIT installFinished();
}
void CompatibilityToolInstaller::removeCompatibilityTool()
{
const QDir appDataDir = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::GenericDataLocation)[0];
const QDir steamDir = appDataDir.absoluteFilePath("Steam");
if (!steamDir.exists()) {
Q_EMIT error("Could not find a Steam installation.");
return;
}
const QDir compatToolDir = steamDir.absoluteFilePath("compatibilitytools.d");
QDir astraToolDir = compatToolDir.absoluteFilePath("astra");
if (!astraToolDir.exists()) {
Q_EMIT error("The compatibility tool is not installed.");
return;
} else {
astraToolDir.removeRecursively();
}
Q_EMIT installFinished();
}

View file

@ -16,6 +16,7 @@
#include "account.h"
#include "assetupdater.h"
#include "compatibilitytoolinstaller.h"
#include "config.h"
#include "encryptedarg.h"
#include "launchercore.h"
@ -450,6 +451,11 @@ GameInstaller *LauncherCore::createInstaller(Profile *profile)
return new GameInstaller(*this, *profile, this);
}
CompatibilityToolInstaller *LauncherCore::createCompatInstaller()
{
return new CompatibilityToolInstaller(*this, this);
}
bool LauncherCore::isLoadingFinished() const
{
return m_loadingFinished;

View file

@ -10,6 +10,7 @@
#include <QtWebEngine>
#include "astra-version.h"
#include "compatibilitytoolinstaller.h"
#include "gameinstaller.h"
#include "launchercore.h"
#include "sapphirelauncher.h"
@ -75,6 +76,11 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("zone.xiv.astra", 1, 0, "LauncherCore", &c);
qmlRegisterUncreatableType<GameInstaller>("zone.xiv.astra", 1, 0, "GameInstaller", QStringLiteral("Use LauncherCore::createInstaller"));
qmlRegisterUncreatableType<CompatibilityToolInstaller>("zone.xiv.astra",
1,
0,
"CompatibilityToolInstaller",
QStringLiteral("Use LauncherCore::createCompatInstaller"));
qmlRegisterUncreatableType<AccountManager>("zone.xiv.astra", 1, 0, "AccountManager", QStringLiteral("Use LauncherCore::accountManager"));
qmlRegisterUncreatableType<ProfileManager>("zone.xiv.astra", 1, 0, "ProfileManager", QStringLiteral("Use LauncherCore::profileManager"));
qmlRegisterUncreatableType<Profile>("zone.xiv.astra", 1, 0, "Profile", QStringLiteral("Use from ProfileManager"));

View file

@ -0,0 +1,84 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick 2.15
import QtQuick.Window 2.15
import org.kde.kirigami 2.20 as Kirigami
import QtQuick.Controls 2.15 as Controls
import QtQuick.Layouts 1.15
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import zone.xiv.astra 1.0
Kirigami.Page {
id: page
property var installer: null
title: i18n("Install Compatibility Tool")
ColumnLayout {
width: parent.width
MobileForm.FormCard {
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormCardHeader {
title: i18n("Compatibility Tool")
}
MobileForm.FormTextDelegate {
text: i18n("Press the button below to install the compatibility tool for Steam.")
}
MobileForm.FormDelegateSeparator {}
MobileForm.FormButtonDelegate {
text: i18n("Install Tool")
icon.name: "install"
onClicked: {
page.installer = LauncherCore.createCompatInstaller();
page.installer.installCompatibilityTool();
}
}
MobileForm.FormDelegateSeparator {}
MobileForm.FormButtonDelegate {
text: i18n("Remove Tool")
icon.name: "delete"
onClicked: {
page.installer = LauncherCore.createCompatInstaller();
page.installer.removeCompatibilityTool();
}
}
}
}
}
Kirigami.PromptDialog {
id: errorDialog
title: i18n("Install error")
showCloseButton: false
standardButtons: Kirigami.Dialog.Ok
onAccepted: applicationWindow().pageStack.layers.pop()
onRejected: applicationWindow().pageStack.layers.pop()
}
Connections {
enabled: page.installer !== null
target: page.installer
function onInstallFinished() {
applicationWindow().pageStack.layers.pop()
}
function onError(message) {
errorDialog.subtitle = message
errorDialog.open()
}
}
}

View file

@ -116,6 +116,14 @@ Kirigami.ScrollablePage {
}
}
MobileForm.FormButtonDelegate {
text: i18n("Setup Compatibility Tool")
icon.name: "install"
onClicked: applicationWindow().pageStack.layers.push('qrc:/ui/Settings/CompatibilityToolSetup.qml')
}
MobileForm.FormDelegateSeparator {}
MobileForm.FormButtonDelegate {
text: i18n("Developer Settings")
icon.name: "configure"