mirror of
https://github.com/araxiaonline/WoW-Launcher.git
synced 2026-06-13 01:22:21 -04:00
Added new command line options to specify custom versions & cdns urls.
Also fall back to default data when these are not reachable.
This commit is contained in:
@@ -16,6 +16,10 @@ static class LaunchOptions
|
||||
public static Option<bool> KeepCache = new("--keepcache", () => true);
|
||||
public static Option<bool> UseStaticAuthSeed = new("--staticseed");
|
||||
public static Option<bool> DevMode = new("--dev", () => true);
|
||||
public static Option<string> VersionUrl = new("--versionurl");
|
||||
public static Option<string> CdnsUrl = new("--cdnsurl");
|
||||
public static Option<string> ProductName = new("--product", () => "wow");
|
||||
public static Option<string> CdnRegion = new("--region", () => "EU");
|
||||
|
||||
// Game command line options.
|
||||
public static Option<string> GameConfig = new("-config", () => "Config.wtf");
|
||||
@@ -36,6 +40,10 @@ static class LaunchOptions
|
||||
KeepCache,
|
||||
UseStaticAuthSeed,
|
||||
DevMode,
|
||||
VersionUrl,
|
||||
CdnsUrl,
|
||||
ProductName,
|
||||
CdnRegion,
|
||||
GameConfig
|
||||
};
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ static class Launcher
|
||||
else
|
||||
{
|
||||
var config = File.ReadAllText(configPath);
|
||||
|
||||
|
||||
portal = ParsePortal(config);
|
||||
|
||||
LaunchOptions.IsDevModeAllowed = IsDevModeAllowed(ipFilter, portal.IPAddress);
|
||||
@@ -113,7 +113,7 @@ static class Launcher
|
||||
Console.WriteLine($"Developer mode: {(devModeEnabled ? "Enabled" : "Disabled")}");
|
||||
Console.WriteLine();
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
|
||||
// Check for valid certificate when dev mode is disabled.
|
||||
if (!devModeEnabled)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ static class Launcher
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
|
||||
sslStream.AuthenticateAsClient(portal.HostName);
|
||||
}
|
||||
catch (SocketException)
|
||||
@@ -166,6 +166,38 @@ static class Launcher
|
||||
|
||||
public static bool LaunchGame(string appPath, string gameCommandLine, ParseResult commandLineResult)
|
||||
{
|
||||
// Build the version URL from the game binary build.
|
||||
var clientVersion = GetVersionValueFromClient(appPath);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine($"Client Build {clientVersion}");
|
||||
Console.WriteLine($"Client Path '{appPath}'");
|
||||
Console.WriteLine();
|
||||
Console.ResetColor();
|
||||
|
||||
// Assign the region and product dependent version url to check it's online status.
|
||||
var versionUrl = commandLineResult.GetValueForOption(LaunchOptions.VersionUrl)
|
||||
?? Patches.Common.GetVersionUrl(clientVersion.Build, commandLineResult.GetValueForOption(LaunchOptions.CdnRegion),
|
||||
commandLineResult.GetValueForOption(LaunchOptions.ProductName));
|
||||
|
||||
if (!CheckUrl(versionUrl, fallbackUrl: Patterns.Common.VersionUrl).GetAwaiter().GetResult())
|
||||
versionUrl = Patterns.Common.VersionUrl;
|
||||
else
|
||||
// Assign the region and product independent version url.
|
||||
versionUrl = commandLineResult.GetValueForOption(LaunchOptions.VersionUrl) ?? Patches.Common.GetVersionUrl(clientVersion.Build);
|
||||
|
||||
var cdnsUrl = commandLineResult.GetValueForOption(LaunchOptions.CdnsUrl) ?? Patches.Common.CdnsUrl;
|
||||
|
||||
if (!CheckUrl(cdnsUrl, fallbackUrl: Patterns.Common.CdnsUrl).GetAwaiter().GetResult())
|
||||
cdnsUrl = Patterns.Common.CdnsUrl;
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("Game CDN connection info:");
|
||||
Console.WriteLine($"Version file: {versionUrl}");
|
||||
Console.WriteLine($"CDNs file: {cdnsUrl}");
|
||||
Console.WriteLine();
|
||||
Console.ResetColor();
|
||||
|
||||
var startupInfo = new StartupInfo();
|
||||
var processInfo = new ProcessInformation();
|
||||
|
||||
@@ -204,17 +236,6 @@ static class Launcher
|
||||
|
||||
byte[] certBundleData = Convert.FromBase64String(Patches.Common.CertBundleData);
|
||||
|
||||
// Build the version URL from the game binary build.
|
||||
var clientVersion = GetVersionValueFromClient(appPath);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Client Build {clientVersion}");
|
||||
Console.WriteLine($"Client Path '{appPath}'");
|
||||
Console.WriteLine();
|
||||
Console.ResetColor();
|
||||
|
||||
byte[] versionPatch = Patches.Common.GetVersionUrl(clientVersion.Build);
|
||||
|
||||
// Refresh the client data before patching.
|
||||
memory.RefreshMemoryData((int)gameAppData.Length);
|
||||
@@ -232,6 +253,7 @@ static class Launcher
|
||||
}, CancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
|
||||
// Wait for all direct memory patch tasks to complete,
|
||||
Task.WaitAll(new[]
|
||||
{
|
||||
@@ -243,8 +265,8 @@ static class Launcher
|
||||
: memory.PatchMemory(Patterns.Common.CryptoRsaModulus, Patches.Common.RsaModulus, "GameCrypto RsaModulus"),
|
||||
|
||||
memory.PatchMemory(Patterns.Common.Portal, Patches.Common.Portal, "Login Portal"),
|
||||
memory.PatchMemory(Patterns.Common.VersionUrl, versionPatch, "Version URL"),
|
||||
memory.PatchMemory(Patterns.Common.CdnsUrl, Patches.Common.CdnsUrl, "CDNs URL"),
|
||||
memory.PatchMemory(Patterns.Common.VersionUrl.ToPattern(), Encoding.UTF8.GetBytes(versionUrl), "Version URL"),
|
||||
memory.PatchMemory(Patterns.Common.CdnsUrl.ToPattern(), Encoding.UTF8.GetBytes(cdnsUrl), "CDNs URL"),
|
||||
memory.PatchMemory(Patterns.Windows.LauncherLogin, Patches.Windows.LauncherLogin, "Launcher Login Registry")
|
||||
}, CancellationTokenSource.Token);
|
||||
|
||||
|
||||
@@ -8,6 +8,15 @@ namespace Arctium.WoW.Launcher.Misc;
|
||||
|
||||
static class Helpers
|
||||
{
|
||||
public static bool IsDebugBuild()
|
||||
{
|
||||
#if DEBUG
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static (int Major, int Minor, int Revision, int Build) GetVersionValueFromClient(string fileName)
|
||||
{
|
||||
var fileVersionInfo = FileVersionInfo.GetVersionInfo(fileName);
|
||||
@@ -90,4 +99,25 @@ static class Helpers
|
||||
return (string.Empty, string.Empty, port);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> CheckUrl(string url, string fallbackUrl)
|
||||
{
|
||||
using var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
|
||||
|
||||
try
|
||||
{
|
||||
var result = await httpClient.GetAsync(url);
|
||||
|
||||
if (!result.IsSuccessStatusCode)
|
||||
Console.WriteLine($"{url} not reachable. Falling back to {fallbackUrl}");
|
||||
|
||||
return result.IsSuccessStatusCode;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine($"{url} not reachable. Falling back to {fallbackUrl}");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class ModLoader
|
||||
var hookAddress = memory.Data.FindPattern(Patterns.Windows.CustomFileIdHook);
|
||||
|
||||
if (hookAddress == 0)
|
||||
return false;
|
||||
throw new InvalidDataException("CustomFileIdHook");
|
||||
|
||||
// Read original data from the hook function.
|
||||
var originalBytes = memory.Read(memory.BaseAddress + hookAddress, 13);
|
||||
|
||||
@@ -43,8 +43,8 @@ static class Common
|
||||
public static byte[] CryptoEdPublicKey = { 0x02, 0x59, 0x6F, 0x0D, 0x0C, 0x06, 0x1A, 0x8B, 0x30, 0x74, 0x59, 0x88, 0xFD, 0x72, 0xC5, 0x9E,
|
||||
0x29, 0xEC, 0x36, 0x7F, 0xB0, 0xF3, 0x41, 0xF2, 0x8E, 0x0F, 0x08, 0xD0, 0x37, 0xBA, 0xFC, 0x69 };
|
||||
|
||||
public static byte[] GetVersionUrl(int build) => Encoding.UTF8.GetBytes($"ngdp.arctium.io/%s/%s/{build}/versions");
|
||||
public static byte[] CdnsUrl => Encoding.UTF8.GetBytes("http://ngdp.arctium.io/customs/wow/cdns");
|
||||
public static string GetVersionUrl(int build, string region = "%s", string product = "%s") => $"http://ngdp.arctium.io/{region}/{product}/{build}/versions";
|
||||
public static string CdnsUrl => "http://ngdp.arctium.io/customs/wow/cdns";
|
||||
public static byte[] Portal = new byte[Patterns.Common.Portal.Length];
|
||||
|
||||
// Our own ca_bundle.txt.signed file.
|
||||
|
||||
@@ -11,8 +11,7 @@ static class Common
|
||||
public static short[] CryptoEdPublicKey = { 0x15, 0xD6, 0x18, 0xBD, 0x7D, 0xB5, 0x77, 0xBD };
|
||||
|
||||
public static short[] CertBundle = "{\"Created\":".ToPattern();
|
||||
public static short[] VersionUrl = "%s.patch.battle.net:1119/%s/versions".ToPattern();
|
||||
public static short[] CdnsUrl = "http://%s.patch.battle.net:1119/%s/cdns".ToPattern();
|
||||
public static string VersionUrl = "http://%s.patch.battle.net:1119/%s/versions";
|
||||
public static string CdnsUrl = "http://%s.patch.battle.net:1119/%s/cdns";
|
||||
public static short[] Portal = ".actual.battle.net\0".ToPattern();
|
||||
public static short[] CommandLineHelp = "World of Warcraft usage".ToPattern();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using System.CommandLine.Parsing;
|
||||
using Arctium.WoW.Launcher;
|
||||
|
||||
using static Arctium.WoW.Launcher.Misc.Helpers;
|
||||
|
||||
// "Arctium" should not be removed from the final binary name.
|
||||
|
||||
Reference in New Issue
Block a user