diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index 24d1ffa..46e0b35 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -4,7 +4,7 @@ net7.0-windows True Resources\ini.ico - 4.4.0.2 + 4.5.0.0 2021, pointfeev (https://github.com/pointfeev) CreamInstaller Automatic DLC Unlocker Installer & Configuration Generator diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs index 02ba6b1..2a2013e 100644 --- a/CreamInstaller/Forms/InstallForm.cs +++ b/CreamInstaller/Forms/InstallForm.cs @@ -80,8 +80,8 @@ internal sealed partial class InstallForm : CustomForm { if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); - directory.GetKoaloaderComponents(out List proxies, out string old_config, out string config); - if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) + directory.GetKoaloaderComponents(out string old_config, out string config); + if (directory.GetKoaloaderProxies().Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) || directory != selection.RootDirectory && Koaloader.AutoLoadDLLs.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(old_config) || File.Exists(config)) { @@ -95,8 +95,8 @@ internal sealed partial class InstallForm : CustomForm { if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); - directory.GetKoaloaderComponents(out List proxies, out string old_config, out string config); - if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) + directory.GetKoaloaderComponents(out string old_config, out string config); + if (directory.GetKoaloaderProxies().Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) || Koaloader.AutoLoadDLLs.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(old_config) || File.Exists(config)) { UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); @@ -113,9 +113,10 @@ internal sealed partial class InstallForm : CustomForm if (selection.Platform is Platform.Steam or Platform.Paradox) { directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, - out string config, out string cache); + out string config, out string old_log, out string log, out string cache); if (uninstallProxy - ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(old_config) || File.Exists(config) || File.Exists(cache) + ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(old_config) || File.Exists(config) || File.Exists(old_log) + || File.Exists(log) || File.Exists(cache) : File.Exists(api32) || File.Exists(api64)) { UpdateUser( @@ -129,8 +130,10 @@ internal sealed partial class InstallForm : CustomForm } if (selection.Platform is Platform.Epic or Platform.Paradox) { - directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64)) + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); + if (uninstallProxy + ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(log) + : File.Exists(api32) || File.Exists(api64)) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name @@ -143,8 +146,10 @@ internal sealed partial class InstallForm : CustomForm } if (selection.Platform is Platform.Ubisoft) { - directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64)) + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); + if (uninstallProxy + ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(log) + : File.Exists(api32) || File.Exists(api64)) { UpdateUser( $"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name @@ -154,9 +159,9 @@ internal sealed partial class InstallForm : CustomForm else await UplayR1.Install(directory, selection, this); } - directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config); + directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, out log); if (uninstallProxy - ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) + ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(log) : File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api64)) { UpdateUser( diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index beef456..eea5027 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -818,30 +818,33 @@ internal sealed partial class SelectForm : CustomForm foreach (string directory in directories) { directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, - out string config, out string cache); + out string config, out string old_log, out string log, out string cache); if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(old_config) - || File.Exists(config) || File.Exists(cache)) + || File.Exists(config) || File.Exists(old_log) || File.Exists(log) || File.Exists(cache)) items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } if (selection.Platform is Platform.Epic or Platform.Paradox) foreach (string directory in directories) { - directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config)) + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); + if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) || File.Exists(log)) items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } if (selection.Platform is Platform.Ubisoft) foreach (string directory in directories) { - directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config)) + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); + if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) || File.Exists(log)) items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); - directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config); + directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, + out log); if (File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) - || File.Exists(api64_o) || File.Exists(config)) + || File.Exists(api64_o) || File.Exists(config) || File.Exists(log)) items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer", (_, _) => Diagnostics.OpenDirectoryInFileExplorer(directory))); } diff --git a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs index 94bbfc5..cedd69e 100644 --- a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs +++ b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; @@ -47,22 +46,14 @@ internal static class ParadoxLauncher paradoxLauncher.ExtraSelectedDlc.Clear(); foreach (ProgramSelection selection in ProgramSelection.AllEnabled.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive")) { - paradoxLauncher.ExtraDlc.Add( - new ValueTuple>(selection.Id, selection.Name, - selection.AllDlc)); - paradoxLauncher.ExtraSelectedDlc.Add( - new ValueTuple>(selection.Id, selection.Name, - selection.SelectedDlc)); + paradoxLauncher.ExtraDlc.Add(selection.Id, (selection.Name, selection.AllDlc)); + paradoxLauncher.ExtraSelectedDlc.Add(selection.Id, (selection.Name, selection.SelectedDlc)); } if (!paradoxLauncher.ExtraDlc.Any()) foreach (ProgramSelection selection in ProgramSelection.AllSafe.Where(s => s != paradoxLauncher && s.Publisher == "Paradox Interactive")) { - paradoxLauncher.ExtraDlc.Add( - new ValueTuple>(selection.Id, selection.Name, - selection.AllDlc)); - paradoxLauncher.ExtraSelectedDlc.Add( - new ValueTuple>(selection.Id, selection.Name, - selection.AllDlc)); + paradoxLauncher.ExtraDlc.Add(selection.Id, (selection.Name, selection.AllDlc)); + paradoxLauncher.ExtraSelectedDlc.Add(selection.Id, (selection.Name, selection.AllDlc)); } } } @@ -100,21 +91,23 @@ internal static class ParadoxLauncher { bool koaloaderInstalled = Koaloader.AutoLoadDLLs.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) .Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile()); - directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string _, out string config, out _); + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, + out string config, out _, out _, out _); smokeInstalled = smokeInstalled || File.Exists(api32_o) || File.Exists(api64_o) - || (File.Exists(config) || File.Exists(config)) && !koaloaderInstalled + || (File.Exists(old_config) || File.Exists(config)) && !koaloaderInstalled || File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.Steamworks32) || File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.Steamworks64); - await SmokeAPI.Uninstall(directory, deleteConfig: false); + await SmokeAPI.Uninstall(directory, deleteOthers: false); if (steamOriginalSdk32 is null && File.Exists(api32) && !api32.IsResourceFile(ResourceIdentifier.Steamworks32)) steamOriginalSdk32 = await File.ReadAllBytesAsync(api32); if (steamOriginalSdk64 is null && File.Exists(api64) && !api64.IsResourceFile(ResourceIdentifier.Steamworks64)) steamOriginalSdk64 = await File.ReadAllBytesAsync(api64); - directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config); - screamInstalled = screamInstalled || File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled + directory.GetScreamApiComponents(out api32, out api32_o, out api64, out api64_o, out config, out string log); + screamInstalled = screamInstalled || File.Exists(api32_o) || File.Exists(api64_o) + || (File.Exists(config) || File.Exists(log)) && !koaloaderInstalled || File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32) || File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64); - await ScreamAPI.Uninstall(directory, deleteConfig: false); + await ScreamAPI.Uninstall(directory, deleteOthers: false); if (epicOriginalSdk32 is null && File.Exists(api32) && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) epicOriginalSdk32 = await File.ReadAllBytesAsync(api32); if (epicOriginalSdk64 is null && File.Exists(api64) && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64)) @@ -126,7 +119,7 @@ internal static class ParadoxLauncher bool neededRepair = false; foreach (string directory in selection.DllDirectories) { - directory.GetSmokeApiComponents(out string api32, out _, out string api64, out _, out _, out _, out _); + directory.GetSmokeApiComponents(out string api32, out _, out string api64, out _, out _, out _, out _, out _, out _); if (steamOriginalSdk32 is not null && api32.IsResourceFile(ResourceIdentifier.Steamworks32)) { steamOriginalSdk32.Write(api32); @@ -141,7 +134,7 @@ internal static class ParadoxLauncher } if (smokeInstalled) await SmokeAPI.Install(directory, selection, generateConfig: false); - directory.GetScreamApiComponents(out api32, out _, out api64, out _, out _); + directory.GetScreamApiComponents(out api32, out _, out api64, out _, out _, out _); if (epicOriginalSdk32 is not null && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) { epicOriginalSdk32.Write(api32); diff --git a/CreamInstaller/ProgramSelection.cs b/CreamInstaller/ProgramSelection.cs index 112e938..e3e9bb7 100644 --- a/CreamInstaller/ProgramSelection.cs +++ b/CreamInstaller/ProgramSelection.cs @@ -27,10 +27,9 @@ internal sealed class ProgramSelection internal readonly SortedList AllDlc = new(PlatformIdComparer.String); - internal readonly List<(string id, string name, SortedList dlc)> ExtraDlc = new(); // for Paradox Launcher + internal readonly SortedList dlc)> ExtraDlc = new(); - internal readonly List<(string id, string name, SortedList dlc)> - ExtraSelectedDlc = new(); // for Paradox Launcher + internal readonly SortedList dlc)> ExtraSelectedDlc = new(); internal readonly SortedList SelectedDlc = new(PlatformIdComparer.String); @@ -68,27 +67,32 @@ internal sealed class ProgramSelection if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.IsFilePathLocked()) return true; - directory.GetSmokeApiComponents(out api32, out api32_o, out api64, out api64_o, out string old_config, out config, out string cache); + directory.GetSmokeApiComponents(out api32, out api32_o, out api64, out api64_o, out string old_config, out config, out string old_log, + out string log, out string cache); if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() - || old_config.IsFilePathLocked() || config.IsFilePathLocked() || cache.IsFilePathLocked()) + || old_config.IsFilePathLocked() || config.IsFilePathLocked() || old_log.IsFilePathLocked() || log.IsFilePathLocked() + || cache.IsFilePathLocked()) return true; } if (Platform is Platform.Epic or Platform.Paradox) { - directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() - || config.IsFilePathLocked()) + || config.IsFilePathLocked() || log.IsFilePathLocked()) return true; } if (Platform is Platform.Ubisoft) { - directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() - || config.IsFilePathLocked()) + || config.IsFilePathLocked() || log.IsFilePathLocked()) return true; - directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config); + directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, + out log); if (old_api32.IsFilePathLocked() || old_api64.IsFilePathLocked() || api32.IsFilePathLocked() || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.IsFilePathLocked()) + || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.IsFilePathLocked() || log.IsFilePathLocked()) return true; } } diff --git a/CreamInstaller/Resources/Koaloader.cs b/CreamInstaller/Resources/Koaloader.cs index 554e89e..c4fc6a6 100644 --- a/CreamInstaller/Resources/Koaloader.cs +++ b/CreamInstaller/Resources/Koaloader.cs @@ -21,13 +21,16 @@ internal static class Koaloader ("Uplay R2 Unlocker", "UplayR2Unlocker.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker64.dll") }; - internal static void GetKoaloaderComponents(this string directory, out List proxies, out string old_config, out string config) + internal static IEnumerable GetKoaloaderProxies(this string directory) + => from resource in EmbeddedResources + select resource[(resource.IndexOf('.') + 1)..] + into resource + select resource[(resource.IndexOf('.') + 1)..] + into resource + select directory + @"\" + resource; + + internal static void GetKoaloaderComponents(this string directory, out string old_config, out string config) { - proxies = EmbeddedResources.Select(proxy => - { - proxy = proxy[(proxy.IndexOf('.') + 1)..]; - return proxy[(proxy.IndexOf('.') + 1)..]; - }).Select(proxy => directory + @"\" + proxy).ToList(); old_config = directory + @"\Koaloader.json"; config = directory + @"\Koaloader.config.json"; } @@ -55,11 +58,19 @@ internal static class Koaloader private static void CheckConfig(string directory, InstallForm installForm = null) { - directory.GetKoaloaderComponents(out _, out string old_config, out string config); + directory.GetKoaloaderComponents(out string old_config, out string config); if (File.Exists(old_config)) { - File.Delete(old_config); - installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); + if (!File.Exists(config)) + { + File.Move(old_config, config!); + installForm?.UpdateUser($"Converted old configuration: {Path.GetFileName(old_config)} -> {Path.GetFileName(config)}", LogTextBox.Action, false); + } + else + { + File.Delete(old_config); + installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); + } } SortedList targets = new(PlatformIdComparer.String); SortedList modules = new(PlatformIdComparer.String); @@ -123,8 +134,9 @@ internal static class Koaloader internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null, bool deleteConfig = true) => await Task.Run(async () => { - directory.GetKoaloaderComponents(out List proxies, out string old_config, out string config); - foreach (string proxyPath in proxies.Where(proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) + directory.GetKoaloaderComponents(out string old_config, out string config); + foreach (string proxyPath in directory.GetKoaloaderProxies() + .Where(proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) { File.Delete(proxyPath); installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false); @@ -157,10 +169,9 @@ internal static class Koaloader InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() => { - directory.GetKoaloaderComponents(out List proxies, out _, out _); string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy; string path = directory + @"\" + proxy + ".dll"; - foreach (string _path in proxies.Where(p => p != path && File.Exists(p) && p.IsResourceFile(ResourceIdentifier.Koaloader))) + foreach (string _path in directory.GetKoaloaderProxies().Where(p => p != path && File.Exists(p) && p.IsResourceFile(ResourceIdentifier.Koaloader))) { File.Delete(_path); installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false); diff --git a/CreamInstaller/Resources/Resources.cs b/CreamInstaller/Resources/Resources.cs index 6543a0f..1d62528 100644 --- a/CreamInstaller/Resources/Resources.cs +++ b/CreamInstaller/Resources/Resources.cs @@ -537,25 +537,31 @@ internal static class Resources if (platform is Platform.Steam or Platform.Paradox) { subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64, out string api64_o, out string old_config, - out string config, out string cache); + out string config, out string old_log, out string log, out string cache); if (File.Exists(api) || File.Exists(api_o) || File.Exists(api64) || File.Exists(api64_o) - || (File.Exists(old_config) || File.Exists(config)) && !koaloaderInstalled || File.Exists(cache) && !koaloaderInstalled) + || (File.Exists(old_config) || File.Exists(config) || File.Exists(old_log) || File.Exists(log) || File.Exists(cache)) + && !koaloaderInstalled) dllDirectories.Add(subDirectory); } if (platform is Platform.Epic or Platform.Paradox) { - subDirectory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled) + subDirectory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); + if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) + || (File.Exists(config) || File.Exists(log)) && !koaloaderInstalled) dllDirectories.Add(subDirectory); } if (platform is Platform.Ubisoft) { - subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); - if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled) + subDirectory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string log); + if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) + || (File.Exists(config) || File.Exists(log)) && !koaloaderInstalled) dllDirectories.Add(subDirectory); - subDirectory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config); + subDirectory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config, + out log); if (File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) - || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled) + || File.Exists(api64_o) || (File.Exists(config) || File.Exists(log)) && !koaloaderInstalled) dllDirectories.Add(subDirectory); } } @@ -576,9 +582,9 @@ internal static class Resources { if (!File.Exists(filePath)) return null; -#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms +#pragma warning disable CA5351 using MD5 md5 = MD5.Create(); -#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms +#pragma warning restore CA5351 using FileStream stream = File.OpenRead(filePath); byte[] hash = md5.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant(); @@ -589,12 +595,7 @@ internal static class Resources internal static bool IsResourceFile(this string filePath) => filePath.ComputeMD5() is { } hash && ResourceMD5s.Values.Any(hashes => hashes.Contains(hash)); - internal enum BinaryType - { - Unknown = -1, BIT32 = 0, DOS = 1, - WOW = 2, PIF = 3, POSIX = 4, - OS216 = 5, BIT64 = 6 - } + internal enum BinaryType { Unknown = -1, BIT32 = 0, BIT64 = 6 } internal enum ResourceIdentifier { diff --git a/CreamInstaller/Resources/ScreamAPI.cs b/CreamInstaller/Resources/ScreamAPI.cs index 8d3a73c..fbc039f 100644 --- a/CreamInstaller/Resources/ScreamAPI.cs +++ b/CreamInstaller/Resources/ScreamAPI.cs @@ -12,26 +12,27 @@ namespace CreamInstaller.Resources; internal static class ScreamAPI { internal static void GetScreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, - out string config) + out string config, out string log) { api32 = directory + @"\EOSSDK-Win32-Shipping.dll"; api32_o = directory + @"\EOSSDK-Win32-Shipping_o.dll"; api64 = directory + @"\EOSSDK-Win64-Shipping.dll"; api64_o = directory + @"\EOSSDK-Win64-Shipping_o.dll"; config = directory + @"\ScreamAPI.json"; + log = directory + @"\ScreamAPI.log"; } internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { - directory.GetScreamApiComponents(out _, out _, out _, out _, out string config); + directory.GetScreamApiComponents(out _, out _, out _, out _, out string config, out _); IEnumerable> overrideCatalogItems = selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc); - foreach ((string _, string _, SortedList extraDlc) in selection.ExtraSelectedDlc) - overrideCatalogItems = overrideCatalogItems.Except(extraDlc); + foreach (KeyValuePair extraDlc)> pair in selection.ExtraSelectedDlc) + overrideCatalogItems = overrideCatalogItems.Except(pair.Value.extraDlc); IEnumerable> entitlements = selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement); - foreach ((string _, string _, SortedList _dlc) in selection.ExtraSelectedDlc) - entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement)); + foreach (KeyValuePair dlc)> pair in selection.ExtraSelectedDlc) + entitlements = entitlements.Concat(pair.Value.dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement)); overrideCatalogItems = overrideCatalogItems.ToList(); entitlements = entitlements.ToList(); if (overrideCatalogItems.Any() || entitlements.Any()) @@ -100,10 +101,10 @@ internal static class ScreamAPI writer.WriteLine("}"); } - internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) + internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true) => await Task.Run(() => { - directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); if (File.Exists(api32_o)) { if (File.Exists(api32)) @@ -124,17 +125,24 @@ internal static class ScreamAPI File.Move(api64_o, api64!); installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(config)) + if (!deleteOthers) + return; + if (File.Exists(config)) { File.Delete(config); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } + if (File.Exists(log)) + { + File.Delete(log); + installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); + } }); internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() => { - directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string _); + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _); if (File.Exists(api32) && !File.Exists(api32_o)) { File.Move(api32, api32_o!); diff --git a/CreamInstaller/Resources/SmokeAPI.cs b/CreamInstaller/Resources/SmokeAPI.cs index eb0a41a..6462e3e 100644 --- a/CreamInstaller/Resources/SmokeAPI.cs +++ b/CreamInstaller/Resources/SmokeAPI.cs @@ -12,7 +12,7 @@ namespace CreamInstaller.Resources; internal static class SmokeAPI { internal static void GetSmokeApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, - out string old_config, out string config, out string cache) + out string old_config, out string config, out string old_log, out string log, out string cache) { api32 = directory + @"\steam_api.dll"; api32_o = directory + @"\steam_api_o.dll"; @@ -20,88 +20,138 @@ internal static class SmokeAPI api64_o = directory + @"\steam_api64_o.dll"; old_config = directory + @"\SmokeAPI.json"; config = directory + @"\SmokeAPI.config.json"; + old_log = directory + @"\SmokeAPI.log"; + log = directory + @"\SmokeAPI.log.log"; cache = directory + @"\SmokeAPI.cache.json"; } internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { - directory.GetSmokeApiComponents(out _, out _, out _, out _, out string old_config, out _, out _); - IEnumerable> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string _, string _, SortedList extraDlc) in selection.ExtraSelectedDlc) - overrideDlc = overrideDlc.Except(extraDlc); - IEnumerable> injectDlc - = new List>(); - if (selection.AllDlc.Count > 64 || selection.ExtraDlc.Any(e => e.dlc.Count > 64)) - { - injectDlc = injectDlc.Concat(selection.SelectedDlc.Where(pair => pair.Value.type is DlcType.SteamHidden)); - foreach ((string id, string _, SortedList extraDlc) in selection.ExtraSelectedDlc) - if (selection.ExtraDlc.Single(e => e.id == id).dlc.Count > 64) - injectDlc = injectDlc.Concat(extraDlc.Where(pair => pair.Value.type is DlcType.SteamHidden)); - } - overrideDlc = overrideDlc.ToList(); + directory.GetSmokeApiComponents(out _, out _, out _, out _, out string old_config, out string config, out _, out _, out _); + List> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc).ToList(); + foreach (KeyValuePair dlc)> pair in selection.ExtraDlc) + if (selection.ExtraSelectedDlc.TryGetValue(pair.Key, + out (string name, SortedList dlc) selectedPair)) + overrideDlc.AddRange(pair.Value.dlc.Except(selectedPair.dlc)); + List> injectDlc = new(); + if (selection.AllDlc.Count > 64) + injectDlc.AddRange(selection.SelectedDlc.Where(pair => pair.Value.type is DlcType.SteamHidden)); + List injectDlc)>> extraApps = new(); + if (selection.ExtraDlc.Any(e => e.Value.dlc.Count > 64)) + foreach (KeyValuePair injectDlc)> pair in selection + .ExtraSelectedDlc) + if (selection.ExtraDlc.First(e => e.Key == pair.Key).Value.dlc.Count > 64) + { + SortedList extraInjectDlc = new(PlatformIdComparer.String); + foreach (KeyValuePair extraPair in pair.Value.injectDlc.Where(extraPair + => extraPair.Value.type is DlcType.SteamHidden)) + extraInjectDlc.Add(extraPair.Key, extraPair.Value); + KeyValuePair injectDlc)> newExtraPair = new(pair.Key, + (pair.Value.name, extraInjectDlc)); + extraApps.Add(newExtraPair); + } injectDlc = injectDlc.ToList(); - if (overrideDlc.Any() || injectDlc.Any()) + if (File.Exists(old_config)) + { + File.Delete(old_config); + installForm?.UpdateUser($"Deleted old configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); + } + if (selection.ExtraSelectedDlc.Any(p => p.Value.dlc.Any()) || overrideDlc.Any() || injectDlc.Any()) { /*if (installForm is not null) installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ - File.Create(old_config).Close(); - StreamWriter writer = new(old_config, true, Encoding.UTF8); - WriteConfig(writer, new(overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), + File.Create(config).Close(); + StreamWriter writer = new(config, true, Encoding.UTF8); + WriteConfig(writer, selection.Id, new(extraApps.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), + new(overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), new(injectDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm); writer.Flush(); writer.Close(); } - else if (File.Exists(old_config)) + else if (File.Exists(config)) { - File.Delete(old_config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); + File.Delete(config); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - private static void WriteConfig(StreamWriter writer, SortedList overrideDlc, - SortedList injectDlc, InstallForm installForm = null) + private static void WriteConfig(StreamWriter writer, string appId, + SortedList injectDlc)> extraApps, + SortedList overrideDlc, SortedList injectDlc, + InstallForm installForm = null) { writer.WriteLine("{"); - writer.WriteLine(" \"$version\": 1,"); + writer.WriteLine(" \"$version\": 2,"); writer.WriteLine(" \"logging\": false,"); - writer.WriteLine(" \"hook_steamclient\": true,"); - writer.WriteLine(" \"unlock_all\": true,"); + writer.WriteLine(" \"unlock_family_sharing\": true,"); + writer.WriteLine(" \"default_app_status\": \"unlocked\","); + writer.WriteLine(" \"override_app_status\": {},"); if (overrideDlc.Count > 0) { - writer.WriteLine(" \"override\": ["); + writer.WriteLine(" \"override_dlc_status\": {"); KeyValuePair lastOverrideDlc = overrideDlc.Last(); foreach (KeyValuePair pair in overrideDlc) { string dlcId = pair.Key; (_, string dlcName, _) = pair.Value; - writer.WriteLine($" {dlcId}{(pair.Equals(lastOverrideDlc) ? "" : ",")}"); - installForm?.UpdateUser($"Added override DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); + writer.WriteLine($" \"{dlcId}\": \"locked\"{(pair.Equals(lastOverrideDlc) ? "" : ",")}"); + installForm?.UpdateUser($"Added locked DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); } - writer.WriteLine(" ],"); + writer.WriteLine(" },"); } else - writer.WriteLine(" \"override\": [],"); - if (injectDlc.Count > 0) - { - writer.WriteLine(" \"dlc_ids\": ["); - KeyValuePair lastInjectDlc = injectDlc.Last(); - foreach (KeyValuePair pair in injectDlc) - { - string dlcId = pair.Key; - (_, string dlcName, _) = pair.Value; - writer.WriteLine($" {dlcId}{(pair.Equals(lastInjectDlc) ? "" : ",")}"); - installForm?.UpdateUser($"Added inject DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); - } - writer.WriteLine(" ],"); - } - else - writer.WriteLine(" \"dlc_ids\": [],"); + writer.WriteLine(" \"override_dlc_status\": {},"); writer.WriteLine(" \"auto_inject_inventory\": true,"); - writer.WriteLine(" \"inventory_items\": []"); + writer.WriteLine(" \"extra_inventory_items\": {},"); + if (injectDlc.Count > 0 || extraApps.Count > 0) + { + writer.WriteLine(" \"extra_dlcs\": {"); + if (injectDlc.Count > 0) + { + writer.WriteLine(" \"" + appId + "\": {"); + writer.WriteLine(" \"dlcs\": {"); + KeyValuePair lastInjectDlc = injectDlc.Last(); + foreach (KeyValuePair pair in injectDlc) + { + string dlcId = pair.Key; + (_, string dlcName, _) = pair.Value; + writer.WriteLine($" \"{dlcId}\": \"{dlcName}\"{(pair.Equals(lastInjectDlc) ? "" : ",")}"); + installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); + } + writer.WriteLine(" }"); + writer.WriteLine(extraApps.Count > 0 ? " }," : " }"); + } + if (extraApps.Count > 0) + { + KeyValuePair injectDlc)> lastExtraApp = extraApps.Last(); + foreach (KeyValuePair injectDlc)> pair in extraApps) + { + string extraAppId = pair.Key; + (string _ /*extraAppName*/, SortedList extraInjectDlc) = pair.Value; + writer.WriteLine(" \"" + extraAppId + "\": {"); + writer.WriteLine(" \"dlcs\": {"); + //installForm?.UpdateUser($"Added extra app to SmokeAPI.config.json with appid {extraAppId} ({extraAppName})", LogTextBox.Action, false); + KeyValuePair lastExtraAppDlc = extraInjectDlc.Last(); + foreach (KeyValuePair extraPair in extraInjectDlc) + { + string dlcId = extraPair.Key; + (_, string dlcName, _) = extraPair.Value; + writer.WriteLine($" \"{dlcId}\": \"{dlcName}\"{(extraPair.Equals(lastExtraAppDlc) ? "" : ",")}"); + installForm?.UpdateUser($"Added extra DLC to SmokeAPI.config.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); + } + writer.WriteLine(" }"); + writer.WriteLine(pair.Equals(lastExtraApp) ? " }" : " },"); + } + } + writer.WriteLine(" },"); + } + else + writer.WriteLine(" \"extra_dlcs\": {},"); + writer.WriteLine(" \"store_config\": null"); writer.WriteLine("}"); } - internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) + internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true) => await Task.Run(() => { directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig); @@ -111,7 +161,7 @@ internal static class SmokeAPI installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false); } directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string old_config, - out string config, out string cache); + out string config, out string old_log, out string log, out string cache); if (File.Exists(api32_o)) { if (File.Exists(api32)) @@ -132,21 +182,33 @@ internal static class SmokeAPI File.Move(api64_o, api64!); installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(old_config)) + if (!deleteOthers) + return; + if (File.Exists(old_config)) { File.Delete(old_config); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(old_config)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(config)) + if (File.Exists(config)) { File.Delete(config); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(cache)) + if (File.Exists(cache)) { File.Delete(cache); installForm?.UpdateUser($"Deleted cache: {Path.GetFileName(cache)}", LogTextBox.Action, false); } + if (File.Exists(old_log)) + { + File.Delete(old_log); + installForm?.UpdateUser($"Deleted log: {Path.GetFileName(old_log)}", LogTextBox.Action, false); + } + if (File.Exists(log)) + { + File.Delete(log); + installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); + } }); internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) @@ -158,7 +220,7 @@ internal static class SmokeAPI File.Delete(oldConfig); installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", LogTextBox.Action, false); } - directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _, out _); + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _, out _, out _, out _); if (File.Exists(api32) && !File.Exists(api32_o)) { File.Move(api32, api32_o!); diff --git a/CreamInstaller/Resources/SmokeAPI/steam_api.dll b/CreamInstaller/Resources/SmokeAPI/steam_api.dll index 2430325..05dd23c 100644 Binary files a/CreamInstaller/Resources/SmokeAPI/steam_api.dll and b/CreamInstaller/Resources/SmokeAPI/steam_api.dll differ diff --git a/CreamInstaller/Resources/SmokeAPI/steam_api64.dll b/CreamInstaller/Resources/SmokeAPI/steam_api64.dll index b957936..4651751 100644 Binary files a/CreamInstaller/Resources/SmokeAPI/steam_api64.dll and b/CreamInstaller/Resources/SmokeAPI/steam_api64.dll differ diff --git a/CreamInstaller/Resources/UplayR1.cs b/CreamInstaller/Resources/UplayR1.cs index ca8af92..c0fce84 100644 --- a/CreamInstaller/Resources/UplayR1.cs +++ b/CreamInstaller/Resources/UplayR1.cs @@ -12,21 +12,22 @@ namespace CreamInstaller.Resources; internal static class UplayR1 { internal static void GetUplayR1Components(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, - out string config) + out string config, out string log) { api32 = directory + @"\uplay_r1_loader.dll"; api32_o = directory + @"\uplay_r1_loader_o.dll"; api64 = directory + @"\uplay_r1_loader64.dll"; api64_o = directory + @"\uplay_r1_loader64_o.dll"; config = directory + @"\UplayR1Unlocker.jsonc"; + log = directory + @"\UplayR1Unlocker.log"; } internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { - directory.GetUplayR1Components(out _, out _, out _, out _, out string config); + directory.GetUplayR1Components(out _, out _, out _, out _, out string config, out _); IEnumerable> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string _, string _, SortedList extraDlc) in selection.ExtraSelectedDlc) - blacklistDlc = blacklistDlc.Except(extraDlc); + foreach (KeyValuePair extraDlc)> pair in selection.ExtraSelectedDlc) + blacklistDlc = blacklistDlc.Except(pair.Value.extraDlc); blacklistDlc = blacklistDlc.ToList(); if (blacklistDlc.Any()) { @@ -70,10 +71,10 @@ internal static class UplayR1 writer.WriteLine("}"); } - internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) + internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true) => await Task.Run(() => { - directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string log); if (File.Exists(api32_o)) { if (File.Exists(api32)) @@ -94,17 +95,24 @@ internal static class UplayR1 File.Move(api64_o, api64!); installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(config)) + if (!deleteOthers) + return; + if (File.Exists(config)) { File.Delete(config); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } + if (File.Exists(log)) + { + File.Delete(log); + installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); + } }); internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() => { - directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string _); + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out _, out _); if (File.Exists(api32) && !File.Exists(api32_o)) { File.Move(api32, api32_o!); diff --git a/CreamInstaller/Resources/UplayR2.cs b/CreamInstaller/Resources/UplayR2.cs index 6a50ba8..1f2c8ce 100644 --- a/CreamInstaller/Resources/UplayR2.cs +++ b/CreamInstaller/Resources/UplayR2.cs @@ -12,7 +12,7 @@ namespace CreamInstaller.Resources; internal static class UplayR2 { internal static void GetUplayR2Components(this string directory, out string old_api32, out string old_api64, out string api32, out string api32_o, - out string api64, out string api64_o, out string config) + out string api64, out string api64_o, out string config, out string log) { old_api32 = directory + @"\uplay_r2_loader.dll"; old_api64 = directory + @"\uplay_r2_loader64.dll"; @@ -21,14 +21,15 @@ internal static class UplayR2 api64 = directory + @"\upc_r2_loader64.dll"; api64_o = directory + @"\upc_r2_loader64_o.dll"; config = directory + @"\UplayR2Unlocker.jsonc"; + log = directory + @"\UplayR2Unlocker.log"; } internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { - directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config); + directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config, out _); IEnumerable> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string _, string _, SortedList extraDlc) in selection.ExtraSelectedDlc) - blacklistDlc = blacklistDlc.Except(extraDlc); + foreach (KeyValuePair extraDlc)> pair in selection.ExtraSelectedDlc) + blacklistDlc = blacklistDlc.Except(pair.Value.extraDlc); blacklistDlc = blacklistDlc.ToList(); if (blacklistDlc.Any()) { @@ -74,11 +75,11 @@ internal static class UplayR2 writer.WriteLine("}"); } - internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) + internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteOthers = true) => await Task.Run(() => { directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64, - out string api64_o, out string config); + out string api64_o, out string config, out string log); if (File.Exists(api32_o)) { string api = File.Exists(old_api32) ? old_api32 : api32; @@ -101,18 +102,25 @@ internal static class UplayR2 File.Move(api64_o, api!); installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false); } - if (deleteConfig && File.Exists(config)) + if (!deleteOthers) + return; + if (File.Exists(config)) { File.Delete(config); installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } + if (File.Exists(log)) + { + File.Delete(log); + installForm?.UpdateUser($"Deleted log: {Path.GetFileName(log)}", LogTextBox.Action, false); + } }); internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() => { directory.GetUplayR2Components(out string old_api32, out string old_api64, out string api32, out string api32_o, out string api64, - out string api64_o, out string _); + out string api64_o, out _, out _); string api = File.Exists(old_api32) ? old_api32 : api32; if (File.Exists(api) && !File.Exists(api32_o)) {