1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-21 20:27:45 +00:00

Fix game installation, and move default game directory to app data

This commit is contained in:
Joshua Goins 2023-08-18 12:59:07 -04:00
parent 99e783ca8f
commit 0584b3a978
8 changed files with 118 additions and 105 deletions

View file

@ -124,7 +124,7 @@ public:
bool m_isSteam = false; bool m_isSteam = false;
Q_INVOKABLE GameInstaller *createInstaller(Profile &profile); Q_INVOKABLE GameInstaller *createInstaller(Profile *profile);
bool isLoadingFinished() const; bool isLoadingFinished() const;
bool hasAccount() const; bool hasAccount() const;

View file

@ -5,10 +5,10 @@
#include <QObject> #include <QObject>
#include "profileconfig.h"
#include "squareboot.h" #include "squareboot.h"
class Account; class Account;
class ProfileConfig;
class Profile : public QObject class Profile : public QObject
{ {
@ -129,8 +129,8 @@ public:
BootData *bootData; BootData *bootData;
GameData *gameData; GameData *gameData;
physis_Repositories repositories; physis_Repositories repositories = {};
const char *bootVersion; const char *bootVersion = nullptr;
QString dalamudVersion; QString dalamudVersion;
int dalamudAssetVersion = -1; int dalamudAssetVersion = -1;
@ -178,7 +178,7 @@ Q_SIGNALS:
private: private:
QString m_uuid; QString m_uuid;
QString m_wineVersion; QString m_wineVersion;
ProfileConfig m_config; ProfileConfig *m_config = nullptr;
Account *m_account = nullptr; Account *m_account = nullptr;
LauncherCore &m_launcher; LauncherCore &m_launcher;
}; };

View file

@ -36,10 +36,11 @@ public:
Q_INVOKABLE bool canDelete(Profile *account) const; Q_INVOKABLE bool canDelete(Profile *account) const;
static QString getDefaultGamePath();
private: private:
void insertProfile(Profile *profile); void insertProfile(Profile *profile);
QString getDefaultGamePath();
QString getDefaultWinePrefixPath(); QString getDefaultWinePrefixPath();
QVector<Profile *> m_profiles; QVector<Profile *> m_profiles;

View file

@ -7,7 +7,7 @@
SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
SPDX-License-Identifier: CC0-1.0 SPDX-License-Identifier: CC0-1.0
--> -->
<kcfgfile/> <include>profilemanager.h</include>
<kcfgfile name="astrastaterc" stateConfig="true"> <kcfgfile name="astrastaterc" stateConfig="true">
<parameter name="uuid"/> <parameter name="uuid"/>
</kcfgfile> </kcfgfile>
@ -20,6 +20,7 @@ SPDX-License-Identifier: CC0-1.0
<default>1</default> <default>1</default>
</entry> </entry>
<entry key="GamePath" type="Path"> <entry key="GamePath" type="Path">
<default code="true">ProfileManager::getDefaultGamePath()</default>
</entry> </entry>
<entry key="WinePath" type="Path"> <entry key="WinePath" type="Path">
</entry> </entry>

View file

@ -11,6 +11,9 @@
#include "launchercore.h" #include "launchercore.h"
#include "profile.h" #include "profile.h"
const QString installerUrl = QStringLiteral("https://download.finalfantasyxiv.com/inst/ffxivsetup.exe");
const QByteArray installerSha256 = QByteArray::fromHex("cf70bfaaf4f429794358ef84acbcbdc4193bee109fa1b6aea81bd4de038e500e");
GameInstaller::GameInstaller(LauncherCore &launcher, Profile &profile, QObject *parent) GameInstaller::GameInstaller(LauncherCore &launcher, Profile &profile, QObject *parent)
: QObject(parent) : QObject(parent)
, m_launcher(launcher) , m_launcher(launcher)
@ -20,28 +23,31 @@ GameInstaller::GameInstaller(LauncherCore &launcher, Profile &profile, QObject *
void GameInstaller::installGame() void GameInstaller::installGame()
{ {
const QString installDirectory = m_profile.gamePath(); const QDir installDirectory = m_profile.gamePath();
qDebug() << "Installing game to " << installDirectory << "!";
qDebug() << "Now downloading installer file...";
QNetworkRequest request(QUrl("https://gdl.square-enix.com/ffxiv/inst/ffxivsetup.exe")); QNetworkRequest request((QUrl(installerUrl)));
auto reply = m_launcher.mgr->get(request); auto reply = m_launcher.mgr->get(request);
QObject::connect(reply, &QNetworkReply::finished, [this, reply, installDirectory] { QObject::connect(reply, &QNetworkReply::finished, [this, reply, installDirectory] {
QString dataDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation); const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
QFile file(dataDir + "/ffxivsetup.exe"); const QByteArray data = reply->readAll();
QCryptographicHash hash(QCryptographicHash::Sha256);
hash.addData(data);
// TODO: turn into a proper error
Q_ASSERT(hash.result() == installerSha256);
QFile file(dataDir.absoluteFilePath("ffxivsetup.exe"));
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
file.write(reply->readAll()); file.write(data);
file.close(); file.close();
const std::string installDirectoryStd = installDirectory.toStdString(); const std::string installDirectoryStd = installDirectory.absolutePath().toStdString();
const std::string fileNameStd = file.fileName().toStdString(); const std::string fileNameStd = file.fileName().toStdString();
physis_install_game(fileNameStd.c_str(), installDirectoryStd.c_str()); physis_install_game(fileNameStd.c_str(), installDirectoryStd.c_str());
qDebug() << "Done installing to " << installDirectory << "!";
Q_EMIT installFinished(); Q_EMIT installFinished();
}); });
} }

View file

@ -377,9 +377,10 @@ bool LauncherCore::autoLogin(Profile &profile)
return true; return true;
} }
GameInstaller *LauncherCore::createInstaller(Profile &profile) GameInstaller *LauncherCore::createInstaller(Profile *profile)
{ {
return new GameInstaller(*this, profile, this); Q_ASSERT(profile != nullptr);
return new GameInstaller(*this, *profile, this);
} }
bool LauncherCore::isLoadingFinished() const bool LauncherCore::isLoadingFinished() const

View file

@ -10,11 +10,12 @@
#include "account.h" #include "account.h"
#include "launchercore.h" #include "launchercore.h"
#include "profileconfig.h"
Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent) Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent)
: QObject(parent) : QObject(parent)
, m_uuid(key) , m_uuid(key)
, m_config(key) , m_config(new ProfileConfig(key))
, m_launcher(launcher) , m_launcher(launcher)
{ {
readGameVersion(); readGameVersion();
@ -119,98 +120,98 @@ void Profile::readWineInfo()
QString Profile::name() const QString Profile::name() const
{ {
return m_config.name(); return m_config->name();
} }
void Profile::setName(const QString &name) void Profile::setName(const QString &name)
{ {
if (m_config.name() != name) { if (m_config->name() != name) {
m_config.setName(name); m_config->setName(name);
m_config.save(); m_config->save();
Q_EMIT nameChanged(); Q_EMIT nameChanged();
} }
} }
int Profile::language() const int Profile::language() const
{ {
return m_config.language(); return m_config->language();
} }
void Profile::setLanguage(const int value) void Profile::setLanguage(const int value)
{ {
if (m_config.language() != value) { if (m_config->language() != value) {
m_config.setLanguage(value); m_config->setLanguage(value);
m_config.save(); m_config->save();
Q_EMIT languageChanged(); Q_EMIT languageChanged();
} }
} }
QString Profile::gamePath() const QString Profile::gamePath() const
{ {
return m_config.gamePath(); return m_config->gamePath();
} }
void Profile::setGamePath(const QString &path) void Profile::setGamePath(const QString &path)
{ {
if (m_config.gamePath() != path) { if (m_config->gamePath() != path) {
m_config.setGamePath(path); m_config->setGamePath(path);
m_config.save(); m_config->save();
Q_EMIT gamePathChanged(); Q_EMIT gamePathChanged();
} }
} }
QString Profile::winePath() const QString Profile::winePath() const
{ {
return m_config.winePath(); return m_config->winePath();
} }
void Profile::setWinePath(const QString &path) void Profile::setWinePath(const QString &path)
{ {
if (m_config.winePath() != path) { if (m_config->winePath() != path) {
m_config.setWinePath(path); m_config->setWinePath(path);
m_config.save(); m_config->save();
Q_EMIT winePathChanged(); Q_EMIT winePathChanged();
} }
} }
QString Profile::winePrefixPath() const QString Profile::winePrefixPath() const
{ {
return m_config.winePrefixPath(); return m_config->winePrefixPath();
} }
void Profile::setWinePrefixPath(const QString &path) void Profile::setWinePrefixPath(const QString &path)
{ {
if (m_config.winePrefixPath() != path) { if (m_config->winePrefixPath() != path) {
m_config.setWinePrefixPath(path); m_config->setWinePrefixPath(path);
m_config.save(); m_config->save();
Q_EMIT winePrefixPathChanged(); Q_EMIT winePrefixPathChanged();
} }
} }
bool Profile::watchdogEnabled() const bool Profile::watchdogEnabled() const
{ {
return m_config.enableWatchdog(); return m_config->enableWatchdog();
} }
void Profile::setWatchdogEnabled(const bool value) void Profile::setWatchdogEnabled(const bool value)
{ {
if (m_config.enableWatchdog() != value) { if (m_config->enableWatchdog() != value) {
m_config.setEnableWatchdog(value); m_config->setEnableWatchdog(value);
m_config.save(); m_config->save();
Q_EMIT enableWatchdogChanged(); Q_EMIT enableWatchdogChanged();
} }
} }
Profile::WineType Profile::wineType() const Profile::WineType Profile::wineType() const
{ {
return static_cast<WineType>(m_config.wineType()); return static_cast<WineType>(m_config->wineType());
} }
void Profile::setWineType(const WineType type) void Profile::setWineType(const WineType type)
{ {
if (static_cast<WineType>(m_config.wineType()) != type) { if (static_cast<WineType>(m_config->wineType()) != type) {
m_config.setWineType(static_cast<int>(type)); m_config->setWineType(static_cast<int>(type));
m_config.save(); m_config->save();
Q_EMIT wineTypeChanged(); Q_EMIT wineTypeChanged();
readWineInfo(); readWineInfo();
} }
@ -218,182 +219,182 @@ void Profile::setWineType(const WineType type)
bool Profile::esyncEnabled() const bool Profile::esyncEnabled() const
{ {
return m_config.useESync(); return m_config->useESync();
} }
void Profile::setESyncEnabled(const bool value) void Profile::setESyncEnabled(const bool value)
{ {
if (m_config.useESync() != value) { if (m_config->useESync() != value) {
m_config.setUseESync(value); m_config->setUseESync(value);
m_config.save(); m_config->save();
Q_EMIT useESyncChanged(); Q_EMIT useESyncChanged();
} }
} }
bool Profile::gamescopeEnabled() const bool Profile::gamescopeEnabled() const
{ {
return m_config.useGamescope(); return m_config->useGamescope();
} }
void Profile::setGamescopeEnabled(const bool value) void Profile::setGamescopeEnabled(const bool value)
{ {
if (m_config.useGamescope() != value) { if (m_config->useGamescope() != value) {
m_config.setUseGamescope(value); m_config->setUseGamescope(value);
m_config.save(); m_config->save();
Q_EMIT useGamescopeChanged(); Q_EMIT useGamescopeChanged();
} }
} }
bool Profile::gamemodeEnabled() const bool Profile::gamemodeEnabled() const
{ {
return m_config.useGamemode(); return m_config->useGamemode();
} }
void Profile::setGamemodeEnabled(const bool value) void Profile::setGamemodeEnabled(const bool value)
{ {
if (m_config.useGamemode() != value) { if (m_config->useGamemode() != value) {
m_config.setUseGamemode(value); m_config->setUseGamemode(value);
m_config.save(); m_config->save();
Q_EMIT useGamemodeChanged(); Q_EMIT useGamemodeChanged();
} }
} }
bool Profile::directx9Enabled() const bool Profile::directx9Enabled() const
{ {
return m_config.useDX9(); return m_config->useDX9();
} }
void Profile::setDirectX9Enabled(const bool value) void Profile::setDirectX9Enabled(const bool value)
{ {
if (m_config.useDX9() != value) { if (m_config->useDX9() != value) {
m_config.setUseDX9(value); m_config->setUseDX9(value);
m_config.save(); m_config->save();
Q_EMIT useDX9Changed(); Q_EMIT useDX9Changed();
} }
} }
bool Profile::gamescopeFullscreen() const bool Profile::gamescopeFullscreen() const
{ {
return m_config.gamescopeFullscreen(); return m_config->gamescopeFullscreen();
} }
void Profile::setGamescopeFullscreen(const bool value) void Profile::setGamescopeFullscreen(const bool value)
{ {
if (m_config.gamescopeFullscreen() != value) { if (m_config->gamescopeFullscreen() != value) {
m_config.setGamescopeFullscreen(value); m_config->setGamescopeFullscreen(value);
m_config.save(); m_config->save();
Q_EMIT gamescopeFullscreenChanged(); Q_EMIT gamescopeFullscreenChanged();
} }
} }
bool Profile::gamescopeBorderless() const bool Profile::gamescopeBorderless() const
{ {
return m_config.gamescopeBorderless(); return m_config->gamescopeBorderless();
} }
void Profile::setGamescopeBorderless(const bool value) void Profile::setGamescopeBorderless(const bool value)
{ {
if (m_config.gamescopeBorderless() != value) { if (m_config->gamescopeBorderless() != value) {
m_config.setGamescopeBorderless(value); m_config->setGamescopeBorderless(value);
m_config.save(); m_config->save();
Q_EMIT gamescopeBorderlessChanged(); Q_EMIT gamescopeBorderlessChanged();
} }
} }
int Profile::gamescopeWidth() const int Profile::gamescopeWidth() const
{ {
return m_config.gamescopeWidth(); return m_config->gamescopeWidth();
} }
void Profile::setGamescopeWidth(const int value) void Profile::setGamescopeWidth(const int value)
{ {
if (m_config.gamescopeWidth() != value) { if (m_config->gamescopeWidth() != value) {
m_config.setGamescopeWidth(value); m_config->setGamescopeWidth(value);
m_config.save(); m_config->save();
Q_EMIT gamescopeWidthChanged(); Q_EMIT gamescopeWidthChanged();
} }
} }
int Profile::gamescopeHeight() const int Profile::gamescopeHeight() const
{ {
return m_config.gamescopeHeight(); return m_config->gamescopeHeight();
} }
void Profile::setGamescopeHeight(const int value) void Profile::setGamescopeHeight(const int value)
{ {
if (m_config.gamescopeHeight() != value) { if (m_config->gamescopeHeight() != value) {
m_config.setGamescopeHeight(value); m_config->setGamescopeHeight(value);
m_config.save(); m_config->save();
Q_EMIT gamescopeHeightChanged(); Q_EMIT gamescopeHeightChanged();
} }
} }
int Profile::gamescopeRefreshRate() const int Profile::gamescopeRefreshRate() const
{ {
return m_config.gamescopeRefreshRate(); return m_config->gamescopeRefreshRate();
} }
void Profile::setGamescopeRefreshRate(const int value) void Profile::setGamescopeRefreshRate(const int value)
{ {
if (m_config.gamescopeRefreshRate() != value) { if (m_config->gamescopeRefreshRate() != value) {
m_config.setGamescopeRefreshRate(value); m_config->setGamescopeRefreshRate(value);
m_config.save(); m_config->save();
Q_EMIT gamescopeRefreshRateChanged(); Q_EMIT gamescopeRefreshRateChanged();
} }
} }
bool Profile::dalamudEnabled() const bool Profile::dalamudEnabled() const
{ {
return m_config.dalamudEnabled(); return m_config->dalamudEnabled();
} }
void Profile::setDalamudEnabled(const bool value) void Profile::setDalamudEnabled(const bool value)
{ {
if (m_config.dalamudEnabled() != value) { if (m_config->dalamudEnabled() != value) {
m_config.setDalamudEnabled(value); m_config->setDalamudEnabled(value);
m_config.save(); m_config->save();
Q_EMIT dalamudEnabledChanged(); Q_EMIT dalamudEnabledChanged();
} }
} }
bool Profile::dalamudOptOut() const bool Profile::dalamudOptOut() const
{ {
return m_config.dalamudOptOut(); return m_config->dalamudOptOut();
} }
void Profile::setDalamudOptOut(const bool value) void Profile::setDalamudOptOut(const bool value)
{ {
if (m_config.dalamudOptOut() != value) { if (m_config->dalamudOptOut() != value) {
m_config.setDalamudOptOut(value); m_config->setDalamudOptOut(value);
m_config.save(); m_config->save();
Q_EMIT dalamudOptOutChanged(); Q_EMIT dalamudOptOutChanged();
} }
} }
Profile::DalamudChannel Profile::dalamudChannel() const Profile::DalamudChannel Profile::dalamudChannel() const
{ {
return static_cast<DalamudChannel>(m_config.dalamudChannel()); return static_cast<DalamudChannel>(m_config->dalamudChannel());
} }
void Profile::setDalamudChannel(const DalamudChannel value) void Profile::setDalamudChannel(const DalamudChannel value)
{ {
if (static_cast<DalamudChannel>(m_config.dalamudChannel()) != value) { if (static_cast<DalamudChannel>(m_config->dalamudChannel()) != value) {
m_config.setDalamudChannel(static_cast<int>(value)); m_config->setDalamudChannel(static_cast<int>(value));
m_config.save(); m_config->save();
Q_EMIT dalamudChannelChanged(); Q_EMIT dalamudChannelChanged();
} }
} }
bool Profile::argumentsEncrypted() const bool Profile::argumentsEncrypted() const
{ {
return m_config.encryptArguments(); return m_config->encryptArguments();
} }
void Profile::setArgumentsEncrypted(const bool value) void Profile::setArgumentsEncrypted(const bool value)
{ {
if (m_config.encryptArguments() != value) { if (m_config->encryptArguments() != value) {
m_config.setEncryptArguments(value); m_config->setEncryptArguments(value);
m_config.save(); m_config->save();
Q_EMIT encryptedArgumentsChanged(); Q_EMIT encryptedArgumentsChanged();
} }
} }
@ -407,9 +408,9 @@ void Profile::setAccount(Account *account)
{ {
if (account != m_account) { if (account != m_account) {
m_account = account; m_account = account;
if (account->uuid() != m_config.account()) { if (account->uuid() != m_config->account()) {
m_config.setAccount(account->uuid()); m_config->setAccount(account->uuid());
m_config.save(); m_config->save();
} }
Q_EMIT accountChanged(); Q_EMIT accountChanged();
} }
@ -438,7 +439,7 @@ void Profile::readGameVersion()
QString Profile::accountUuid() const QString Profile::accountUuid() const
{ {
return m_config.account(); return m_config->account();
} }
QString Profile::expansionVersionText() const QString Profile::expansionVersionText() const

View file

@ -3,7 +3,9 @@
#include "profilemanager.h" #include "profilemanager.h"
#include <KSharedConfig>
#include <QDir> #include <QDir>
#include <QUuid>
ProfileManager::ProfileManager(LauncherCore &launcher, QObject *parent) ProfileManager::ProfileManager(LauncherCore &launcher, QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
@ -79,7 +81,8 @@ QString ProfileManager::getDefaultGamePath()
#endif #endif
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
return QDir::homePath() + "/.wine/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn"; const QString appData = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::AppDataLocation)[0];
return QStringLiteral("%1/game").arg(appData);
#endif #endif
} }