From 4e55829c5dbff98a0b9fa5cf2932f9e1f4c940c2 Mon Sep 17 00:00:00 2001 From: InvoxiPlayGames Date: Sat, 11 Nov 2023 12:42:09 +0000 Subject: [PATCH] add launch argument support --- EpicCaldera.cs | 51 ++++++++++++++++++++++++++++++++++++ Program.cs | 71 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 EpicCaldera.cs diff --git a/EpicCaldera.cs b/EpicCaldera.cs new file mode 100644 index 0000000..4830aeb --- /dev/null +++ b/EpicCaldera.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Headers; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Net.Http.Json; +using System.Web; + +namespace EricLauncher +{ + public class CalderaRequest + { + public string? account_id { get; set; } + public string? exchange_code { get; set; } + public bool test_mode { get; set; } + public string? epic_app { get; set; } + public bool nvidia { get; set; } + public bool luna { get; set; } + public bool salmon { get; set; } + } + + public class CalderaResponse + { + public string? provider { get; set; } + public string? jwt { get; set; } + } + + class EpicCaldera + { + public const string CALDERA_HOST = "https://caldera-service-prod.ecosec.on.epicgames.com"; + public const string CALDERA_RACP_PATH = "/caldera/api/v1/launcher/racp"; + + public static async Task GetCalderaResponse(string accountid, string exchangecode, string app) + { + HttpClient client = new(); + client.BaseAddress = new Uri(CALDERA_HOST); + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Add("User-Agent", "Caldera/UNKNOWN-UNKNOWN-UNKNOWN"); + CalderaRequest req = new CalderaRequest + { + account_id = accountid, + exchange_code = exchangecode, + epic_app = app + }; + HttpResponseMessage resp = await client.PostAsJsonAsync(CALDERA_RACP_PATH, req); + return await resp.Content.ReadFromJsonAsync(); + } + } +} diff --git a/Program.cs b/Program.cs index 735580a..f008f2b 100644 --- a/Program.cs +++ b/Program.cs @@ -13,7 +13,7 @@ internal class Program static void PrintUsage() { - Console.WriteLine("Usage: EricLauncher.exe [executable path] (options)"); + Console.WriteLine("Usage: EricLauncher.exe [executable path] (options) (game arguments)"); Console.WriteLine(); Console.WriteLine("Options:"); Console.WriteLine(" --accountId [id] - use a specific Epic Games account ID to sign in."); @@ -44,29 +44,37 @@ static async Task Main(string[] args) bool dry_run = false; bool offline = false; bool skip_fortnite_update = false; + bool caldera = false; + string extra_args = ""; if (args.Length > 1) { for (int i = 1; i < args.Length; i++) { if (args[i] == "--accountId") account_id = args[++i]; - if (args[i] == "--manifest") + else if (args[i] == "--manifest") manifest_path = args[++i]; - if (args[i] == "--setDefault") + else if (args[i] == "--setDefault") set_default = true; - if (args[i] == "--noManifest") + else if (args[i] == "--noManifest") no_manifest = true; - if (args[i] == "--stayOpen") + else if (args[i] == "--stayOpen") stay_open = true; - if (args[i] == "--dryRun") + else if (args[i] == "--dryRun") dry_run = true; - if (args[i] == "--offline") + else if (args[i] == "--offline") offline = true; - if (args[i] == "--noCheckFn") + else if (args[i] == "--caldera") + caldera = true; + else if (args[i] == "--noCheckFn") skip_fortnite_update = true; + else + extra_args += args[i] + " "; } } + string exe_name = args[0]; + // always run as a dry run if we're on Linux or FreeBSD if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD)) @@ -74,13 +82,13 @@ static async Task Main(string[] args) // if we're launching fortnite, do an update check if (!skip_fortnite_update && !offline && - Path.GetFileName(args[0]).ToLower() == "fortnitelauncher.exe") + Path.GetFileName(exe_name).ToLower() == "fortnitelauncher.exe") { Console.WriteLine("Checking for Fortnite updates..."); // traverse back to the cloud content json try { - string cloudcontent_path = Path.GetDirectoryName(args[0]) + @"\..\..\..\Cloud\cloudcontent.json"; + string cloudcontent_path = Path.GetDirectoryName(exe_name) + @"\..\..\..\Cloud\cloudcontent.json"; string jsonstring = File.ReadAllText(cloudcontent_path); FortniteCloudContent? cloudcontent = JsonSerializer.Deserialize(jsonstring); Console.WriteLine($"Current version: {cloudcontent!.BuildVersion!} ({cloudcontent!.Platform!})"); @@ -209,7 +217,7 @@ static async Task Main(string[] args) EGLManifest? manifest = null; if (!no_manifest && manifest_path == null) { - manifest = GetEGLManifest(Path.GetFileName(args[0])); + manifest = GetEGLManifest(Path.GetFileName(exe_name)); } else if (!no_manifest && manifest_path != null) { string jsonstring = File.ReadAllText(manifest_path); @@ -226,8 +234,38 @@ static async Task Main(string[] args) string exchange = ""; if (!offline) exchange = await account.GetExchangeCode(); + + // caldera simulation + if (caldera && Path.GetFileName(exe_name).StartsWith("Fortnite")) + { + string? gamedir = Path.GetDirectoryName(exe_name); + CalderaResponse? cal_resp = await EpicCaldera.GetCalderaResponse(account_id!, exchange, "fortnite"); + string acargs = $" -caldera={cal_resp!.jwt}"; + string acexe = "FortniteClient-Win64-Shipping"; + switch (cal_resp.provider) + { + case "EasyAntiCheatEOS": + acargs += " -fromfl=eaceos -noeac -nobe "; + acexe += "_EAC_EOS.exe"; + break; + case "EasyAntiCheat": + acargs += " -fromfl=eac -noeaceos -nobe "; + acexe += "_EAC.exe"; + break; + case "BattlEye": + acargs += " -fromfl=be -noeaceos -noeac "; + acexe += "_BE.exe"; + break; + default: + Console.WriteLine($"Unknown Caldera provider '{cal_resp.provider}'."); + return; + } + extra_args += acargs; + exe_name = Path.Combine(gamedir!, acexe); + } + Console.WriteLine("Launching game..."); - Process game = await LaunchGame(args[0], exchange, account, manifest, dry_run, offline); + Process game = await LaunchGame(exe_name, exchange, account, manifest, dry_run, offline, extra_args); if (stay_open && !dry_run) { game.WaitForExit(); @@ -235,7 +273,7 @@ static async Task Main(string[] args) } } - static async Task LaunchGame(string filename, string? exchange, EpicAccount? account, EGLManifest? manifest, bool dry_run, bool skip_ovt) + static async Task LaunchGame(string filename, string? exchange, EpicAccount? account, EGLManifest? manifest, bool dry_run, bool skip_ovt, string launch_args) { Process p = new Process(); p.StartInfo.FileName = filename; @@ -270,6 +308,13 @@ static async Task LaunchGame(string filename, string? exchange, EpicAcc } } + if (launch_args != "") + { + string[] split_args = launch_args.Split(' '); + foreach (string arg in split_args) + p.StartInfo.ArgumentList.Add(arg); + } + if (account != null && manifest != null && !skip_ovt && manifest.OwnershipToken == "true") {