diff --git a/launcher/include/launchercore.h b/launcher/include/launchercore.h index 2ebbe5a..c096ca0 100755 --- a/launcher/include/launchercore.h +++ b/launcher/include/launchercore.h @@ -124,7 +124,7 @@ public: bool m_isSteam = false; - Q_INVOKABLE GameInstaller *createInstaller(Profile &profile); + Q_INVOKABLE GameInstaller *createInstaller(Profile *profile); bool isLoadingFinished() const; bool hasAccount() const; diff --git a/launcher/include/profile.h b/launcher/include/profile.h index 3f3c339..8fb2f47 100644 --- a/launcher/include/profile.h +++ b/launcher/include/profile.h @@ -5,10 +5,10 @@ #include -#include "profileconfig.h" #include "squareboot.h" class Account; +class ProfileConfig; class Profile : public QObject { @@ -129,8 +129,8 @@ public: BootData *bootData; GameData *gameData; - physis_Repositories repositories; - const char *bootVersion; + physis_Repositories repositories = {}; + const char *bootVersion = nullptr; QString dalamudVersion; int dalamudAssetVersion = -1; @@ -178,7 +178,7 @@ Q_SIGNALS: private: QString m_uuid; QString m_wineVersion; - ProfileConfig m_config; + ProfileConfig *m_config = nullptr; Account *m_account = nullptr; LauncherCore &m_launcher; }; \ No newline at end of file diff --git a/launcher/include/profilemanager.h b/launcher/include/profilemanager.h index 0ce8191..7dc479b 100644 --- a/launcher/include/profilemanager.h +++ b/launcher/include/profilemanager.h @@ -36,10 +36,11 @@ public: Q_INVOKABLE bool canDelete(Profile *account) const; + static QString getDefaultGamePath(); + private: void insertProfile(Profile *profile); - QString getDefaultGamePath(); QString getDefaultWinePrefixPath(); QVector m_profiles; diff --git a/launcher/profileconfig.kcfg b/launcher/profileconfig.kcfg index 80d86a0..ecd9c71 100644 --- a/launcher/profileconfig.kcfg +++ b/launcher/profileconfig.kcfg @@ -7,7 +7,7 @@ SPDX-FileCopyrightText: 2023 Joshua Goins SPDX-License-Identifier: CC0-1.0 --> - + profilemanager.h @@ -20,6 +20,7 @@ SPDX-License-Identifier: CC0-1.0 1 + ProfileManager::getDefaultGamePath() diff --git a/launcher/src/gameinstaller.cpp b/launcher/src/gameinstaller.cpp index d79f8ca..bc1fc57 100644 --- a/launcher/src/gameinstaller.cpp +++ b/launcher/src/gameinstaller.cpp @@ -11,6 +11,9 @@ #include "launchercore.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) : QObject(parent) , m_launcher(launcher) @@ -20,28 +23,31 @@ GameInstaller::GameInstaller(LauncherCore &launcher, Profile &profile, QObject * void GameInstaller::installGame() { - const QString installDirectory = m_profile.gamePath(); - qDebug() << "Installing game to " << installDirectory << "!"; - qDebug() << "Now downloading installer file..."; + const QDir installDirectory = m_profile.gamePath(); - QNetworkRequest request(QUrl("https://gdl.square-enix.com/ffxiv/inst/ffxivsetup.exe")); + QNetworkRequest request((QUrl(installerUrl))); auto reply = m_launcher.mgr->get(request); 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.write(reply->readAll()); + file.write(data); file.close(); - const std::string installDirectoryStd = installDirectory.toStdString(); + const std::string installDirectoryStd = installDirectory.absolutePath().toStdString(); const std::string fileNameStd = file.fileName().toStdString(); physis_install_game(fileNameStd.c_str(), installDirectoryStd.c_str()); - qDebug() << "Done installing to " << installDirectory << "!"; - Q_EMIT installFinished(); }); } diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp index ca98831..d8f9235 100755 --- a/launcher/src/launchercore.cpp +++ b/launcher/src/launchercore.cpp @@ -377,9 +377,10 @@ bool LauncherCore::autoLogin(Profile &profile) 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 diff --git a/launcher/src/profile.cpp b/launcher/src/profile.cpp index 7cbc3b8..fc1220b 100644 --- a/launcher/src/profile.cpp +++ b/launcher/src/profile.cpp @@ -10,11 +10,12 @@ #include "account.h" #include "launchercore.h" +#include "profileconfig.h" Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent) : QObject(parent) , m_uuid(key) - , m_config(key) + , m_config(new ProfileConfig(key)) , m_launcher(launcher) { readGameVersion(); @@ -119,98 +120,98 @@ void Profile::readWineInfo() QString Profile::name() const { - return m_config.name(); + return m_config->name(); } void Profile::setName(const QString &name) { - if (m_config.name() != name) { - m_config.setName(name); - m_config.save(); + if (m_config->name() != name) { + m_config->setName(name); + m_config->save(); Q_EMIT nameChanged(); } } int Profile::language() const { - return m_config.language(); + return m_config->language(); } void Profile::setLanguage(const int value) { - if (m_config.language() != value) { - m_config.setLanguage(value); - m_config.save(); + if (m_config->language() != value) { + m_config->setLanguage(value); + m_config->save(); Q_EMIT languageChanged(); } } QString Profile::gamePath() const { - return m_config.gamePath(); + return m_config->gamePath(); } void Profile::setGamePath(const QString &path) { - if (m_config.gamePath() != path) { - m_config.setGamePath(path); - m_config.save(); + if (m_config->gamePath() != path) { + m_config->setGamePath(path); + m_config->save(); Q_EMIT gamePathChanged(); } } QString Profile::winePath() const { - return m_config.winePath(); + return m_config->winePath(); } void Profile::setWinePath(const QString &path) { - if (m_config.winePath() != path) { - m_config.setWinePath(path); - m_config.save(); + if (m_config->winePath() != path) { + m_config->setWinePath(path); + m_config->save(); Q_EMIT winePathChanged(); } } QString Profile::winePrefixPath() const { - return m_config.winePrefixPath(); + return m_config->winePrefixPath(); } void Profile::setWinePrefixPath(const QString &path) { - if (m_config.winePrefixPath() != path) { - m_config.setWinePrefixPath(path); - m_config.save(); + if (m_config->winePrefixPath() != path) { + m_config->setWinePrefixPath(path); + m_config->save(); Q_EMIT winePrefixPathChanged(); } } bool Profile::watchdogEnabled() const { - return m_config.enableWatchdog(); + return m_config->enableWatchdog(); } void Profile::setWatchdogEnabled(const bool value) { - if (m_config.enableWatchdog() != value) { - m_config.setEnableWatchdog(value); - m_config.save(); + if (m_config->enableWatchdog() != value) { + m_config->setEnableWatchdog(value); + m_config->save(); Q_EMIT enableWatchdogChanged(); } } Profile::WineType Profile::wineType() const { - return static_cast(m_config.wineType()); + return static_cast(m_config->wineType()); } void Profile::setWineType(const WineType type) { - if (static_cast(m_config.wineType()) != type) { - m_config.setWineType(static_cast(type)); - m_config.save(); + if (static_cast(m_config->wineType()) != type) { + m_config->setWineType(static_cast(type)); + m_config->save(); Q_EMIT wineTypeChanged(); readWineInfo(); } @@ -218,182 +219,182 @@ void Profile::setWineType(const WineType type) bool Profile::esyncEnabled() const { - return m_config.useESync(); + return m_config->useESync(); } void Profile::setESyncEnabled(const bool value) { - if (m_config.useESync() != value) { - m_config.setUseESync(value); - m_config.save(); + if (m_config->useESync() != value) { + m_config->setUseESync(value); + m_config->save(); Q_EMIT useESyncChanged(); } } bool Profile::gamescopeEnabled() const { - return m_config.useGamescope(); + return m_config->useGamescope(); } void Profile::setGamescopeEnabled(const bool value) { - if (m_config.useGamescope() != value) { - m_config.setUseGamescope(value); - m_config.save(); + if (m_config->useGamescope() != value) { + m_config->setUseGamescope(value); + m_config->save(); Q_EMIT useGamescopeChanged(); } } bool Profile::gamemodeEnabled() const { - return m_config.useGamemode(); + return m_config->useGamemode(); } void Profile::setGamemodeEnabled(const bool value) { - if (m_config.useGamemode() != value) { - m_config.setUseGamemode(value); - m_config.save(); + if (m_config->useGamemode() != value) { + m_config->setUseGamemode(value); + m_config->save(); Q_EMIT useGamemodeChanged(); } } bool Profile::directx9Enabled() const { - return m_config.useDX9(); + return m_config->useDX9(); } void Profile::setDirectX9Enabled(const bool value) { - if (m_config.useDX9() != value) { - m_config.setUseDX9(value); - m_config.save(); + if (m_config->useDX9() != value) { + m_config->setUseDX9(value); + m_config->save(); Q_EMIT useDX9Changed(); } } bool Profile::gamescopeFullscreen() const { - return m_config.gamescopeFullscreen(); + return m_config->gamescopeFullscreen(); } void Profile::setGamescopeFullscreen(const bool value) { - if (m_config.gamescopeFullscreen() != value) { - m_config.setGamescopeFullscreen(value); - m_config.save(); + if (m_config->gamescopeFullscreen() != value) { + m_config->setGamescopeFullscreen(value); + m_config->save(); Q_EMIT gamescopeFullscreenChanged(); } } bool Profile::gamescopeBorderless() const { - return m_config.gamescopeBorderless(); + return m_config->gamescopeBorderless(); } void Profile::setGamescopeBorderless(const bool value) { - if (m_config.gamescopeBorderless() != value) { - m_config.setGamescopeBorderless(value); - m_config.save(); + if (m_config->gamescopeBorderless() != value) { + m_config->setGamescopeBorderless(value); + m_config->save(); Q_EMIT gamescopeBorderlessChanged(); } } int Profile::gamescopeWidth() const { - return m_config.gamescopeWidth(); + return m_config->gamescopeWidth(); } void Profile::setGamescopeWidth(const int value) { - if (m_config.gamescopeWidth() != value) { - m_config.setGamescopeWidth(value); - m_config.save(); + if (m_config->gamescopeWidth() != value) { + m_config->setGamescopeWidth(value); + m_config->save(); Q_EMIT gamescopeWidthChanged(); } } int Profile::gamescopeHeight() const { - return m_config.gamescopeHeight(); + return m_config->gamescopeHeight(); } void Profile::setGamescopeHeight(const int value) { - if (m_config.gamescopeHeight() != value) { - m_config.setGamescopeHeight(value); - m_config.save(); + if (m_config->gamescopeHeight() != value) { + m_config->setGamescopeHeight(value); + m_config->save(); Q_EMIT gamescopeHeightChanged(); } } int Profile::gamescopeRefreshRate() const { - return m_config.gamescopeRefreshRate(); + return m_config->gamescopeRefreshRate(); } void Profile::setGamescopeRefreshRate(const int value) { - if (m_config.gamescopeRefreshRate() != value) { - m_config.setGamescopeRefreshRate(value); - m_config.save(); + if (m_config->gamescopeRefreshRate() != value) { + m_config->setGamescopeRefreshRate(value); + m_config->save(); Q_EMIT gamescopeRefreshRateChanged(); } } bool Profile::dalamudEnabled() const { - return m_config.dalamudEnabled(); + return m_config->dalamudEnabled(); } void Profile::setDalamudEnabled(const bool value) { - if (m_config.dalamudEnabled() != value) { - m_config.setDalamudEnabled(value); - m_config.save(); + if (m_config->dalamudEnabled() != value) { + m_config->setDalamudEnabled(value); + m_config->save(); Q_EMIT dalamudEnabledChanged(); } } bool Profile::dalamudOptOut() const { - return m_config.dalamudOptOut(); + return m_config->dalamudOptOut(); } void Profile::setDalamudOptOut(const bool value) { - if (m_config.dalamudOptOut() != value) { - m_config.setDalamudOptOut(value); - m_config.save(); + if (m_config->dalamudOptOut() != value) { + m_config->setDalamudOptOut(value); + m_config->save(); Q_EMIT dalamudOptOutChanged(); } } Profile::DalamudChannel Profile::dalamudChannel() const { - return static_cast(m_config.dalamudChannel()); + return static_cast(m_config->dalamudChannel()); } void Profile::setDalamudChannel(const DalamudChannel value) { - if (static_cast(m_config.dalamudChannel()) != value) { - m_config.setDalamudChannel(static_cast(value)); - m_config.save(); + if (static_cast(m_config->dalamudChannel()) != value) { + m_config->setDalamudChannel(static_cast(value)); + m_config->save(); Q_EMIT dalamudChannelChanged(); } } bool Profile::argumentsEncrypted() const { - return m_config.encryptArguments(); + return m_config->encryptArguments(); } void Profile::setArgumentsEncrypted(const bool value) { - if (m_config.encryptArguments() != value) { - m_config.setEncryptArguments(value); - m_config.save(); + if (m_config->encryptArguments() != value) { + m_config->setEncryptArguments(value); + m_config->save(); Q_EMIT encryptedArgumentsChanged(); } } @@ -407,9 +408,9 @@ void Profile::setAccount(Account *account) { if (account != m_account) { m_account = account; - if (account->uuid() != m_config.account()) { - m_config.setAccount(account->uuid()); - m_config.save(); + if (account->uuid() != m_config->account()) { + m_config->setAccount(account->uuid()); + m_config->save(); } Q_EMIT accountChanged(); } @@ -438,7 +439,7 @@ void Profile::readGameVersion() QString Profile::accountUuid() const { - return m_config.account(); + return m_config->account(); } QString Profile::expansionVersionText() const diff --git a/launcher/src/profilemanager.cpp b/launcher/src/profilemanager.cpp index e0c7595..6bf1a9c 100644 --- a/launcher/src/profilemanager.cpp +++ b/launcher/src/profilemanager.cpp @@ -3,7 +3,9 @@ #include "profilemanager.h" +#include #include +#include ProfileManager::ProfileManager(LauncherCore &launcher, QObject *parent) : QAbstractListModel(parent) @@ -79,7 +81,8 @@ QString ProfileManager::getDefaultGamePath() #endif #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 }