diff --git a/CreamInstaller/Components/ContextMenuItem.cs b/CreamInstaller/Components/ContextMenuItem.cs index 67e0cf9..6a47922 100644 --- a/CreamInstaller/Components/ContextMenuItem.cs +++ b/CreamInstaller/Components/ContextMenuItem.cs @@ -21,31 +21,25 @@ internal class ContextMenuItem : ToolStripMenuItem OnClickEvent = onClick; } - internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null) - : this(text, onClick) => _ = TryImageIdentifier(this, imageIdentifier); + internal ContextMenuItem(string text, string imageIdentifier, EventHandler onClick = null) : this(text, onClick) + => _ = TryImageIdentifier(this, imageIdentifier); - internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null) - : this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo); + internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, EventHandler onClick = null) : this(text, onClick) + => _ = TryImageIdentifierInfo(this, imageIdentifierInfo); - internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, - string imageIdentifierFallback, EventHandler onClick = null) - : this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo, - async () => await TryImageIdentifier( - this, imageIdentifierFallback)); + internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, string imageIdentifierFallback, EventHandler onClick = null) : + this(text, onClick) + => _ = TryImageIdentifierInfo(this, imageIdentifierInfo, async () => await TryImageIdentifier(this, imageIdentifierFallback)); - internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, - (string id, string iconUrl) imageIdentifierInfoFallback, EventHandler onClick = null) - : this(text, onClick) => _ = TryImageIdentifierInfo(this, imageIdentifierInfo, - async () => await TryImageIdentifierInfo( - this, imageIdentifierInfoFallback)); + internal ContextMenuItem(string text, (string id, string iconUrl) imageIdentifierInfo, (string id, string iconUrl) imageIdentifierInfoFallback, + EventHandler onClick = null) : this(text, onClick) + => _ = TryImageIdentifierInfo(this, imageIdentifierInfo, async () => await TryImageIdentifierInfo(this, imageIdentifierInfoFallback)); - private static async Task TryImageIdentifier(ContextMenuItem item, string imageIdentifier) => await Task.Run( - async () => + private static async Task TryImageIdentifier(ContextMenuItem item, string imageIdentifier) + => await Task.Run(async () => { if (images.TryGetValue(imageIdentifier, out Image image) && image is not null) - { item.Image = image; - } else { switch (imageIdentifier) @@ -68,28 +62,22 @@ internal class ContextMenuItem : ToolStripMenuItem image = IconGrabber.GetFileExplorerImage(); break; case "SteamDB": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("steamdb.info")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamdb.info")); break; case "Steam Store": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("store.steampowered.com")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.steampowered.com")); break; case "Steam Community": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("steamcommunity.com")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("steamcommunity.com")); break; case "ScreamDB": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("scream-db.web.app")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("scream-db.web.app")); break; case "Epic Games": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("epicgames.com")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("epicgames.com")); break; case "Ubisoft Store": - image = await HttpClientManager.GetImageFromUrl( - IconGrabber.GetDomainFaviconUrl("store.ubi.com")); + image = await HttpClientManager.GetImageFromUrl(IconGrabber.GetDomainFaviconUrl("store.ubi.com")); break; default: return; @@ -102,35 +90,31 @@ internal class ContextMenuItem : ToolStripMenuItem } }); - private static async Task TryImageIdentifierInfo(ContextMenuItem item, - (string id, string iconUrl) imageIdentifierInfo, - Action onFail = null) => await Task.Run(async () => - { - (string id, string iconUrl) = imageIdentifierInfo; - string imageIdentifier = "Icon_" + id; - if (images.TryGetValue(imageIdentifier, out Image image) && image is not null) + private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null) + => await Task.Run(async () => { - item.Image = image; - } - else - { - image = await HttpClientManager.GetImageFromUrl(iconUrl); - if (image is not null) - { - images[imageIdentifier] = image; + (string id, string iconUrl) = imageIdentifierInfo; + string imageIdentifier = "Icon_" + id; + if (images.TryGetValue(imageIdentifier, out Image image) && image is not null) item.Image = image; - } - else if (onFail is not null) + else { - onFail(); + image = await HttpClientManager.GetImageFromUrl(iconUrl); + if (image is not null) + { + images[imageIdentifier] = image; + item.Image = image; + } + else if (onFail is not null) + onFail(); } - } - }); + }); protected override void OnClick(EventArgs e) { base.OnClick(e); - if (OnClickEvent is null) return; + if (OnClickEvent is null) + return; OnClickEvent.Invoke(this, e); } } \ No newline at end of file diff --git a/CreamInstaller/Components/CustomForm.cs b/CreamInstaller/Components/CustomForm.cs index 4a95650..acf4af3 100644 --- a/CreamInstaller/Components/CustomForm.cs +++ b/CreamInstaller/Components/CustomForm.cs @@ -58,46 +58,38 @@ internal class CustomForm : Form string acidicoala = "https://github.com/acidicoala"; string repository = $"https://github.com/{Program.RepositoryOwner}/{Program.RepositoryName}"; _ = helpDialog.Show(SystemIcons.Information, - "Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n" - + "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n" - + "utilizing the gathered information for the maintenance of DLC unlockers.\n" - + "\n" - + $"The program utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [SmokeAPI]({acidicoala}/SmokeAPI), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1 Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by\n" - + $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n" - + "\n" - + "NOTE: This program does not automatically download nor install actual DLC files for you. As the title of the program says, it's\n" - + "only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed (very many\n" - + "do not), you have to find, download, and install those yourself. Preferably, you should be referring to the proper cs.rin.ru post for\n" - + "the game(s) you're tinkering with; you'll usually find any answer to your problems there.\n" - + "\n" - + "USAGE:\n" - + " 1. Choose which programs and/or games the program should scan for DLC.\n" - + " The program automatically gathers all installed games from Steam, Epic and Ubisoft directories.\n" - + " 2. Wait for the program to download and install SteamCMD (if you chose a Steam game).\n" - + " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n" - + " May take some time on the first run; depends on how many DLCs the games you chose have.\n" - + " 4. CAREFULLY select which games' DLCs you wish to unlock.\n" - + " Obviously none of the DLC unlockers are tested for every single game!\n" - + " 5. Choose whether or not to install with Koaloader, and if so then also pick the proxy DLL to use.\n" - + " If the default \'version.dll\' doesn't work, then see [here](https://cs.rin.ru/forum/viewtopic.php?p=2552172#p2552172) to find one that does.\n" - + " 6. Click the \"Generate and Install\" button.\n" - + " 7. Click the \"OK\" button to close the program.\n" - + " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n" - + " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n" - + "\n" - + $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n" - + "\n" - + "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n" - + $"The program automatically and very quickly updates from [GitHub]({repository}) using [Onova](https://github.com/Tyrrrz/Onova). (updates can be ignored)\n" - + $"The program source and other information can be found on [GitHub]({repository})."); + "Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n" + + "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n" + + "utilizing the gathered information for the maintenance of DLC unlockers.\n" + "\n" + + $"The program utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [SmokeAPI]({acidicoala}/SmokeAPI), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1 Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by\n" + + $"the wonderful [acidicoala]({acidicoala}), and all downloaded and embedded into the program itself; no further downloads necessary on your part!\n" + + "\n" + "NOTE: This program does not automatically download nor install actual DLC files for you. As the title of the program says, it's\n" + + "only a DLC Unlocker installer. Should the game you wish to unlock DLC for not already come with the DLCs installed (very many\n" + + "do not), you have to find, download, and install those yourself. Preferably, you should be referring to the proper cs.rin.ru post for\n" + + "the game(s) you're tinkering with; you'll usually find any answer to your problems there.\n" + "\n" + "USAGE:\n" + + " 1. Choose which programs and/or games the program should scan for DLC.\n" + + " The program automatically gathers all installed games from Steam, Epic and Ubisoft directories.\n" + + " 2. Wait for the program to download and install SteamCMD (if you chose a Steam game).\n" + + " 3. Wait for the program to gather and cache the chosen games' information && DLCs.\n" + + " May take some time on the first run; depends on how many DLCs the games you chose have.\n" + + " 4. CAREFULLY select which games' DLCs you wish to unlock.\n" + + " Obviously none of the DLC unlockers are tested for every single game!\n" + + " 5. Choose whether or not to install with Koaloader, and if so then also pick the proxy DLL to use.\n" + + " If the default \'version.dll\' doesn't work, then see [here](https://cs.rin.ru/forum/viewtopic.php?p=2552172#p2552172) to find one that does.\n" + + " 6. Click the \"Generate and Install\" button.\n" + " 7. Click the \"OK\" button to close the program.\n" + + " 8. If any of the DLC unlockers cause problems with any of the games you installed them on, simply go back\n" + + " to step 5 and select what games you wish you revert changes to, and instead click the \"Uninstall\" button this time.\n" + "\n" + + $"For reliable and quick assistance, all bugs, crashes and other issues should be referred to the [GitHub Issues]({repository}/issues) page!\n" + + "\n" + "SteamCMD installation and appinfo cache can be found at [C:\\ProgramData\\CreamInstaller]().\n" + + $"The program automatically and very quickly updates from [GitHub]({repository}) using [Onova](https://github.com/Tyrrrz/Onova). (updates can be ignored)\n" + + $"The program source and other information can be found on [GitHub]({repository})."); } internal void OnActivation(object sender, EventArgs args) => Activate(); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - internal static extern void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, - uint uFlags); + internal static extern void SetWindowPos(nint hWnd, nint hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); internal void BringToFrontWithoutActivation() { @@ -113,12 +105,13 @@ internal class CustomForm : Form return; int X = fromForm.Location.X + fromForm.Size.Width / 2 - Size.Width / 2; int Y = fromForm.Location.Y + fromForm.Size.Height / 2 - Size.Height / 2; - Location = new Point(X, Y); + Location = new(X, Y); } private void OnKeyPress(object s, KeyPressEventArgs e) { - if (e.KeyChar != 'S') return; // Shift + S + if (e.KeyChar != 'S') + return; // Shift + S UpdateBounds(); Rectangle bounds = Bounds; using Bitmap bitmap = new(Size.Width - 14, Size.Height - 7); @@ -127,8 +120,7 @@ internal class CustomForm : Form using EncoderParameters encoding = new(1); using EncoderParameter encoderParam = new(Encoder.Quality, 100L); encoding.Param[0] = encoderParam; - graphics.CopyFromScreen(new Point(bounds.Left + 7, bounds.Top), Point.Empty, - new Size(Size.Width - 14, Size.Height - 7)); + graphics.CopyFromScreen(new(bounds.Left + 7, bounds.Top), Point.Empty, new(Size.Width - 14, Size.Height - 7)); Clipboard.SetImage(bitmap); e.Handled = true; } diff --git a/CreamInstaller/Components/CustomTreeView.cs b/CreamInstaller/Components/CustomTreeView.cs index f3bd61f..0d361e7 100644 --- a/CreamInstaller/Components/CustomTreeView.cs +++ b/CreamInstaller/Components/CustomTreeView.cs @@ -65,8 +65,7 @@ internal class CustomTreeView : TreeView Size size; Rectangle bounds = node.Bounds; Rectangle selectionBounds = bounds; - Color - color; // = highlighted ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor; + Color color; // = highlighted ? SystemColors.HighlightText : (node.ForeColor != Color.Empty) ? node.ForeColor : node.TreeView.ForeColor; Point point; /*Size textSize = TextRenderer.MeasureText(text, font); Point textLoc = new(bounds.X - 1, bounds.Y); @@ -88,8 +87,7 @@ internal class CustomTreeView : TreeView text = platform.ToString(); size = TextRenderer.MeasureText(graphics, text, font); bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width }; - selectionBounds - = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 }); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 }); graphics.FillRectangle(brush, bounds); point = new Point(bounds.Location.X - 1, bounds.Location.Y + 1); TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default); @@ -104,8 +102,7 @@ internal class CustomTreeView : TreeView size = TextRenderer.MeasureText(graphics, text, font); int left = -4; bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width }; - selectionBounds = new Rectangle(selectionBounds.Location, - selectionBounds.Size + new Size(bounds.Size.Width + left, 0)); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0)); graphics.FillRectangle(brush, bounds); point = new Point(bounds.Location.X - 1, bounds.Location.Y + 1); TextRenderer.DrawText(graphics, text, font, point, color, TextFormatFlags.Default); @@ -130,8 +127,7 @@ internal class CustomTreeView : TreeView : CheckBoxState.UncheckedDisabled; size = CheckBoxRenderer.GetGlyphSize(graphics, checkBoxState); bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width }; - selectionBounds = new Rectangle(selectionBounds.Location, - selectionBounds.Size + bounds.Size with { Height = 0 }); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 }); Rectangle checkBoxBounds = bounds; graphics.FillRectangle(backBrush, bounds); point = new Point(bounds.Left, bounds.Top + bounds.Height / 2 - size.Height / 2 - 1); @@ -140,41 +136,31 @@ internal class CustomTreeView : TreeView size = TextRenderer.MeasureText(graphics, text, font); int left = 1; bounds = bounds with { X = bounds.X + bounds.Width, Width = size.Width + left }; - selectionBounds = new Rectangle(selectionBounds.Location, - selectionBounds.Size + bounds.Size with { Height = 0 }); - checkBoxBounds = new Rectangle(checkBoxBounds.Location, - checkBoxBounds.Size + bounds.Size with { Height = 0 }); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 }); + checkBoxBounds = new Rectangle(checkBoxBounds.Location, checkBoxBounds.Size + bounds.Size with { Height = 0 }); graphics.FillRectangle(backBrush, bounds); point = new Point(bounds.Location.X - 1 + left, bounds.Location.Y + 1); - TextRenderer.DrawText(graphics, text, font, point, - Enabled - ? ColorTranslator.FromHtml("#006900") - : ColorTranslator.FromHtml("#69AA69"), - TextFormatFlags.Default); + TextRenderer.DrawText(graphics, text, font, point, Enabled ? ColorTranslator.FromHtml("#006900") : ColorTranslator.FromHtml("#69AA69"), + TextFormatFlags.Default); this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds); string proxy = selection.KoaloaderProxy ?? ProgramSelection.DefaultKoaloaderProxy; if (selection.Koaloader && proxy is not null) { - comboBoxFont ??= new Font(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet, - font.GdiVerticalFont); + comboBoxFont ??= new Font(font.FontFamily, 6, font.Style, font.Unit, font.GdiCharSet, font.GdiVerticalFont); ComboBoxState comboBoxState = Enabled ? ComboBoxState.Normal : ComboBoxState.Disabled; text = proxy + ".dll"; size = TextRenderer.MeasureText(graphics, text, comboBoxFont) + new Size(6, 0); int padding = 2; - bounds = new Rectangle(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, - bounds.Height - padding); - selectionBounds = new Rectangle(selectionBounds.Location, - selectionBounds.Size + bounds.Size with { Height = 0 }); + bounds = new Rectangle(bounds.X + bounds.Width, bounds.Y + padding / 2, size.Width, bounds.Height - padding); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + bounds.Size with { Height = 0 }); Rectangle comboBoxBounds = bounds; graphics.FillRectangle(backBrush, bounds); ComboBoxRenderer.DrawTextBox(graphics, bounds, text, comboBoxFont, comboBoxState); size = new Size(14, 0); left = -1; bounds = bounds with { X = bounds.X + bounds.Width + left, Width = size.Width }; - selectionBounds = new Rectangle(selectionBounds.Location, - selectionBounds.Size + new Size(bounds.Size.Width + left, 0)); - comboBoxBounds = new Rectangle(comboBoxBounds.Location, - comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0)); + selectionBounds = new Rectangle(selectionBounds.Location, selectionBounds.Size + new Size(bounds.Size.Width + left, 0)); + comboBoxBounds = new Rectangle(comboBoxBounds.Location, comboBoxBounds.Size + new Size(bounds.Size.Width + left, 0)); ComboBoxRenderer.DrawDropDownButton(graphics, bounds, comboBoxState); this.comboBoxBounds[selection] = RectangleToClient(comboBoxBounds); } @@ -215,13 +201,11 @@ internal class CustomTreeView : TreeView } else if (pair.Value.Contains(clickPoint)) { - List proxies = EmbeddedResources.FindAll(r => r.StartsWith("Koaloader")) - .Select(p => - { - p.GetProxyInfoFromIdentifier( - out string proxyName, out _); - return proxyName; - }).Distinct().ToList(); + List proxies = EmbeddedResources.FindAll(r => r.StartsWith("Koaloader")).Select(p => + { + p.GetProxyInfoFromIdentifier(out string proxyName, out _); + return proxyName; + }).Distinct().ToList(); comboBoxDropDown ??= new ToolStripDropDown(); comboBoxDropDown.ShowItemToolTips = false; comboBoxDropDown.Items.Clear(); @@ -240,8 +224,7 @@ internal class CustomTreeView : TreeView if (canUse) _ = comboBoxDropDown.Items.Add(new ToolStripButton(proxy + ".dll", null, (s, e) => { - pair.Key.KoaloaderProxy - = proxy == ProgramSelection.DefaultKoaloaderProxy ? null : proxy; + pair.Key.KoaloaderProxy = proxy == ProgramSelection.DefaultKoaloaderProxy ? null : proxy; selectForm.OnKoaloaderChanged(); }) { Font = comboBoxFont }); } diff --git a/CreamInstaller/Components/PlatformIdComparer.cs b/CreamInstaller/Components/PlatformIdComparer.cs index c6cfb92..e4af468 100644 --- a/CreamInstaller/Components/PlatformIdComparer.cs +++ b/CreamInstaller/Components/PlatformIdComparer.cs @@ -14,16 +14,16 @@ internal static class PlatformIdComparer private static NodeNameComparer nodeNameComparer; private static NodeTextComparer nodeTextComparer; - internal static StringComparer String => stringComparer ??= new StringComparer(); - internal static NodeComparer Node => nodeComparer ??= new NodeComparer(); - internal static NodeNameComparer NodeName => nodeNameComparer ??= new NodeNameComparer(); - internal static NodeTextComparer NodeText => nodeTextComparer ??= new NodeTextComparer(); + internal static StringComparer String => stringComparer ??= new(); + internal static NodeComparer Node => nodeComparer ??= new(); + internal static NodeNameComparer NodeName => nodeNameComparer ??= new(); + internal static NodeTextComparer NodeText => nodeTextComparer ??= new(); } internal class StringComparer : IComparer { - public int Compare(string a, string b) => - !int.TryParse(a, out _) && !int.TryParse(b, out _) + public int Compare(string a, string b) + => !int.TryParse(a, out _) && !int.TryParse(b, out _) ? string.Compare(a, b, StringComparison.Ordinal) : !int.TryParse(a, out int A) ? 1 @@ -38,8 +38,8 @@ internal class StringComparer : IComparer internal class NodeComparer : IComparer { - public int Compare(TreeNode a, TreeNode b) => - a.Tag is not Platform A + public int Compare(TreeNode a, TreeNode b) + => a.Tag is not Platform A ? 1 : b.Tag is not Platform B ? -1 @@ -52,8 +52,8 @@ internal class NodeComparer : IComparer internal class NodeNameComparer : IComparer { - public int Compare(object a, object b) => - a is not TreeNode A + public int Compare(object a, object b) + => a is not TreeNode A ? 1 : b is not TreeNode B ? -1 @@ -64,8 +64,8 @@ internal class NodeNameComparer : IComparer internal class NodeTextComparer : IComparer { - public int Compare(object a, object b) => - a is not TreeNode A + public int Compare(object a, object b) + => a is not TreeNode A ? 1 : b is not TreeNode B ? -1 diff --git a/CreamInstaller/Forms/DebugForm.cs b/CreamInstaller/Forms/DebugForm.cs index 6d8c389..52a56e3 100644 --- a/CreamInstaller/Forms/DebugForm.cs +++ b/CreamInstaller/Forms/DebugForm.cs @@ -24,7 +24,7 @@ internal partial class DebugForm : CustomForm { if (current is not null && (current.Disposing || current.IsDisposed)) current = null; - return current ??= new DebugForm(); + return current ??= new(); } set => current = value; } @@ -64,7 +64,7 @@ internal partial class DebugForm : CustomForm if (attachedForm is not null && attachedForm.Visible) { //Size = new(Size.Width, attachedForm.Size.Height); - Location = new Point(attachedForm.Right, attachedForm.Top); + Location = new(attachedForm.Right, attachedForm.Top); BringToFrontWithoutActivation(); } } diff --git a/CreamInstaller/Forms/DialogForm.cs b/CreamInstaller/Forms/DialogForm.cs index b28e247..e90a3c1 100644 --- a/CreamInstaller/Forms/DialogForm.cs +++ b/CreamInstaller/Forms/DialogForm.cs @@ -12,8 +12,8 @@ internal partial class DialogForm : CustomForm { internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent(); - internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK", - string cancelButtonText = null, string customFormText = null, Icon customFormIcon = null) + internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText = "OK", string cancelButtonText = null, + string customFormText = null, Icon customFormIcon = null) { descriptionIcon ??= Icon; icon.Image = descriptionIcon.ToBitmap(); @@ -32,7 +32,7 @@ internal partial class DialogForm : CustomForm if (string.IsNullOrWhiteSpace(link)) link = text; descriptionText = descriptionText.Remove(i, linkRight + 1 - i).Insert(i, text); - links.Add(new LinkLabel.Link(i, text.Length, link)); + links.Add(new(i, text.Length, link)); } } descriptionLabel.Text = descriptionText; @@ -43,13 +43,9 @@ internal partial class DialogForm : CustomForm cancelButton.Visible = false; } else - { cancelButton.Text = cancelButtonText; - } if (customFormText is not null) - { Text = customFormText; - } else { OnResize(null, null); @@ -61,16 +57,13 @@ internal partial class DialogForm : CustomForm { foreach (LinkLabel.Link link in links) _ = descriptionLabel.Links.Add(link); - descriptionLabel.LinkClicked += (s, e) - => Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true }); + descriptionLabel.LinkClicked += (s, e) => Process.Start(new ProcessStartInfo((string)e.Link.LinkData) { UseShellExecute = true }); } return ShowDialog(); } - private void OnResize(object s, EventArgs e) => - Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 - ? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100 - ? Program.Name - : Program.ApplicationNameShort + private void OnResize(object s, EventArgs e) + => Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 + ? TextRenderer.MeasureText(Program.ApplicationNameShort, Font).Width > Size.Width - 100 ? Program.Name : Program.ApplicationNameShort : Program.ApplicationName; } diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs index 8d1adf5..2509864 100644 --- a/CreamInstaller/Forms/InstallForm.cs +++ b/CreamInstaller/Forms/InstallForm.cs @@ -38,18 +38,21 @@ internal partial class InstallForm : CustomForm userProgressBar.Invoke(() => { int value = (int)((float)CompleteOperationsCount / OperationsCount * 100) + progress / OperationsCount; - if (value < userProgressBar.Value) return; + if (value < userProgressBar.Value) + return; userProgressBar.Value = value; }); } internal void UpdateUser(string text, Color color, bool info = true, bool log = true) { - if (info) _ = userInfoLabel.Invoke(() => userInfoLabel.Text = text); + if (info) + _ = userInfoLabel.Invoke(() => userInfoLabel.Text = text); if (log && !logTextBox.Disposing && !logTextBox.IsDisposed) logTextBox.Invoke(() => { - if (logTextBox.Text.Length > 0) logTextBox.AppendText(Environment.NewLine, color); + if (logTextBox.Text.Length > 0) + logTextBox.AppendText(Environment.NewLine, color); logTextBox.AppendText(text, color); logTextBox.Invalidate(); }); @@ -63,12 +66,11 @@ internal partial class InstallForm : CustomForm UpdateUser("Repairing Paradox Launcher . . . ", LogTextBox.Operation); _ = await Repair(this, selection); } - UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")}" + - $" {(Uninstalling ? "from" : "for")} " + selection.Name - + $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation); + UpdateUser( + $"{(Uninstalling ? "Uninstalling" : "Installing")}" + $" {(Uninstalling ? "from" : "for")} " + selection.Name + + $" with root directory \"{selection.RootDirectory}\" . . . ", LogTextBox.Operation); IEnumerable invalidDirectories = (await selection.RootDirectory.GetExecutables()) - ?.Where(d => !selection.ExecutableDirectories.Any( - s => s.directory == Path.GetDirectoryName(d.path))) + ?.Where(d => !selection.ExecutableDirectories.Any(s => s.directory == Path.GetDirectoryName(d.path))) ?.Select(d => Path.GetDirectoryName(d.path)); if (!selection.ExecutableDirectories.Any(s => s.directory == selection.RootDirectory)) invalidDirectories = invalidDirectories?.Append(selection.RootDirectory); @@ -76,16 +78,13 @@ internal partial class InstallForm : CustomForm if (invalidDirectories is not null) foreach (string directory in invalidDirectories) { - if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); + if (Program.Canceled) + throw new CustomMessageException("The operation was canceled."); directory.GetKoaloaderComponents(out List proxies, out string config); if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) - || (directory != selection.RootDirectory - && Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll))) - || File.Exists(config)) + || directory != selection.RootDirectory && Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(config)) { - UpdateUser("Uninstalling Koaloader from " + selection.Name - + $" in incorrect directory \"{directory}\" . . . ", - LogTextBox.Operation); + UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation); await Koaloader.Uninstall(directory, selection.RootDirectory, this); } Thread.Sleep(1); @@ -93,15 +92,13 @@ internal partial class InstallForm : CustomForm if (Uninstalling || !selection.Koaloader) foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories) { - if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); + if (Program.Canceled) + throw new CustomMessageException("The operation was canceled."); directory.GetKoaloaderComponents(out List proxies, out string config); if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(ResourceIdentifier.Koaloader)) - || Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)) - || File.Exists(config)) + || Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll)) || File.Exists(config)) { - UpdateUser( - "Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", - LogTextBox.Operation); + UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); await Koaloader.Uninstall(directory, selection.RootDirectory, this); } Thread.Sleep(1); @@ -110,18 +107,19 @@ internal partial class InstallForm : CustomForm int count = selection.DllDirectories.Count, cur = 0; foreach (string directory in selection.DllDirectories) { - if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); + if (Program.Canceled) + throw new CustomMessageException("The operation was canceled."); 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 config, out string cache); + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string cache); if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(cache) : File.Exists(api32) || File.Exists(api64)) { - UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" + - $" {(uninstallProxy ? "from" : "for")} " + selection.Name - + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); + UpdateUser( + $"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name + + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); if (uninstallProxy) await SmokeAPI.Uninstall(directory, this); else @@ -130,15 +128,12 @@ internal 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); + if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64)) { - UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + - $" {(uninstallProxy ? "from" : "for")} " + selection.Name - + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); + UpdateUser( + $"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name + + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); if (uninstallProxy) await ScreamAPI.Uninstall(directory, this); else @@ -147,29 +142,25 @@ internal 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); + if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(api32) || File.Exists(api64)) { - UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + - $" {(uninstallProxy ? "from" : "for")} " + selection.Name - + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); + UpdateUser( + $"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name + + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); if (uninstallProxy) await UplayR1.Uninstall(directory, this); 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); if (uninstallProxy ? File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) : File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api64)) { - UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" + - $" {(uninstallProxy ? "from" : "for")} " + selection.Name - + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); + UpdateUser( + $"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" + $" {(uninstallProxy ? "from" : "for")} " + selection.Name + + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); if (uninstallProxy) await UplayR2.Uninstall(directory, this); else @@ -182,9 +173,9 @@ internal partial class InstallForm : CustomForm if (selection.Koaloader && !Uninstalling) foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories) { - if (Program.Canceled) throw new CustomMessageException("The operation was canceled."); - UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ", - LogTextBox.Operation); + if (Program.Canceled) + throw new CustomMessageException("The operation was canceled."); + UpdateUser("Installing Koaloader to " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation); await Koaloader.Install(directory, binaryType, selection, selection.RootDirectory, this); Thread.Sleep(1); } @@ -236,13 +227,12 @@ internal partial class InstallForm : CustomForm try { await Operate(); - UpdateUser($"DLC unlocker(s) successfully {(Uninstalling ? "uninstalled" : "installed and generated")} for " - + ProgramCount + " program(s).", LogTextBox.Success); + UpdateUser($"DLC unlocker(s) successfully {(Uninstalling ? "uninstalled" : "installed and generated")} for " + ProgramCount + " program(s).", + LogTextBox.Success); } catch (Exception exception) { - UpdateUser($"DLC unlocker {(Uninstalling ? "uninstallation" : "installation and/or generation")} failed: " - + exception, LogTextBox.Error); + UpdateUser($"DLC unlocker {(Uninstalling ? "uninstallation" : "installation and/or generation")} failed: " + exception, LogTextBox.Error); retryButton.Enabled = true; } userProgressBar.Value = userProgressBar.Maximum; @@ -262,7 +252,8 @@ internal partial class InstallForm : CustomForm } catch (Exception e) { - if (e.HandleException(this)) goto retry; + if (e.HandleException(this)) + goto retry; Close(); } } diff --git a/CreamInstaller/Forms/MainForm.cs b/CreamInstaller/Forms/MainForm.cs index c43df4a..754ea1f 100644 --- a/CreamInstaller/Forms/MainForm.cs +++ b/CreamInstaller/Forms/MainForm.cs @@ -58,24 +58,18 @@ internal partial class MainForm : CustomForm updateButton.Click -= OnUpdateCancel; progressLabel.Text = "Checking for updates . . ."; changelogTreeView.Visible = false; - changelogTreeView.Location = progressLabel.Location with - { - Y = progressLabel.Location.Y + progressLabel.Size.Height + 13 - }; + changelogTreeView.Location = progressLabel.Location with { Y = progressLabel.Location.Y + progressLabel.Size.Height + 13 }; Refresh(); #if DEBUG DebugForm.Current.Attach(this); #endif - GithubPackageResolver resolver = new(Program.RepositoryOwner, Program.RepositoryName, - Program.RepositoryPackage); + GithubPackageResolver resolver = new(Program.RepositoryOwner, Program.RepositoryName, Program.RepositoryPackage); ZipPackageExtractor extractor = new(); - updateManager - = new UpdateManager(AssemblyMetadata.FromAssembly(Program.EntryAssembly, Program.CurrentProcessFilePath), - resolver, extractor); + updateManager = new(AssemblyMetadata.FromAssembly(Program.EntryAssembly, Program.CurrentProcessFilePath), resolver, extractor); if (latestVersion is null) { CheckForUpdatesResult checkForUpdatesResult = null; - cancellationTokenSource = new CancellationTokenSource(); + cancellationTokenSource = new(); try { checkForUpdatesResult = await updateManager.CheckForUpdatesAsync(cancellationTokenSource.Token); @@ -93,8 +87,7 @@ internal partial class MainForm : CustomForm catch (TaskCanceledException) { } catch (Exception e) { - DebugForm.Current.Log($"Exception while checking for updates: {e.GetType()} ({e.Message})", - LogTextBox.Warning); + DebugForm.Current.Log($"Exception while checking for updates: {e.GetType()} ({e.Message})", LogTextBox.Warning); } #else catch { } @@ -120,8 +113,7 @@ internal partial class MainForm : CustomForm changelogTreeView.Visible = true; Version currentVersion = new(Program.Version); #if DEBUG - foreach (Version version in versions.Where(v => (v > currentVersion || v == latestVersion) - && !changelogTreeView.Nodes.ContainsKey(v.ToString()))) + foreach (Version version in versions.Where(v => (v > currentVersion || v == latestVersion) && !changelogTreeView.Nodes.ContainsKey(v.ToString()))) #else foreach (Version version in versions.Where(v => v > currentVersion && !changelogTreeView.Nodes.ContainsKey(v.ToString()))) #endif @@ -162,9 +154,8 @@ internal partial class MainForm : CustomForm { using DialogForm form = new(this); if (form.Show(SystemIcons.Warning, - "WARNING: " + Program.ApplicationExecutable + " was renamed!" + - "\n\nThis will cause undesirable behavior when updating the program!", - "Ignore", "Abort") == DialogResult.Cancel) + "WARNING: " + Program.ApplicationExecutable + " was renamed!" + "\n\nThis will cause undesirable behavior when updating the program!", + "Ignore", "Abort") == DialogResult.Cancel) { Application.Exit(); return; @@ -174,7 +165,8 @@ internal partial class MainForm : CustomForm } catch (Exception e) { - if (e.HandleException(this)) goto retry; + if (e.HandleException(this)) + goto retry; Close(); } } @@ -188,8 +180,7 @@ internal partial class MainForm : CustomForm updateButton.Text = "Cancel"; updateButton.Click -= OnUpdate; updateButton.Click += OnUpdateCancel; - changelogTreeView.Location - = progressBar.Location with { Y = progressBar.Location.Y + progressBar.Size.Height + 6 }; + changelogTreeView.Location = progressBar.Location with { Y = progressBar.Location.Y + progressBar.Size.Height + 6 }; Refresh(); Progress progress = new(); progress.ProgressChanged += delegate(object sender, double _progress) @@ -198,7 +189,7 @@ internal partial class MainForm : CustomForm progressBar.Value = (int)_progress; }; progressLabel.Text = "Updating . . . "; - cancellationTokenSource = new CancellationTokenSource(); + cancellationTokenSource = new(); try { await updateManager.PrepareUpdateAsync(latestVersion, progress, cancellationTokenSource.Token); @@ -207,8 +198,7 @@ internal partial class MainForm : CustomForm catch (TaskCanceledException) { } catch (Exception ex) { - DebugForm.Current.Log($"Exception while preparing update: {ex.GetType()} ({ex.Message})", - LogTextBox.Warning); + DebugForm.Current.Log($"Exception while preparing update: {ex.GetType()} ({ex.Message})", LogTextBox.Warning); } #else catch { } diff --git a/CreamInstaller/Forms/SelectDialogForm.cs b/CreamInstaller/Forms/SelectDialogForm.cs index 8e71d29..117494f 100644 --- a/CreamInstaller/Forms/SelectDialogForm.cs +++ b/CreamInstaller/Forms/SelectDialogForm.cs @@ -12,10 +12,11 @@ internal partial class SelectDialogForm : CustomForm private readonly List<(Platform platform, string id, string name)> selected = new(); internal SelectDialogForm(IWin32Window owner) : base(owner) => InitializeComponent(); - internal List<(Platform platform, string id, string name)> QueryUser( - string groupBoxText, List<(Platform platform, string id, string name, bool alreadySelected)> choices) + internal List<(Platform platform, string id, string name)> QueryUser(string groupBoxText, + List<(Platform platform, string id, string name, bool alreadySelected)> choices) { - if (!choices.Any()) return null; + if (!choices.Any()) + return null; groupBox.Text = groupBoxText; allCheckBox.Enabled = false; acceptButton.Enabled = false; @@ -26,7 +27,8 @@ internal partial class SelectDialogForm : CustomForm OnTreeNodeChecked(node); _ = selectionTreeView.Nodes.Add(node); } - if (!selected.Any()) OnLoad(null, null); + if (!selected.Any()) + OnLoad(null, null); allCheckBox.CheckedChanged -= OnAllCheckBoxChanged; allCheckBox.Checked = selectionTreeView.Nodes.Cast().All(n => n.Checked); allCheckBox.CheckedChanged += OnAllCheckBoxChanged; @@ -59,13 +61,11 @@ internal partial class SelectDialogForm : CustomForm allCheckBox.CheckedChanged += OnAllCheckBoxChanged; } - private void OnResize(object s, EventArgs e) => - Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 - ? Program.ApplicationNameShort - : Program.ApplicationName; + private void OnResize(object s, EventArgs e) + => Text = TextRenderer.MeasureText(Program.ApplicationName, Font).Width > Size.Width - 100 ? Program.ApplicationNameShort : Program.ApplicationName; - private void OnSortCheckBoxChanged(object sender, EventArgs e) => selectionTreeView.TreeViewNodeSorter - = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName; + private void OnSortCheckBoxChanged(object sender, EventArgs e) + => selectionTreeView.TreeViewNodeSorter = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName; private void OnAllCheckBoxChanged(object sender, EventArgs e) { @@ -85,7 +85,8 @@ internal partial class SelectDialogForm : CustomForm private void OnLoad(object sender, EventArgs e) { List<(Platform platform, string id)> choices = ProgramData.ReadProgramChoices(); - if (choices is null) return; + if (choices is null) + return; foreach (TreeNode node in selectionTreeView.Nodes) { node.Checked = choices.Any(n => n.platform == (Platform)node.Tag && n.id == node.Name); diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index 96d4221..0da3760 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -38,23 +38,23 @@ internal partial class SelectForm : CustomForm Text = Program.ApplicationName; } - public override ContextMenuStrip ContextMenuStrip => base.ContextMenuStrip ??= new ContextMenuStrip(); + public override ContextMenuStrip ContextMenuStrip => base.ContextMenuStrip ??= new(); internal List TreeNodes => GatherTreeNodes(selectionTreeView.Nodes); - private static void UpdateRemaining(Label label, SynchronizedCollection list, string descriptor) => - label.Text = list.Any() - ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") - : ""; + private static void UpdateRemaining(Label label, SynchronizedCollection list, string descriptor) + => label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : ""; private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, RemainingGames, "games"); private void AddToRemainingGames(string gameName) { - if (Program.Canceled) return; + if (Program.Canceled) + return; progressLabelGames.Invoke(delegate { - if (Program.Canceled) return; + if (Program.Canceled) + return; if (!RemainingGames.Contains(gameName)) RemainingGames.Add(gameName); UpdateRemainingGames(); @@ -63,10 +63,12 @@ internal partial class SelectForm : CustomForm private void RemoveFromRemainingGames(string gameName) { - if (Program.Canceled) return; + if (Program.Canceled) + return; progressLabelGames.Invoke(delegate { - if (Program.Canceled) return; + if (Program.Canceled) + return; RemainingGames.Remove(gameName); UpdateRemainingGames(); }); @@ -76,10 +78,12 @@ internal partial class SelectForm : CustomForm private void AddToRemainingDLCs(string dlcId) { - if (Program.Canceled) return; + if (Program.Canceled) + return; progressLabelDLCs.Invoke(delegate { - if (Program.Canceled) return; + if (Program.Canceled) + return; if (!RemainingDLCs.Contains(dlcId)) RemainingDLCs.Add(dlcId); UpdateRemainingDLCs(); @@ -88,10 +92,12 @@ internal partial class SelectForm : CustomForm private void RemoveFromRemainingDLCs(string dlcId) { - if (Program.Canceled) return; + if (Program.Canceled) + return; progressLabelDLCs.Invoke(delegate { - if (Program.Canceled) return; + if (Program.Canceled) + return; RemainingDLCs.Remove(dlcId); UpdateRemainingDLCs(); }); @@ -99,7 +105,8 @@ internal partial class SelectForm : CustomForm private async Task GetApplicablePrograms(IProgress progress) { - if (ProgramsToScan is null || !ProgramsToScan.Any()) return; + if (ProgramsToScan is null || !ProgramsToScan.Any()) + return; int TotalGameCount = 0; int CompleteGameCount = 0; void AddToRemainingGames(string gameName) @@ -113,30 +120,30 @@ internal partial class SelectForm : CustomForm this.RemoveFromRemainingGames(gameName); progress.Report(Interlocked.Increment(ref CompleteGameCount)); } - if (Program.Canceled) return; + if (Program.Canceled) + return; List treeNodes = TreeNodes; RemainingGames.Clear(); // for display purposes only, otherwise ignorable RemainingDLCs.Clear(); // for display purposes only, otherwise ignorable List appTasks = new(); if (ProgramsToScan.Any(c => c.platform is Platform.Paradox)) { - List dllDirectories - = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox); + List dllDirectories = await ParadoxLauncher.InstallPath.GetDllDirectoriesFromGameDirectory(Platform.Paradox); if (dllDirectories is not null) { ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Paradox, "PL"); - selection ??= new ProgramSelection(); - if (allCheckBox.Checked) selection.Enabled = true; - if (koaloaderAllCheckBox.Checked) selection.Koaloader = true; + selection ??= new(); + if (allCheckBox.Checked) + selection.Enabled = true; + if (koaloaderAllCheckBox.Checked) + selection.Koaloader = true; selection.Id = "PL"; selection.Name = "Paradox Launcher"; selection.RootDirectory = ParadoxLauncher.InstallPath; - selection.ExecutableDirectories - = await ParadoxLauncher.GetExecutableDirectories(selection.RootDirectory); + selection.ExecutableDirectories = await ParadoxLauncher.GetExecutableDirectories(selection.RootDirectory); selection.DllDirectories = dllDirectories; selection.Platform = Platform.Paradox; - TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Paradox && s.Name == selection.Id) - ?? new TreeNode(); + TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Paradox && s.Name == selection.Id) ?? new TreeNode(); programNode.Tag = selection.Platform; programNode.Name = selection.Id; programNode.Text = selection.Name; @@ -148,14 +155,13 @@ internal partial class SelectForm : CustomForm int steamGamesToCheck; if (ProgramsToScan.Any(c => c.platform is Platform.Steam)) { - List<(string appId, string name, string branch, int buildId, string gameDirectory)> steamGames - = await SteamLibrary.GetGames(); + List<(string appId, string name, string branch, int buildId, string gameDirectory)> steamGames = await SteamLibrary.GetGames(); steamGamesToCheck = steamGames.Count; foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames) { - if (Program.Canceled) return; - if (Program.IsGameBlocked(name, gameDirectory) - || !ProgramsToScan.Any(c => c.platform is Platform.Steam && c.id == appId)) + if (Program.Canceled) + return; + if (Program.IsGameBlocked(name, gameDirectory) || !ProgramsToScan.Any(c => c.platform is Platform.Steam && c.id == appId)) { Interlocked.Decrement(ref steamGamesToCheck); continue; @@ -163,9 +169,9 @@ internal partial class SelectForm : CustomForm AddToRemainingGames(name); Task task = Task.Run(async () => { - if (Program.Canceled) return; - List dllDirectories - = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam); + if (Program.Canceled) + return; + List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Steam); if (dllDirectories is null) { Interlocked.Decrement(ref steamGamesToCheck); @@ -180,25 +186,30 @@ internal partial class SelectForm : CustomForm RemoveFromRemainingGames(name); return; } - if (Program.Canceled) return; + if (Program.Canceled) + return; ConcurrentDictionary dlc = new(); List dlcTasks = new(); List dlcIds = new(); - if (appData is not null) dlcIds.AddRange(await SteamStore.ParseDlcAppIds(appData)); - if (appInfo is not null) dlcIds.AddRange(await SteamCMD.ParseDlcAppIds(appInfo)); + if (appData is not null) + dlcIds.AddRange(await SteamStore.ParseDlcAppIds(appData)); + if (appInfo is not null) + dlcIds.AddRange(await SteamCMD.ParseDlcAppIds(appInfo)); if (dlcIds.Count > 0) - { foreach (string dlcAppId in dlcIds) { - if (Program.Canceled) return; + if (Program.Canceled) + return; AddToRemainingDLCs(dlcAppId); Task task = Task.Run(async () => { - if (Program.Canceled) return; + if (Program.Canceled) + return; do // give games steam store api limit priority Thread.Sleep(200); while (!Program.Canceled && steamGamesToCheck > 0); - if (Program.Canceled) return; + if (Program.Canceled) + return; string dlcName = null; string dlcIcon = null; bool onSteamStore = false; @@ -215,18 +226,15 @@ internal partial class SelectForm : CustomForm if (dlcAppInfo is not null) { dlcName = dlcAppInfo.Value?.GetChild("common")?.GetChild("name")?.ToString(); - string dlcIconStaticId = dlcAppInfo.Value?.GetChild("common")?.GetChild("icon") - ?.ToString(); - dlcIconStaticId ??= dlcAppInfo.Value?.GetChild("common")?.GetChild("logo_small") - ?.ToString(); - dlcIconStaticId ??= dlcAppInfo.Value?.GetChild("common")?.GetChild("logo") - ?.ToString(); + string dlcIconStaticId = dlcAppInfo.Value?.GetChild("common")?.GetChild("icon")?.ToString(); + dlcIconStaticId ??= dlcAppInfo.Value?.GetChild("common")?.GetChild("logo_small")?.ToString(); + dlcIconStaticId ??= dlcAppInfo.Value?.GetChild("common")?.GetChild("logo")?.ToString(); if (dlcIconStaticId is not null) - dlcIcon = IconGrabber.SteamAppImagesPath - + @$"\{dlcAppId}\{dlcIconStaticId}.jpg"; + dlcIcon = IconGrabber.SteamAppImagesPath + @$"\{dlcAppId}\{dlcIconStaticId}.jpg"; } } - if (Program.Canceled) return; + if (Program.Canceled) + return; if (string.IsNullOrWhiteSpace(dlcName)) dlcName = "Unknown"; dlc[dlcAppId] = (onSteamStore ? DlcType.Steam : DlcType.SteamHidden, dlcName, dlcIcon); @@ -234,45 +242,43 @@ internal partial class SelectForm : CustomForm }); dlcTasks.Add(task); } - } else { RemoveFromRemainingGames(name); return; } - if (Program.Canceled) return; + if (Program.Canceled) + return; foreach (Task task in dlcTasks) { - if (Program.Canceled) return; + if (Program.Canceled) + return; await task; } steamGamesToCheck = 0; - ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Steam, appId) - ?? new ProgramSelection(); - selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() - || selection.ExtraSelectedDlc.Any(); - if (koaloaderAllCheckBox.Checked) selection.Koaloader = true; + ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Steam, appId) ?? new ProgramSelection(); + selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); + if (koaloaderAllCheckBox.Checked) + selection.Koaloader = true; selection.Id = appId; selection.Name = appData?.name ?? name; selection.RootDirectory = gameDirectory; - selection.ExecutableDirectories - = await SteamLibrary.GetExecutableDirectories(selection.RootDirectory); + selection.ExecutableDirectories = await SteamLibrary.GetExecutableDirectories(selection.RootDirectory); selection.DllDirectories = dllDirectories; selection.Platform = Platform.Steam; selection.ProductUrl = "https://store.steampowered.com/app/" + appId; - selection.IconUrl = IconGrabber.SteamAppImagesPath - + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("icon")}.jpg"; + selection.IconUrl = IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("icon")}.jpg"; selection.SubIconUrl = appData?.header_image ?? IconGrabber.SteamAppImagesPath + @$"\{appId}\{appInfo?.Value?.GetChild("common")?.GetChild("clienticon")}.ico"; - selection.Publisher = appData?.publishers[0] - ?? appInfo?.Value?.GetChild("extended")?.GetChild("publisher")?.ToString(); + selection.Publisher = appData?.publishers[0] ?? appInfo?.Value?.GetChild("extended")?.GetChild("publisher")?.ToString(); selection.WebsiteUrl = appData?.website; - if (Program.Canceled) return; + if (Program.Canceled) + return; selectionTreeView.Invoke(delegate { - if (Program.Canceled) return; - TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) - ?? new TreeNode(); + if (Program.Canceled) + return; + TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) ?? new TreeNode(); programNode.Tag = selection.Platform; programNode.Name = appId; programNode.Text = appData?.name ?? name; @@ -281,13 +287,14 @@ internal partial class SelectForm : CustomForm _ = selectionTreeView.Nodes.Add(programNode); foreach (KeyValuePair pair in dlc) { - if (Program.Canceled || programNode is null) return; + if (Program.Canceled || programNode is null) + return; string appId = pair.Key; (DlcType type, string name, string icon) dlcApp = pair.Value; selection.AllDlc[appId] = dlcApp; - if (allCheckBox.Checked && dlcApp.name != "Unknown") selection.SelectedDlc[appId] = dlcApp; - TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) - ?? new TreeNode(); + if (allCheckBox.Checked && dlcApp.name != "Unknown") + selection.SelectedDlc[appId] = dlcApp; + TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Steam && s.Name == appId) ?? new TreeNode(); dlcNode.Tag = selection.Platform; dlcNode.Name = appId; dlcNode.Text = dlcApp.name; @@ -296,7 +303,8 @@ internal partial class SelectForm : CustomForm _ = programNode.Nodes.Add(dlcNode); } }); - if (Program.Canceled) return; + if (Program.Canceled) + return; RemoveFromRemainingGames(name); }); appTasks.Add(task); @@ -310,34 +318,37 @@ internal partial class SelectForm : CustomForm string @namespace = manifest.CatalogNamespace; string name = manifest.DisplayName; string directory = manifest.InstallLocation; - if (Program.Canceled) return; - if (Program.IsGameBlocked(name, directory) - || !ProgramsToScan.Any(c => c.platform is Platform.Epic && c.id == @namespace)) continue; + if (Program.Canceled) + return; + if (Program.IsGameBlocked(name, directory) || !ProgramsToScan.Any(c => c.platform is Platform.Epic && c.id == @namespace)) + continue; AddToRemainingGames(name); Task task = Task.Run(async () => { - if (Program.Canceled) return; + if (Program.Canceled) + return; List dllDirectories = await directory.GetDllDirectoriesFromGameDirectory(Platform.Epic); if (dllDirectories is null) { RemoveFromRemainingGames(name); return; } - if (Program.Canceled) return; - ConcurrentDictionary - entitlements = new(); + if (Program.Canceled) + return; + ConcurrentDictionary entitlements = new(); List dlcTasks = new(); List<(string id, string name, string product, string icon, string developer)> entitlementIds = await EpicStore.QueryEntitlements(@namespace); if (entitlementIds.Any()) - foreach ((string id, string name, string product, string icon, string developer) in - entitlementIds) + foreach ((string id, string name, string product, string icon, string developer) in entitlementIds) { - if (Program.Canceled) return; + if (Program.Canceled) + return; AddToRemainingDLCs(id); Task task = Task.Run(() => { - if (Program.Canceled) return; + if (Program.Canceled) + return; entitlements[id] = (name, product, icon, developer); RemoveFromRemainingDLCs(id); }); @@ -348,37 +359,38 @@ internal partial class SelectForm : CustomForm RemoveFromRemainingGames(name); return; } - if (Program.Canceled) return; + if (Program.Canceled) + return; foreach (Task task in dlcTasks) { - if (Program.Canceled) return; + if (Program.Canceled) + return; await task; } - ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) - ?? new ProgramSelection(); - selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() - || selection.ExtraSelectedDlc.Any(); - if (koaloaderAllCheckBox.Checked) selection.Koaloader = true; + ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) ?? new ProgramSelection(); + selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); + if (koaloaderAllCheckBox.Checked) + selection.Koaloader = true; selection.Id = @namespace; selection.Name = name; selection.RootDirectory = directory; - selection.ExecutableDirectories - = await EpicLibrary.GetExecutableDirectories(selection.RootDirectory); + selection.ExecutableDirectories = await EpicLibrary.GetExecutableDirectories(selection.RootDirectory); selection.DllDirectories = dllDirectories; selection.Platform = Platform.Epic; - foreach (KeyValuePair pair in - entitlements.Where(p => p.Value.name == selection.Name)) + foreach (KeyValuePair pair in entitlements.Where(p + => p.Value.name == selection.Name)) { selection.ProductUrl = "https://www.epicgames.com/store/product/" + pair.Value.product; selection.IconUrl = pair.Value.icon; selection.Publisher = pair.Value.developer; } - if (Program.Canceled) return; + if (Program.Canceled) + return; selectionTreeView.Invoke(delegate { - if (Program.Canceled) return; - TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == @namespace) - ?? new TreeNode(); + if (Program.Canceled) + return; + TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == @namespace) ?? new TreeNode(); programNode.Tag = selection.Platform; programNode.Name = @namespace; programNode.Text = name; @@ -400,17 +412,16 @@ internal partial class SelectForm : CustomForm entitlementsNode.Checked = selection.SelectedDlc.Any(pair => pair.Value.type == DlcType.Entitlement); if (entitlementsNode.Parent is null) programNode.Nodes.Add(entitlementsNode);*/ - foreach (KeyValuePair - pair in entitlements) + foreach (KeyValuePair pair in entitlements) { - if (programNode is null /* || entitlementsNode is null*/) return; + if (programNode is null /* || entitlementsNode is null*/) + return; string dlcId = pair.Key; - (DlcType type, string name, string icon) dlcApp = ( - DlcType.EpicEntitlement, 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.Tag is Platform.Epic && s.Name == dlcId) - ?? new TreeNode(); + if (allCheckBox.Checked) + selection.SelectedDlc[dlcId] = dlcApp; + TreeNode dlcNode = treeNodes.Find(s => s.Tag is Platform.Epic && s.Name == dlcId) ?? new TreeNode(); dlcNode.Tag = selection.Platform; dlcNode.Name = dlcId; dlcNode.Text = dlcApp.name; @@ -419,7 +430,8 @@ internal partial class SelectForm : CustomForm _ = programNode.Nodes.Add(dlcNode); //entitlementsNode.Nodes.Add(dlcNode); } }); - if (Program.Canceled) return; + if (Program.Canceled) + return; RemoveFromRemainingGames(name); }); appTasks.Add(task); @@ -430,39 +442,39 @@ internal partial class SelectForm : CustomForm List<(string gameId, string name, string gameDirectory)> ubisoftGames = await UbisoftLibrary.GetGames(); foreach ((string gameId, string name, string gameDirectory) in ubisoftGames) { - if (Program.Canceled) return; - if (Program.IsGameBlocked(name, gameDirectory) - || !ProgramsToScan.Any(c => c.platform is Platform.Ubisoft && c.id == gameId)) continue; + if (Program.Canceled) + return; + if (Program.IsGameBlocked(name, gameDirectory) || !ProgramsToScan.Any(c => c.platform is Platform.Ubisoft && c.id == gameId)) + continue; AddToRemainingGames(name); Task task = Task.Run(async () => { - if (Program.Canceled) return; - List dllDirectories - = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft); + if (Program.Canceled) + return; + List dllDirectories = await gameDirectory.GetDllDirectoriesFromGameDirectory(Platform.Ubisoft); if (dllDirectories is null) { RemoveFromRemainingGames(name); return; } - if (Program.Canceled) return; - ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) - ?? new ProgramSelection(); - selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() - || selection.ExtraSelectedDlc.Any(); - if (koaloaderAllCheckBox.Checked) selection.Koaloader = true; + if (Program.Canceled) + return; + ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) ?? new ProgramSelection(); + selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); + if (koaloaderAllCheckBox.Checked) + selection.Koaloader = true; selection.Id = gameId; selection.Name = name; selection.RootDirectory = gameDirectory; - selection.ExecutableDirectories - = await UbisoftLibrary.GetExecutableDirectories(selection.RootDirectory); + selection.ExecutableDirectories = await UbisoftLibrary.GetExecutableDirectories(selection.RootDirectory); selection.DllDirectories = dllDirectories; selection.Platform = Platform.Ubisoft; selection.IconUrl = IconGrabber.GetDomainFaviconUrl("store.ubi.com"); selectionTreeView.Invoke(delegate { - if (Program.Canceled) return; - TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Ubisoft && s.Name == gameId) - ?? new TreeNode(); + if (Program.Canceled) + return; + TreeNode programNode = treeNodes.Find(s => s.Tag is Platform.Ubisoft && s.Name == gameId) ?? new TreeNode(); programNode.Tag = selection.Platform; programNode.Name = gameId; programNode.Text = name; @@ -470,7 +482,8 @@ internal partial class SelectForm : CustomForm if (programNode.TreeView is null) _ = selectionTreeView.Nodes.Add(programNode); }); - if (Program.Canceled) return; + if (Program.Canceled) + return; RemoveFromRemainingGames(name); }); appTasks.Add(task); @@ -478,7 +491,8 @@ internal partial class SelectForm : CustomForm } foreach (Task task in appTasks) { - if (Program.Canceled) return; + if (Program.Canceled) + return; await task; } steamGamesToCheck = 0; @@ -512,30 +526,24 @@ internal partial class SelectForm : CustomForm List<(Platform platform, string id, string name, bool alreadySelected)> gameChoices = new(); if (Directory.Exists(ParadoxLauncher.InstallPath)) gameChoices.Add((Platform.Paradox, "PL", "Paradox Launcher", - ProgramsToScan is not null - && ProgramsToScan.Any(p => p.platform is Platform.Paradox && p.id == "PL"))); + ProgramsToScan is not null && ProgramsToScan.Any(p => p.platform is Platform.Paradox && p.id == "PL"))); if (Directory.Exists(SteamLibrary.InstallPath)) - foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in - (await SteamLibrary.GetGames()).Where(g => !Program.IsGameBlocked(g.name, g.gameDirectory))) + foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in (await SteamLibrary.GetGames()).Where(g + => !Program.IsGameBlocked(g.name, g.gameDirectory))) gameChoices.Add((Platform.Steam, appId, name, - ProgramsToScan is not null - && ProgramsToScan.Any(p => p.platform is Platform.Steam && p.id == appId))); + ProgramsToScan is not null && ProgramsToScan.Any(p => p.platform is Platform.Steam && p.id == appId))); if (Directory.Exists(EpicLibrary.EpicManifestsPath)) - foreach (Manifest manifest in (await EpicLibrary.GetGames()).Where( - m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation))) + foreach (Manifest manifest in (await EpicLibrary.GetGames()).Where(m => !Program.IsGameBlocked(m.DisplayName, m.InstallLocation))) gameChoices.Add((Platform.Epic, manifest.CatalogNamespace, manifest.DisplayName, - ProgramsToScan is not null && ProgramsToScan.Any( - p => p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))); - foreach ((string gameId, string name, string gameDirectory) in (await UbisoftLibrary.GetGames()).Where( - g => !Program.IsGameBlocked(g.name, g.gameDirectory))) + ProgramsToScan is not null && ProgramsToScan.Any(p => p.platform is Platform.Epic && p.id == manifest.CatalogNamespace))); + foreach ((string gameId, string name, string gameDirectory) in (await UbisoftLibrary.GetGames()).Where(g + => !Program.IsGameBlocked(g.name, g.gameDirectory))) gameChoices.Add((Platform.Ubisoft, gameId, name, - ProgramsToScan is not null - && ProgramsToScan.Any(p => p.platform is Platform.Ubisoft && p.id == gameId))); + ProgramsToScan is not null && ProgramsToScan.Any(p => p.platform is Platform.Ubisoft && p.id == gameId))); if (gameChoices.Any()) { using SelectDialogForm form = new(this); - List<(Platform platform, string id, string name)> choices - = form.QueryUser("Choose which programs and/or games to scan for DLC:", gameChoices); + List<(Platform platform, string id, string name)> choices = form.QueryUser("Choose which programs and/or games to scan for DLC:", gameChoices); scan = choices is not null && choices.Any(); string retry = "\n\nPress the \"Rescan Programs / Games\" button to re-choose."; if (scan) @@ -544,14 +552,10 @@ internal partial class SelectForm : CustomForm noneFoundLabel.Text = "None of the chosen programs nor games were applicable!" + retry; } else - { noneFoundLabel.Text = "You didn't choose any programs nor games!" + retry; - } } else - { noneFoundLabel.Text = "No applicable programs nor games were found on your computer!"; - } } if (scan) { @@ -562,17 +566,17 @@ internal partial class SelectForm : CustomForm IProgress iProgress = progress; progress.ProgressChanged += (sender, _progress) => { - if (Program.Canceled) return; - if (_progress < 0 || _progress > maxProgress) maxProgress = -_progress; - else curProgress = _progress; + if (Program.Canceled) + return; + if (_progress < 0 || _progress > maxProgress) + maxProgress = -_progress; + else + curProgress = _progress; int p = Math.Max(Math.Min((int)((float)curProgress / maxProgress * 100), 100), 0); - progressLabel.Text = setup - ? $"Setting up SteamCMD . . . {p}%" - : $"Gathering and caching your applicable games and their DLCs . . . {p}%"; + progressLabel.Text = setup ? $"Setting up SteamCMD . . . {p}%" : $"Gathering and caching your applicable games and their DLCs . . . {p}%"; progressBar.Value = p; }; - if (Directory.Exists(SteamLibrary.InstallPath) && ProgramsToScan is not null - && ProgramsToScan.Any(c => c.platform is Platform.Steam)) + if (Directory.Exists(SteamLibrary.InstallPath) && ProgramsToScan is not null && ProgramsToScan.Any(c => c.platform is Platform.Steam)) { progressLabel.Text = "Setting up SteamCMD . . . "; await SteamCMD.Setup(iProgress); @@ -615,9 +619,11 @@ internal partial class SelectForm : CustomForm private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e) { - if (e.Action == TreeViewAction.Unknown) return; + if (e.Action == TreeViewAction.Unknown) + return; TreeNode node = e.Node; - if (node is null) return; + if (node is null) + return; SyncNode(node); SyncNodeAncestors(node); SyncNodeDescendants(node); @@ -640,10 +646,11 @@ internal partial class SelectForm : CustomForm } } - private static void SyncNodeDescendants(TreeNode node) => - node.Nodes.Cast().ToList().ForEach(childNode => + private static void SyncNodeDescendants(TreeNode node) + => node.Nodes.Cast().ToList().ForEach(childNode => { - if (childNode.Text == "Unknown") return; + if (childNode.Text == "Unknown") + return; childNode.Checked = node.Checked; SyncNode(childNode); SyncNodeDescendants(childNode); @@ -653,8 +660,7 @@ internal partial class SelectForm : CustomForm { string id = node.Name; Platform platform = (Platform)node.Tag; - (string gameId, (DlcType type, string name, string icon) app)? dlc - = ProgramSelection.GetDlcFromPlatformId(platform, id); + (string gameId, (DlcType type, string name, string icon) app)? dlc = ProgramSelection.GetDlcFromPlatformId(platform, id); if (dlc.HasValue) { (string gameId, _) = dlc.Value; @@ -692,11 +698,8 @@ internal partial class SelectForm : CustomForm progressBar.Visible = true; programsGroupBox.Size = programsGroupBox.Size with { - Height = programsGroupBox.Size.Height - 3 - - progressLabel.Size.Height - - progressLabelGames.Size.Height - - progressLabelDLCs.Size.Height - - progressBar.Size.Height + Height = programsGroupBox.Size.Height - 3 - progressLabel.Size.Height - progressLabelGames.Size.Height - progressLabelDLCs.Size.Height + - progressBar.Size.Height }; } @@ -709,200 +712,174 @@ internal partial class SelectForm : CustomForm progressBar.Visible = false; programsGroupBox.Size = programsGroupBox.Size with { - Height = programsGroupBox.Size.Height + 3 - + progressLabel.Size.Height - + progressLabelGames.Size.Height - + progressLabelDLCs.Size.Height - + progressBar.Size.Height + Height = programsGroupBox.Size.Height + 3 + progressLabel.Size.Height + progressLabelGames.Size.Height + progressLabelDLCs.Size.Height + + progressBar.Size.Height }; } - internal void OnNodeRightClick(TreeNode node, Point location) => Invoke(() => - { - ContextMenuStrip contextMenuStrip = ContextMenuStrip; - while (ContextMenuStrip.Tag is bool used && used) - Thread.Sleep(100); - ContextMenuStrip.Tag = true; - ToolStripItemCollection items = contextMenuStrip.Items; - items.Clear(); - string id = node.Name; - Platform platform = (Platform)node.Tag; - ProgramSelection selection = ProgramSelection.FromPlatformId(platform, id); - (string gameAppId, (DlcType type, string name, string icon) app)? dlc = null; - if (selection is null) - dlc = ProgramSelection.GetDlcFromPlatformId(platform, id); - ProgramSelection dlcParentSelection = null; - if (dlc is not null) - dlcParentSelection = ProgramSelection.FromPlatformId(platform, dlc.Value.gameAppId); - if (selection is null && dlcParentSelection is null) - return; - ContextMenuItem header = null; - if (id == "PL") - header = new ContextMenuItem(node.Text, "Paradox Launcher"); - else if (selection is not null) - header = new ContextMenuItem(node.Text, (id, selection.IconUrl)); - else if (dlc is not null && dlcParentSelection is not null) - header = new ContextMenuItem(node.Text, (id, dlc.Value.app.icon), (id, dlcParentSelection.IconUrl)); - items.Add(header ?? new ContextMenuItem(node.Text)); - string appInfoVDF = $@"{SteamCMD.AppInfoPath}\{id}.vdf"; - string appInfoJSON = $@"{SteamCMD.AppInfoPath}\{id}.json"; - string cooldown = $@"{ProgramData.CooldownPath}\{id}.txt"; - if ((File.Exists(appInfoVDF) || File.Exists(appInfoJSON)) && (selection is not null || dlc is not null)) - { - List queries = new(); - if (File.Exists(appInfoJSON)) - { - string platformString = selection is null || selection.Platform is Platform.Steam - ? "Steam Store " - : selection.Platform is Platform.Epic - ? "Epic GraphQL " - : ""; - queries.Add(new ContextMenuItem($"Open {platformString}Query", "Notepad", - (sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON))); - } - if (File.Exists(appInfoVDF)) - queries.Add(new ContextMenuItem("Open SteamCMD Query", "Notepad", - (sender, e) => Diagnostics.OpenFileInNotepad(appInfoVDF))); - if (queries.Any()) - { - items.Add(new ToolStripSeparator()); - foreach (ContextMenuItem query in queries) - items.Add(query); - items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt", - (sender, e) => - { - try - { - File.Delete(appInfoVDF); - } - catch { } - try - { - File.Delete(appInfoJSON); - } - catch { } - try - { - File.Delete(cooldown); - } - catch { } - OnLoad(true); - })); - } - } - if (selection is not null) + internal void OnNodeRightClick(TreeNode node, Point location) + => Invoke(() => { + ContextMenuStrip contextMenuStrip = ContextMenuStrip; + while (ContextMenuStrip.Tag is bool used && used) + Thread.Sleep(100); + ContextMenuStrip.Tag = true; + ToolStripItemCollection items = contextMenuStrip.Items; + items.Clear(); + string id = node.Name; + Platform platform = (Platform)node.Tag; + ProgramSelection selection = ProgramSelection.FromPlatformId(platform, id); + (string gameAppId, (DlcType type, string name, string icon) app)? dlc = null; + if (selection is null) + dlc = ProgramSelection.GetDlcFromPlatformId(platform, id); + ProgramSelection dlcParentSelection = null; + if (dlc is not null) + dlcParentSelection = ProgramSelection.FromPlatformId(platform, dlc.Value.gameAppId); + if (selection is null && dlcParentSelection is null) + return; + ContextMenuItem header = null; if (id == "PL") + header = new(node.Text, "Paradox Launcher"); + else if (selection is not null) + header = new(node.Text, (id, selection.IconUrl)); + else if (dlc is not null && dlcParentSelection is not null) + header = new(node.Text, (id, dlc.Value.app.icon), (id, dlcParentSelection.IconUrl)); + items.Add(header ?? new ContextMenuItem(node.Text)); + string appInfoVDF = $@"{SteamCMD.AppInfoPath}\{id}.vdf"; + string appInfoJSON = $@"{SteamCMD.AppInfoPath}\{id}.json"; + string cooldown = $@"{ProgramData.CooldownPath}\{id}.txt"; + if ((File.Exists(appInfoVDF) || File.Exists(appInfoJSON)) && (selection is not null || dlc is not null)) { - items.Add(new ToolStripSeparator()); - items.Add(new ContextMenuItem("Repair", "Command Prompt", - async (sender, e) => await ParadoxLauncher.Repair(this, selection))); - } - items.Add(new ToolStripSeparator()); - items.Add(new ContextMenuItem("Open Root Directory", "File Explorer", - (sender, e) => Diagnostics.OpenDirectoryInFileExplorer( - selection.RootDirectory))); - int executables = 0; - foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories.ToList()) - items.Add(new ContextMenuItem( - $"Open Executable Directory #{++executables} ({(binaryType == BinaryType.BIT32 ? "32" : "64")}-bit)", - "File Explorer", - (sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))); - List directories = selection.DllDirectories.ToList(); - int steam = 0, epic = 0, r1 = 0, r2 = 0; - if (selection.Platform is Platform.Steam or Platform.Paradox) - foreach (string directory in directories) + List queries = new(); + if (File.Exists(appInfoJSON)) { - directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, - out string api64_o, out string config, out string cache); - if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) - || File.Exists(config) || File.Exists(cache)) - items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer", - (sender, e) => Diagnostics - .OpenDirectoryInFileExplorer(directory))); + string platformString = selection is null || selection.Platform is Platform.Steam + ? "Steam Store " + : selection.Platform is Platform.Epic + ? "Epic GraphQL " + : ""; + queries.Add(new($"Open {platformString}Query", "Notepad", (sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON))); } - if (selection.Platform is Platform.Epic or Platform.Paradox) - foreach (string directory in directories) + if (File.Exists(appInfoVDF)) + queries.Add(new("Open SteamCMD Query", "Notepad", (sender, e) => Diagnostics.OpenFileInNotepad(appInfoVDF))); + if (queries.Any()) { - 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)) - items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer", - (sender, e) => Diagnostics - .OpenDirectoryInFileExplorer(directory))); + items.Add(new ToolStripSeparator()); + foreach (ContextMenuItem query in queries) + items.Add(query); + items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt", (sender, e) => + { + try + { + File.Delete(appInfoVDF); + } + catch { } + try + { + File.Delete(appInfoJSON); + } + catch { } + try + { + File.Delete(cooldown); + } + catch { } + OnLoad(true); + })); } - 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)) - items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer", - (sender, e) => 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); - 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)) - items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer", - (sender, e) => Diagnostics - .OpenDirectoryInFileExplorer(directory))); - } - } - if (id != "PL") - { - if ((selection is not null && selection.Platform is Platform.Steam) - || (dlcParentSelection is not null && dlcParentSelection.Platform is Platform.Steam)) - { - items.Add(new ToolStripSeparator()); - items.Add(new ContextMenuItem("Open SteamDB", "SteamDB", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - "https://steamdb.info/app/" + id))); } if (selection is not null) { - if (selection.Platform is Platform.Steam) - { - items.Add(new ContextMenuItem("Open Steam Store", "Steam Store", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - selection.ProductUrl))); - items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIconUrl), - "Steam Community", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - "https://steamcommunity.com/app/" + id))); - } - if (selection.Platform is Platform.Epic) + if (id == "PL") { items.Add(new ToolStripSeparator()); - items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - "https://scream-db.web.app/offers/" + id))); - items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - selection.ProductUrl))); + items.Add(new ContextMenuItem("Repair", "Command Prompt", async (sender, e) => await ParadoxLauncher.Repair(this, selection))); } + items.Add(new ToolStripSeparator()); + items.Add(new ContextMenuItem("Open Root Directory", "File Explorer", + (sender, e) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory))); + int executables = 0; + foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories.ToList()) + items.Add(new ContextMenuItem($"Open Executable Directory #{++executables} ({(binaryType == BinaryType.BIT32 ? "32" : "64")}-bit)", + "File Explorer", (sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))); + List directories = selection.DllDirectories.ToList(); + int steam = 0, epic = 0, r1 = 0, r2 = 0; + if (selection.Platform is Platform.Steam or Platform.Paradox) + foreach (string directory in directories) + { + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, + out string cache); + if (File.Exists(api32) || File.Exists(api32_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) + || File.Exists(cache)) + items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer", + (sender, e) => 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)) + items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer", + (sender, e) => 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)) + items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer", + (sender, e) => 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); + 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)) + items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer", + (sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))); + } + } + if (id != "PL") + { + if (selection is not null && selection.Platform is Platform.Steam + || dlcParentSelection is not null && dlcParentSelection.Platform is Platform.Steam) { items.Add(new ToolStripSeparator()); + items.Add(new ContextMenuItem("Open SteamDB", "SteamDB", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id))); + } + if (selection is not null) + { + if (selection.Platform is Platform.Steam) + { + items.Add(new ContextMenuItem("Open Steam Store", "Steam Store", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))); + items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIconUrl), "Steam Community", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id))); + } + if (selection.Platform is Platform.Epic) + { + items.Add(new ToolStripSeparator()); + items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" + id))); + items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))); + } + if (selection.Platform is Platform.Ubisoft) + { + items.Add(new ToolStripSeparator()); #pragma warning disable CA1308 // Normalize strings to uppercase - items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store", - (sender, e) => Diagnostics.OpenUrlInInternetBrowser( - "https://store.ubi.com/us/" + selection.Name.Replace(" ", "-") - .ToLowerInvariant()))); + items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store", + (sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://store.ubi.com/us/" + + selection.Name.Replace(" ", "-").ToLowerInvariant()))); #pragma warning restore CA1308 // Normalize strings to uppercase + } } } - } - if (selection is not null && selection.WebsiteUrl is not null) - items.Add(new ContextMenuItem("Open Official Website", - ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.WebsiteUrl)), - (sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.WebsiteUrl))); - contextMenuStrip.Show(selectionTreeView, location); - contextMenuStrip.Refresh(); - ContextMenuStrip.Tag = null; - }); + if (selection is not null && selection.WebsiteUrl is not null) + items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.WebsiteUrl)), + (sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.WebsiteUrl))); + contextMenuStrip.Show(selectionTreeView, location); + contextMenuStrip.Refresh(); + ContextMenuStrip.Tag = null; + }); private void OnLoad(object sender, EventArgs _) { @@ -915,7 +892,8 @@ internal partial class SelectForm : CustomForm } catch (Exception e) { - if (e.HandleException(this)) goto retry; + if (e.HandleException(this)) + goto retry; Close(); } } @@ -927,7 +905,8 @@ internal partial class SelectForm : CustomForm foreach (ProgramSelection selection in ProgramSelection.AllEnabled) if (!Program.IsProgramRunningDialog(this, selection)) return; - if (!uninstall && ParadoxLauncher.DlcDialog(this)) return; + if (!uninstall && ParadoxLauncher.DlcDialog(this)) + return; Hide(); #pragma warning disable CA2000 // Dispose objects before losing scope InstallForm form = new(uninstall); @@ -945,9 +924,7 @@ internal partial class SelectForm : CustomForm OnLoad(); } else - { Close(); - } }; form.Show(); Hide(); @@ -982,7 +959,7 @@ internal partial class SelectForm : CustomForm if (node.Parent is null && node.Checked != shouldCheck) { node.Checked = shouldCheck; - OnTreeViewNodeCheckedChanged(null, new TreeViewEventArgs(node, TreeViewAction.ByMouse)); + OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse)); } allCheckBox.CheckedChanged -= OnAllCheckBoxChanged; allCheckBox.Checked = shouldCheck; @@ -1009,20 +986,17 @@ internal partial class SelectForm : CustomForm private bool AreSelectionsDefault() { foreach (TreeNode node in TreeNodes) - if (node.Parent is not null && node.Tag is Platform - && (node.Text == "Unknown" ? node.Checked : !node.Checked)) + if (node.Parent is not null && node.Tag is Platform && (node.Text == "Unknown" ? node.Checked : !node.Checked)) return false; return true; } - private bool CanSaveDlc() - => installButton.Enabled && (ProgramData.ReadDlcChoices() is not null || !AreSelectionsDefault()); + private bool CanSaveDlc() => installButton.Enabled && (ProgramData.ReadDlcChoices() is not null || !AreSelectionsDefault()); private void OnSaveDlc(object sender, EventArgs e) { List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices() - ?? new List<(Platform platform, string gameId, - string dlcId)>(); + ?? new List<(Platform platform, string gameId, string dlcId)>(); foreach (TreeNode node in TreeNodes) if (node.Parent is TreeNode parent && node.Tag is Platform platform) { @@ -1042,15 +1016,15 @@ internal partial class SelectForm : CustomForm private void OnLoadDlc(object sender, EventArgs e) { List<(Platform platform, string gameId, string dlcId)> choices = ProgramData.ReadDlcChoices(); - if (choices is null) return; + if (choices is null) + return; foreach (TreeNode node in TreeNodes) if (node.Parent is TreeNode parent && node.Tag is Platform platform) { - node.Checked - = choices.Any(c => c.platform == platform && c.gameId == parent.Name && c.dlcId == node.Name) - ? node.Text == "Unknown" - : node.Text != "Unknown"; - OnTreeViewNodeCheckedChanged(null, new TreeViewEventArgs(node, TreeViewAction.ByMouse)); + node.Checked = choices.Any(c => c.platform == platform && c.gameId == parent.Name && c.dlcId == node.Name) + ? node.Text == "Unknown" + : node.Text != "Unknown"; + OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse)); } } @@ -1062,7 +1036,7 @@ internal partial class SelectForm : CustomForm if (node.Parent is not null && node.Tag is Platform) { node.Checked = node.Text != "Unknown"; - OnTreeViewNodeCheckedChanged(null, new TreeViewEventArgs(node, TreeViewAction.ByMouse)); + OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse)); } resetButton.Enabled = CanResetDlc(); } @@ -1075,22 +1049,18 @@ internal partial class SelectForm : CustomForm return true; } - private static bool CanSaveKoaloader() - => ProgramData.ReadKoaloaderChoices() is not null || !AreKoaloaderSelectionsDefault(); + private static bool CanSaveKoaloader() => ProgramData.ReadKoaloaderChoices() is not null || !AreKoaloaderSelectionsDefault(); private void OnSaveKoaloader(object sender, EventArgs e) { List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices() - ?? new List<(Platform platform, string id, string proxy, bool enabled)>(); + ?? new List<(Platform platform, string id, string proxy, bool enabled)>(); foreach (ProgramSelection selection in ProgramSelection.AllSafe) { _ = choices.RemoveAll(c => c.platform == selection.Platform && c.id == selection.Id); - if (selection.KoaloaderProxy is not null and not ProgramSelection.DefaultKoaloaderProxy - || !selection.Koaloader) + if (selection.KoaloaderProxy is not null and not ProgramSelection.DefaultKoaloaderProxy || !selection.Koaloader) choices.Add((selection.Platform, selection.Id, - selection.KoaloaderProxy == ProgramSelection.DefaultKoaloaderProxy - ? null - : selection.KoaloaderProxy, selection.Koaloader)); + selection.KoaloaderProxy == ProgramSelection.DefaultKoaloaderProxy ? null : selection.KoaloaderProxy, selection.Koaloader)); } ProgramData.WriteKoaloaderProxyChoices(choices); saveKoaloaderButton.Enabled = CanSaveKoaloader(); @@ -1102,12 +1072,13 @@ internal partial class SelectForm : CustomForm private void OnLoadKoaloader(object sender, EventArgs e) { List<(Platform platform, string id, string proxy, bool enabled)> choices = ProgramData.ReadKoaloaderChoices(); - if (choices is null) return; + if (choices is null) + return; foreach (ProgramSelection selection in ProgramSelection.AllSafe) if (choices.Any(c => c.platform == selection.Platform && c.id == selection.Id)) { - (Platform platform, string id, string proxy, bool enabled) choice = - choices.First(c => c.platform == selection.Platform && c.id == selection.Id); + (Platform platform, string id, string proxy, bool enabled) + choice = choices.First(c => c.platform == selection.Platform && c.id == selection.Id); (Platform platform, string id, string proxy, bool enabled) = choice; string currentProxy = proxy; if (proxy is not null && proxy.Contains('.')) // convert pre-v4.1.0.0 choices @@ -1115,14 +1086,11 @@ internal partial class SelectForm : CustomForm if (proxy != currentProxy && choices.Remove(choice)) // convert pre-v4.1.0.0 choices choices.Add((platform, id, currentProxy, enabled)); if (currentProxy is null or ProgramSelection.DefaultKoaloaderProxy && enabled) - { _ = choices.RemoveAll(c => c.platform == platform && c.id == id); - } else { selection.Koaloader = enabled; - selection.KoaloaderProxy - = currentProxy == ProgramSelection.DefaultKoaloaderProxy ? currentProxy : proxy; + selection.KoaloaderProxy = currentProxy == ProgramSelection.DefaultKoaloaderProxy ? currentProxy : proxy; } } else @@ -1176,22 +1144,16 @@ internal partial class SelectForm : CustomForm _ = blockedDirectoryExceptions.Append(helpButtonListPrefix + name); using DialogForm form = new(this); _ = form.Show(SystemIcons.Information, - "Blocks the program from caching and displaying games protected by anti-cheats." + - "\nYou disable this option and install DLC unlockers to protected games at your own risk!" + - "\n\nBlocked games: " - + (string.IsNullOrWhiteSpace(blockedGames.ToString()) ? "(none)" : blockedGames) + - "\n\nBlocked game sub-directories: " + (string.IsNullOrWhiteSpace(blockedDirectories.ToString()) - ? "(none)" - : blockedDirectories) + - "\n\nBlocked game sub-directory exceptions: " - + (string.IsNullOrWhiteSpace(blockedDirectoryExceptions.ToString()) - ? "(none)" - : blockedDirectoryExceptions), - "OK", customFormText: "Block Protected Games"); + "Blocks the program from caching and displaying games protected by anti-cheats." + + "\nYou disable this option and install DLC unlockers to protected games at your own risk!" + "\n\nBlocked games: " + + (string.IsNullOrWhiteSpace(blockedGames.ToString()) ? "(none)" : blockedGames) + "\n\nBlocked game sub-directories: " + + (string.IsNullOrWhiteSpace(blockedDirectories.ToString()) ? "(none)" : blockedDirectories) + "\n\nBlocked game sub-directory exceptions: " + + (string.IsNullOrWhiteSpace(blockedDirectoryExceptions.ToString()) ? "(none)" : blockedDirectoryExceptions), "OK", + customFormText: "Block Protected Games"); } - private void OnSortCheckBoxChanged(object sender, EventArgs e) => selectionTreeView.TreeViewNodeSorter - = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName; + private void OnSortCheckBoxChanged(object sender, EventArgs e) + => selectionTreeView.TreeViewNodeSorter = sortCheckBox.Checked ? PlatformIdComparer.NodeText : PlatformIdComparer.NodeName; } #pragma warning restore IDE0058 \ No newline at end of file diff --git a/CreamInstaller/Platforms/Epic/EpicLibrary.cs b/CreamInstaller/Platforms/Epic/EpicLibrary.cs index 3ecd0f8..d6dc38b 100644 --- a/CreamInstaller/Platforms/Epic/EpicLibrary.cs +++ b/CreamInstaller/Platforms/Epic/EpicLibrary.cs @@ -17,48 +17,41 @@ internal static class EpicLibrary { get { - epicManifestsPath - ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir", - null) as string; - epicManifestsPath - ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Epic Games\EOS", "ModSdkMetadataDir", - null) as string; - epicManifestsPath - ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath", - null) as string; - epicManifestsPath - ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher", - "AppDataPath", null) as string; + epicManifestsPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Epic Games\EOS", "ModSdkMetadataDir", null) as string; + epicManifestsPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Epic Games\EOS", "ModSdkMetadataDir", null) as string; + epicManifestsPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Epic Games\EpicGamesLauncher", "AppDataPath", null) as string; + epicManifestsPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Epic Games\EpicGamesLauncher", "AppDataPath", null) as string; if (epicManifestsPath is not null && epicManifestsPath.EndsWith(@"\Data")) epicManifestsPath += @"\Manifests"; return epicManifestsPath.BeautifyPath(); } } - internal static async Task> GetExecutableDirectories( - string gameDirectory) => - await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); + internal static async Task> GetExecutableDirectories(string gameDirectory) + => await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); - internal static async Task> GetGames() => await Task.Run(() => - { - List games = new(); - string manifests = EpicManifestsPath; - if (!Directory.Exists(manifests)) return games; - foreach (string file in Directory.EnumerateFiles(manifests, "*.item")) + internal static async Task> GetGames() + => await Task.Run(() => { - if (Program.Canceled) return games; - string json = File.ReadAllText(file); - try + List games = new(); + string manifests = EpicManifestsPath; + if (!Directory.Exists(manifests)) + return games; + foreach (string file in Directory.EnumerateFiles(manifests, "*.item")) { - Manifest manifest = JsonSerializer.Deserialize(json); - if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId - && !games.Any(g => g.CatalogItemId == manifest.CatalogItemId - && g.InstallLocation == manifest.InstallLocation)) - games.Add(manifest); + if (Program.Canceled) + return games; + string json = File.ReadAllText(file); + try + { + Manifest manifest = JsonSerializer.Deserialize(json); + if (manifest is not null && manifest.CatalogItemId == manifest.MainGameCatalogItemId && !games.Any(g + => g.CatalogItemId == manifest.CatalogItemId && g.InstallLocation == manifest.InstallLocation)) + games.Add(manifest); + } + catch { } + ; } - catch { } - ; - } - return games; - }); + return games; + }); } \ No newline at end of file diff --git a/CreamInstaller/Platforms/Epic/EpicStore.cs b/CreamInstaller/Platforms/Epic/EpicStore.cs index 983e1d8..47b82da 100644 --- a/CreamInstaller/Platforms/Epic/EpicStore.cs +++ b/CreamInstaller/Platforms/Epic/EpicStore.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web; using CreamInstaller.Platforms.Epic.GraphQL; @@ -23,8 +22,7 @@ internal static class EpicStore private const int COOLDOWN_ENTITLEMENT = 600; - internal static async Task> - QueryEntitlements(string categoryNamespace) + internal static async Task> QueryEntitlements(string categoryNamespace) { List<(string id, string name, string product, string icon, string developer)> dlcIds = new(); string cacheFile = ProgramData.AppInfoPath + @$"\{categoryNamespace}.json"; @@ -40,7 +38,6 @@ internal static class EpicStore catch { } } else if (cachedExists) - { try { response = JsonConvert.DeserializeObject(await File.ReadAllTextAsync(cacheFile)); @@ -49,16 +46,13 @@ internal static class EpicStore { File.Delete(cacheFile); } - } if (response is null) return dlcIds; List searchStore = new(response.Data.Catalog.SearchStore.Elements); foreach (Element element in searchStore) { string title = element.Title; - string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() - ? element.CatalogNs.Mappings.First().PageSlug - : null; + string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null; string icon = null; for (int i = 0; i < element.KeyImages?.Length; i++) { @@ -76,9 +70,7 @@ internal static class EpicStore foreach (Element element in catalogOffers) { string title = element.Title; - string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() - ? element.CatalogNs.Mappings.First().PageSlug - : null; + string product = element.CatalogNs is not null && element.CatalogNs.Mappings.Any() ? element.CatalogNs.Mappings.First().PageSlug : null; string icon = null; for (int i = 0; i < element.KeyImages?.Length; i++) { @@ -95,11 +87,11 @@ internal static class EpicStore return dlcIds; } - private static void Populate( - this List<(string id, string name, string product, string icon, string developer)> dlcIds, string id, - string title, string product, string icon, string developer, bool canOverwrite = false) + private static void Populate(this List<(string id, string name, string product, string icon, string developer)> dlcIds, string id, string title, + string product, string icon, string developer, bool canOverwrite = false) { - if (id == null) return; + if (id == null) + return; bool found = false; for (int i = 0; i < dlcIds.Count; i++) { @@ -113,7 +105,8 @@ internal static class EpicStore break; } } - if (!found) dlcIds.Add((id, title, product, icon, developer)); + if (!found) + dlcIds.Add((id, title, product, icon, developer)); } private static async Task QueryGraphQL(string categoryNamespace) @@ -124,11 +117,11 @@ internal static class EpicStore Request request = new(encoded); string payload = JsonConvert.SerializeObject(request); using HttpContent content = new StringContent(payload); - content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + content.Headers.ContentType = new("application/json"); HttpClient client = HttpClientManager.HttpClient; - if (client is null) return null; - HttpResponseMessage httpResponse - = await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content); + if (client is null) + return null; + HttpResponseMessage httpResponse = await client.PostAsync(new Uri("https://graphql.epicgames.com/graphql"), content); _ = httpResponse.EnsureSuccessStatusCode(); string response = await httpResponse.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(response); diff --git a/CreamInstaller/Platforms/Epic/GraphQL/Request.cs b/CreamInstaller/Platforms/Epic/GraphQL/Request.cs index d33af00..d762c67 100644 --- a/CreamInstaller/Platforms/Epic/GraphQL/Request.cs +++ b/CreamInstaller/Platforms/Epic/GraphQL/Request.cs @@ -9,10 +9,11 @@ namespace CreamInstaller.Platforms.Epic.GraphQL; internal class Request { - internal Request(string @namespace) => Vars = new Variables(@namespace); + internal Request(string @namespace) => Vars = new(@namespace); [JsonProperty(PropertyName = "query")] - private string Query => @"query searchOffers($namespace: String!) { + private string Query + => @"query searchOffers($namespace: String!) { Catalog { searchStore(category: ""*"", namespace: $namespace){ elements { diff --git a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs index 5c0f0d9..14cb6ed 100644 --- a/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs +++ b/CreamInstaller/Platforms/Paradox/ParadoxLauncher.cs @@ -27,20 +27,16 @@ internal static class ParadoxLauncher { get { - installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Paradox Interactive\Paradox Launcher v2", - "LauncherInstallation", null) as string; - installPath ??= Registry.GetValue( - @"HKEY_CURRENT_USER\Software\Wow6432Node\Paradox Interactive\Paradox Launcher v2", - "LauncherInstallation", null) as string; + installPath ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Paradox Interactive\Paradox Launcher v2", "LauncherInstallation", null) as string; + installPath + ??= Registry.GetValue(@"HKEY_CURRENT_USER\Software\Wow6432Node\Paradox Interactive\Paradox Launcher v2", "LauncherInstallation", + null) as string; return installPath.BeautifyPath(); } } - internal static async Task> GetExecutableDirectories( - string gameDirectory) => - await Task.Run(async () => await gameDirectory.GetExecutableDirectories(validFunc: path - => !Path.GetFileName(path) - .Contains("bootstrapper"))); + internal static async Task> GetExecutableDirectories(string gameDirectory) + => await Task.Run(async () => await gameDirectory.GetExecutableDirectories(validFunc: path => !Path.GetFileName(path).Contains("bootstrapper"))); private static void PopulateDlc(ProgramSelection paradoxLauncher = null) { @@ -49,26 +45,24 @@ internal static class ParadoxLauncher { paradoxLauncher.ExtraDlc.Clear(); paradoxLauncher.ExtraSelectedDlc.Clear(); - foreach (ProgramSelection selection in ProgramSelection.AllEnabled.Where( - s => s != paradoxLauncher && s.Publisher == "Paradox Interactive")) + 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)); + new ValueTuple>(selection.Id, selection.Name, + selection.AllDlc)); paradoxLauncher.ExtraSelectedDlc.Add( - new ValueTuple>( - selection.Id, selection.Name, selection.SelectedDlc)); + new ValueTuple>(selection.Id, selection.Name, + selection.SelectedDlc)); } if (!paradoxLauncher.ExtraDlc.Any()) - foreach (ProgramSelection selection in ProgramSelection.AllSafe.Where( - s => s != paradoxLauncher && s.Publisher == "Paradox Interactive")) + 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)); + new ValueTuple>(selection.Id, selection.Name, + selection.AllDlc)); paradoxLauncher.ExtraSelectedDlc.Add( - new ValueTuple>( - selection.Id, selection.Name, selection.AllDlc)); + new ValueTuple>(selection.Id, selection.Name, + selection.AllDlc)); } } } @@ -83,10 +77,9 @@ internal static class ParadoxLauncher { using DialogForm dialogForm = new(form); return dialogForm.Show(SystemIcons.Warning, - "WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!" - + - "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!", - "Ignore", "Cancel", "Paradox Launcher") != DialogResult.OK; + "WARNING: There are no scanned games with DLC that can be added to the Paradox Launcher!" + + "\n\nInstalling DLC unlockers for the Paradox Launcher alone can cause existing configurations to be deleted!", "Ignore", "Cancel", + "Paradox Launcher") != DialogResult.OK; } } return false; @@ -96,9 +89,7 @@ internal static class ParadoxLauncher { InstallForm installForm = form as InstallForm; if (!Program.IsProgramRunningDialog(form, selection)) - return form is InstallForm - ? throw new CustomMessageException("Repair failed! The launcher is currently running!") - : RepairResult.ProgramRunning; + return form is InstallForm ? throw new CustomMessageException("Repair failed! The launcher is currently running!") : RepairResult.ProgramRunning; bool smokeInstalled = false; byte[] steamOriginalSdk32 = null; byte[] steamOriginalSdk64 = null; @@ -107,40 +98,29 @@ internal static class ParadoxLauncher byte[] epicOriginalSdk64 = null; foreach (string directory in selection.DllDirectories) { - bool koaloaderInstalled = Koaloader.AutoLoadDlls - .Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) + 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 config, out _); - smokeInstalled = smokeInstalled - || File.Exists(api32_o) || File.Exists(api64_o) - || (File.Exists(config) && !koaloaderInstalled) - || (File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.Steamworks32)) - || (File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.Steamworks64)); + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out _); + smokeInstalled = smokeInstalled || File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled + || File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.Steamworks32) + || File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.Steamworks64); await SmokeAPI.Uninstall(directory, deleteConfig: false); - if (steamOriginalSdk32 is null && File.Exists(api32) - && !api32.IsResourceFile(ResourceIdentifier.Steamworks32)) + 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)) + 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) - || (File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) - || (File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64)); + screamInstalled = screamInstalled || File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled + || File.Exists(api32) && api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32) + || File.Exists(api64) && api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64); await ScreamAPI.Uninstall(directory, deleteConfig: false); - if (epicOriginalSdk32 is null && File.Exists(api32) - && !api32.IsResourceFile(ResourceIdentifier.EpicOnlineServices32)) + 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)) + if (epicOriginalSdk64 is null && File.Exists(api64) && !api64.IsResourceFile(ResourceIdentifier.EpicOnlineServices64)) epicOriginalSdk64 = await File.ReadAllBytesAsync(api64); } using DialogForm dialogForm = new(form); - if (steamOriginalSdk32 is not null || steamOriginalSdk64 is not null || epicOriginalSdk32 is not null - || epicOriginalSdk64 is not null) + if (steamOriginalSdk32 is not null || steamOriginalSdk64 is not null || epicOriginalSdk32 is not null || epicOriginalSdk64 is not null) { bool neededRepair = false; foreach (string directory in selection.DllDirectories) @@ -181,26 +161,22 @@ internal static class ParadoxLauncher if (installForm is not null) installForm.UpdateUser("Paradox Launcher successfully repaired!", LogTextBox.Success); else - _ = dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK", - customFormText: "Paradox Launcher"); + _ = dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK", customFormText: "Paradox Launcher"); return RepairResult.Success; } if (installForm is not null) installForm.UpdateUser("Paradox Launcher did not need to be repaired.", LogTextBox.Success); else - _ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK", - customFormText: "Paradox Launcher"); + _ = dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK", customFormText: "Paradox Launcher"); return RepairResult.Unnecessary; } _ = form is InstallForm - ? throw new CustomMessageException("Repair failed! " + - "An original Steamworks and/or Epic Online Services file could not be found. " - + - "You will likely have to reinstall Paradox Launcher to fix this issue.") - : dialogForm.Show(SystemIcons.Error, "Paradox Launcher repair failed!" - + "\n\nAn original Steamworks and/or Epic Online Services file could not be found." - + "\nYou will likely have to reinstall Paradox Launcher to fix this issue.", - "OK", customFormText: "Paradox Launcher"); + ? throw new CustomMessageException("Repair failed! " + "An original Steamworks and/or Epic Online Services file could not be found. " + + "You will likely have to reinstall Paradox Launcher to fix this issue.") + : dialogForm.Show(SystemIcons.Error, + "Paradox Launcher repair failed!" + "\n\nAn original Steamworks and/or Epic Online Services file could not be found." + + "\nYou will likely have to reinstall Paradox Launcher to fix this issue.", "OK", + customFormText: "Paradox Launcher"); return RepairResult.Failure; } } diff --git a/CreamInstaller/Platforms/Steam/SteamCMD.cs b/CreamInstaller/Platforms/Steam/SteamCMD.cs index 16a0628..ae89776 100644 --- a/CreamInstaller/Platforms/Steam/SteamCMD.cs +++ b/CreamInstaller/Platforms/Steam/SteamCMD.cs @@ -21,8 +21,7 @@ internal static class SteamCMD internal static readonly string FilePath = DirectoryPath + @"\steamcmd.exe"; - private static readonly ConcurrentDictionary - AttemptCount = new(); // the more app_updates, the longer SteamCMD should wait for app_info_print + private static readonly ConcurrentDictionary AttemptCount = new(); // the more app_updates, the longer SteamCMD should wait for app_info_print private static readonly int[] locks = new int[ProcessLimit]; @@ -38,84 +37,86 @@ internal static class SteamCMD internal static string DirectoryPath => ProgramData.DirectoryPath; internal static string AppInfoPath => ProgramData.AppInfoPath; - private static string GetArguments(string appId) => AttemptCount.TryGetValue(appId, out int attempts) - ? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} " - + string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit" - : $"+login anonymous +app_info_print {appId} +quit"; + private static string GetArguments(string appId) + => AttemptCount.TryGetValue(appId, out int attempts) + ? $@"@ShutdownOnFailedCommand 0 +force_install_dir {DirectoryPath} +login anonymous +app_info_print {appId} " + + string.Concat(Enumerable.Repeat("+app_update 4 ", attempts)) + "+quit" + : $"+login anonymous +app_info_print {appId} +quit"; - internal static async Task Run(string appId) => await Task.Run(() => - { - wait_for_lock: - if (Program.Canceled) return ""; - for (int i = 0; i < locks.Length; i++) + internal static async Task Run(string appId) + => await Task.Run(() => { - if (Program.Canceled) return ""; - if (Interlocked.CompareExchange(ref locks[i], 1, 0) == 0) + wait_for_lock: + if (Program.Canceled) + return ""; + for (int i = 0; i < locks.Length; i++) { - if (appId is not null) - { - AttemptCount.TryGetValue(appId, out int count); - AttemptCount[appId] = ++count; - } - if (Program.Canceled) return ""; - ProcessStartInfo processStartInfo = new() - { - FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true, - RedirectStandardError = true, UseShellExecute = false, - Arguments = appId is null ? "+quit" : GetArguments(appId), CreateNoWindow = true, - StandardInputEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8, - StandardErrorEncoding = Encoding.UTF8 - }; - Process process = Process.Start(processStartInfo); - StringBuilder output = new(); - StringBuilder appInfo = new(); - bool appInfoStarted = false; - DateTime lastOutput = DateTime.UtcNow; - while (true) + if (Program.Canceled) + return ""; + if (Interlocked.CompareExchange(ref locks[i], 1, 0) == 0) { + if (appId is not null) + { + AttemptCount.TryGetValue(appId, out int count); + AttemptCount[appId] = ++count; + } if (Program.Canceled) + return ""; + ProcessStartInfo processStartInfo = new() { - process.Kill(true); - process.Close(); - break; - } - int c = process.StandardOutput.Read(); - if (c != -1) + FileName = FilePath, RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true, + UseShellExecute = false, Arguments = appId is null ? "+quit" : GetArguments(appId), CreateNoWindow = true, + StandardInputEncoding = Encoding.UTF8, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8 + }; + Process process = Process.Start(processStartInfo); + StringBuilder output = new(); + StringBuilder appInfo = new(); + bool appInfoStarted = false; + DateTime lastOutput = DateTime.UtcNow; + while (true) { - lastOutput = DateTime.UtcNow; - char ch = (char)c; - if (ch == '{') appInfoStarted = true; - _ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch); - } - DateTime now = DateTime.UtcNow; - TimeSpan timeDiff = now - lastOutput; - if (timeDiff.TotalSeconds > 0.1) - { - process.Kill(true); - process.Close(); - if (output.ToString().Contains($"No app info for AppID {appId} found, requesting...")) - { - AttemptCount[appId]++; - processStartInfo.Arguments = GetArguments(appId); - process = Process.Start(processStartInfo); - appInfoStarted = false; - _ = output.Clear(); - _ = appInfo.Clear(); - } - else + if (Program.Canceled) { + process.Kill(true); + process.Close(); break; } + int c = process.StandardOutput.Read(); + if (c != -1) + { + lastOutput = DateTime.UtcNow; + char ch = (char)c; + if (ch == '{') + appInfoStarted = true; + _ = appInfoStarted ? appInfo.Append(ch) : output.Append(ch); + } + DateTime now = DateTime.UtcNow; + TimeSpan timeDiff = now - lastOutput; + if (timeDiff.TotalSeconds > 0.1) + { + process.Kill(true); + process.Close(); + if (output.ToString().Contains($"No app info for AppID {appId} found, requesting...")) + { + AttemptCount[appId]++; + processStartInfo.Arguments = GetArguments(appId); + process = Process.Start(processStartInfo); + appInfoStarted = false; + _ = output.Clear(); + _ = appInfo.Clear(); + } + else + break; + } } + _ = Interlocked.Decrement(ref locks[i]); + return appInfo.ToString(); } - _ = Interlocked.Decrement(ref locks[i]); - return appInfo.ToString(); + Thread.Sleep(200); } Thread.Sleep(200); - } - Thread.Sleep(200); - goto wait_for_lock; - }); + goto wait_for_lock; + }); internal static async Task Setup(IProgress progress) { @@ -123,21 +124,20 @@ internal static class SteamCMD if (!File.Exists(FilePath)) { HttpClient httpClient = HttpClientManager.HttpClient; - if (httpClient is null) return; - byte[] file = await httpClient.GetByteArrayAsync( - new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip")); + if (httpClient is null) + return; + byte[] file = await httpClient.GetByteArrayAsync(new Uri("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip")); file.Write(ArchivePath); ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath); File.Delete(ArchivePath); } if (!File.Exists(DllPath)) { - FileSystemWatcher watcher = new(DirectoryPath) - { - Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true - }; - if (File.Exists(DllPath)) progress.Report(-15); // update (not used at the moment) - else progress.Report(-1660); // install + FileSystemWatcher watcher = new(DirectoryPath) { Filter = "*", IncludeSubdirectories = true, EnableRaisingEvents = true }; + if (File.Exists(DllPath)) + progress.Report(-15); // update (not used at the moment) + else + progress.Report(-1660); // install int cur = 0; progress.Report(cur); watcher.Changed += (sender, e) => progress.Report(++cur); @@ -146,45 +146,47 @@ internal static class SteamCMD } } - internal static async Task Cleanup() => await Task.Run(async () => - { - if (!Directory.Exists(DirectoryPath)) return; - await Kill(); - try + internal static async Task Cleanup() + => await Task.Run(async () => { - if (Directory.Exists(ConfigPath)) - foreach (string file in Directory.EnumerateFiles(ConfigPath, "*.tmp")) + if (!Directory.Exists(DirectoryPath)) + return; + await Kill(); + try + { + if (Directory.Exists(ConfigPath)) + foreach (string file in Directory.EnumerateFiles(ConfigPath, "*.tmp")) + File.Delete(file); + foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.old")) File.Delete(file); - foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.old")) - File.Delete(file); - foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.delete")) - File.Delete(file); - foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.crash")) - File.Delete(file); - foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.ntfs_transaction_failed")) - File.Delete(file); - if (Directory.Exists(AppCachePath)) - Directory.Delete(AppCachePath, - true); // this is definitely needed, so SteamCMD gets the latest information for us - if (Directory.Exists(DumpsPath)) - Directory.Delete(DumpsPath, true); - if (Directory.Exists(LogsPath)) - Directory.Delete(LogsPath, true); - if (Directory.Exists(SteamAppsPath)) - Directory.Delete(SteamAppsPath, true); // this is just a useless folder created from +app_update 4 - } - catch { } - }); + foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.delete")) + File.Delete(file); + foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.crash")) + File.Delete(file); + foreach (string file in Directory.EnumerateFiles(DirectoryPath, "*.ntfs_transaction_failed")) + File.Delete(file); + if (Directory.Exists(AppCachePath)) + Directory.Delete(AppCachePath, true); // this is definitely needed, so SteamCMD gets the latest information for us + if (Directory.Exists(DumpsPath)) + Directory.Delete(DumpsPath, true); + if (Directory.Exists(LogsPath)) + Directory.Delete(LogsPath, true); + if (Directory.Exists(SteamAppsPath)) + Directory.Delete(SteamAppsPath, true); // this is just a useless folder created from +app_update 4 + } + catch { } + }); internal static async Task GetAppInfo(string appId, string branch = "public", int buildId = 0) { - if (Program.Canceled) return null; + if (Program.Canceled) + return null; string output; string appUpdateFile = $@"{AppInfoPath}\{appId}.vdf"; restart: - if (Program.Canceled) return null; + if (Program.Canceled) + return null; if (File.Exists(appUpdateFile)) - { try { output = await File.ReadAllTextAsync(appUpdateFile, Encoding.UTF8); @@ -193,7 +195,6 @@ internal static class SteamCMD { goto restart; } - } else { output = await Run(appId) ?? ""; @@ -213,74 +214,75 @@ internal static class SteamCMD } } else - { goto restart; - } } - if (Program.Canceled) return null; + if (Program.Canceled) + return null; if (!ValveDataFile.TryDeserialize(output, out VProperty appInfo) || appInfo.Value is VValue) { File.Delete(appUpdateFile); goto restart; } - if (appInfo is null || appInfo.Value?.Children()?.ToList()?.Count == 0) return appInfo; + if (appInfo is null || appInfo.Value?.Children()?.ToList()?.Count == 0) + return appInfo; VToken type = appInfo.Value?.GetChild("common")?.GetChild("type"); if (type is not null && type.ToString() != "Game") return appInfo; - string buildid = appInfo.Value?.GetChild("depots")?.GetChild("branches")?.GetChild(branch) - ?.GetChild("buildid")?.ToString(); - if (buildid is null && type is not null) return appInfo; + string buildid = appInfo.Value?.GetChild("depots")?.GetChild("branches")?.GetChild(branch)?.GetChild("buildid")?.ToString(); + if (buildid is null && type is not null) + return appInfo; if (type is not null && (!int.TryParse(buildid, out int gamebuildId) || gamebuildId >= buildId)) return appInfo; List dlcAppIds = await ParseDlcAppIds(appInfo); foreach (string dlcAppUpdateFile in dlcAppIds.Select(id => $@"{AppInfoPath}\{id}.vdf")) if (File.Exists(dlcAppUpdateFile)) File.Delete(dlcAppUpdateFile); - if (File.Exists(appUpdateFile)) File.Delete(appUpdateFile); + if (File.Exists(appUpdateFile)) + File.Delete(appUpdateFile); goto restart; } - internal static async Task> ParseDlcAppIds(VProperty appInfo) => await Task.Run(() => - { - List dlcIds = new(); - if (Program.Canceled || appInfo is null) return dlcIds; - VToken extended = appInfo.Value.GetChild("extended"); - if (extended is not null) - foreach (VToken vToken in extended.Where(p => p is VProperty { Key: "listofdlc" })) + internal static async Task> ParseDlcAppIds(VProperty appInfo) + => await Task.Run(() => + { + List dlcIds = new(); + if (Program.Canceled || appInfo is null) + return dlcIds; + VToken extended = appInfo.Value.GetChild("extended"); + if (extended is not null) + foreach (VToken vToken in extended.Where(p => p is VProperty { Key: "listofdlc" })) + { + VProperty property = (VProperty)vToken; + foreach (string id in property.Value.ToString().Split(",")) + if (int.TryParse(id, out int appId) && appId > 0 && !dlcIds.Contains("" + appId)) + dlcIds.Add("" + appId); + } + VToken depots = appInfo.Value.GetChild("depots"); + if (depots is null) + return dlcIds; + foreach (VToken vToken in depots.Where(p => p is VProperty property && int.TryParse(property.Key, out int _))) { VProperty property = (VProperty)vToken; - foreach (string id in property.Value.ToString().Split(",")) - if (int.TryParse(id, out int appId) && appId > 0 && !dlcIds.Contains("" + appId)) - dlcIds.Add("" + appId); + if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0 && !dlcIds.Contains("" + appId)) + dlcIds.Add("" + appId); } - VToken depots = appInfo.Value.GetChild("depots"); - if (depots is null) return dlcIds; - foreach (VToken vToken in depots.Where(p => p is VProperty property && int.TryParse(property.Key, out int _))) - { - VProperty property = (VProperty)vToken; - if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0 - && !dlcIds.Contains("" + appId)) - dlcIds.Add("" + appId); - } - return dlcIds; - }); + }); private static async Task Kill() { - List tasks = Process.GetProcessesByName("steamcmd") - .Select(process => Task.Run(() => - { - try - { - process.Kill(true); - process.WaitForExit(); - process.Close(); - } - catch { } - })) - .ToList(); - foreach (Task task in tasks) await task; + List tasks = Process.GetProcessesByName("steamcmd").Select(process => Task.Run(() => + { + try + { + process.Kill(true); + process.WaitForExit(); + process.Close(); + } + catch { } + })).ToList(); + foreach (Task task in tasks) + await task; } internal static void Dispose() diff --git a/CreamInstaller/Platforms/Steam/SteamLibrary.cs b/CreamInstaller/Platforms/Steam/SteamLibrary.cs index f59fe8d..d50c205 100644 --- a/CreamInstaller/Platforms/Steam/SteamLibrary.cs +++ b/CreamInstaller/Platforms/Steam/SteamLibrary.cs @@ -18,93 +18,96 @@ internal static class SteamLibrary { get { - installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", - null) as string; - installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam", "InstallPath", - null) as string; + installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null) as string; + installPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Valve\Steam", "InstallPath", null) as string; return installPath.BeautifyPath(); } } - internal static async Task> GetExecutableDirectories( - string gameDirectory) => - await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); + internal static async Task> GetExecutableDirectories(string gameDirectory) + => await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); - internal static async Task> - GetGames() => await Task.Run(async () => - { - List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new(); - List gameLibraryDirectories = await GetLibraryDirectories(); - foreach (string libraryDirectory in gameLibraryDirectories) + internal static async Task> GetGames() + => await Task.Run(async () => { - if (Program.Canceled) return games; - foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in - (await GetGamesFromLibraryDirectory(libraryDirectory)) - .Where(game => !games.Any(_game => _game.appId == game.appId - && _game.gameDirectory == game.gameDirectory))) - games.Add(game); - } - return games; - }); - - internal static async Task> - GetGamesFromLibraryDirectory(string libraryDirectory) => await Task.Run(() => - { - List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new(); - if (Program.Canceled || !Directory.Exists(libraryDirectory)) return games; - foreach (string file in Directory.EnumerateFiles(libraryDirectory, "*.acf")) - { - if (Program.Canceled) return games; - if (ValveDataFile.TryDeserialize(File.ReadAllText(file, Encoding.UTF8), out VProperty result)) + List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new(); + List gameLibraryDirectories = await GetLibraryDirectories(); + foreach (string libraryDirectory in gameLibraryDirectories) { - string appId = result.Value.GetChild("appid")?.ToString(); - string installdir = result.Value.GetChild("installdir")?.ToString(); - string name = result.Value.GetChild("name")?.ToString(); - string buildId = result.Value.GetChild("buildid")?.ToString(); - if (string.IsNullOrWhiteSpace(appId) - || string.IsNullOrWhiteSpace(installdir) - || string.IsNullOrWhiteSpace(name) - || string.IsNullOrWhiteSpace(buildId)) - continue; - string gameDirectory = (libraryDirectory + @"\common\" + installdir).BeautifyPath(); - if (games.Any(g => g.appId == appId && g.gameDirectory == gameDirectory)) continue; - if (!int.TryParse(appId, out int appIdInt)) continue; - if (!int.TryParse(buildId, out int buildIdInt)) continue; - string branch = result.Value.GetChild("UserConfig")?.GetChild("betakey")?.ToString(); - if (string.IsNullOrWhiteSpace(branch)) branch = "public"; - games.Add((appId, name, branch, buildIdInt, gameDirectory)); + if (Program.Canceled) + return games; + foreach ((string appId, string name, string branch, int buildId, string gameDirectory) game in + (await GetGamesFromLibraryDirectory(libraryDirectory)).Where(game + => !games.Any(_game => _game.appId == game.appId && _game.gameDirectory == game.gameDirectory))) + games.Add(game); } - } - return games; - }); + return games; + }); - internal static async Task> GetLibraryDirectories() => await Task.Run(() => - { - List gameDirectories = new(); - if (Program.Canceled) return gameDirectories; - string steamInstallPath = InstallPath; - if (steamInstallPath != null && Directory.Exists(steamInstallPath)) + internal static async Task> + GetGamesFromLibraryDirectory(string libraryDirectory) + => await Task.Run(() => { - string libraryFolder = steamInstallPath + @"\steamapps"; - if (Directory.Exists(libraryFolder)) + List<(string appId, string name, string branch, int buildId, string gameDirectory)> games = new(); + if (Program.Canceled || !Directory.Exists(libraryDirectory)) + return games; + foreach (string file in Directory.EnumerateFiles(libraryDirectory, "*.acf")) { - gameDirectories.Add(libraryFolder); - string libraryFolders = libraryFolder + @"\libraryfolders.vdf"; - if (File.Exists(libraryFolders) - && ValveDataFile.TryDeserialize(File.ReadAllText(libraryFolders, Encoding.UTF8), out VProperty result)) + if (Program.Canceled) + return games; + if (ValveDataFile.TryDeserialize(File.ReadAllText(file, Encoding.UTF8), out VProperty result)) + { + string appId = result.Value.GetChild("appid")?.ToString(); + string installdir = result.Value.GetChild("installdir")?.ToString(); + string name = result.Value.GetChild("name")?.ToString(); + string buildId = result.Value.GetChild("buildid")?.ToString(); + if (string.IsNullOrWhiteSpace(appId) || string.IsNullOrWhiteSpace(installdir) || string.IsNullOrWhiteSpace(name) + || string.IsNullOrWhiteSpace(buildId)) + continue; + string gameDirectory = (libraryDirectory + @"\common\" + installdir).BeautifyPath(); + if (games.Any(g => g.appId == appId && g.gameDirectory == gameDirectory)) + continue; + if (!int.TryParse(appId, out int appIdInt)) + continue; + if (!int.TryParse(buildId, out int buildIdInt)) + continue; + string branch = result.Value.GetChild("UserConfig")?.GetChild("betakey")?.ToString(); + if (string.IsNullOrWhiteSpace(branch)) + branch = "public"; + games.Add((appId, name, branch, buildIdInt, gameDirectory)); + } + } + return games; + }); + + internal static async Task> GetLibraryDirectories() + => await Task.Run(() => + { + List gameDirectories = new(); + if (Program.Canceled) + return gameDirectories; + string steamInstallPath = InstallPath; + if (steamInstallPath != null && Directory.Exists(steamInstallPath)) + { + string libraryFolder = steamInstallPath + @"\steamapps"; + if (Directory.Exists(libraryFolder)) + { + gameDirectories.Add(libraryFolder); + string libraryFolders = libraryFolder + @"\libraryfolders.vdf"; + if (File.Exists(libraryFolders) && ValveDataFile.TryDeserialize(File.ReadAllText(libraryFolders, Encoding.UTF8), out VProperty result)) #pragma warning disable IDE0220 // Add explicit cast - foreach (VProperty property in result.Value.Where( - p => p is VProperty && int.TryParse((p as VProperty).Key, out int _))) - { - string path = property.Value.GetChild("path")?.ToString(); - if (string.IsNullOrWhiteSpace(path)) continue; - path += @"\steamapps"; - if (Directory.Exists(path) && !gameDirectories.Contains(path)) - gameDirectories.Add(path); - } + foreach (VProperty property in result.Value.Where(p => p is VProperty && int.TryParse((p as VProperty).Key, out int _))) + { + string path = property.Value.GetChild("path")?.ToString(); + if (string.IsNullOrWhiteSpace(path)) + continue; + path += @"\steamapps"; + if (Directory.Exists(path) && !gameDirectories.Contains(path)) + gameDirectories.Add(path); + } #pragma warning restore IDE0220 // Add explicit cast + } } - } - return gameDirectories; - }); + return gameDirectories; + }); } diff --git a/CreamInstaller/Platforms/Steam/SteamStore.cs b/CreamInstaller/Platforms/Steam/SteamStore.cs index b2dee78..46e64cc 100644 --- a/CreamInstaller/Platforms/Steam/SteamStore.cs +++ b/CreamInstaller/Platforms/Steam/SteamStore.cs @@ -18,23 +18,25 @@ internal static class SteamStore private const int COOLDOWN_GAME = 600; private const int COOLDOWN_DLC = 1200; - internal static async Task> ParseDlcAppIds(AppData appData) => await Task.Run(() => - { - List dlcIds = new(); - if (appData.dlc is null) return dlcIds; - dlcIds.AddRange(from appId in appData.dlc where appId > 0 select appId.ToString()); - return dlcIds; - }); + internal static async Task> ParseDlcAppIds(AppData appData) + => await Task.Run(() => + { + List dlcIds = new(); + if (appData.dlc is null) + return dlcIds; + dlcIds.AddRange(from appId in appData.dlc where appId > 0 select appId.ToString()); + return dlcIds; + }); internal static async Task QueryStoreAPI(string appId, bool isDlc = false, int attempts = 0) { - if (Program.Canceled) return null; + if (Program.Canceled) + return null; string cacheFile = ProgramData.AppInfoPath + @$"\{appId}.json"; bool cachedExists = File.Exists(cacheFile); if (!cachedExists || ProgramData.CheckCooldown(appId, isDlc ? COOLDOWN_DLC : COOLDOWN_GAME)) { - string response - = await HttpClientManager.EnsureGet($"https://store.steampowered.com/api/appdetails?appids={appId}"); + string response = await HttpClientManager.EnsureGet($"https://store.steampowered.com/api/appdetails?appids={appId}"); if (response is not null) { IDictionary apps = (IDictionary)JsonConvert.DeserializeObject(response); @@ -60,8 +62,7 @@ internal static class SteamStore { try { - await File.WriteAllTextAsync( - cacheFile, JsonConvert.SerializeObject(data, Formatting.Indented)); + await File.WriteAllTextAsync(cacheFile, JsonConvert.SerializeObject(data, Formatting.Indented)); } catch #if DEBUG @@ -76,16 +77,13 @@ internal static class SteamStore return data; } #if DEBUG - DebugForm.Current.Log( - $"Response data null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}"); + DebugForm.Current.Log($"Response data null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}"); #endif } #if DEBUG else - { DebugForm.Current.Log( $"Response details null for appid {appId}{(isDlc ? " (DLC)" : "")}: {app.Value.ToString(Formatting.None)}"); - } #endif } catch @@ -99,7 +97,8 @@ internal static class SteamStore { } #endif #if DEBUG - else DebugForm.Current.Log("Response deserialization null for appid " + appId); + else + DebugForm.Current.Log("Response deserialization null for appid " + appId); #endif } else diff --git a/CreamInstaller/Platforms/Ubisoft/UbisoftLibrary.cs b/CreamInstaller/Platforms/Ubisoft/UbisoftLibrary.cs index 6b59b0a..b8b6a7c 100644 --- a/CreamInstaller/Platforms/Ubisoft/UbisoftLibrary.cs +++ b/CreamInstaller/Platforms/Ubisoft/UbisoftLibrary.cs @@ -22,16 +22,16 @@ internal static class UbisoftLibrary } } - internal static async Task> GetExecutableDirectories( - string gameDirectory) => - await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); + internal static async Task> GetExecutableDirectories(string gameDirectory) + => await Task.Run(async () => await gameDirectory.GetExecutableDirectories(true)); - internal static async Task> GetGames() => await Task.Run( - () => + internal static async Task> GetGames() + => await Task.Run(() => { List<(string gameId, string name, string gameDirectory)> games = new(); RegistryKey installsKey = InstallsKey; - if (installsKey is null) return games; + if (installsKey is null) + return games; foreach (string gameId in installsKey.GetSubKeyNames()) { RegistryKey installKey = installsKey.OpenSubKey(gameId); diff --git a/CreamInstaller/Program.cs b/CreamInstaller/Program.cs index cab718c..340d049 100644 --- a/CreamInstaller/Program.cs +++ b/CreamInstaller/Program.cs @@ -42,8 +42,10 @@ internal static class Program internal static bool IsGameBlocked(string name, string directory = null) { - if (!BlockProtectedGames) return false; - if (ProtectedGames.Contains(name)) return true; + if (!BlockProtectedGames) + return false; + if (ProtectedGames.Contains(name)) + return true; if (directory is not null && !ProtectedGameDirectoryExceptions.Contains(name)) foreach (string path in ProtectedGameDirectories) if (Directory.Exists(directory + path)) @@ -56,16 +58,12 @@ internal static class Program if (selection.AreDllsLocked) { using DialogForm dialogForm = new(form); - if (dialogForm.Show(SystemIcons.Error, - $"ERROR: {selection.Name} is currently running!" + - "\n\nPlease close the program/game to continue . . . ", - "Retry", "Cancel") == DialogResult.OK) + if (dialogForm.Show(SystemIcons.Error, $"ERROR: {selection.Name} is currently running!" + "\n\nPlease close the program/game to continue . . . ", + "Retry", "Cancel") == DialogResult.OK) return IsProgramRunningDialog(form, selection); } else - { return true; - } return false; } @@ -81,8 +79,7 @@ internal static class Program Application.ApplicationExit += OnApplicationExit; Application.ThreadException += (s, e) => e.Exception?.HandleFatalException(); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - AppDomain.CurrentDomain.UnhandledException += (s, e) - => (e.ExceptionObject as Exception)?.HandleFatalException(); + AppDomain.CurrentDomain.UnhandledException += (s, e) => (e.ExceptionObject as Exception)?.HandleFatalException(); retry: try { @@ -95,7 +92,8 @@ internal static class Program } catch (Exception e) { - if (e.HandleException()) goto retry; + if (e.HandleException()) + goto retry; Application.Exit(); return; } diff --git a/CreamInstaller/ProgramSelection.cs b/CreamInstaller/ProgramSelection.cs index 86507b0..d04e0fb 100644 --- a/CreamInstaller/ProgramSelection.cs +++ b/CreamInstaller/ProgramSelection.cs @@ -25,17 +25,14 @@ internal class ProgramSelection internal static readonly List All = new(); - internal readonly SortedList AllDlc - = new(PlatformIdComparer.String); + internal readonly SortedList AllDlc = new(PlatformIdComparer.String); - internal readonly List<(string id, string name, SortedList dlc)> - ExtraDlc = new(); // for Paradox Launcher + internal readonly List<(string id, string name, SortedList dlc)> ExtraDlc = new(); // for Paradox Launcher internal readonly List<(string id, string name, SortedList dlc)> ExtraSelectedDlc = new(); // for Paradox Launcher - internal readonly SortedList SelectedDlc - = new(PlatformIdComparer.String); + internal readonly SortedList SelectedDlc = new(PlatformIdComparer.String); internal List DllDirectories; internal bool Enabled; @@ -67,54 +64,31 @@ internal class ProgramSelection { if (Platform is Platform.Steam or Platform.Paradox) { - directory.GetCreamApiComponents(out string api32, out string api32_o, out string api64, - out string api64_o, out string config); - if (api32.IsFilePathLocked() - || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() - || api64_o.IsFilePathLocked() + directory.GetCreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + 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 config, - out string cache); - if (api32.IsFilePathLocked() - || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() - || api64_o.IsFilePathLocked() - || config.IsFilePathLocked() - || cache.IsFilePathLocked()) + directory.GetSmokeApiComponents(out api32, out api32_o, out api64, out api64_o, out config, out string cache); + if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() + || config.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); - if (api32.IsFilePathLocked() - || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() - || api64_o.IsFilePathLocked() + directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.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); - if (api32.IsFilePathLocked() - || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() - || api64_o.IsFilePathLocked() + directory.GetUplayR1Components(out string api32, out string api32_o, out string api64, out string api64_o, out string config); + if (api32.IsFilePathLocked() || api32_o.IsFilePathLocked() || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.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); - if (old_api32.IsFilePathLocked() - || old_api64.IsFilePathLocked() - || api32.IsFilePathLocked() - || api32_o.IsFilePathLocked() - || api64.IsFilePathLocked() - || api64_o.IsFilePathLocked() - || config.IsFilePathLocked()) + directory.GetUplayR2Components(out string old_api32, out string old_api64, out api32, out api32_o, out api64, out api64_o, out config); + if (old_api32.IsFilePathLocked() || old_api64.IsFilePathLocked() || api32.IsFilePathLocked() || api32_o.IsFilePathLocked() + || api64.IsFilePathLocked() || api64_o.IsFilePathLocked() || config.IsFilePathLocked()) return true; } } @@ -128,8 +102,10 @@ internal class ProgramSelection private void Toggle(string dlcAppId, (DlcType type, string name, string icon) dlcApp, bool enabled) { - if (enabled) SelectedDlc[dlcAppId] = dlcApp; - else _ = SelectedDlc.Remove(dlcAppId); + if (enabled) + SelectedDlc[dlcAppId] = dlcApp; + else + _ = SelectedDlc.Remove(dlcAppId); } internal void ToggleDlc(string dlcId, bool enabled) @@ -160,7 +136,8 @@ internal class ProgramSelection return; } _ = DllDirectories.RemoveAll(directory => !Directory.Exists(directory)); - if (!DllDirectories.Any()) _ = All.Remove(this); + if (!DllDirectories.Any()) + _ = All.Remove(this); } internal void Validate(List<(Platform platform, string id, string name)> programsToScan) @@ -178,15 +155,12 @@ internal class ProgramSelection internal static void ValidateAll(List<(Platform platform, string id, string name)> programsToScan) => AllSafe.ForEach(selection => selection.Validate(programsToScan)); - internal static ProgramSelection FromPlatformId(Platform platform, string gameId) - => AllSafe.Find(s => s.Platform == platform && s.Id == gameId); + internal static ProgramSelection FromPlatformId(Platform platform, string gameId) => AllSafe.Find(s => s.Platform == platform && s.Id == gameId); - internal static (string gameId, (DlcType type, string name, string icon) app)? GetDlcFromPlatformId( - Platform platform, string dlcId) + internal static (string gameId, (DlcType type, string name, string icon) app)? GetDlcFromPlatformId(Platform platform, string dlcId) { foreach (ProgramSelection selection in AllSafe.Where(s => s.Platform == platform)) - foreach (KeyValuePair pair in selection.AllDlc.Where( - p => p.Key == dlcId)) + foreach (KeyValuePair pair in selection.AllDlc.Where(p => p.Key == dlcId)) return (selection.Id, pair.Value); return null; } diff --git a/CreamInstaller/Resources/Koaloader.cs b/CreamInstaller/Resources/Koaloader.cs index b931656..492bd98 100644 --- a/CreamInstaller/Resources/Koaloader.cs +++ b/CreamInstaller/Resources/Koaloader.cs @@ -14,27 +14,22 @@ internal static class Koaloader { internal static readonly List<(string unlocker, string dll)> AutoLoadDlls = new() { - ("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"), - ("Lyptus", "Lyptus.dll"), ("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"), - ("SmokeAPI", "SmokeAPI.dll"), ("SmokeAPI", "SmokeAPI32.dll"), ("SmokeAPI", "SmokeAPI64.dll"), - ("ScreamAPI", "ScreamAPI.dll"), ("ScreamAPI", "ScreamAPI32.dll"), ("ScreamAPI", "ScreamAPI64.dll"), - ("Uplay R1 Unlocker", "UplayR1Unlocker.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker32.dll"), - ("Uplay R1 Unlocker", "UplayR1Unlocker64.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker.dll"), - ("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker64.dll") + ("Koaloader", "Unlocker.dll"), ("Koaloader", "Unlocker32.dll"), ("Koaloader", "Unlocker64.dll"), ("Lyptus", "Lyptus.dll"), + ("Lyptus", "Lyptus32.dll"), ("Lyptus", "Lyptus64.dll"), ("SmokeAPI", "SmokeAPI.dll"), ("SmokeAPI", "SmokeAPI32.dll"), + ("SmokeAPI", "SmokeAPI64.dll"), ("ScreamAPI", "ScreamAPI.dll"), ("ScreamAPI", "ScreamAPI32.dll"), ("ScreamAPI", "ScreamAPI64.dll"), + ("Uplay R1 Unlocker", "UplayR1Unlocker.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker32.dll"), ("Uplay R1 Unlocker", "UplayR1Unlocker64.dll"), + ("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 config - ) + internal static void GetKoaloaderComponents(this string directory, out List proxies, out string config) { - proxies = new List(); + proxies = new(); foreach (string proxy in EmbeddedResources.Select(proxy => { proxy = proxy[(proxy.IndexOf('.') + 1)..]; return proxy[(proxy.IndexOf('.') + 1)..]; - })) proxies.Add(directory + @"\" + proxy); + })) + proxies.Add(directory + @"\" + proxy); config = directory + @"\Koaloader.json"; } @@ -51,8 +46,7 @@ internal static class Koaloader } } - internal static void GetProxyInfoFromIdentifier(this string resourceIdentifier, out string proxyName, - out BinaryType binaryType) + internal static void GetProxyInfoFromIdentifier(this string resourceIdentifier, out string proxyName, out BinaryType binaryType) { string baseIdentifier = resourceIdentifier[(resourceIdentifier.IndexOf('.') + 1)..]; baseIdentifier = baseIdentifier[..baseIdentifier.IndexOf('.')]; @@ -83,13 +77,12 @@ internal static class Koaloader else if (File.Exists(config)) { File.Delete(config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - internal static void WriteConfig(StreamWriter writer, SortedList targets, - SortedList modules, InstallForm installForm = null) + internal static void WriteConfig(StreamWriter writer, SortedList targets, SortedList modules, + InstallForm installForm = null) { writer.WriteLine("{"); writer.WriteLine(" \"logging\": false,"); @@ -108,9 +101,7 @@ internal static class Koaloader writer.WriteLine(" ]"); } else - { writer.WriteLine(" \"targets\": []"); - } if (modules.Any()) { writer.WriteLine(" \"modules\": ["); @@ -127,235 +118,216 @@ internal static class Koaloader writer.WriteLine(" ]"); } else - { writer.WriteLine(" \"modules\": []"); - } writer.WriteLine("}"); } - 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 config); - foreach (string proxyPath in proxies.Where( - proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) + internal static async Task Uninstall(string directory, string rootDirectory = null, InstallForm installForm = null, bool deleteConfig = true) + => await Task.Run(async () => { - File.Delete(proxyPath); - installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false); - } - foreach ((string unlocker, string path) in AutoLoadDlls - .Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) - .Where(pair => File.Exists(pair.path) && pair.path.IsResourceFile())) - { - File.Delete(path); - installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false); - } - if (deleteConfig && File.Exists(config)) - { - File.Delete(config); - installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); - } - await SmokeAPI.Uninstall(directory, installForm, deleteConfig); - await ScreamAPI.Uninstall(directory, installForm, deleteConfig); - await UplayR1.Uninstall(directory, installForm, deleteConfig); - await UplayR2.Uninstall(directory, installForm, deleteConfig); - if (rootDirectory is not null && directory != rootDirectory) - await Uninstall(rootDirectory, null, installForm, deleteConfig); - }); + directory.GetKoaloaderComponents(out List proxies, out string config); + foreach (string proxyPath in proxies.Where(proxyPath => File.Exists(proxyPath) && proxyPath.IsResourceFile(ResourceIdentifier.Koaloader))) + { + File.Delete(proxyPath); + installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(proxyPath)}", LogTextBox.Action, false); + } + foreach ((string unlocker, string path) in AutoLoadDlls.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) + .Where(pair => File.Exists(pair.path) && pair.path.IsResourceFile())) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted {unlocker}: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + if (deleteConfig && File.Exists(config)) + { + File.Delete(config); + installForm?.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); + } + await SmokeAPI.Uninstall(directory, installForm, deleteConfig); + await ScreamAPI.Uninstall(directory, installForm, deleteConfig); + await UplayR1.Uninstall(directory, installForm, deleteConfig); + await UplayR2.Uninstall(directory, installForm, deleteConfig); + if (rootDirectory is not null && directory != rootDirectory) + await Uninstall(rootDirectory, null, installForm, deleteConfig); + }); - internal static async Task Install(string directory, BinaryType binaryType, ProgramSelection selection, - string rootDirectory = null, InstallForm installForm = null, - bool generateConfig = true) => await Task.Run(() => - { - directory.GetKoaloaderComponents(out List proxies, out string config); - 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))) + internal static async Task Install(string directory, BinaryType binaryType, ProgramSelection selection, string rootDirectory = null, + InstallForm installForm = null, bool generateConfig = true) + => await Task.Run(() => { - File.Delete(_path); - installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false); - } - if (File.Exists(path) && !path.IsResourceFile(ResourceIdentifier.Koaloader)) - throw new CustomMessageException("A non-Koaloader DLL named " + proxy - + ".dll already exists in this directory!"); - path.WriteProxy(proxy, binaryType); - installForm?.UpdateUser( - $"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}", - LogTextBox.Action, false); - bool bit32 = false, bit64 = false; - foreach (string executable in Directory.EnumerateFiles(directory, "*.exe")) - if (executable.TryGetFileBinaryType(out BinaryType binaryType)) + directory.GetKoaloaderComponents(out List proxies, out string config); + 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))) { - if (binaryType == BinaryType.BIT32) - bit32 = true; - else if (binaryType == BinaryType.BIT64) - bit64 = true; - if (bit32 && bit64) - break; + File.Delete(_path); + installForm?.UpdateUser($"Deleted Koaloader: {Path.GetFileName(_path)}", LogTextBox.Action, false); } - if (selection.Platform is Platform.Steam or Platform.Paradox) - { - if (bit32) - { - path = directory + @"\SmokeAPI32.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (File.Exists(path) && !path.IsResourceFile(ResourceIdentifier.Koaloader)) + throw new CustomMessageException("A non-Koaloader DLL named " + proxy + ".dll already exists in this directory!"); + path.WriteProxy(proxy, binaryType); + installForm?.UpdateUser($"Wrote {(binaryType == BinaryType.BIT32 ? "32-bit" : "64-bit")} Koaloader: {Path.GetFileName(path)}", LogTextBox.Action, + false); + bool bit32 = false, bit64 = false; + foreach (string executable in Directory.EnumerateFiles(directory, "*.exe")) + if (executable.TryGetFileBinaryType(out BinaryType binaryType)) { - if (File.Exists(path)) - { - File.Delete(path); - installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - path = rootDirectory + @"\SmokeAPI32.dll"; + if (binaryType == BinaryType.BIT32) + bit32 = true; + else if (binaryType == BinaryType.BIT64) + bit64 = true; + if (bit32 && bit64) + break; } - "SmokeAPI.steam_api.dll".Write(path); - installForm?.UpdateUser( - $"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - if (bit64) + if (selection.Platform is Platform.Steam or Platform.Paradox) { - path = directory + @"\SmokeAPI64.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (bit32) { - if (File.Exists(path)) + path = directory + @"\SmokeAPI32.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\SmokeAPI32.dll"; } - path = rootDirectory + @"\SmokeAPI64.dll"; + "SmokeAPI.steam_api.dll".Write(path); + installForm?.UpdateUser( + $"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "SmokeAPI.steam_api64.dll".Write(path); - installForm?.UpdateUser( - $"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (bit64) + { + path = directory + @"\SmokeAPI64.dll"; + if (rootDirectory is not null && directory != rootDirectory) + { + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted SmokeAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\SmokeAPI64.dll"; + } + "SmokeAPI.steam_api64.dll".Write(path); + installForm?.UpdateUser( + $"Wrote SmokeAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); + } + SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm); } - SmokeAPI.CheckConfig(rootDirectory ?? directory, selection, installForm); - } - if (selection.Platform is Platform.Epic or Platform.Paradox) - { - if (bit32) + if (selection.Platform is Platform.Epic or Platform.Paradox) { - path = directory + @"\ScreamAPI32.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (bit32) { - if (File.Exists(path)) + path = directory + @"\ScreamAPI32.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\ScreamAPI32.dll"; } - path = rootDirectory + @"\ScreamAPI32.dll"; + "ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(path); + installForm?.UpdateUser( + $"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(path); - installForm?.UpdateUser( - $"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (bit64) + { + path = directory + @"\ScreamAPI64.dll"; + if (rootDirectory is not null && directory != rootDirectory) + { + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\ScreamAPI64.dll"; + } + "ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(path); + installForm?.UpdateUser( + $"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); + } + ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm); } - if (bit64) + if (selection.Platform is Platform.Ubisoft) { - path = directory + @"\ScreamAPI64.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (bit32) { - if (File.Exists(path)) + path = directory + @"\UplayR1Unlocker32.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser($"Deleted ScreamAPI from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\UplayR1Unlocker32.dll"; } - path = rootDirectory + @"\ScreamAPI64.dll"; + "UplayR1.uplay_r1_loader.dll".Write(path); + installForm?.UpdateUser( + $"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(path); - installForm?.UpdateUser( - $"Wrote ScreamAPI{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - ScreamAPI.CheckConfig(rootDirectory ?? directory, selection, installForm); - } - if (selection.Platform is Platform.Ubisoft) - { - if (bit32) - { - path = directory + @"\UplayR1Unlocker32.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (bit64) { - if (File.Exists(path)) + path = directory + @"\UplayR1Unlocker64.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser( - $"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\UplayR1Unlocker64.dll"; } - path = rootDirectory + @"\UplayR1Unlocker32.dll"; + "UplayR1.uplay_r1_loader64.dll".Write(path); + installForm?.UpdateUser( + $"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "UplayR1.uplay_r1_loader.dll".Write(path); - installForm?.UpdateUser( - $"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - if (bit64) - { - path = directory + @"\UplayR1Unlocker64.dll"; - if (rootDirectory is not null && directory != rootDirectory) + UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm); + if (bit32) { - if (File.Exists(path)) + path = directory + @"\UplayR2Unlocker32.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser( - $"Deleted Uplay R1 Unlocker from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\UplayR2Unlocker32.dll"; } - path = rootDirectory + @"\UplayR1Unlocker64.dll"; + "UplayR2.upc_r2_loader.dll".Write(path); + installForm?.UpdateUser( + $"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "UplayR1.uplay_r1_loader64.dll".Write(path); - installForm?.UpdateUser( - $"Wrote Uplay R1 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - UplayR1.CheckConfig(rootDirectory ?? directory, selection, installForm); - if (bit32) - { - path = directory + @"\UplayR2Unlocker32.dll"; - if (rootDirectory is not null && directory != rootDirectory) + if (bit64) { - if (File.Exists(path)) + path = directory + @"\UplayR2Unlocker64.dll"; + if (rootDirectory is not null && directory != rootDirectory) { - File.Delete(path); - installForm?.UpdateUser( - $"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); + if (File.Exists(path)) + { + File.Delete(path); + installForm?.UpdateUser($"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", LogTextBox.Action, false); + } + path = rootDirectory + @"\UplayR2Unlocker64.dll"; } - path = rootDirectory + @"\UplayR2Unlocker32.dll"; + "UplayR2.upc_r2_loader64.dll".Write(path); + installForm?.UpdateUser( + $"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", + LogTextBox.Action, false); } - "UplayR2.upc_r2_loader.dll".Write(path); - installForm?.UpdateUser( - $"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); + UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm); } - if (bit64) - { - path = directory + @"\UplayR2Unlocker64.dll"; - if (rootDirectory is not null && directory != rootDirectory) - { - if (File.Exists(path)) - { - File.Delete(path); - installForm?.UpdateUser( - $"Deleted Uplay R2 Unlocker from non-root directory: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - path = rootDirectory + @"\UplayR2Unlocker64.dll"; - } - "UplayR2.upc_r2_loader64.dll".Write(path); - installForm?.UpdateUser( - $"Wrote Uplay R2 Unlocker{(rootDirectory is not null && directory != rootDirectory ? " to root directory" : "")}: {Path.GetFileName(path)}", - LogTextBox.Action, false); - } - UplayR2.CheckConfig(rootDirectory ?? directory, selection, installForm); - } - if (generateConfig) - CheckConfig(directory, selection, installForm); - }); + if (generateConfig) + CheckConfig(directory, selection, installForm); + }); } diff --git a/CreamInstaller/Resources/Resources.cs b/CreamInstaller/Resources/Resources.cs index e9441bb..c89fbd9 100644 --- a/CreamInstaller/Resources/Resources.cs +++ b/CreamInstaller/Resources/Resources.cs @@ -335,7 +335,7 @@ internal static class Resources if (embeddedResources is null) { string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames(); - embeddedResources = new List(); + embeddedResources = new(); foreach (string resourceName in names.Where(n => n.StartsWith("CreamInstaller.Resources."))) embeddedResources.Add(resourceName[25..]); } @@ -345,8 +345,7 @@ internal static class Resources internal static void Write(this string resourceIdentifier, string filePath) { - using Stream resource = Assembly.GetExecutingAssembly() - .GetManifestResourceStream("CreamInstaller.Resources." + resourceIdentifier); + using Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("CreamInstaller.Resources." + resourceIdentifier); using FileStream file = new(filePath, FileMode.Create, FileAccess.Write); resource.CopyTo(file); } @@ -378,45 +377,42 @@ internal static class Resources [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] private static extern bool GetBinaryType(string lpApplicationName, out BinaryType lpBinaryType); - internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) - => GetBinaryType(path, out binaryType); + internal static bool TryGetFileBinaryType(this string path, out BinaryType binaryType) => GetBinaryType(path, out binaryType); - internal static async Task> GetExecutableDirectories( - this string rootDirectory, bool filterCommon = false, Func validFunc = null) => - await Task.Run(async () => (await rootDirectory.GetExecutables(filterCommon, validFunc) - ?? (filterCommon || validFunc is not null - ? await rootDirectory.GetExecutables() - : null))?.Select(e => - { - e.path = Path.GetDirectoryName(e.path); - return e; - })?.DistinctBy(e => e.path).ToList()); + internal static async Task> GetExecutableDirectories(this string rootDirectory, bool filterCommon = false, + Func validFunc = null) + => await Task.Run(async () + => (await rootDirectory.GetExecutables(filterCommon, validFunc) + ?? (filterCommon || validFunc is not null ? await rootDirectory.GetExecutables() : null))?.Select(e => + { + e.path = Path.GetDirectoryName(e.path); + return e; + })?.DistinctBy(e => e.path).ToList()); - internal static async Task> GetExecutables( - this string rootDirectory, bool filterCommon = false, Func validFunc = null) => await Task.Run( - () => + internal static async Task> GetExecutables(this string rootDirectory, bool filterCommon = false, + Func validFunc = null) + => await Task.Run(() => { List<(string path, BinaryType binaryType)> executables = new(); - if (Program.Canceled || !Directory.Exists(rootDirectory)) return null; - foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", - new EnumerationOptions { RecurseSubdirectories = true })) + if (Program.Canceled || !Directory.Exists(rootDirectory)) + return null; + foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", new EnumerationOptions { RecurseSubdirectories = true })) { - if (Program.Canceled) return null; - if (executables.All(e => e.path != path) - && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path)) - && (validFunc is null || validFunc(path)) - && path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT64) + if (Program.Canceled) + return null; + if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path)) + && (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType) + && binaryType is BinaryType.BIT64) executables.Add((path, binaryType)); Thread.Sleep(1); } - foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", - new EnumerationOptions { RecurseSubdirectories = true })) + foreach (string path in Directory.EnumerateFiles(rootDirectory, "*.exe", new EnumerationOptions { RecurseSubdirectories = true })) { - if (Program.Canceled) return null; - if (executables.All(e => e.path != path) - && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path)) - && (validFunc is null || validFunc(path)) - && path.TryGetFileBinaryType(out BinaryType binaryType) && binaryType is BinaryType.BIT32) + if (Program.Canceled) + return null; + if (executables.All(e => e.path != path) && (!filterCommon || !rootDirectory.IsCommonIncorrectExecutable(path)) + && (validFunc is null || validFunc(path)) && path.TryGetFileBinaryType(out BinaryType binaryType) + && binaryType is BinaryType.BIT32) executables.Add((path, binaryType)); Thread.Sleep(1); } @@ -426,91 +422,62 @@ internal static class Resources internal static bool IsCommonIncorrectExecutable(this string rootDirectory, string path) { string subPath = path[rootDirectory.Length..].ToUpperInvariant().BeautifyPath(); - return subPath.Contains("SETUP") - || subPath.Contains("REDIST") - || subPath.Contains("SUPPORT") - || (subPath.Contains("CRASH") && (subPath.Contains("PAD") || subPath.Contains("REPORT"))) - || subPath.Contains("HELPER") - || subPath.Contains("CEFPROCESS") - || subPath.Contains("ZFGAMEBROWSER") - || subPath.Contains("MONO") - || subPath.Contains("PLUGINS") - || subPath.Contains("MODDING") - || (subPath.Contains("MOD") && subPath.Contains("MANAGER")) - || subPath.Contains("BATTLEYE") + return subPath.Contains("SETUP") || subPath.Contains("REDIST") || subPath.Contains("SUPPORT") + || subPath.Contains("CRASH") && (subPath.Contains("PAD") || subPath.Contains("REPORT")) || subPath.Contains("HELPER") + || subPath.Contains("CEFPROCESS") || subPath.Contains("ZFGAMEBROWSER") || subPath.Contains("MONO") || subPath.Contains("PLUGINS") + || subPath.Contains("MODDING") || subPath.Contains("MOD") && subPath.Contains("MANAGER") || subPath.Contains("BATTLEYE") || subPath.Contains("ANTICHEAT"); } - internal static async Task> GetDllDirectoriesFromGameDirectory( - this string gameDirectory, Platform platform) => await Task.Run(() => - { - List dllDirectories = new(); - if (Program.Canceled || !Directory.Exists(gameDirectory)) return null; - foreach (string directory in Directory - .EnumerateDirectories(gameDirectory, "*", - new EnumerationOptions { RecurseSubdirectories = true }) - .Append(gameDirectory)) + internal static async Task> GetDllDirectoriesFromGameDirectory(this string gameDirectory, Platform platform) + => await Task.Run(() => { - if (Program.Canceled) return null; - string subDirectory = directory.BeautifyPath(); - if (!dllDirectories.Contains(subDirectory)) + List dllDirectories = new(); + if (Program.Canceled || !Directory.Exists(gameDirectory)) + return null; + foreach (string directory in Directory.EnumerateDirectories(gameDirectory, "*", new EnumerationOptions { RecurseSubdirectories = true }) + .Append(gameDirectory)) { - bool koaloaderInstalled = Koaloader.AutoLoadDlls - .Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) - .Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile()); - if (platform is Platform.Steam or Platform.Paradox) + if (Program.Canceled) + return null; + string subDirectory = directory.BeautifyPath(); + if (!dllDirectories.Contains(subDirectory)) { - subDirectory.GetSmokeApiComponents(out string api, out string api_o, out string api64, - out string api64_o, out string config, out string cache); - if (File.Exists(api) - || File.Exists(api_o) - || File.Exists(api64) - || File.Exists(api64_o) - || (File.Exists(config) && !koaloaderInstalled) - || (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)) - 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)) - 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); - 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)) - dllDirectories.Add(subDirectory); + bool koaloaderInstalled = Koaloader.AutoLoadDlls.Select(pair => (pair.unlocker, path: directory + @"\" + pair.dll)) + .Any(pair => File.Exists(pair.path) && pair.path.IsResourceFile()); + 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 config, + out string cache); + if (File.Exists(api) || File.Exists(api_o) || File.Exists(api64) || File.Exists(api64_o) || File.Exists(config) && !koaloaderInstalled + || 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) + 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) + 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); + 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) + dllDirectories.Add(subDirectory); + } } } - } - return !dllDirectories.Any() ? null : dllDirectories; - }); + return !dllDirectories.Any() ? null : dllDirectories; + }); - internal static void GetCreamApiComponents( - this string directory, - out string api32, out string api32_o, - out string api64, out string api64_o, + internal static void GetCreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, out string config) { api32 = directory + @"\steam_api.dll"; @@ -522,7 +489,8 @@ internal static class Resources internal static string ComputeMD5(this string filePath) { - if (!File.Exists(filePath)) return null; + if (!File.Exists(filePath)) + return null; #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms using MD5 md5 = MD5.Create(); #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms @@ -534,9 +502,8 @@ internal static class Resources internal static bool IsResourceFile(this string filePath, ResourceIdentifier identifier) => filePath.ComputeMD5() is string hash && ResourceMD5s[identifier].Contains(hash); - internal static bool IsResourceFile(this string filePath) => filePath.ComputeMD5() is string hash - && ResourceMD5s.Values.Any( - hashes => hashes.Contains(hash)); + internal static bool IsResourceFile(this string filePath) + => filePath.ComputeMD5() is string hash && ResourceMD5s.Values.Any(hashes => hashes.Contains(hash)); internal enum BinaryType { diff --git a/CreamInstaller/Resources/ScreamAPI.cs b/CreamInstaller/Resources/ScreamAPI.cs index 84c4fe3..30a232d 100644 --- a/CreamInstaller/Resources/ScreamAPI.cs +++ b/CreamInstaller/Resources/ScreamAPI.cs @@ -11,12 +11,8 @@ 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 - ) + internal static void GetScreamApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, + out string config) { api32 = directory + @"\EOSSDK-Win32-Shipping.dll"; api32_o = directory + @"\EOSSDK-Win32-Shipping_o.dll"; @@ -30,13 +26,11 @@ internal static class ScreamAPI directory.GetScreamApiComponents(out _, out _, out _, out _, out string config); IEnumerable> overrideCatalogItems = selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc); - foreach ((string id, string name, SortedList extraDlc) in - selection.ExtraSelectedDlc) + foreach ((string id, string name, SortedList extraDlc) in selection.ExtraSelectedDlc) overrideCatalogItems = overrideCatalogItems.Except(extraDlc); IEnumerable> entitlements = selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement); - foreach ((string id, string name, SortedList _dlc) in - selection.ExtraSelectedDlc) + foreach ((string id, string name, SortedList _dlc) in selection.ExtraSelectedDlc) entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement)); if (overrideCatalogItems.Any() || entitlements.Any()) { @@ -44,28 +38,20 @@ internal static class ScreamAPI installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ File.Create(config).Close(); StreamWriter writer = new(config, true, Encoding.UTF8); - WriteConfig(writer, - new SortedList( - overrideCatalogItems.ToDictionary(pair => pair.Key, pair => pair.Value), - PlatformIdComparer.String), - new SortedList( - entitlements.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), - installForm); + WriteConfig(writer, new(overrideCatalogItems.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), + new(entitlements.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm); writer.Flush(); writer.Close(); } else if (File.Exists(config)) { File.Delete(config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - internal static void WriteConfig(StreamWriter writer, - SortedList overrideCatalogItems, - SortedList entitlements, - InstallForm installForm = null) + internal static void WriteConfig(StreamWriter writer, SortedList overrideCatalogItems, + SortedList entitlements, InstallForm installForm = null) { writer.WriteLine("{"); writer.WriteLine(" \"version\": 2,"); @@ -77,22 +63,18 @@ internal static class ScreamAPI if (overrideCatalogItems.Any()) { writer.WriteLine(" \"override\": ["); - KeyValuePair lastOverrideCatalogItem - = overrideCatalogItems.Last(); + KeyValuePair lastOverrideCatalogItem = overrideCatalogItems.Last(); foreach (KeyValuePair pair in overrideCatalogItems) { string id = pair.Key; (_, string name, _) = pair.Value; writer.WriteLine($" \"{id}\"{(pair.Equals(lastOverrideCatalogItem) ? "" : ",")}"); - installForm?.UpdateUser($"Added override catalog item to ScreamAPI.json with id {id} ({name})", - LogTextBox.Action, false); + installForm?.UpdateUser($"Added override catalog item to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false); } writer.WriteLine(" ]"); } else - { writer.WriteLine(" \"override\": []"); - } writer.WriteLine(" },"); writer.WriteLine(" \"entitlements\": {"); writer.WriteLine(" \"unlock_all\": true,"); @@ -106,15 +88,12 @@ internal static class ScreamAPI string id = pair.Key; (_, string name, _) = pair.Value; writer.WriteLine($" \"{id}\"{(pair.Equals(lastEntitlement) ? "" : ",")}"); - installForm?.UpdateUser($"Added entitlement to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, - false); + installForm?.UpdateUser($"Added entitlement to ScreamAPI.json with id {id} ({name})", LogTextBox.Action, false); } writer.WriteLine(" ]"); } else - { writer.WriteLine(" \"inject\": []"); - } writer.WriteLine(" }"); writer.WriteLine("}"); } @@ -122,8 +101,7 @@ internal static class ScreamAPI internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = 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); if (File.Exists(api32_o)) { if (File.Exists(api32)) @@ -132,8 +110,7 @@ internal static class ScreamAPI installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); } File.Move(api32_o, api32); - installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } if (File.Exists(api64_o)) { @@ -143,8 +120,7 @@ internal static class ScreamAPI installForm?.UpdateUser($"Deleted ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); } File.Move(api64_o, api64); - installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored EOS: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } if (deleteConfig && File.Exists(config)) { @@ -153,34 +129,31 @@ internal static class ScreamAPI } }); - 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 config); - if (File.Exists(api32) && !File.Exists(api32_o)) + internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) + => await Task.Run(() => { - File.Move(api32, api32_o); - installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api32_o)) - { - "ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(api32); - installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); - } - if (File.Exists(api64) && !File.Exists(api64_o)) - { - File.Move(api64, api64_o); - installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api64_o)) - { - "ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(api64); - installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); - } - if (generateConfig) - CheckConfig(directory, selection, installForm); - }); + 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.Move(api32, api32_o); + installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); + } + if (File.Exists(api32_o)) + { + "ScreamAPI.EOSSDK-Win32-Shipping.dll".Write(api32); + installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); + } + if (File.Exists(api64) && !File.Exists(api64_o)) + { + File.Move(api64, api64_o); + installForm?.UpdateUser($"Renamed EOS: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); + } + if (File.Exists(api64_o)) + { + "ScreamAPI.EOSSDK-Win64-Shipping.dll".Write(api64); + installForm?.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); + } + if (generateConfig) + CheckConfig(directory, selection, installForm); + }); } diff --git a/CreamInstaller/Resources/SmokeAPI.cs b/CreamInstaller/Resources/SmokeAPI.cs index 6b3c96d..3c2c7e5 100644 --- a/CreamInstaller/Resources/SmokeAPI.cs +++ b/CreamInstaller/Resources/SmokeAPI.cs @@ -11,12 +11,8 @@ 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 config, - out string cache) + internal static void GetSmokeApiComponents(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, + out string config, out string cache) { api32 = directory + @"\steam_api.dll"; api32_o = directory + @"\steam_api_o.dll"; @@ -29,18 +25,15 @@ internal static class SmokeAPI internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { directory.GetSmokeApiComponents(out _, out _, out _, out _, out string config, out _); - IEnumerable> overrideDlc - = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string id, string name, SortedList extraDlc) in - selection.ExtraSelectedDlc) + IEnumerable> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc); + foreach ((string id, string name, 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 name, SortedList extraDlc) in - selection.ExtraSelectedDlc) + foreach ((string id, string name, SortedList extraDlc) in selection.ExtraSelectedDlc) if (selection.ExtraDlc.Where(e => e.id == id).Single().dlc.Count > 64) injectDlc = injectDlc.Concat(extraDlc.Where(pair => pair.Value.type is DlcType.SteamHidden)); } @@ -50,27 +43,20 @@ internal static class SmokeAPI installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ File.Create(config).Close(); StreamWriter writer = new(config, true, Encoding.UTF8); - WriteConfig(writer, - new SortedList( - overrideDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), - new SortedList( - injectDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), - installForm); + WriteConfig(writer, 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(config)) { File.Delete(config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - internal static void WriteConfig(StreamWriter writer, - SortedList overrideDlc, - SortedList injectDlc, - InstallForm installForm = null) + internal static void WriteConfig(StreamWriter writer, SortedList overrideDlc, + SortedList injectDlc, InstallForm installForm = null) { writer.WriteLine("{"); writer.WriteLine(" \"$version\": 1,"); @@ -86,15 +72,12 @@ internal static class SmokeAPI 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); + installForm?.UpdateUser($"Added override DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); } writer.WriteLine(" ],"); } else - { writer.WriteLine(" \"override\": [],"); - } if (injectDlc.Count > 0) { writer.WriteLine(" \"dlc_ids\": ["); @@ -104,15 +87,12 @@ internal static class SmokeAPI 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); + installForm?.UpdateUser($"Added inject DLC to SmokeAPI.json with appid {dlcId} ({dlcName})", LogTextBox.Action, false); } writer.WriteLine(" ],"); } else - { writer.WriteLine(" \"dlc_ids\": [],"); - } writer.WriteLine(" \"auto_inject_inventory\": true,"); writer.WriteLine(" \"inventory_items\": []"); writer.WriteLine("}"); @@ -125,11 +105,9 @@ internal static class SmokeAPI if (File.Exists(oldConfig)) { File.Delete(oldConfig); - installForm?.UpdateUser($"Deleted old CreamAPI configuration: {Path.GetFileName(oldConfig)}", - LogTextBox.Action, false); + 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 config, out string cache); + directory.GetSmokeApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config, out string cache); if (File.Exists(api32_o)) { if (File.Exists(api32)) @@ -138,9 +116,7 @@ internal static class SmokeAPI installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); } File.Move(api32_o, api32); - installForm?.UpdateUser( - $"Restored Steamworks: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } if (File.Exists(api64_o)) { @@ -150,9 +126,7 @@ internal static class SmokeAPI installForm?.UpdateUser($"Deleted SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); } File.Move(api64_o, api64); - installForm?.UpdateUser( - $"Restored Steamworks: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Restored Steamworks: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } if (deleteConfig && File.Exists(config)) { @@ -166,41 +140,37 @@ internal static class SmokeAPI } }); - internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, - bool generateConfig = true) => await Task.Run(() => - { - directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig); - if (File.Exists(oldConfig)) + internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) + => await Task.Run(() => { - 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 string config, out _); - if (File.Exists(api32) && !File.Exists(api32_o)) - { - File.Move(api32, api32_o); - installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api32_o)) - { - "SmokeAPI.steam_api.dll".Write(api32); - installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); - } - if (File.Exists(api64) && !File.Exists(api64_o)) - { - File.Move(api64, api64_o); - installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api64_o)) - { - "SmokeAPI.steam_api64.dll".Write(api64); - installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); - } - if (generateConfig) - CheckConfig(directory, selection, installForm); - }); + directory.GetCreamApiComponents(out _, out _, out _, out _, out string oldConfig); + if (File.Exists(oldConfig)) + { + 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 string config, out _); + if (File.Exists(api32) && !File.Exists(api32_o)) + { + File.Move(api32, api32_o); + installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); + } + if (File.Exists(api32_o)) + { + "SmokeAPI.steam_api.dll".Write(api32); + installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api32)}", LogTextBox.Action, false); + } + if (File.Exists(api64) && !File.Exists(api64_o)) + { + File.Move(api64, api64_o); + installForm?.UpdateUser($"Renamed Steamworks: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); + } + if (File.Exists(api64_o)) + { + "SmokeAPI.steam_api64.dll".Write(api64); + installForm?.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", LogTextBox.Action, false); + } + if (generateConfig) + CheckConfig(directory, selection, installForm); + }); } diff --git a/CreamInstaller/Resources/UplayR1.cs b/CreamInstaller/Resources/UplayR1.cs index 8177cd9..e8b7e8d 100644 --- a/CreamInstaller/Resources/UplayR1.cs +++ b/CreamInstaller/Resources/UplayR1.cs @@ -11,12 +11,8 @@ 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 - ) + internal static void GetUplayR1Components(this string directory, out string api32, out string api32_o, out string api64, out string api64_o, + out string config) { api32 = directory + @"\uplay_r1_loader.dll"; api32_o = directory + @"\uplay_r1_loader_o.dll"; @@ -28,10 +24,8 @@ internal static class UplayR1 internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { directory.GetUplayR1Components(out _, out _, out _, out _, out string config); - IEnumerable> blacklistDlc - = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string id, string name, SortedList extraDlc) in - selection.ExtraSelectedDlc) + IEnumerable> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc); + foreach ((string id, string name, SortedList extraDlc) in selection.ExtraSelectedDlc) blacklistDlc = blacklistDlc.Except(extraDlc); if (blacklistDlc.Any()) { @@ -39,24 +33,19 @@ internal static class UplayR1 installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ File.Create(config).Close(); StreamWriter writer = new(config, true, Encoding.UTF8); - WriteConfig(writer, - new SortedList( - blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), - installForm); + WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm); writer.Flush(); writer.Close(); } else if (File.Exists(config)) { File.Delete(config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - internal static void WriteConfig(StreamWriter writer, - SortedList blacklistDlc, - InstallForm installForm = null) + internal static void WriteConfig(StreamWriter writer, SortedList blacklistDlc, + InstallForm installForm = null) { writer.WriteLine("{"); writer.WriteLine(" \"logging\": false,"); @@ -71,46 +60,38 @@ internal static class UplayR1 string dlcId = pair.Key; (_, string dlcName, _) = pair.Value; writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}"); - installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {dlcId} ({dlcName})", - LogTextBox.Action, false); + installForm?.UpdateUser($"Added blacklist DLC to UplayR1Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false); } writer.WriteLine(" ],"); } else - { writer.WriteLine(" \"blacklist\": [],"); - } writer.WriteLine("}"); } internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = 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); if (File.Exists(api32_o)) { if (File.Exists(api32)) { File.Delete(api32); - installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false); } File.Move(api32_o, api32); - installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api32)}", LogTextBox.Action, false); } if (File.Exists(api64_o)) { if (File.Exists(api64)) { File.Delete(api64); - installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false); } File.Move(api64_o, api64); - installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored Uplay R1: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", LogTextBox.Action, false); } if (deleteConfig && File.Exists(config)) { @@ -119,34 +100,31 @@ internal static class UplayR1 } }); - 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 config); - if (File.Exists(api32) && !File.Exists(api32_o)) + internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) + => await Task.Run(() => { - File.Move(api32, api32_o); - installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api32_o)) - { - "UplayR1.uplay_r1_loader.dll".Write(api32); - installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false); - } - if (File.Exists(api64) && !File.Exists(api64_o)) - { - File.Move(api64, api64_o); - installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api64_o)) - { - "UplayR1.uplay_r1_loader64.dll".Write(api64); - installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false); - } - if (generateConfig) - CheckConfig(directory, selection, installForm); - }); + 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.Move(api32, api32_o); + installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api32)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); + } + if (File.Exists(api32_o)) + { + "UplayR1.uplay_r1_loader.dll".Write(api32); + installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api32)}", LogTextBox.Action, false); + } + if (File.Exists(api64) && !File.Exists(api64_o)) + { + File.Move(api64, api64_o); + installForm?.UpdateUser($"Renamed Uplay R1: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); + } + if (File.Exists(api64_o)) + { + "UplayR1.uplay_r1_loader64.dll".Write(api64); + installForm?.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", LogTextBox.Action, false); + } + if (generateConfig) + CheckConfig(directory, selection, installForm); + }); } diff --git a/CreamInstaller/Resources/UplayR2.cs b/CreamInstaller/Resources/UplayR2.cs index d9845e3..3fb9a73 100644 --- a/CreamInstaller/Resources/UplayR2.cs +++ b/CreamInstaller/Resources/UplayR2.cs @@ -11,12 +11,8 @@ 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) + 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) { old_api32 = directory + @"\uplay_r2_loader.dll"; old_api64 = directory + @"\uplay_r2_loader64.dll"; @@ -30,10 +26,8 @@ internal static class UplayR2 internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null) { directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config); - IEnumerable> blacklistDlc - = selection.AllDlc.Except(selection.SelectedDlc); - foreach ((string id, string name, SortedList extraDlc) in - selection.ExtraSelectedDlc) + IEnumerable> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc); + foreach ((string id, string name, SortedList extraDlc) in selection.ExtraSelectedDlc) blacklistDlc = blacklistDlc.Except(extraDlc); if (blacklistDlc.Any()) { @@ -41,24 +35,19 @@ internal static class UplayR2 installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", LogTextBox.Operation);*/ File.Create(config).Close(); StreamWriter writer = new(config, true, Encoding.UTF8); - WriteConfig(writer, - new SortedList( - blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), - installForm); + WriteConfig(writer, new(blacklistDlc.ToDictionary(pair => pair.Key, pair => pair.Value), PlatformIdComparer.String), installForm); writer.Flush(); writer.Close(); } else if (File.Exists(config)) { File.Delete(config); - installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", LogTextBox.Action, false); } } - internal static void WriteConfig(StreamWriter writer, - SortedList blacklistDlc, - InstallForm installForm = null) + internal static void WriteConfig(StreamWriter writer, SortedList blacklistDlc, + InstallForm installForm = null) { writer.WriteLine("{"); writer.WriteLine(" \"logging\": false,"); @@ -75,35 +64,30 @@ internal static class UplayR2 string dlcId = pair.Key; (_, string dlcName, _) = pair.Value; writer.WriteLine($" {dlcId}{(pair.Equals(lastBlacklistDlc) ? "" : ",")}"); - installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {dlcId} ({dlcName})", - LogTextBox.Action, false); + installForm?.UpdateUser($"Added blacklist DLC to UplayR2Unlocker.jsonc with appid {dlcId} ({dlcName})", LogTextBox.Action, false); } writer.WriteLine(" ],"); } else - { writer.WriteLine(" \"blacklist\": [],"); - } writer.WriteLine("}"); } internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = 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); + 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); if (File.Exists(api32_o)) { string api = File.Exists(old_api32) ? old_api32 : api32; if (File.Exists(api)) { File.Delete(api); - installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); } File.Move(api32_o, api); - installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api32_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false); } if (File.Exists(api64_o)) { @@ -111,12 +95,10 @@ internal static class UplayR2 if (File.Exists(api)) { File.Delete(api); - installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, - false); + installForm?.UpdateUser($"Deleted Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); } File.Move(api64_o, api); - installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api)}", - LogTextBox.Action, false); + installForm?.UpdateUser($"Restored Uplay R2: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api)}", LogTextBox.Action, false); } if (deleteConfig && File.Exists(config)) { @@ -125,36 +107,34 @@ internal static class UplayR2 } }); - 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 config); - string api = File.Exists(old_api32) ? old_api32 : api32; - if (File.Exists(api) && !File.Exists(api32_o)) + internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) + => await Task.Run(() => { - File.Move(api, api32_o); - installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api32_o)) - { - "UplayR2.upc_r2_loader.dll".Write(api); - installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); - } - api = File.Exists(old_api64) ? old_api64 : api64; - if (File.Exists(api) && !File.Exists(api64_o)) - { - File.Move(api, api64_o); - installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}", - LogTextBox.Action, false); - } - if (File.Exists(api64_o)) - { - "UplayR2.upc_r2_loader64.dll".Write(api); - installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); - } - if (generateConfig) - CheckConfig(directory, selection, installForm); - }); + 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); + string api = File.Exists(old_api32) ? old_api32 : api32; + if (File.Exists(api) && !File.Exists(api32_o)) + { + File.Move(api, api32_o); + installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api32_o)}", LogTextBox.Action, false); + } + if (File.Exists(api32_o)) + { + "UplayR2.upc_r2_loader.dll".Write(api); + installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); + } + api = File.Exists(old_api64) ? old_api64 : api64; + if (File.Exists(api) && !File.Exists(api64_o)) + { + File.Move(api, api64_o); + installForm?.UpdateUser($"Renamed Uplay R2: {Path.GetFileName(api)} -> {Path.GetFileName(api64_o)}", LogTextBox.Action, false); + } + if (File.Exists(api64_o)) + { + "UplayR2.upc_r2_loader64.dll".Write(api); + installForm?.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", LogTextBox.Action, false); + } + if (generateConfig) + CheckConfig(directory, selection, installForm); + }); } diff --git a/CreamInstaller/Utility/Diagnostics.cs b/CreamInstaller/Utility/Diagnostics.cs index 05123d7..78f2d51 100644 --- a/CreamInstaller/Utility/Diagnostics.cs +++ b/CreamInstaller/Utility/Diagnostics.cs @@ -14,8 +14,7 @@ internal static class Diagnostics get { notepadPlusPlusPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Notepad++", "", null) as string; - notepadPlusPlusPath - ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\Notepad++", "", null) as string; + notepadPlusPlusPath ??= Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\Notepad++", "", null) as string; return notepadPlusPlusPath; } } @@ -35,18 +34,13 @@ internal static class Diagnostics OpenFileInWindowsNotepad(path); } - private static void OpenFileInNotepadPlusPlus(string npp, string path) - => Process.Start(new ProcessStartInfo { FileName = npp, Arguments = path }); + private static void OpenFileInNotepadPlusPlus(string npp, string path) => Process.Start(new ProcessStartInfo { FileName = npp, Arguments = path }); - private static void OpenFileInWindowsNotepad(string path) - => Process.Start(new ProcessStartInfo { FileName = "notepad.exe", Arguments = path }); + private static void OpenFileInWindowsNotepad(string path) => Process.Start(new ProcessStartInfo { FileName = "notepad.exe", Arguments = path }); - internal static void OpenDirectoryInFileExplorer(string path) - => Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = path }); + internal static void OpenDirectoryInFileExplorer(string path) => Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = path }); - internal static void OpenUrlInInternetBrowser(string url) - => Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true }); + internal static void OpenUrlInInternetBrowser(string url) => Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true }); - internal static string BeautifyPath(this string path) - => path is null ? null : Path.TrimEndingDirectorySeparator(Path.GetFullPath(path)); + internal static string BeautifyPath(this string path) => path is null ? null : Path.TrimEndingDirectorySeparator(Path.GetFullPath(path)); } diff --git a/CreamInstaller/Utility/ExceptionHandler.cs b/CreamInstaller/Utility/ExceptionHandler.cs index 92d8c9f..5e79648 100644 --- a/CreamInstaller/Utility/ExceptionHandler.cs +++ b/CreamInstaller/Utility/ExceptionHandler.cs @@ -8,8 +8,8 @@ namespace CreamInstaller.Utility; internal static class ExceptionHandler { - internal static bool HandleException(this Exception e, Form form = null, string caption = null, - string acceptButtonText = "Retry", string cancelButtonText = "Cancel") + internal static bool HandleException(this Exception e, Form form = null, string caption = null, string acceptButtonText = "Retry", + string cancelButtonText = "Cancel") { caption ??= Program.Name + " encountered an exception"; StringBuilder output = new(); @@ -32,31 +32,23 @@ internal static class ExceptionHandler int ciNum = line.LastIndexOf(@"CreamInstaller\", StringComparison.Ordinal); int lineNum = line.LastIndexOf(":line ", StringComparison.Ordinal); if (atNum != -1) - _ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..]) - + (inNum != -1 - ? "\n " - + (ciNum != -1 - ? "in " - + (lineNum != -1 - ? line[ciNum..lineNum] - + "\n on " + line[(lineNum + 1)..] - : line[ciNum..]) - : line[inNum..]) - : null)); + _ = output.Append("\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..]) + (inNum != -1 + ? "\n " + (ciNum != -1 + ? "in " + (lineNum != -1 ? line[ciNum..lineNum] + "\n on " + line[(lineNum + 1)..] : line[ciNum..]) + : line[inNum..]) + : null)); } } e = e.InnerException; stackDepth++; } using DialogForm dialogForm = new(form ?? Form.ActiveForm); - return dialogForm.Show(SystemIcons.Error, output.ToString(), acceptButtonText, cancelButtonText, caption) - == DialogResult.OK; + return dialogForm.Show(SystemIcons.Error, output.ToString(), acceptButtonText, cancelButtonText, caption) == DialogResult.OK; } internal static void HandleFatalException(this Exception e) { - bool? restart = e?.HandleException(caption: Program.Name + " encountered a fatal exception", - acceptButtonText: "Restart"); + bool? restart = e?.HandleException(caption: Program.Name + " encountered a fatal exception", acceptButtonText: "Restart"); if (restart.HasValue && restart.Value) Application.Restart(); Application.Exit(); diff --git a/CreamInstaller/Utility/HttpClientManager.cs b/CreamInstaller/Utility/HttpClientManager.cs index 5232845..033fda7 100644 --- a/CreamInstaller/Utility/HttpClientManager.cs +++ b/CreamInstaller/Utility/HttpClientManager.cs @@ -12,7 +12,7 @@ internal static class HttpClientManager internal static void Setup() { - HttpClient = new HttpClient(); + HttpClient = new(); HttpClient.DefaultRequestHeaders.Add("User-Agent", $"CI{Program.Version.Replace(".", "")}"); } @@ -21,8 +21,7 @@ internal static class HttpClientManager try { using HttpRequestMessage request = new(HttpMethod.Get, url); - using HttpResponseMessage response - = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + using HttpResponseMessage response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); _ = response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } @@ -42,8 +41,7 @@ internal static class HttpClientManager internal static async Task GetDocumentNodes(string url, string xpath) => (await EnsureGet(url))?.ToHtmlDocument()?.DocumentNode?.SelectNodes(xpath); - internal static HtmlNodeCollection GetDocumentNodes(this HtmlDocument htmlDocument, string xpath) - => htmlDocument.DocumentNode?.SelectNodes(xpath); + internal static HtmlNodeCollection GetDocumentNodes(this HtmlDocument htmlDocument, string xpath) => htmlDocument.DocumentNode?.SelectNodes(xpath); internal static async Task GetImageFromUrl(string url) { diff --git a/CreamInstaller/Utility/IconGrabber.cs b/CreamInstaller/Utility/IconGrabber.cs index e9951fa..1ed0809 100644 --- a/CreamInstaller/Utility/IconGrabber.cs +++ b/CreamInstaller/Utility/IconGrabber.cs @@ -6,27 +6,23 @@ namespace CreamInstaller.Utility; internal static class IconGrabber { - internal const string SteamAppImagesPath - = "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/"; + internal const string SteamAppImagesPath = "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/"; internal const string GoogleFaviconsApiUrl = "https://www.google.com/s2/favicons"; internal static Icon ToIcon(this Image image) { - using Bitmap dialogIconBitmap = new(image, new Size(image.Width, image.Height)); + using Bitmap dialogIconBitmap = new(image, new(image.Width, image.Height)); return Icon.FromHandle(dialogIconBitmap.GetHicon()); } - internal static string GetDomainFaviconUrl(string domain, int size = 16) - => GoogleFaviconsApiUrl + $"?domain={domain}&sz={size}"; + internal static string GetDomainFaviconUrl(string domain, int size = 16) => GoogleFaviconsApiUrl + $"?domain={domain}&sz={size}"; - internal static Image GetFileIconImage(this string path) - => File.Exists(path) ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null; + internal static Image GetFileIconImage(this string path) => File.Exists(path) ? Icon.ExtractAssociatedIcon(path)?.ToBitmap() : null; internal static Image GetNotepadImage() => GetFileIconImage(Diagnostics.GetNotepadPath()); internal static Image GetCommandPromptImage() => GetFileIconImage(Environment.SystemDirectory + @"\cmd.exe"); - internal static Image GetFileExplorerImage() - => GetFileIconImage(Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\explorer.exe"); + internal static Image GetFileExplorerImage() => GetFileIconImage(Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\explorer.exe"); } diff --git a/CreamInstaller/Utility/LogTextBox.cs b/CreamInstaller/Utility/LogTextBox.cs index 46a10e7..f4f44b1 100644 --- a/CreamInstaller/Utility/LogTextBox.cs +++ b/CreamInstaller/Utility/LogTextBox.cs @@ -18,9 +18,11 @@ internal static class LogTextBox textBox.SelectionStart = textBox.TextLength; textBox.SelectionLength = 0; textBox.SelectionColor = color; - if (scroll) textBox.ScrollToCaret(); + if (scroll) + textBox.ScrollToCaret(); textBox.AppendText(text); - if (scroll) textBox.ScrollToCaret(); + if (scroll) + textBox.ScrollToCaret(); textBox.SelectionColor = textBox.ForeColor; textBox.Invalidate(); } diff --git a/CreamInstaller/Utility/ProgramData.cs b/CreamInstaller/Utility/ProgramData.cs index ddecc48..c3416b8 100644 --- a/CreamInstaller/Utility/ProgramData.cs +++ b/CreamInstaller/Utility/ProgramData.cs @@ -11,11 +11,9 @@ namespace CreamInstaller.Utility; internal static class ProgramData { - internal static readonly string DirectoryPathOld - = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller"; + internal static readonly string DirectoryPathOld = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\CreamInstaller"; - internal static readonly string DirectoryPath - = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller"; + internal static readonly string DirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\CreamInstaller"; internal static readonly string AppInfoPath = DirectoryPath + @"\appinfo"; internal static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt"; @@ -29,27 +27,30 @@ internal static class ProgramData internal static readonly string DlcChoicesPath = DirectoryPath + @"\dlc.json"; internal static readonly string KoaloaderProxyChoicesPath = DirectoryPath + @"\proxies.json"; - internal static async Task Setup() => await Task.Run(() => - { - if (Directory.Exists(DirectoryPathOld)) + internal static async Task Setup() + => await Task.Run(() => { - if (Directory.Exists(DirectoryPath)) Directory.Delete(DirectoryPath, true); - Directory.Move(DirectoryPathOld, DirectoryPath); - } - if (!Directory.Exists(DirectoryPath)) _ = Directory.CreateDirectory(DirectoryPath); - if (!File.Exists(AppInfoVersionPath) - || !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version) - || version < MinimumAppInfoVersion) - { - if (Directory.Exists(AppInfoPath)) Directory.Delete(AppInfoPath, true); - _ = Directory.CreateDirectory(AppInfoPath); - File.WriteAllText(AppInfoVersionPath, Program.Version, Encoding.UTF8); - } - if (!Directory.Exists(CooldownPath)) - _ = Directory.CreateDirectory(CooldownPath); - if (File.Exists(OldProgramChoicesPath)) - File.Delete(OldProgramChoicesPath); - }); + if (Directory.Exists(DirectoryPathOld)) + { + if (Directory.Exists(DirectoryPath)) + Directory.Delete(DirectoryPath, true); + Directory.Move(DirectoryPathOld, DirectoryPath); + } + if (!Directory.Exists(DirectoryPath)) + _ = Directory.CreateDirectory(DirectoryPath); + if (!File.Exists(AppInfoVersionPath) || !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version) + || version < MinimumAppInfoVersion) + { + if (Directory.Exists(AppInfoPath)) + Directory.Delete(AppInfoPath, true); + _ = Directory.CreateDirectory(AppInfoPath); + File.WriteAllText(AppInfoVersionPath, Program.Version, Encoding.UTF8); + } + if (!Directory.Exists(CooldownPath)) + _ = Directory.CreateDirectory(CooldownPath); + if (File.Exists(OldProgramChoicesPath)) + File.Delete(OldProgramChoicesPath); + }); internal static bool CheckCooldown(string identifier, int cooldown) { @@ -91,16 +92,16 @@ internal static class ProgramData internal static List<(Platform platform, string id)> ReadProgramChoices() { - if (!File.Exists(ProgramChoicesPath)) return null; + if (!File.Exists(ProgramChoicesPath)) + return null; try { - return JsonConvert.DeserializeObject(File.ReadAllText(ProgramChoicesPath), - typeof(List<(Platform platform, string id)>)) as + return JsonConvert.DeserializeObject(File.ReadAllText(ProgramChoicesPath), typeof(List<(Platform platform, string id)>)) as List<(Platform platform, string id)>; } catch { - return new List<(Platform platform, string id)>(); + return new(); } } @@ -118,16 +119,16 @@ internal static class ProgramData internal static List<(Platform platform, string gameId, string dlcId)> ReadDlcChoices() { - if (!File.Exists(DlcChoicesPath)) return null; + if (!File.Exists(DlcChoicesPath)) + return null; try { - return JsonConvert.DeserializeObject(File.ReadAllText(DlcChoicesPath), - typeof(List<(Platform platform, string gameId, string dlcId)>)) as + return JsonConvert.DeserializeObject(File.ReadAllText(DlcChoicesPath), typeof(List<(Platform platform, string gameId, string dlcId)>)) as List<(Platform platform, string gameId, string dlcId)>; } catch { - return new List<(Platform platform, string gameId, string dlcId)>(); + return new(); } } @@ -145,22 +146,20 @@ internal static class ProgramData internal static List<(Platform platform, string id, string proxy, bool enabled)> ReadKoaloaderChoices() { - if (!File.Exists(KoaloaderProxyChoicesPath)) return null; + if (!File.Exists(KoaloaderProxyChoicesPath)) + return null; try { return JsonConvert.DeserializeObject(File.ReadAllText(KoaloaderProxyChoicesPath), - typeof( - List<(Platform platform, string id, string proxy, bool enabled)>)) - as List<(Platform platform, string id, string proxy, bool enabled)>; + typeof(List<(Platform platform, string id, string proxy, bool enabled)>)) as List<(Platform platform, string id, string proxy, bool enabled)>; } catch { - return new List<(Platform platform, string id, string proxy, bool enabled)>(); + return new(); } } - internal static void WriteKoaloaderProxyChoices( - List<(Platform platform, string id, string proxy, bool enabled)> choices) + internal static void WriteKoaloaderProxyChoices(List<(Platform platform, string id, string proxy, bool enabled)> choices) { try {