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 + } } } }