diff --git a/src/XIVLauncher.Common/Constants.cs b/src/XIVLauncher.Common/Constants.cs
index af481d561..2bea5eacc 100644
--- a/src/XIVLauncher.Common/Constants.cs
+++ b/src/XIVLauncher.Common/Constants.cs
@@ -10,6 +10,8 @@ public static class Constants
public const uint STEAM_APP_ID = 39210;
public const uint STEAM_FT_APP_ID = 312060;
+ public const string LAUNCHER_CONFIG_URL = "https://kamori.goats.dev/Launcher/GetLauncherClientConfig";
+ public const string FRONTIER_FALLBACK = "https://launcher.finalfantasyxiv.com/v650/index.html?rc_lang={0}&time={1}";
public static string PatcherUserAgent => GetPatcherUserAgent(PlatformHelpers.GetPlatform());
private static string GetPatcherUserAgent(Platform platform)
@@ -29,4 +31,4 @@ private static string GetPatcherUserAgent(Platform platform)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/XIVLauncher.Common/Util/ApiHelpers.cs b/src/XIVLauncher.Common/Util/ApiHelpers.cs
index b9dd9de84..48e1bb52d 100644
--- a/src/XIVLauncher.Common/Util/ApiHelpers.cs
+++ b/src/XIVLauncher.Common/Util/ApiHelpers.cs
@@ -1,6 +1,10 @@
+using Serilog;
using System;
using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Json;
using System.Net.Http.Headers;
+using System.Threading.Tasks;
namespace XIVLauncher.Common.Util;
@@ -95,4 +99,34 @@ public static void AddWithoutValidation(this HttpHeaders headers, string key, st
var attributes = memInfo[0].GetCustomAttributes(typeof(TAttribute), false);
return (attributes.Length > 0) ? (TAttribute)attributes[0] : null;
}
+
+ ///
+ /// Represents a response from Kamori's GetLauncherClientConfig endpoint.
+ ///
+ public struct LauncherClientConfig
+ {
+ public string frontierUrl { get; set; }
+ public string? cutOffBootver { get; set; }
+ public uint flags { get; set; }
+
+ public static async Task GetAsync()
+ {
+ try
+ {
+ HttpClient HttpClient = new()
+ {
+ Timeout = TimeSpan.FromSeconds(5)
+ };
+ return await HttpClient.GetFromJsonAsync(Constants.LAUNCHER_CONFIG_URL).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Could not obtain LauncherClientConfig");
+ return new LauncherClientConfig()
+ {
+ frontierUrl = Constants.FRONTIER_FALLBACK,
+ };
+ }
+ }
+ }
}
diff --git a/src/XIVLauncher.Common/XIVLauncher.Common.csproj b/src/XIVLauncher.Common/XIVLauncher.Common.csproj
index 446e58d25..aaf9f3e5e 100644
--- a/src/XIVLauncher.Common/XIVLauncher.Common.csproj
+++ b/src/XIVLauncher.Common/XIVLauncher.Common.csproj
@@ -1,4 +1,4 @@
-
+
XIVLauncher.Common
XIVLauncher.Common
@@ -52,6 +52,7 @@
+
diff --git a/src/XIVLauncher.PatchInstaller/Commands/IndexUpdateCommand.cs b/src/XIVLauncher.PatchInstaller/Commands/IndexUpdateCommand.cs
index fa5bf8efb..bbf2c8af8 100644
--- a/src/XIVLauncher.PatchInstaller/Commands/IndexUpdateCommand.cs
+++ b/src/XIVLauncher.PatchInstaller/Commands/IndexUpdateCommand.cs
@@ -78,7 +78,7 @@ private IndexUpdateCommand(ParseResult parseResult)
private async Task Handle(CancellationToken cancellationToken)
{
- var la = new Launcher((ISteam?)null, new CommonUniqueIdCache(null), this.settings, "https://launcher.finalfantasyxiv.com/v650/index.html?rc_lang={0}&time={1}");
+ var la = new Launcher((ISteam?)null, new CommonUniqueIdCache(null), this.settings, XIVLauncher.Common.Util.ApiHelpers.LauncherClientConfig.GetAsync().GetAwaiter().GetResult().frontierUrl);
var bootPatchListFile = new FileInfo(Path.Combine(this.settings.GamePath.FullName, "bootlist.json"));
diff --git a/src/XIVLauncher/Windows/ViewModel/MainWindowViewModel.cs b/src/XIVLauncher/Windows/ViewModel/MainWindowViewModel.cs
index 08e22c5e8..a6442bd49 100644
--- a/src/XIVLauncher/Windows/ViewModel/MainWindowViewModel.cs
+++ b/src/XIVLauncher/Windows/ViewModel/MainWindowViewModel.cs
@@ -78,7 +78,7 @@ public MainWindowViewModel(Window window)
var frontierUrl = Updates.UpdateLease?.FrontierUrl;
#if DEBUG || RELEASENOUPDATE
// FALLBACK
- frontierUrl ??= "https://launcher.finalfantasyxiv.com/v650/index.html?rc_lang={0}&time={1}";
+ frontierUrl ??= XIVLauncher.Common.Util.ApiHelpers.LauncherClientConfig.GetAsync().GetAwaiter().GetResult().frontierUrl;
#endif
Launcher = App.GlobalSteamTicket == null