diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index 1802c78..5d57411 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -5,7 +5,7 @@ True Resources\ini.ico true - 3.4.1.1 + 3.4.2.0 Resources\ini.ico LICENSE 2021, pointfeev (https://github.com/pointfeev) diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs index d980c29..c5d6d59 100644 --- a/CreamInstaller/Forms/InstallForm.cs +++ b/CreamInstaller/Forms/InstallForm.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -51,11 +52,13 @@ internal partial class InstallForm : CustomForm if (logTextBox.Text.Length > 0) logTextBox.AppendText(Environment.NewLine, color); logTextBox.AppendText(text, color); }); + Thread.Sleep(0); } } internal static void WriteCreamConfiguration(StreamWriter writer, string appId, string name, SortedList dlc, InstallForm installForm = null) { + Thread.Sleep(0); writer.WriteLine($"; {name}"); writer.WriteLine("[steam]"); writer.WriteLine($"appid = {appId}"); @@ -65,6 +68,7 @@ internal partial class InstallForm : CustomForm installForm.UpdateUser($"Added game to cream_api.ini with appid {appId} ({name})", InstallationLog.Action, info: false); foreach (KeyValuePair pair in dlc) { + Thread.Sleep(0); string dlcId = pair.Key; (_, string dlcName, _) = pair.Value; writer.WriteLine($"{dlcId} = {dlcName}"); @@ -141,21 +145,24 @@ internal partial class InstallForm : CustomForm StreamWriter writer = new(config, true, Encoding.UTF8); if (selection.Id != "ParadoxLauncher") WriteCreamConfiguration(writer, selection.Id, selection.Name, selection.SelectedDlc, installForm); - foreach (Tuple> extraAppDlc in selection.ExtraDlc) - WriteCreamConfiguration(writer, extraAppDlc.Item1, extraAppDlc.Item2, extraAppDlc.Item3, installForm); + foreach ((string id, string name, SortedList dlc) in selection.ExtraDlc) + WriteCreamConfiguration(writer, id, name, dlc, installForm); writer.Flush(); writer.Close(); }); - internal static void WriteScreamConfiguration(StreamWriter writer, SortedList dlc, InstallForm installForm = null) + internal static void WriteScreamConfiguration(StreamWriter writer, SortedList dlc, List<(string id, string name, SortedList dlc)> extraDlc, InstallForm installForm = null) { + Thread.Sleep(0); writer.WriteLine("{"); writer.WriteLine(" \"version\": 2,"); writer.WriteLine(" \"logging\": false,"); writer.WriteLine(" \"eos_logging\": false,"); writer.WriteLine(" \"block_metrics\": false,"); writer.WriteLine(" \"catalog_items\": {"); - IEnumerable> catalogItems = dlc.Where(pair => pair.Value.type == DlcType.CatalogItem); + IEnumerable> catalogItems = dlc.Where(pair => pair.Value.type == DlcType.EpicCatalogItem); + foreach ((string id, string name, SortedList _dlc) in extraDlc) + catalogItems = catalogItems.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicCatalogItem)); if (catalogItems.Any()) { writer.WriteLine(" \"unlock_all\": false,"); @@ -163,6 +170,7 @@ internal partial class InstallForm : CustomForm KeyValuePair lastCatalogItem = catalogItems.Last(); foreach (KeyValuePair pair in catalogItems) { + Thread.Sleep(0); string id = pair.Key; (_, string name, _) = pair.Value; writer.WriteLine($" \"{id}\"{(pair.Equals(lastCatalogItem) ? "" : ",")}"); @@ -178,7 +186,9 @@ internal partial class InstallForm : CustomForm } writer.WriteLine(" },"); writer.WriteLine(" \"entitlements\": {"); - IEnumerable> entitlements = dlc.Where(pair => pair.Value.type == DlcType.Entitlement); + IEnumerable> entitlements = dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement); + foreach ((string id, string name, SortedList _dlc) in extraDlc) + entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement)); if (entitlements.Any()) { writer.WriteLine(" \"unlock_all\": false,"); @@ -187,6 +197,7 @@ internal partial class InstallForm : CustomForm KeyValuePair lastEntitlement = entitlements.Last(); foreach (KeyValuePair pair in entitlements) { + Thread.Sleep(0); string id = pair.Key; (_, string name, _) = pair.Value; writer.WriteLine($" \"{id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}"); @@ -271,10 +282,7 @@ internal partial class InstallForm : CustomForm installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); File.Create(config).Close(); StreamWriter writer = new(config, true, Encoding.UTF8); - if (selection.Id != "ParadoxLauncher") - WriteScreamConfiguration(writer, selection.SelectedDlc, installForm); - foreach (Tuple> extraAppDlc in selection.ExtraDlc) - WriteScreamConfiguration(writer, extraAppDlc.Item3, installForm); + WriteScreamConfiguration(writer, selection.SelectedDlc, selection.ExtraDlc, installForm); writer.Flush(); writer.Close(); }); @@ -306,27 +314,36 @@ internal partial class InstallForm : CustomForm } } if (code < 0) throw new CustomMessageException("Repair failed!"); - string platform = selection.Platform == Platform.Steam ? "CreamAPI" - : selection.Platform == Platform.Epic ? "ScreamAPI" - : throw new InvalidPlatformException(selection.Platform); foreach (string directory in selection.DllDirectories) { - UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} {platform}" + - $" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); - if (Program.Canceled || !Program.IsProgramRunningDialog(this, selection)) throw new CustomMessageException("The operation was canceled."); - if (platform == "CreamAPI") + Thread.Sleep(0); + if (selection.IsSteam && selection.SelectedDlc.Any(d => d.Value.type is DlcType.Steam) + || selection.ExtraDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.Steam))) { - if (Uninstalling) - await UninstallCreamAPI(directory, this); - else - await InstallCreamAPI(directory, selection, this); + directory.GetCreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config); + if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config)) + { + UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} CreamAPI" + + $" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); + if (Uninstalling) + await UninstallCreamAPI(directory, this); + else + await InstallCreamAPI(directory, selection, this); + } } - else if (platform == "ScreamAPI") + if (selection.IsEpic && selection.SelectedDlc.Any(d => d.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement) + || selection.ExtraDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement))) { - if (Uninstalling) - await UninstallScreamAPI(directory, this); - else - await InstallScreamAPI(directory, selection, this); + directory.GetScreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config); + if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config)) + { + UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} ScreamAPI" + + $" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); + if (Uninstalling) + await UninstallScreamAPI(directory, this); + else + await InstallScreamAPI(directory, selection, this); + } } UpdateProgress(++cur / count * 100); } @@ -342,6 +359,7 @@ internal partial class InstallForm : CustomForm foreach (ProgramSelection selection in programSelections) { if (Program.Canceled || !Program.IsProgramRunningDialog(this, selection)) throw new CustomMessageException("The operation was canceled."); + Thread.Sleep(0); try { await OperateFor(selection); diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index 9b87802..03c1eae 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -103,9 +103,7 @@ internal partial class SelectForm : CustomForm if (Directory.Exists(ParadoxLauncher.InstallPath) && ProgramsToScan.Any(c => c.platform == "Paradox" && c.id == "ParadoxLauncher")) { List steamDllDirectories = await SteamLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath); - List epicDllDirectories = null; - if (steamDllDirectories is null) - epicDllDirectories = await EpicLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath); + List epicDllDirectories = await EpicLibrary.GetDllDirectoriesFromGameDirectory(ParadoxLauncher.InstallPath); if (steamDllDirectories is not null || epicDllDirectories is not null) { ProgramSelection selection = ProgramSelection.FromId("ParadoxLauncher"); @@ -115,7 +113,8 @@ internal partial class SelectForm : CustomForm selection.Name = "Paradox Launcher"; selection.RootDirectory = ParadoxLauncher.InstallPath; selection.DllDirectories = steamDllDirectories ?? epicDllDirectories; - selection.Platform = steamDllDirectories is not null ? Platform.Steam : Platform.Epic; + selection.IsSteam = steamDllDirectories is not null; + selection.IsEpic = epicDllDirectories is not null; TreeNode programNode = treeNodes.Find(s => s.Name == selection.Id) ?? new(); programNode.Name = selection.Id; @@ -196,7 +195,7 @@ internal partial class SelectForm : CustomForm } if (Program.Canceled) return; if (!string.IsNullOrWhiteSpace(dlcName)) - dlc[dlcAppId] = (DlcType.Default, dlcName, dlcIcon); + dlc[dlcAppId] = (DlcType.Steam, dlcName, dlcIcon); RemoveFromRemainingDLCs(dlcAppId); }); dlcTasks.Add(task); @@ -217,11 +216,11 @@ internal partial class SelectForm : CustomForm ProgramSelection selection = ProgramSelection.FromId(appId) ?? new(); selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraDlc.Any(); - selection.Platform = Platform.Steam; selection.Id = appId; selection.Name = appData?.name ?? name; selection.RootDirectory = directory; selection.DllDirectories = dllDirectories; + selection.IsSteam = true; selection.ProductUrl = "https://store.steampowered.com/app/" + appId; selection.IconUrl = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("icon")?.ToString()}.jpg"; selection.SubIconUrl = appData?.header_image ?? IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("clienticon")?.ToString()}.ico"; @@ -318,11 +317,11 @@ internal partial class SelectForm : CustomForm ProgramSelection selection = ProgramSelection.FromId(@namespace) ?? new(); selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraDlc.Any(); - selection.Platform = Platform.Epic; selection.Id = @namespace; selection.Name = name; selection.RootDirectory = directory; selection.DllDirectories = dllDirectories; + selection.IsEpic = true; foreach (KeyValuePair pair in entitlements) { Thread.Sleep(0); @@ -364,7 +363,7 @@ internal partial class SelectForm : CustomForm if (programNode is null/* || entitlementsNode is null*/) return; Thread.Sleep(0); string dlcId = pair.Key; - (DlcType type, string name, string icon) dlcApp = (DlcType.Entitlement, pair.Value.name, pair.Value.icon); + (DlcType type, string name, string icon) dlcApp = (DlcType.EpicEntitlement, pair.Value.name, pair.Value.icon); selection.AllDlc[dlcId] = dlcApp; if (allCheckBox.Checked) selection.SelectedDlc[dlcId] = dlcApp; TreeNode dlcNode = treeNodes.Find(s => s.Name == dlcId) ?? new(); @@ -614,10 +613,8 @@ internal partial class SelectForm : CustomForm List queries = new(); if (File.Exists(appInfoJSON)) { - string platform = (selection is null || selection.Platform == Platform.Steam) ? "Steam Store" - : selection.Platform == Platform.Epic ? "Epic GraphQL" - : throw new InvalidPlatformException(selection.Platform); - queries.Add(new ContextMenuItem($"Open {platform} Query", "Notepad", + string platform = (selection is null || selection.IsSteam) ? "Steam Store " : selection.IsEpic ? "Epic GraphQL " : ""; + queries.Add(new ContextMenuItem($"Open {platform}Query", "Notepad", new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON)))); } if (File.Exists(appInfoVDF)) @@ -662,20 +659,32 @@ internal partial class SelectForm : CustomForm contextMenuStrip.Items.Add(new ContextMenuItem("Open Root Directory", "File Explorer", new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory)))); List directories = selection.DllDirectories.ToList(); - string platform = selection.Platform == Platform.Steam ? "Steamworks" - : selection.Platform == Platform.Epic ? "Epic Online Services" - : throw new InvalidPlatformException(selection.Platform); - for (int i = 0; i < directories.Count; i++) - { - string directory = directories[i]; - contextMenuStrip.Items.Add(new ContextMenuItem($"Open {platform} SDK Directory #{i + 1}", "File Explorer", - new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory)))); - } + if (selection.IsSteam) + for (int i = 0; i < directories.Count; i++) + { + string directory = directories[i]; + directory.GetCreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config); + if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config)) + { + contextMenuStrip.Items.Add(new ContextMenuItem($"Open Steamworks SDK Directory #{i + 1}", "File Explorer", + new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory)))); + } + } + if (selection.IsEpic) + for (int i = 0; i < directories.Count; i++) + { + string directory = directories[i]; + directory.GetScreamApiComponents(out string sdk32, out string sdk32_o, out string sdk64, out string sdk64_o, out string config); + if (File.Exists(sdk32) || File.Exists(sdk32_o) || File.Exists(sdk64) || File.Exists(sdk64_o) || File.Exists(config)) + { + contextMenuStrip.Items.Add(new ContextMenuItem($"Open Epic Online Services SDK Directory #{i + 1}", "File Explorer", + new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory)))); + } + } } if (id != "ParadoxLauncher") { - if (selection is not null && selection.Platform == Platform.Steam - || dlcParentSelection is not null && dlcParentSelection.Platform == Platform.Steam) + if (selection is not null && selection.IsSteam || dlcParentSelection is not null && dlcParentSelection.IsSteam) { contextMenuStrip.Items.Add(new ToolStripSeparator()); contextMenuStrip.Items.Add(new ContextMenuItem("Open SteamDB", "SteamDB", @@ -683,14 +692,14 @@ internal partial class SelectForm : CustomForm } if (selection is not null) { - if (selection.Platform == Platform.Steam) + if (selection.IsSteam) { contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Store", "Steam Store", new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl)))); contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Community", (id, selection.SubIconUrl, true), "Steam Community", new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id)))); } - else if (selection.Platform == Platform.Epic) + else if (selection.IsEpic) { contextMenuStrip.Items.Add(new ToolStripSeparator()); contextMenuStrip.Items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB", diff --git a/CreamInstaller/ProgramSelection.cs b/CreamInstaller/ProgramSelection.cs index 3b8be85..e3ebcce 100644 --- a/CreamInstaller/ProgramSelection.cs +++ b/CreamInstaller/ProgramSelection.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -7,30 +6,16 @@ using CreamInstaller.Components; namespace CreamInstaller; -public enum Platform -{ - Steam = 0, - Epic = 1 -} -public class InvalidPlatformException : Exception -{ - public InvalidPlatformException() : base("Invalid platform!") { } - public InvalidPlatformException(Platform platform) : base($"Invalid platform ({platform})!") { } - public InvalidPlatformException(string message) : base(message) { } - public InvalidPlatformException(string message, Exception innerException) : base(message, innerException) { } -} - public enum DlcType { - Default = 0, - CatalogItem = 1, - Entitlement = 2 + Steam = 0, + EpicCatalogItem = 1, + EpicEntitlement = 2 } internal class ProgramSelection { internal bool Enabled; - internal Platform Platform = (Platform)(-1); internal string Id = "0"; internal string Name = "Program"; @@ -44,9 +29,12 @@ internal class ProgramSelection internal string RootDirectory; internal List DllDirectories; + internal bool IsSteam; + internal bool IsEpic; + internal readonly SortedList AllDlc = new(AppIdComparer.Comparer); internal readonly SortedList SelectedDlc = new(AppIdComparer.Comparer); - internal readonly List>> ExtraDlc = new(); // for Paradox Launcher + internal readonly List<(string id, string name, SortedList dlc)> ExtraDlc = new(); // for Paradox Launcher internal bool AreDllsLocked {