From 8d4a081ad7477ff65834d9a4d7d17978bb9cf5dd Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 18 Aug 2023 21:36:29 -0400 Subject: [PATCH] Make some hardcoded domains and servers configurable Not every domain and server will be around forever, so now you can configure the two Square Enix domains used for login and patching. And you can configure the Dalamud domain used to download assets, etc. --- launcher/config.kcfg | 9 ++++ launcher/include/assetupdater.h | 4 ++ launcher/include/launchercore.h | 15 ++++++ launcher/src/assetupdater.cpp | 53 +++++++++++++------ launcher/src/launchercore.cpp | 60 ++++++++++++++++++++-- launcher/src/profile.cpp | 26 ++++++---- launcher/src/squareboot.cpp | 9 ++-- launcher/src/squarelauncher.cpp | 14 +++-- launcher/ui/Settings/DeveloperSettings.qml | 18 +++++++ 9 files changed, 172 insertions(+), 36 deletions(-) diff --git a/launcher/config.kcfg b/launcher/config.kcfg index 07abb68..683a5b6 100644 --- a/launcher/config.kcfg +++ b/launcher/config.kcfg @@ -20,5 +20,14 @@ SPDX-License-Identifier: CC0-1.0 false + + goatcorp.github.io + + + ffxiv.com + + + square-enix.com + diff --git a/launcher/include/assetupdater.h b/launcher/include/assetupdater.h index 5bc4f27..42f12d1 100644 --- a/launcher/include/assetupdater.h +++ b/launcher/include/assetupdater.h @@ -29,6 +29,10 @@ signals: void finishedUpdating(); private: + QUrl dalamudVersionManifestUrl(Profile::DalamudChannel channel) const; + QUrl dalamudLatestPackageUrl(Profile::DalamudChannel channel) const; + QUrl dalamudAssetManifestUrl() const; + LauncherCore &launcher; Profile::DalamudChannel chosenChannel; diff --git a/launcher/include/launchercore.h b/launcher/include/launchercore.h index bade3b3..94429ff 100755 --- a/launcher/include/launchercore.h +++ b/launcher/include/launchercore.h @@ -64,6 +64,9 @@ class LauncherCore : public QObject Q_PROPERTY(bool closeWhenLaunched READ closeWhenLaunched WRITE setCloseWhenLaunched NOTIFY closeWhenLaunchedChanged) Q_PROPERTY(bool showNews READ showNews WRITE setShowNews NOTIFY showNewsChanged) Q_PROPERTY(bool keepPatches READ keepPatches WRITE setKeepPatches NOTIFY keepPatchesChanged) + Q_PROPERTY(QString dalamudDistribServer READ dalamudDistribServer WRITE setDalamudDistribServer NOTIFY dalamudDistribServerChanged) + Q_PROPERTY(QString squareEnixServer READ squareEnixServer WRITE setSquareEnixServer NOTIFY squareEnixServerChanged) + Q_PROPERTY(QString squareEnixLoginServer READ squareEnixLoginServer WRITE setSquareEnixLoginServer NOTIFY squareEnixLoginServerChanged) Q_PROPERTY(Headline *headline READ headline NOTIFY newsChanged) public: @@ -124,6 +127,15 @@ public: bool keepPatches() const; void setKeepPatches(bool value); + QString dalamudDistribServer() const; + void setDalamudDistribServer(const QString &value); + + QString squareEnixServer() const; + void setSquareEnixServer(const QString &value); + + QString squareEnixLoginServer() const; + void setSquareEnixLoginServer(const QString &value); + int defaultProfileIndex = 0; bool m_isSteam = false; @@ -152,6 +164,9 @@ signals: void closeWhenLaunchedChanged(); void showNewsChanged(); void keepPatchesChanged(); + void dalamudDistribServerChanged(); + void squareEnixServerChanged(); + void squareEnixLoginServerChanged(); void loginError(QString message); void stageChanged(QString message); void stageIndeterminate(); diff --git a/launcher/src/assetupdater.cpp b/launcher/src/assetupdater.cpp index b1071be..347ea3c 100644 --- a/launcher/src/assetupdater.cpp +++ b/launcher/src/assetupdater.cpp @@ -11,22 +11,9 @@ #include -const QString baseGoatDomain = "https://goatcorp.github.io"; - -const QString baseDalamudDistribution = baseGoatDomain + "/dalamud-distrib/"; -const QString dalamudLatestPackageURL = baseDalamudDistribution + "%1latest.zip"; -const QString dalamudVersionManifestURL = baseDalamudDistribution + "%1version"; - -const QString baseDalamudAssetDistribution = baseGoatDomain + "/DalamudAssets"; -const QString dalamudAssetManifestURL = baseDalamudAssetDistribution + "/asset.json"; - const QString dotnetRuntimePackageURL = "https://dotnetcli.azureedge.net/dotnet/Runtime/%1/dotnet-runtime-%1-win-x64.zip"; const QString dotnetDesktopPackageURL = "https://dotnetcli.azureedge.net/dotnet/WindowsDesktop/%1/windowsdesktop-runtime-%1-win-x64.zip"; -QMap channelToDistribPrefix = {{Profile::DalamudChannel::Stable, "/"}, - {Profile::DalamudChannel::Staging, "stg/"}, - {Profile::DalamudChannel::Net5, "net5/"}}; - AssetUpdater::AssetUpdater(Profile &profile, LauncherCore &launcher, QObject *parent) : QObject(parent) , launcher(launcher) @@ -74,7 +61,7 @@ void AssetUpdater::update() dalamudAssetNeededFilenames.append("dummy"); // first we want to fetch the list of assets required - QNetworkRequest request(dalamudAssetManifestURL); + QNetworkRequest request(dalamudAssetManifestUrl()); auto reply = launcher.mgr->get(request); connect(reply, &QNetworkReply::finished, [reply, this] { @@ -97,7 +84,7 @@ void AssetUpdater::update() // dalamud injector / net runtime // they're all updated in unison, so there's no reason to have multiple checks { - QNetworkRequest request(dalamudVersionManifestURL.arg(channelToDistribPrefix[m_profile.dalamudChannel()])); + QNetworkRequest request(dalamudVersionManifestUrl(m_profile.dalamudChannel())); chosenChannel = m_profile.dalamudChannel(); @@ -260,7 +247,7 @@ void AssetUpdater::checkIfCheckingIsDone() needsDalamudInstall = true; - QNetworkRequest request(dalamudLatestPackageURL.arg(channelToDistribPrefix[chosenChannel])); + QNetworkRequest request(dalamudLatestPackageUrl(chosenChannel)); auto reply = launcher.mgr->get(request); connect(reply, &QNetworkReply::finished, [this, reply] { @@ -330,3 +317,37 @@ void AssetUpdater::checkIfCheckingIsDone() checkIfFinished(); } } + +static const QMap channelToDistribPrefix = {{Profile::DalamudChannel::Stable, "/"}, + {Profile::DalamudChannel::Staging, "stg/"}, + {Profile::DalamudChannel::Net5, "net5/"}}; + +QUrl AssetUpdater::dalamudVersionManifestUrl(const Profile::DalamudChannel channel) const +{ + QUrl url; + url.setScheme("https"); + url.setHost(launcher.dalamudDistribServer()); + url.setPath(QStringLiteral("/dalamud-distrib/%1version").arg(channelToDistribPrefix[channel])); + + return url; +} + +QUrl AssetUpdater::dalamudLatestPackageUrl(Profile::DalamudChannel channel) const +{ + QUrl url; + url.setScheme("https"); + url.setHost(launcher.dalamudDistribServer()); + url.setPath(QStringLiteral("/dalamud-distrib/%1latest.zip").arg(channelToDistribPrefix[channel])); + + return url; +} + +QUrl AssetUpdater::dalamudAssetManifestUrl() const +{ + QUrl url; + url.setScheme("https"); + url.setHost(launcher.dalamudDistribServer()); + url.setPath(QStringLiteral("/DalamudAssets/asset.json")); + + return url; +} diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp index 0483df1..a95dc28 100755 --- a/launcher/src/launchercore.cpp +++ b/launcher/src/launchercore.cpp @@ -107,17 +107,26 @@ void LauncherCore::beginDalamudGame(const QString &gameExecutablePath, const Pro const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); const QDir configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); const QDir stateDir = Utility::stateDirectory(); + const QDir dalamudDir = dataDir.absoluteFilePath("dalamud"); + + const QDir dalamudConfigDir = configDir.absoluteFilePath("dalamud"); + const QDir userDalamudConfigDir = dalamudConfigDir.absoluteFilePath(profile.account()->uuid()); + + const QDir dalamudBasePluginDir = dalamudDir.absoluteFilePath("plugins"); + const QDir dalamudUserPluginDir = dalamudBasePluginDir.absoluteFilePath(profile.account()->uuid()); + + // Some really dumb plugins check for "installedPlugins" in their assembly directory FOR SOME REASON + // so we need to match typical XIVQuickLauncher behavior here. Why? I have no clue. + const QDir dalamudPluginDir = dalamudUserPluginDir.absoluteFilePath("installedPlugins"); const QString logDir = stateDir.absoluteFilePath("logs"); if (!QDir().exists(logDir)) QDir().mkpath(logDir); - const QDir dalamudDir = dataDir.absoluteFilePath("dalamud"); const QDir dalamudRuntimeDir = dalamudDir.absoluteFilePath("runtime"); const QDir dalamudAssetDir = dalamudDir.absoluteFilePath("assets"); - const QDir dalamudConfigPath = configDir.absoluteFilePath("dalamud-config.json"); - const QDir dalamudPluginDir = dalamudDir.absoluteFilePath("plugins"); + const QDir dalamudConfigPath = userDalamudConfigDir.absoluteFilePath("dalamud-config.json"); const QDir dalamudInstallDir = dalamudDir.absoluteFilePath(profile.dalamudChannelName()); const QString dalamudInjector = dalamudInstallDir.absoluteFilePath("Dalamud.Injector.exe"); @@ -145,7 +154,6 @@ void LauncherCore::beginDalamudGame(const QString &gameExecutablePath, const Pro "-m", "inject", "--game=" + Utility::toWindowsPath(gameExecutablePath), - "--dalamud-working-directory=" + Utility::toWindowsPath(dalamudDir), "--dalamud-configuration-path=" + Utility::toWindowsPath(dalamudConfigPath), "--dalamud-plugin-directory=" + Utility::toWindowsPath(dalamudPluginDir), "--dalamud-asset-directory=" + Utility::toWindowsPath(dalamudAssetDir), @@ -465,6 +473,48 @@ void LauncherCore::setKeepPatches(const bool value) } } +QString LauncherCore::dalamudDistribServer() const +{ + return Config::dalamudDistribServer(); +} + +void LauncherCore::setDalamudDistribServer(const QString &value) +{ + if (value != Config::dalamudDistribServer()) { + Config::setDalamudDistribServer(value); + Config::self()->save(); + Q_EMIT dalamudDistribServerChanged(); + } +} + +QString LauncherCore::squareEnixServer() const +{ + return Config::squareEnixServer(); +} + +void LauncherCore::setSquareEnixServer(const QString &value) +{ + if (value != Config::squareEnixServer()) { + Config::setSquareEnixServer(value); + Config::self()->save(); + Q_EMIT squareEnixServerChanged(); + } +} + +QString LauncherCore::squareEnixLoginServer() const +{ + return Config::squareEnixLoginServer(); +} + +void LauncherCore::setSquareEnixLoginServer(const QString &value) +{ + if (value != Config::squareEnixLoginServer()) { + Config::setSquareEnixLoginServer(value); + Config::self()->save(); + Q_EMIT squareEnixLoginServerChanged(); + } +} + void LauncherCore::refreshNews() { QUrlQuery query; @@ -473,7 +523,7 @@ void LauncherCore::refreshNews() QUrl url; url.setScheme("https"); - url.setHost("frontier.ffxiv.com"); + url.setHost(QStringLiteral("frontier.%1").arg(squareEnixServer())); url.setPath("/news/headline.json"); url.setQuery(query); diff --git a/launcher/src/profile.cpp b/launcher/src/profile.cpp index 70a2edd..229f2ad 100644 --- a/launcher/src/profile.cpp +++ b/launcher/src/profile.cpp @@ -21,12 +21,18 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent) readGameVersion(); readWineInfo(); - const QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - const bool hasDalamud = QFile::exists(dataDir + "/Dalamud"); - if (hasDalamud) { - if (QFile::exists(dataDir + "/Dalamud/Dalamud.deps.json")) { - QFile depsJson(dataDir + "/Dalamud/Dalamud.deps.json"); + const QDir dalamudDir = dataDir.absoluteFilePath("dalamud"); + + if (dalamudDir.exists()) { + const QDir dalamudInstallDir = dalamudDir.absoluteFilePath(dalamudChannelName()); + const QDir dalamudAssetsDir = dalamudDir.absoluteFilePath("assets"); + const QDir dalamudRuntimeDir = dalamudDir.absoluteFilePath("runtime"); + + const QString dalamudDepsJson = dalamudInstallDir.absoluteFilePath("Dalamud.deps.json"); + if (QFile::exists(dalamudDepsJson)) { + QFile depsJson(dalamudDepsJson); depsJson.open(QFile::ReadOnly); QJsonDocument doc = QJsonDocument::fromJson(depsJson.readAll()); @@ -40,15 +46,17 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent) dalamudVersion = versionString.remove("Dalamud/"); } - if (QFile::exists(dataDir + "/DalamudAssets/asset.ver")) { - QFile assetJson(dataDir + "/DalamudAssets/asset.ver"); + const QString dalamudAssetsVer = dalamudAssetsDir.absoluteFilePath("asset.ver"); + if (QFile::exists(dalamudAssetsVer)) { + QFile assetJson(dalamudAssetsVer); assetJson.open(QFile::ReadOnly | QFile::Text); dalamudAssetVersion = QString(assetJson.readAll()).toInt(); } - if (QFile::exists(dataDir + "/DalamudRuntime/runtime.ver")) { - QFile runtimeVer(dataDir + "/DalamudRuntime/runtime.ver"); + const QString dalamudRuntimeVer = dalamudRuntimeDir.absoluteFilePath("runtime.ver"); + if (QFile::exists(dalamudRuntimeVer)) { + QFile runtimeVer(dalamudRuntimeVer); runtimeVer.open(QFile::ReadOnly | QFile::Text); runtimeVersion = QString(runtimeVer.readAll()); diff --git a/launcher/src/squareboot.cpp b/launcher/src/squareboot.cpp index e75c424..5e6bd28 100644 --- a/launcher/src/squareboot.cpp +++ b/launcher/src/squareboot.cpp @@ -38,7 +38,7 @@ void SquareBoot::bootCheck(const LoginInformation &info) QUrl url; url.setScheme("http"); - url.setHost("patch-bootver.ffxiv.com"); + url.setHost(QStringLiteral("patch-bootver.%1").arg(window.squareEnixServer())); url.setPath(QString("/http/win32/ffxivneo_release_boot/%1").arg(info.profile->bootVersion)); url.setQuery(query); @@ -49,7 +49,7 @@ void SquareBoot::bootCheck(const LoginInformation &info) request.setRawHeader("User-Agent", "FFXIV PATCH CLIENT"); } - request.setRawHeader("Host", "patch-bootver.ffxiv.com"); + request.setRawHeader("Host", QStringLiteral("patch-bootver.%1").arg(window.squareEnixServer()).toUtf8()); auto reply = window.mgr->get(request); connect(reply, &QNetworkReply::finished, [this, reply] { @@ -64,7 +64,10 @@ void SquareBoot::checkGateStatus(LoginInformation *info) Q_EMIT window.stageChanged(i18n("Checking gate...")); qDebug() << "Checking gate..."; - QUrl url("https://frontier.ffxiv.com/worldStatus/gate_status.json"); + QUrl url; + url.setScheme("https"); + url.setHost(QStringLiteral("frontier.%1").arg(window.squareEnixServer())); + url.setPath("/worldStatus/gate_status.json"); url.setQuery(QString::number(QDateTime::currentMSecsSinceEpoch())); QNetworkRequest request(url); diff --git a/launcher/src/squarelauncher.cpp b/launcher/src/squarelauncher.cpp index bfaee19..25180c8 100644 --- a/launcher/src/squarelauncher.cpp +++ b/launcher/src/squarelauncher.cpp @@ -53,7 +53,10 @@ void SquareLauncher::getStored(const LoginInformation &info) query.addQueryItem("ticket_size", "1"); } - QUrl url("https://ffxiv-login.square-enix.com/oauth/ffxivarr/login/top"); + QUrl url; + url.setScheme("https"); + url.setHost(QStringLiteral("ffxiv-login.%1").arg(window.squareEnixLoginServer())); + url.setPath("/oauth/ffxivarr/login/top"); url.setQuery(query); auto request = QNetworkRequest(url); @@ -98,7 +101,12 @@ void SquareLauncher::login(const LoginInformation &info, const QUrl &referer) postData.addQueryItem("password", info.password); postData.addQueryItem("otppw", info.oneTimePassword); - QNetworkRequest request(QUrl("https://ffxiv-login.square-enix.com/oauth/ffxivarr/login/login.send")); + QUrl url; + url.setScheme("https"); + url.setHost(QStringLiteral("ffxiv-login.%1").arg(window.squareEnixLoginServer())); + url.setPath("/oauth/ffxivarr/login/login.send"); + + QNetworkRequest request(url); window.buildRequest(*info.profile, request); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setRawHeader("Referer", referer.toEncoded()); @@ -149,7 +157,7 @@ void SquareLauncher::registerSession(const LoginInformation &info) { QUrl url; url.setScheme("https"); - url.setHost("patch-gamever.ffxiv.com"); + url.setHost(QStringLiteral("patch-gamever.%1").arg(window.squareEnixServer())); url.setPath(QString("/http/win32/ffxivneo_release_game/%1/%2").arg(info.profile->repositories.repositories[0].version, SID)); auto request = QNetworkRequest(url); diff --git a/launcher/ui/Settings/DeveloperSettings.qml b/launcher/ui/Settings/DeveloperSettings.qml index 59aa3d6..d6efd20 100644 --- a/launcher/ui/Settings/DeveloperSettings.qml +++ b/launcher/ui/Settings/DeveloperSettings.qml @@ -31,6 +31,24 @@ Kirigami.ScrollablePage { checked: LauncherCore.keepPatches onCheckedChanged: LauncherCore.keepPatches = checked } + + MobileForm.FormTextFieldDelegate { + label: i18n("Dalamud Distribution Server") + text: LauncherCore.dalamudDistribServer + onTextChanged: LauncherCore.dalamudDistribServer = text + } + + MobileForm.FormTextFieldDelegate { + label: i18n("SE Main Server") + text: LauncherCore.squareEnixServer + onTextChanged: LauncherCore.squareEnixServer = text + } + + MobileForm.FormTextFieldDelegate { + label: i18n("SE Login Server") + text: LauncherCore.squareEnixLoginServer + onTextChanged: LauncherCore.squareEnixLoginServer = text + } } } }