From 8d103c33d87a2ac50d95ed9618cef9392ba22aaa Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 17 Sep 2023 08:51:26 -0400 Subject: [PATCH] Modernize Profile --- launcher/include/profile.h | 94 +++++++++++--------- launcher/src/assetupdater.cpp | 12 +-- launcher/src/launchercore.cpp | 2 +- launcher/src/profile.cpp | 147 +++++++++++++++++++++++--------- launcher/src/squareboot.cpp | 4 +- launcher/src/squarelauncher.cpp | 12 +-- 6 files changed, 176 insertions(+), 95 deletions(-) diff --git a/launcher/include/profile.h b/launcher/include/profile.h index 2bf2858..343b11e 100644 --- a/launcher/include/profile.h +++ b/launcher/include/profile.h @@ -56,100 +56,97 @@ public: enum class DalamudChannel { Stable, Staging, Net5 }; Q_ENUM(DalamudChannel) - QString uuid() const; + [[nodiscard]] QString uuid() const; - QString name() const; + [[nodiscard]] QString name() const; void setName(const QString &name); - QString gamePath() const; + [[nodiscard]] QString gamePath() const; void setGamePath(const QString &path); - QString winePath() const; + [[nodiscard]] QString winePath() const; void setWinePath(const QString &path); - QString winePrefixPath() const; + [[nodiscard]] QString winePrefixPath() const; void setWinePrefixPath(const QString &path); - bool watchdogEnabled() const; + [[nodiscard]] bool watchdogEnabled() const; void setWatchdogEnabled(bool value); - WineType wineType() const; + [[nodiscard]] WineType wineType() const; void setWineType(WineType type); - bool esyncEnabled() const; + [[nodiscard]] bool esyncEnabled() const; void setESyncEnabled(bool value); - bool gamescopeEnabled() const; + [[nodiscard]] bool gamescopeEnabled() const; void setGamescopeEnabled(bool value); - bool gamemodeEnabled() const; + [[nodiscard]] bool gamemodeEnabled() const; void setGamemodeEnabled(bool value); - bool directx9Enabled() const; + [[nodiscard]] bool directx9Enabled() const; void setDirectX9Enabled(bool value); - bool gamescopeFullscreen() const; + [[nodiscard]] bool gamescopeFullscreen() const; void setGamescopeFullscreen(bool value); - bool gamescopeBorderless() const; + [[nodiscard]] bool gamescopeBorderless() const; void setGamescopeBorderless(bool value); - int gamescopeWidth() const; + [[nodiscard]] int gamescopeWidth() const; void setGamescopeWidth(int value); - int gamescopeHeight() const; + [[nodiscard]] int gamescopeHeight() const; void setGamescopeHeight(int value); - int gamescopeRefreshRate() const; + [[nodiscard]] int gamescopeRefreshRate() const; void setGamescopeRefreshRate(int value); - bool dalamudEnabled() const; + [[nodiscard]] bool dalamudEnabled() const; void setDalamudEnabled(bool value); - bool dalamudOptOut() const; + [[nodiscard]] bool dalamudOptOut() const; void setDalamudOptOut(bool value); - DalamudChannel dalamudChannel() const; + [[nodiscard]] DalamudChannel dalamudChannel() const; void setDalamudChannel(DalamudChannel channel); - bool argumentsEncrypted() const; + [[nodiscard]] bool argumentsEncrypted() const; void setArgumentsEncrypted(bool value); - Account *account() const; - QString accountUuid() const; + [[nodiscard]] Account *account() const; + [[nodiscard]] QString accountUuid() const; void setAccount(Account *account); void readGameData(); void readGameVersion(); void readWineInfo(); - QVector expansionNames; + [[nodiscard]] QString expansionVersionText() const; + [[nodiscard]] QString dalamudVersionText() const; + [[nodiscard]] QString wineVersionText() const; - BootData *bootData; - GameData *gameData; + [[nodiscard]] QString dalamudChannelName() const; - physis_Repositories repositories = {}; - const char *bootVersion = nullptr; + [[nodiscard]] bool isGameInstalled() const; + [[nodiscard]] bool isWineInstalled() const; - QString dalamudVersion; - int dalamudAssetVersion = -1; - QString runtimeVersion; + [[nodiscard]] QString bootVersion() const; + [[nodiscard]] QString baseGameVersion() const; + [[nodiscard]] int numInstalledExpansions() const; + [[nodiscard]] QString expansionVersion(int index) const; - QString expansionVersionText() const; - QString dalamudVersionText() const; - QString wineVersionText() const; + [[nodiscard]] int dalamudAssetVersion() const; + void setDalamudAssetVersion(int version); - [[nodiscard]] bool isGameInstalled() const - { - return repositories.repositories_count > 0; - } + [[nodiscard]] QString runtimeVersion() const; - [[nodiscard]] bool isWineInstalled() const - { - return !m_wineVersion.isEmpty(); - } + [[nodiscard]] QString dalamudVersion() const; + void setDalamudVersion(const QString &version); - QString dalamudChannelName() const; + BootData *bootData(); + GameData *gameData(); Q_SIGNALS: void gameInstallChanged(); @@ -180,5 +177,18 @@ private: QString m_wineVersion; ProfileConfig *m_config = nullptr; Account *m_account = nullptr; + + QVector m_expansionNames; + + BootData *m_bootData = nullptr; + GameData *m_gameData = nullptr; + + physis_Repositories m_repositories = {}; + const char *m_bootVersion = nullptr; + + QString m_dalamudVersion; + int m_dalamudAssetVersion = -1; + QString m_runtimeVersion; + LauncherCore &m_launcher; }; \ No newline at end of file diff --git a/launcher/src/assetupdater.cpp b/launcher/src/assetupdater.cpp index 8a559a0..b0ed487 100644 --- a/launcher/src/assetupdater.cpp +++ b/launcher/src/assetupdater.cpp @@ -71,7 +71,7 @@ void AssetUpdater::update() QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); qInfo() << "Dalamud asset remote version" << doc.object()["Version"].toInt(); - qInfo() << "Dalamud asset local version" << m_profile.dalamudAssetVersion; + qInfo() << "Dalamud asset local version" << m_profile.dalamudAssetVersion(); remoteDalamudAssetVersion = doc.object()["Version"].toInt(); @@ -162,7 +162,7 @@ void AssetUpdater::checkIfDalamudAssetsDone() if (dalamudAssetNeededFilenames.empty()) { qInfo() << "Finished downloading Dalamud assets."; - m_profile.dalamudAssetVersion = remoteDalamudAssetVersion; + m_profile.setDalamudAssetVersion(remoteDalamudAssetVersion); QFile file(dalamudAssetDir.absoluteFilePath("asset.ver")); file.open(QIODevice::WriteOnly | QIODevice::Text); @@ -196,7 +196,7 @@ void AssetUpdater::checkIfCheckingIsDone() Q_EMIT launcher.stageChanged("Starting Dalamud update..."); // dalamud injector / net runtime - if (m_profile.runtimeVersion != remoteRuntimeVersion) { + if (m_profile.runtimeVersion() != remoteRuntimeVersion) { needsRuntimeInstall = true; // core @@ -248,7 +248,7 @@ void AssetUpdater::checkIfCheckingIsDone() checkIfFinished(); } - if (remoteDalamudVersion != m_profile.dalamudVersion) { + if (remoteDalamudVersion != m_profile.dalamudVersion()) { qInfo() << "Downloading Dalamud..."; needsDalamudInstall = true; @@ -268,7 +268,7 @@ void AssetUpdater::checkIfCheckingIsDone() doneDownloadingDalamud = true; - m_profile.dalamudVersion = remoteDalamudVersion; + m_profile.setDalamudVersion(remoteDalamudVersion); checkIfFinished(); }); @@ -282,7 +282,7 @@ void AssetUpdater::checkIfCheckingIsDone() } // dalamud assets - if (remoteDalamudAssetVersion != m_profile.dalamudAssetVersion) { + if (remoteDalamudAssetVersion != m_profile.dalamudAssetVersion()) { qInfo() << "Dalamud assets out of date."; Q_EMIT launcher.stageChanged("Updating Dalamud assets..."); diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp index ed6d88d..c3a2f1d 100755 --- a/launcher/src/launchercore.cpp +++ b/launcher/src/launchercore.cpp @@ -182,7 +182,7 @@ QString LauncherCore::getGameArgs(const Profile &profile, const LoginAuth &auth) gameArgs.push_back({QStringLiteral("DEV.TestSID"), auth.SID}); gameArgs.push_back({QStringLiteral("SYS.Region"), QString::number(auth.region)}); gameArgs.push_back({QStringLiteral("language"), QString::number(profile.account()->language())}); - gameArgs.push_back({QStringLiteral("ver"), profile.repositories.repositories[0].version}); + gameArgs.push_back({QStringLiteral("ver"), profile.baseGameVersion()}); gameArgs.push_back({QStringLiteral("UserPath"), Utility::toWindowsPath(profile.account()->getConfigDir().absolutePath())}); // FIXME: this should belong somewhere else... diff --git a/launcher/src/profile.cpp b/launcher/src/profile.cpp index 54d6940..40e9d13 100644 --- a/launcher/src/profile.cpp +++ b/launcher/src/profile.cpp @@ -3,6 +3,7 @@ #include "profile.h" +#include #include #include #include @@ -23,55 +24,55 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent) const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - const QDir dalamudDir = dataDir.absoluteFilePath("dalamud"); + const QDir dalamudDir = dataDir.absoluteFilePath(QStringLiteral("dalamud")); if (dalamudDir.exists()) { const QDir dalamudInstallDir = dalamudDir.absoluteFilePath(dalamudChannelName()); - const QDir dalamudAssetsDir = dalamudDir.absoluteFilePath("assets"); - const QDir dalamudRuntimeDir = dalamudDir.absoluteFilePath("runtime"); + const QDir dalamudAssetsDir = dalamudDir.absoluteFilePath(QStringLiteral("assets")); + const QDir dalamudRuntimeDir = dalamudDir.absoluteFilePath(QStringLiteral("runtime")); - const QString dalamudDepsJson = dalamudInstallDir.absoluteFilePath("Dalamud.deps.json"); + const QString dalamudDepsJson = dalamudInstallDir.absoluteFilePath(QStringLiteral("Dalamud.deps.json")); if (QFile::exists(dalamudDepsJson)) { QFile depsJson(dalamudDepsJson); depsJson.open(QFile::ReadOnly); QJsonDocument doc = QJsonDocument::fromJson(depsJson.readAll()); QString versionString; - for (auto target : doc["targets"].toObject().keys()) { - if (target.contains(".NETCoreApp")) { - versionString = doc["targets"].toObject()[target].toObject().keys().filter("Dalamud/")[0]; + for (const auto &target : doc[QLatin1String("targets")].toObject().keys()) { + if (target.contains(QLatin1String(".NETCoreApp"))) { + versionString = doc[QLatin1String("targets")].toObject()[target].toObject().keys().filter(QStringLiteral("Dalamud/"))[0]; } } - dalamudVersion = versionString.remove("Dalamud/"); + m_dalamudVersion = versionString.remove(QLatin1String("Dalamud/")); } - const QString dalamudAssetsVer = dalamudAssetsDir.absoluteFilePath("asset.ver"); + const QString dalamudAssetsVer = dalamudAssetsDir.absoluteFilePath(QStringLiteral("asset.ver")); if (QFile::exists(dalamudAssetsVer)) { QFile assetJson(dalamudAssetsVer); assetJson.open(QFile::ReadOnly | QFile::Text); - dalamudAssetVersion = QString(assetJson.readAll()).toInt(); + m_dalamudAssetVersion = QString(assetJson.readAll()).toInt(); } - const QString dalamudRuntimeVer = dalamudRuntimeDir.absoluteFilePath("runtime.ver"); + const QString dalamudRuntimeVer = dalamudRuntimeDir.absoluteFilePath(QStringLiteral("runtime.ver")); if (QFile::exists(dalamudRuntimeVer)) { QFile runtimeVer(dalamudRuntimeVer); runtimeVer.open(QFile::ReadOnly | QFile::Text); - runtimeVersion = QString(runtimeVer.readAll()); + m_runtimeVersion = QString(runtimeVer.readAll()); } } } void Profile::readGameData() { - physis_EXH *exh = physis_gamedata_read_excel_sheet_header(gameData, "ExVersion"); + physis_EXH *exh = physis_gamedata_read_excel_sheet_header(m_gameData, "ExVersion"); if (exh != nullptr) { - physis_EXD exd = physis_gamedata_read_excel_sheet(gameData, "ExVersion", exh, Language::English, 0); + physis_EXD exd = physis_gamedata_read_excel_sheet(m_gameData, "ExVersion", exh, Language::English, 0); for (unsigned int i = 0; i < exd.row_count; i++) { - expansionNames.push_back(exd.row_data[i].column_data[0].string._0); + m_expansionNames.push_back(exd.row_data[i].column_data[0].string._0); } physis_gamedata_free_sheet(exd); @@ -103,7 +104,7 @@ void Profile::readWineInfo() #if defined(Q_OS_LINUX) switch (wineType()) { case WineType::System: // system wine (should be in $PATH) - setWinePath("wine"); + setWinePath(QStringLiteral("wine")); break; case WineType::Custom: // custom pth default: @@ -117,10 +118,10 @@ void Profile::readWineInfo() connect(wineProcess, &QProcess::readyRead, this, [wineProcess, this] { m_wineVersion = wineProcess->readAllStandardOutput().trimmed(); - Q_EMIT wineVersionText(); + Q_EMIT wineChanged(); }); - m_launcher.launchExecutable(*this, wineProcess, {"--version"}, false, false); + m_launcher.launchExecutable(*this, wineProcess, {QStringLiteral("--version")}, false, false); wineProcess->waitForFinished(); #endif @@ -416,15 +417,15 @@ void Profile::readGameVersion() return; } - gameData = physis_gamedata_initialize((gamePath() + "/game").toStdString().c_str()); - bootData = physis_bootdata_initialize((gamePath() + "/boot").toStdString().c_str()); + m_gameData = physis_gamedata_initialize((gamePath() + QStringLiteral("/game")).toStdString().c_str()); + m_bootData = physis_bootdata_initialize((gamePath() + QStringLiteral("/boot")).toStdString().c_str()); - if (bootData != nullptr) { - bootVersion = physis_bootdata_get_version(bootData); + if (m_bootData != nullptr) { + m_bootVersion = physis_bootdata_get_version(m_bootData); } - if (gameData != nullptr) { - repositories = physis_gamedata_get_repositories(gameData); + if (m_gameData != nullptr) { + m_repositories = physis_gamedata_get_repositories(m_gameData); readGameData(); } @@ -439,20 +440,20 @@ QString Profile::accountUuid() const QString Profile::expansionVersionText() const { if (!isGameInstalled()) { - return "No game installed."; + return i18n("No game installed."); } else { QString expacString; - expacString += "Boot"; - expacString += QString(" (%1)").arg(bootVersion); + expacString += QStringLiteral("Boot"); + expacString += QStringLiteral(" (%1)").arg(m_bootVersion); - for (unsigned int i = 0; i < repositories.repositories_count; i++) { - QString expansionName = "Unknown Expansion"; - if (i < static_cast(expansionNames.size())) { - expansionName = expansionNames[i]; + for (unsigned int i = 0; i < m_repositories.repositories_count; i++) { + QString expansionName = i18n("Unknown Expansion"); + if (i < static_cast(m_expansionNames.size())) { + expansionName = m_expansionNames[i]; } - expacString += QString("\n%1 (%2)").arg(expansionName, repositories.repositories[i].version); + expacString += QStringLiteral("\n%1 (%2)").arg(expansionName, m_repositories.repositories[i].version); } return expacString; @@ -462,14 +463,14 @@ QString Profile::expansionVersionText() const QString Profile::dalamudVersionText() const { QString text; - if (dalamudVersion.isEmpty()) { - text += "Dalamud is not installed."; + if (m_dalamudVersion.isEmpty()) { + text += i18n("Dalamud is not installed."); } else { - text += QStringLiteral("Dalamud (%1)").arg(dalamudVersion); + text += QStringLiteral("Dalamud (%1)").arg(m_dalamudVersion); } - if (dalamudAssetVersion != -1) { - text += QStringLiteral("\nAssets (%1)").arg(QString::number(dalamudAssetVersion)); + if (m_dalamudAssetVersion != -1) { + text += QStringLiteral("\nAssets (%1)").arg(QString::number(m_dalamudAssetVersion)); } return text; @@ -483,11 +484,11 @@ QString Profile::uuid() const QString Profile::wineVersionText() const { if (m_launcher.isSteam()) { - return "Wine is being managed by Steam."; + return i18n("Wine is being managed by Steam."); } if (!isWineInstalled()) { - return "Wine is not installed."; + return i18n("Wine is not installed."); } else { return m_wineVersion; } @@ -506,3 +507,71 @@ QString Profile::dalamudChannelName() const Q_UNREACHABLE(); } + +[[nodiscard]] bool Profile::isGameInstalled() const +{ + return m_repositories.repositories_count > 0; +} + +[[nodiscard]] bool Profile::isWineInstalled() const +{ + return !m_wineVersion.isEmpty(); +} + +QString Profile::bootVersion() const +{ + return m_bootVersion; +} + +QString Profile::baseGameVersion() const +{ + Q_ASSERT(m_repositories.repositories_count > 1); + return m_repositories.repositories[0].version; +} + +int Profile::numInstalledExpansions() const +{ + Q_ASSERT(m_repositories.repositories_count > 1); + return m_repositories.repositories_count - 1; +} + +QString Profile::expansionVersion(const int index) const +{ + Q_ASSERT(index < numInstalledExpansions()); + return m_repositories.repositories[index + 1].version; +} + +int Profile::dalamudAssetVersion() const +{ + return m_dalamudAssetVersion; +} + +void Profile::setDalamudAssetVersion(int version) +{ + m_dalamudAssetVersion = version; +} + +QString Profile::runtimeVersion() const +{ + return m_runtimeVersion; +} + +QString Profile::dalamudVersion() const +{ + return m_dalamudVersion; +} + +void Profile::setDalamudVersion(const QString &version) +{ + m_dalamudVersion = version; +} + +BootData *Profile::bootData() +{ + return m_bootData; +} + +GameData *Profile::gameData() +{ + return m_gameData; +} diff --git a/launcher/src/squareboot.cpp b/launcher/src/squareboot.cpp index 993b5a7..1131abf 100644 --- a/launcher/src/squareboot.cpp +++ b/launcher/src/squareboot.cpp @@ -32,7 +32,7 @@ QCoro::Task<> SquareBoot::bootCheck(const LoginInformation &info) QUrl url; url.setScheme(QStringLiteral("http")); url.setHost(QStringLiteral("patch-bootver.%1").arg(window.squareEnixServer())); - url.setPath(QStringLiteral("/http/win32/ffxivneo_release_boot/%1").arg(info.profile->bootVersion)); + url.setPath(QStringLiteral("/http/win32/ffxivneo_release_boot/%1").arg(info.profile->bootVersion())); url.setQuery(query); auto request = QNetworkRequest(url); @@ -47,7 +47,7 @@ QCoro::Task<> SquareBoot::bootCheck(const LoginInformation &info) const auto reply = window.mgr->get(request); co_await reply; - patcher = new Patcher(window, info.profile->gamePath() + QStringLiteral("/boot"), *info.profile->bootData, this); + patcher = new Patcher(window, info.profile->gamePath() + QStringLiteral("/boot"), *info.profile->bootData(), this); co_await patcher->patch(reply->readAll()); // update game version information diff --git a/launcher/src/squarelauncher.cpp b/launcher/src/squarelauncher.cpp index fe70206..e0472bb 100644 --- a/launcher/src/squarelauncher.cpp +++ b/launcher/src/squarelauncher.cpp @@ -160,7 +160,7 @@ QCoro::Task<> SquareLauncher::registerSession(const LoginInformation &info) QUrl url; url.setScheme(QStringLiteral("https")); url.setHost(QStringLiteral("patch-gamever.%1").arg(window.squareEnixServer())); - url.setPath(QStringLiteral("/http/win32/ffxivneo_release_game/%1/%2").arg(info.profile->repositories.repositories[0].version, SID)); + url.setPath(QStringLiteral("/http/win32/ffxivneo_release_game/%1/%2").arg(info.profile->baseGameVersion(), SID)); auto request = QNetworkRequest(url); window.setSSL(request); @@ -168,15 +168,17 @@ QCoro::Task<> SquareLauncher::registerSession(const LoginInformation &info) request.setRawHeader(QByteArrayLiteral("User-Agent"), QByteArrayLiteral("FFXIV PATCH CLIENT")); request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded")); - QString report = QStringLiteral("%1=%2").arg(info.profile->bootVersion, getBootHash(info)); + QString report = QStringLiteral("%1=%2").arg(info.profile->bootVersion(), getBootHash(info)); for (int i = 1; i < auth.maxExpansion + 1; i++) { - if (i < static_cast(info.profile->repositories.repositories_count)) { - report += QStringLiteral("\nex%1\t%2").arg(QString::number(i), info.profile->repositories.repositories[i].version); + if (i < static_cast(info.profile->numInstalledExpansions())) { + report += QStringLiteral("\nex%1\t%2").arg(QString::number(i), info.profile->expansionVersion(i)); } else { report += QStringLiteral("\nex%1\t2012.01.01.0000.0000").arg(QString::number(i)); } } + qInfo() << report; + const auto reply = window.mgr->post(request, report.toUtf8()); co_await reply; @@ -184,7 +186,7 @@ QCoro::Task<> SquareLauncher::registerSession(const LoginInformation &info) if (reply->rawHeaderList().contains(QByteArrayLiteral("X-Patch-Unique-Id"))) { const QString body = reply->readAll(); - patcher = new Patcher(window, info.profile->gamePath() + QStringLiteral("/game"), *info.profile->gameData, this); + patcher = new Patcher(window, info.profile->gamePath() + QStringLiteral("/game"), *info.profile->gameData(), this); co_await patcher->patch(body); info.profile->readGameVersion();