fixes, color changes & game koaloader toggles

- Improved tabbing in the selection forms
- Improved main select form "All" check box logic
- Swapped multiple main select form operations with their thread-safe alternatives (fixes game scanning lockups)
- Extra text in the selection forms are now highlighted the same as nodes and can be left/right clicked
This commit is contained in:
pointfeev 2022-08-24 22:56:26 -04:00
parent 600e6e71f9
commit 91880aa698
15 changed files with 650 additions and 424 deletions

View file

@ -65,7 +65,7 @@ internal class ContextMenuItem : ToolStripMenuItem
item.Image = image; item.Image = image;
} }
} }
}).ConfigureAwait(false); });
private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null) => await Task.Run(async () => private static async Task TryImageIdentifierInfo(ContextMenuItem item, (string id, string iconUrl) imageIdentifierInfo, Action onFail = null) => await Task.Run(async () =>
{ {
@ -83,7 +83,7 @@ internal class ContextMenuItem : ToolStripMenuItem
else if (onFail is not null) else if (onFail is not null)
onFail(); onFail();
} }
}).ConfigureAwait(false); });
private readonly EventHandler OnClickEvent; private readonly EventHandler OnClickEvent;
protected override void OnClick(EventArgs e) protected override void OnClick(EventArgs e)

View file

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace CreamInstaller.Components; namespace CreamInstaller.Components;
@ -21,35 +23,126 @@ internal class CustomTreeView : TreeView
TreeViewNodeSorter = PlatformIdComparer.NodeName; TreeViewNodeSorter = PlatformIdComparer.NodeName;
} }
private readonly Dictionary<TreeNode, Rectangle> selectionBounds = new();
private readonly Dictionary<ProgramSelection, Rectangle> checkBoxBounds = new();
private const string koaloaderToggleString = "Koaloader";
private void DrawTreeNode(object sender, DrawTreeNodeEventArgs e) private void DrawTreeNode(object sender, DrawTreeNodeEventArgs e)
{ {
e.DrawDefault = true; e.DrawDefault = true;
TreeNode node = e.Node; TreeNode node = e.Node;
if (!node.IsVisible) if (!node.IsVisible)
return; return;
bool highlighted = node.IsSelected && SelectedNode == node && ContainsFocus;
string subText = node.Name; Form form = FindForm();
Platform? platform = node.Tag as Platform?; if (form is not SelectForm and not SelectDialogForm)
string tagText = platform?.ToString(); return;
if (string.IsNullOrWhiteSpace(subText) || string.IsNullOrWhiteSpace(tagText) || subText == "PL")
string platformId = node.Name;
Platform platform = (node.Tag as Platform?).GetValueOrDefault(Platform.None);
if (string.IsNullOrWhiteSpace(platformId) || platform is Platform.None)
return; return;
Graphics graphics = e.Graphics; Graphics graphics = e.Graphics;
Color backColor = BackColor; using SolidBrush backBrush = new(BackColor);
using SolidBrush brush = new(backColor); using SolidBrush highlightBrush = new(SystemColors.Highlight);
Font font = Font; Font font = Font;
Rectangle bounds = node.Bounds; Size lastSize;
Rectangle lastBounds = node.Bounds;
Rectangle selectionBounds = lastBounds;
Point lastPoint;
Size tagSize = TextRenderer.MeasureText(graphics, tagText, font); string tagText = platform.ToString();
Rectangle tagBounds = new(bounds.X + bounds.Width, bounds.Y, tagSize.Width, bounds.Height); lastSize = TextRenderer.MeasureText(graphics, tagText, font);
graphics.FillRectangle(brush, tagBounds); lastBounds = new(lastBounds.X + lastBounds.Width, lastBounds.Y, lastSize.Width, lastBounds.Height);
Point tagLocation = new(tagBounds.Location.X - 1, tagBounds.Location.Y + 1); selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(lastBounds.Size.Width, 0));
TextRenderer.DrawText(graphics, tagText, font, tagLocation, Color.Gray); graphics.FillRectangle(highlighted ? highlightBrush : backBrush, lastBounds);
lastPoint = new(lastBounds.Location.X - 1, lastBounds.Location.Y + 1);
TextRenderer.DrawText(graphics, tagText, font, lastPoint, highlighted ? ColorTranslator.FromHtml("#FFFF99") : Enabled ? ColorTranslator.FromHtml("#696900") : ColorTranslator.FromHtml("#AAAA69"));
Size subSize = TextRenderer.MeasureText(graphics, subText, font); if (platform is not Platform.Paradox)
Rectangle subBounds = new(tagBounds.X + tagBounds.Width - 4, bounds.Y, subSize.Width, bounds.Height); {
graphics.FillRectangle(brush, subBounds); string subText = platformId.ToString();
Point subLocation = new(subBounds.Location.X - 1, subBounds.Location.Y + 1); lastSize = TextRenderer.MeasureText(graphics, subText, font);
TextRenderer.DrawText(graphics, subText, font, subLocation, Color.LightSlateGray); lastBounds = new(lastBounds.X + lastBounds.Width - 4, lastBounds.Y, lastSize.Width, lastBounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(lastBounds.Size.Width - 4, 0));
graphics.FillRectangle(highlighted ? highlightBrush : backBrush, lastBounds);
lastPoint = new(lastBounds.Location.X - 1, lastBounds.Location.Y + 1);
TextRenderer.DrawText(graphics, subText, font, lastPoint, highlighted ? ColorTranslator.FromHtml("#99FFFF") : Enabled ? ColorTranslator.FromHtml("#006969") : ColorTranslator.FromHtml("#69AAAA"));
}
if (form is SelectForm)
{
ProgramSelection selection = ProgramSelection.FromPlatformId(platform, platformId);
if (selection is not null)
{
if (lastBounds == node.Bounds)
{
lastSize = new(4, 0);
lastBounds = new(lastBounds.X + lastBounds.Width, lastBounds.Y, lastSize.Width, lastBounds.Height);
graphics.FillRectangle(highlighted ? highlightBrush : backBrush, lastBounds);
}
CheckBoxState checkBoxState = selection.Koaloader ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
lastSize = CheckBoxRenderer.GetGlyphSize(graphics, checkBoxState);
lastBounds = new(lastBounds.X + lastBounds.Width, lastBounds.Y, lastSize.Width, lastBounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(lastBounds.Size.Width, 0));
Rectangle checkBoxBounds = lastBounds;
graphics.FillRectangle(backBrush, lastBounds);
lastPoint = new(lastBounds.Left, lastBounds.Top + lastBounds.Height / 2 - lastSize.Height / 2 - 1);
CheckBoxRenderer.DrawCheckBox(graphics, lastPoint, checkBoxState);
lastSize = TextRenderer.MeasureText(graphics, koaloaderToggleString, font);
int left = 1;
lastBounds = new(lastBounds.X + lastBounds.Width, lastBounds.Y, lastSize.Width + left, lastBounds.Height);
selectionBounds = new(selectionBounds.Location, selectionBounds.Size + new Size(lastBounds.Size.Width + left, 0));
checkBoxBounds = new(checkBoxBounds.Location, checkBoxBounds.Size + new Size(lastBounds.Size.Width + left, 0));
graphics.FillRectangle(backBrush, lastBounds);
lastPoint = new(lastBounds.Location.X - 1 + left, lastBounds.Location.Y + 1);
TextRenderer.DrawText(graphics, koaloaderToggleString, font, lastPoint, Enabled ? ColorTranslator.FromHtml("#006900") : ColorTranslator.FromHtml("#69AA69"));
this.checkBoxBounds[selection] = RectangleToClient(checkBoxBounds);
}
}
this.selectionBounds[node] = RectangleToClient(selectionBounds);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Refresh();
Point clickPoint = PointToClient(e.Location);
foreach (KeyValuePair<TreeNode, Rectangle> pair in selectionBounds)
if (pair.Key.IsVisible && pair.Value.Contains(clickPoint))
{
SelectedNode = pair.Key;
if (e.Button is MouseButtons.Right && FindForm() is SelectForm selectForm)
selectForm.OnNodeRightClick(pair.Key, e.Location);
break;
}
if (e.Button is MouseButtons.Left)
{
bool invalidate = false;
foreach (KeyValuePair<ProgramSelection, Rectangle> pair in checkBoxBounds)
if (pair.Value.Contains(clickPoint))
{
pair.Key.Koaloader = !pair.Key.Koaloader;
invalidate = true;
break;
}
if (invalidate)
{
Invalidate();
if (FindForm() is SelectForm selectForm)
{
CheckBox koaloaderAllCheckBox = selectForm.KoaloaderAllCheckBox();
koaloaderAllCheckBox.CheckedChanged -= selectForm.OnKoaloaderAllCheckBoxChanged;
koaloaderAllCheckBox.Checked = ProgramSelection.AllSafe.TrueForAll(selection => selection.Koaloader);
koaloaderAllCheckBox.CheckedChanged += selectForm.OnKoaloaderAllCheckBoxChanged;
}
}
}
} }
} }

View file

@ -151,6 +151,7 @@
<PackageReference Include="HtmlAgilityPack" Version="1.11.45" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.45" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Onova" Version="2.6.2" /> <PackageReference Include="Onova" Version="2.6.2" />
<PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Forms\SelectDialogForm.cs"> <Compile Update="Forms\SelectDialogForm.cs">

View file

@ -50,7 +50,7 @@ internal partial class InstallForm : CustomForm
{ {
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.AppendText(text, color);
logTextBox.Refresh(); logTextBox.Invalidate();
}); });
} }
} }
@ -63,6 +63,81 @@ internal partial class InstallForm : CustomForm
UpdateUser($"Repairing Paradox Launcher . . . ", InstallationLog.Operation); UpdateUser($"Repairing Paradox Launcher . . . ", InstallationLog.Operation);
_ = await Repair(this, selection); _ = await Repair(this, selection);
} }
if (Uninstalling || !selection.Koaloader)
{
foreach (string directory in selection.ExecutableDirectories)
{
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(Resources.Resources.ResourceIdentifier.Koaloader))
|| Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll))
|| File.Exists(config))
{
UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
await Koaloader.Uninstall(directory, this);
}
}
}
bool uninstallProxy = Uninstalling || selection.Koaloader;
int count = selection.DllDirectories.Count, cur = 0;
foreach (string directory in selection.DllDirectories)
{
if (selection.Platform is Platform.Steam || selection.SelectedDlc.Any(d => d.Value.type is DlcType.Steam or DlcType.SteamHidden)
|| selection.Platform is Platform.Paradox || selection.ExtraSelectedDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.Steam or DlcType.SteamHidden)))
{
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) || File.Exists(api64))
|| uninstallProxy && (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(cache)))
{
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} SmokeAPI" +
$" {(uninstallProxy ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (uninstallProxy)
await SmokeAPI.Uninstall(directory, this);
else
await SmokeAPI.Install(directory, selection, this);
}
}
if (selection.Platform is Platform.Epic || selection.SelectedDlc.Any(d => d.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)
|| selection.Platform is Platform.Paradox || selection.ExtraSelectedDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)))
{
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64, out string api64_o, out string config);
if (!uninstallProxy && (File.Exists(api32) || File.Exists(api64))
|| uninstallProxy && (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)))
{
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} ScreamAPI" +
$" {(uninstallProxy ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (uninstallProxy)
await ScreamAPI.Uninstall(directory, this);
else
await ScreamAPI.Install(directory, selection, this);
}
}
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) || File.Exists(api64))
|| uninstallProxy && (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)))
{
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" +
$" {(uninstallProxy ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.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);
if (!uninstallProxy && (File.Exists(old_api32) || File.Exists(old_api64) || File.Exists(api32) || File.Exists(api64))
|| uninstallProxy && (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config)))
{
UpdateUser($"{(uninstallProxy ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" +
$" {(uninstallProxy ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (uninstallProxy)
await UplayR2.Uninstall(directory, this);
else
await UplayR2.Install(directory, selection, this);
}
}
UpdateProgress(++cur / count * 100);
}
if (selection.Koaloader && !Uninstalling) if (selection.Koaloader && !Uninstalling)
{ {
foreach (string directory in selection.ExecutableDirectories) foreach (string directory in selection.ExecutableDirectories)
@ -71,79 +146,6 @@ internal partial class InstallForm : CustomForm
await Koaloader.Install(directory, selection, this); await Koaloader.Install(directory, selection, this);
} }
} }
else
{
if (Uninstalling)
{
foreach (string directory in selection.ExecutableDirectories)
{
directory.GetKoaloaderComponents(out List<string> proxies, out string config);
if (proxies.Any(proxy => File.Exists(proxy) && proxy.IsResourceFile(Resources.Resources.ResourceIdentifier.Koaloader))
|| Koaloader.AutoLoadDlls.Any(pair => File.Exists(directory + @"\" + pair.dll))
|| File.Exists(config))
{
UpdateUser("Uninstalling Koaloader from " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
await Koaloader.Uninstall(directory, this);
}
}
}
int count = selection.DllDirectories.Count, cur = 0;
foreach (string directory in selection.DllDirectories)
{
if (selection.Platform is Platform.Steam || selection.SelectedDlc.Any(d => d.Value.type is DlcType.Steam or DlcType.SteamHidden)
|| selection.Platform is Platform.Paradox || selection.ExtraSelectedDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.Steam or DlcType.SteamHidden)))
{
directory.GetSmokeApiComponents(out _, out string api32_o, out _, out string api64_o, out string config, out string cache);
if (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config) || File.Exists(cache))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} SmokeAPI" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await SmokeAPI.Uninstall(directory, this);
else
await SmokeAPI.Install(directory, selection, this);
}
}
if (selection.Platform is Platform.Epic || selection.SelectedDlc.Any(d => d.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)
|| selection.Platform is Platform.Paradox || selection.ExtraSelectedDlc.Any(item => item.dlc.Any(dlc => dlc.Value.type is DlcType.EpicCatalogItem or DlcType.EpicEntitlement)))
{
directory.GetScreamApiComponents(out _, out string api32_o, out _, out string api64_o, out string config);
if (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} ScreamAPI" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await ScreamAPI.Uninstall(directory, this);
else
await ScreamAPI.Install(directory, selection, this);
}
}
if (selection.Platform is Platform.Ubisoft)
{
directory.GetUplayR1Components(out _, out string api32_o, out _, out string api64_o, out string config);
if (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} Uplay R1 Unlocker" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await UplayR1.Uninstall(directory, this);
else
await UplayR1.Install(directory, selection, this);
}
directory.GetUplayR2Components(out _, out _, out _, out api32_o, out _, out api64_o, out config);
if (File.Exists(api32_o) || File.Exists(api64_o) || File.Exists(config))
{
UpdateUser($"{(Uninstalling ? "Uninstalling" : "Installing")} Uplay R2 Unlocker" +
$" {(Uninstalling ? "from" : "for")} " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (Uninstalling)
await UplayR2.Uninstall(directory, this);
else
await UplayR2.Install(directory, selection, this);
}
}
UpdateProgress(++cur / count * 100);
}
}
UpdateProgress(100); UpdateProgress(100);
} }

View file

@ -56,7 +56,7 @@ internal partial class MainForm : CustomForm
progressLabel.Text = "Checking for updates . . ."; progressLabel.Text = "Checking for updates . . .";
changelogTreeView.Visible = false; changelogTreeView.Visible = false;
changelogTreeView.Location = new(progressLabel.Location.X, progressLabel.Location.Y + progressLabel.Size.Height + 13); changelogTreeView.Location = new(progressLabel.Location.X, progressLabel.Location.Y + progressLabel.Size.Height + 13);
Refresh(); Invalidate();
GithubPackageResolver resolver = new("pointfeev", "CreamInstaller", "CreamInstaller.zip"); GithubPackageResolver resolver = new("pointfeev", "CreamInstaller", "CreamInstaller.zip");
ZipPackageExtractor extractor = new(); ZipPackageExtractor extractor = new();
@ -181,7 +181,7 @@ internal partial class MainForm : CustomForm
updateButton.Click -= OnUpdate; updateButton.Click -= OnUpdate;
updateButton.Click += new(OnUpdateCancel); updateButton.Click += new(OnUpdateCancel);
changelogTreeView.Location = new(progressBar.Location.X, progressBar.Location.Y + progressBar.Size.Height + 6); changelogTreeView.Location = new(progressBar.Location.X, progressBar.Location.Y + progressBar.Size.Height + 6);
Refresh(); Invalidate();
Progress<double> progress = new(); Progress<double> progress = new();
progress.ProgressChanged += new(delegate (object sender, double _progress) progress.ProgressChanged += new(delegate (object sender, double _progress)

View file

@ -53,7 +53,7 @@ namespace CreamInstaller
this.acceptButton.Name = "acceptButton"; this.acceptButton.Name = "acceptButton";
this.acceptButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.acceptButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.acceptButton.Size = new System.Drawing.Size(61, 24); this.acceptButton.Size = new System.Drawing.Size(61, 24);
this.acceptButton.TabIndex = 1; this.acceptButton.TabIndex = 6;
this.acceptButton.Text = "OK"; this.acceptButton.Text = "OK";
this.acceptButton.UseVisualStyleBackColor = true; this.acceptButton.UseVisualStyleBackColor = true;
// //
@ -108,7 +108,7 @@ namespace CreamInstaller
this.allCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.allCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.allCheckBox.Name = "allCheckBox"; this.allCheckBox.Name = "allCheckBox";
this.allCheckBox.Size = new System.Drawing.Size(34, 19); this.allCheckBox.Size = new System.Drawing.Size(34, 19);
this.allCheckBox.TabIndex = 2; this.allCheckBox.TabIndex = 1;
this.allCheckBox.Text = "All"; this.allCheckBox.Text = "All";
this.allCheckBox.CheckedChanged += new System.EventHandler(this.OnAllCheckBoxChanged); this.allCheckBox.CheckedChanged += new System.EventHandler(this.OnAllCheckBoxChanged);
// //
@ -121,7 +121,7 @@ namespace CreamInstaller
this.sortCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.sortCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.sortCheckBox.Name = "sortCheckBox"; this.sortCheckBox.Name = "sortCheckBox";
this.sortCheckBox.Size = new System.Drawing.Size(104, 20); this.sortCheckBox.Size = new System.Drawing.Size(104, 20);
this.sortCheckBox.TabIndex = 2; this.sortCheckBox.TabIndex = 3;
this.sortCheckBox.Text = "Sort By Name"; this.sortCheckBox.Text = "Sort By Name";
this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged); this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged);
// //
@ -136,7 +136,7 @@ namespace CreamInstaller
this.cancelButton.Name = "cancelButton"; this.cancelButton.Name = "cancelButton";
this.cancelButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.cancelButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.cancelButton.Size = new System.Drawing.Size(81, 24); this.cancelButton.Size = new System.Drawing.Size(81, 24);
this.cancelButton.TabIndex = 0; this.cancelButton.TabIndex = 2;
this.cancelButton.Text = "Cancel"; this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true; this.cancelButton.UseVisualStyleBackColor = true;
// //
@ -151,7 +151,7 @@ namespace CreamInstaller
this.loadButton.Name = "loadButton"; this.loadButton.Name = "loadButton";
this.loadButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.loadButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.loadButton.Size = new System.Drawing.Size(71, 24); this.loadButton.Size = new System.Drawing.Size(71, 24);
this.loadButton.TabIndex = 4; this.loadButton.TabIndex = 5;
this.loadButton.Text = "Load"; this.loadButton.Text = "Load";
this.loadButton.UseVisualStyleBackColor = true; this.loadButton.UseVisualStyleBackColor = true;
this.loadButton.Click += new System.EventHandler(this.OnLoad); this.loadButton.Click += new System.EventHandler(this.OnLoad);
@ -167,7 +167,7 @@ namespace CreamInstaller
this.saveButton.Name = "saveButton"; this.saveButton.Name = "saveButton";
this.saveButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.saveButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.saveButton.Size = new System.Drawing.Size(69, 24); this.saveButton.Size = new System.Drawing.Size(69, 24);
this.saveButton.TabIndex = 5; this.saveButton.TabIndex = 4;
this.saveButton.Text = "Save"; this.saveButton.Text = "Save";
this.saveButton.UseVisualStyleBackColor = true; this.saveButton.UseVisualStyleBackColor = true;
this.saveButton.Click += new System.EventHandler(this.OnSave); this.saveButton.Click += new System.EventHandler(this.OnSave);

View file

@ -31,10 +31,14 @@ namespace CreamInstaller
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.components = new System.ComponentModel.Container();
this.installButton = new System.Windows.Forms.Button(); this.installButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox1 = new System.Windows.Forms.GroupBox();
this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel();
this.koaloaderAllCheckBox = new System.Windows.Forms.CheckBox();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.noneFoundLabel = new System.Windows.Forms.Label(); this.noneFoundLabel = new System.Windows.Forms.Label();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.blockedGamesCheckBox = new System.Windows.Forms.CheckBox(); this.blockedGamesCheckBox = new System.Windows.Forms.CheckBox();
@ -49,7 +53,9 @@ namespace CreamInstaller
this.progressLabelGames = new System.Windows.Forms.Label(); this.progressLabelGames = new System.Windows.Forms.Label();
this.progressLabelDLCs = new System.Windows.Forms.Label(); this.progressLabelDLCs = new System.Windows.Forms.Label();
this.sortCheckBox = new System.Windows.Forms.CheckBox(); this.sortCheckBox = new System.Windows.Forms.CheckBox();
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.groupBox1.SuspendLayout(); this.groupBox1.SuspendLayout();
this.flowLayoutPanel4.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout(); this.flowLayoutPanel2.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@ -65,7 +71,7 @@ namespace CreamInstaller
this.installButton.Name = "installButton"; this.installButton.Name = "installButton";
this.installButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.installButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.installButton.Size = new System.Drawing.Size(149, 24); this.installButton.Size = new System.Drawing.Size(149, 24);
this.installButton.TabIndex = 10003; this.installButton.TabIndex = 10004;
this.installButton.Text = "Generate and Install"; this.installButton.Text = "Generate and Install";
this.installButton.UseVisualStyleBackColor = true; this.installButton.UseVisualStyleBackColor = true;
this.installButton.Click += new System.EventHandler(this.OnInstall); this.installButton.Click += new System.EventHandler(this.OnInstall);
@ -97,6 +103,8 @@ namespace CreamInstaller
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.flowLayoutPanel4);
this.groupBox1.Controls.Add(this.flowLayoutPanel3);
this.groupBox1.Controls.Add(this.noneFoundLabel); this.groupBox1.Controls.Add(this.noneFoundLabel);
this.groupBox1.Controls.Add(this.flowLayoutPanel1); this.groupBox1.Controls.Add(this.flowLayoutPanel1);
this.groupBox1.Controls.Add(this.selectionTreeView); this.groupBox1.Controls.Add(this.selectionTreeView);
@ -109,6 +117,46 @@ namespace CreamInstaller
this.groupBox1.TabStop = false; this.groupBox1.TabStop = false;
this.groupBox1.Text = "Programs / Games"; this.groupBox1.Text = "Programs / Games";
// //
// flowLayoutPanel4
//
this.flowLayoutPanel4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.flowLayoutPanel4.AutoSize = true;
this.flowLayoutPanel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel4.Controls.Add(this.koaloaderAllCheckBox);
this.flowLayoutPanel4.Location = new System.Drawing.Point(420, -1);
this.flowLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel4.Name = "flowLayoutPanel4";
this.flowLayoutPanel4.Size = new System.Drawing.Size(75, 19);
this.flowLayoutPanel4.TabIndex = 10005;
this.flowLayoutPanel4.WrapContents = false;
//
// koaloaderAllCheckBox
//
this.koaloaderAllCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.koaloaderAllCheckBox.Checked = true;
this.koaloaderAllCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.koaloaderAllCheckBox.Enabled = false;
this.koaloaderAllCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.koaloaderAllCheckBox.Location = new System.Drawing.Point(3, 0);
this.koaloaderAllCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.koaloaderAllCheckBox.Name = "koaloaderAllCheckBox";
this.koaloaderAllCheckBox.Size = new System.Drawing.Size(72, 19);
this.koaloaderAllCheckBox.TabIndex = 4;
this.koaloaderAllCheckBox.Text = "Koaloader";
this.koaloaderAllCheckBox.CheckedChanged += new System.EventHandler(this.OnKoaloaderAllCheckBoxChanged);
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.flowLayoutPanel3.AutoSize = true;
this.flowLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel3.Location = new System.Drawing.Point(500, -1);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(0, 0);
this.flowLayoutPanel3.TabIndex = 1007;
this.flowLayoutPanel3.WrapContents = false;
//
// noneFoundLabel // noneFoundLabel
// //
this.noneFoundLabel.Dock = System.Windows.Forms.DockStyle.Fill; this.noneFoundLabel.Dock = System.Windows.Forms.DockStyle.Fill;
@ -127,15 +175,15 @@ namespace CreamInstaller
this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel1.Controls.Add(this.blockedGamesCheckBox); this.flowLayoutPanel1.Controls.Add(this.blockedGamesCheckBox);
this.flowLayoutPanel1.Controls.Add(this.blockProtectedHelpButton); this.flowLayoutPanel1.Controls.Add(this.blockProtectedHelpButton);
this.flowLayoutPanel1.Location = new System.Drawing.Point(224, -1); this.flowLayoutPanel1.Location = new System.Drawing.Point(124, -1);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1"; this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(179, 20); this.flowLayoutPanel1.Size = new System.Drawing.Size(165, 20);
this.flowLayoutPanel1.TabIndex = 1005; this.flowLayoutPanel1.TabIndex = 1005;
this.flowLayoutPanel1.WrapContents = false;
// //
// blockedGamesCheckBox // blockedGamesCheckBox
// //
this.blockedGamesCheckBox.AutoSize = true;
this.blockedGamesCheckBox.Checked = true; this.blockedGamesCheckBox.Checked = true;
this.blockedGamesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; this.blockedGamesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.blockedGamesCheckBox.Enabled = false; this.blockedGamesCheckBox.Enabled = false;
@ -143,8 +191,8 @@ namespace CreamInstaller
this.blockedGamesCheckBox.Location = new System.Drawing.Point(3, 0); this.blockedGamesCheckBox.Location = new System.Drawing.Point(3, 0);
this.blockedGamesCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.blockedGamesCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.blockedGamesCheckBox.Name = "blockedGamesCheckBox"; this.blockedGamesCheckBox.Name = "blockedGamesCheckBox";
this.blockedGamesCheckBox.Size = new System.Drawing.Size(154, 20); this.blockedGamesCheckBox.Size = new System.Drawing.Size(140, 20);
this.blockedGamesCheckBox.TabIndex = 1003; this.blockedGamesCheckBox.TabIndex = 1;
this.blockedGamesCheckBox.Text = "Block Protected Games"; this.blockedGamesCheckBox.Text = "Block Protected Games";
this.blockedGamesCheckBox.UseVisualStyleBackColor = true; this.blockedGamesCheckBox.UseVisualStyleBackColor = true;
this.blockedGamesCheckBox.CheckedChanged += new System.EventHandler(this.OnBlockProtectedGamesCheckBoxChanged); this.blockedGamesCheckBox.CheckedChanged += new System.EventHandler(this.OnBlockProtectedGamesCheckBoxChanged);
@ -154,11 +202,11 @@ namespace CreamInstaller
this.blockProtectedHelpButton.Enabled = false; this.blockProtectedHelpButton.Enabled = false;
this.blockProtectedHelpButton.FlatStyle = System.Windows.Forms.FlatStyle.System; this.blockProtectedHelpButton.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.blockProtectedHelpButton.Font = new System.Drawing.Font("Segoe UI", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); this.blockProtectedHelpButton.Font = new System.Drawing.Font("Segoe UI", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.blockProtectedHelpButton.Location = new System.Drawing.Point(157, 0); this.blockProtectedHelpButton.Location = new System.Drawing.Point(143, 0);
this.blockProtectedHelpButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0); this.blockProtectedHelpButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.blockProtectedHelpButton.Name = "blockProtectedHelpButton"; this.blockProtectedHelpButton.Name = "blockProtectedHelpButton";
this.blockProtectedHelpButton.Size = new System.Drawing.Size(19, 19); this.blockProtectedHelpButton.Size = new System.Drawing.Size(19, 19);
this.blockProtectedHelpButton.TabIndex = 1004; this.blockProtectedHelpButton.TabIndex = 2;
this.blockProtectedHelpButton.Text = "?"; this.blockProtectedHelpButton.Text = "?";
this.blockProtectedHelpButton.UseVisualStyleBackColor = true; this.blockProtectedHelpButton.UseVisualStyleBackColor = true;
this.blockProtectedHelpButton.Click += new System.EventHandler(this.OnBlockProtectedGamesHelpButtonClicked); this.blockProtectedHelpButton.Click += new System.EventHandler(this.OnBlockProtectedGamesHelpButtonClicked);
@ -184,11 +232,12 @@ namespace CreamInstaller
this.flowLayoutPanel2.AutoSize = true; this.flowLayoutPanel2.AutoSize = true;
this.flowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.flowLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel2.Controls.Add(this.allCheckBox); this.flowLayoutPanel2.Controls.Add(this.allCheckBox);
this.flowLayoutPanel2.Location = new System.Drawing.Point(517, -1); this.flowLayoutPanel2.Location = new System.Drawing.Point(515, -1);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2"; this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(37, 19); this.flowLayoutPanel2.Size = new System.Drawing.Size(37, 19);
this.flowLayoutPanel2.TabIndex = 1006; this.flowLayoutPanel2.TabIndex = 1006;
this.flowLayoutPanel2.WrapContents = false;
// //
// allCheckBox // allCheckBox
// //
@ -201,7 +250,7 @@ namespace CreamInstaller
this.allCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.allCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.allCheckBox.Name = "allCheckBox"; this.allCheckBox.Name = "allCheckBox";
this.allCheckBox.Size = new System.Drawing.Size(34, 19); this.allCheckBox.Size = new System.Drawing.Size(34, 19);
this.allCheckBox.TabIndex = 1; this.allCheckBox.TabIndex = 4;
this.allCheckBox.Text = "All"; this.allCheckBox.Text = "All";
this.allCheckBox.CheckedChanged += new System.EventHandler(this.OnAllCheckBoxChanged); this.allCheckBox.CheckedChanged += new System.EventHandler(this.OnAllCheckBoxChanged);
// //
@ -235,7 +284,7 @@ namespace CreamInstaller
this.scanButton.Name = "scanButton"; this.scanButton.Name = "scanButton";
this.scanButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.scanButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.scanButton.Size = new System.Drawing.Size(82, 24); this.scanButton.Size = new System.Drawing.Size(82, 24);
this.scanButton.TabIndex = 10001; this.scanButton.TabIndex = 10002;
this.scanButton.Text = "Rescan"; this.scanButton.Text = "Rescan";
this.scanButton.UseVisualStyleBackColor = true; this.scanButton.UseVisualStyleBackColor = true;
this.scanButton.Click += new System.EventHandler(this.OnScan); this.scanButton.Click += new System.EventHandler(this.OnScan);
@ -251,7 +300,7 @@ namespace CreamInstaller
this.uninstallButton.Name = "uninstallButton"; this.uninstallButton.Name = "uninstallButton";
this.uninstallButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0); this.uninstallButton.Padding = new System.Windows.Forms.Padding(12, 0, 12, 0);
this.uninstallButton.Size = new System.Drawing.Size(91, 24); this.uninstallButton.Size = new System.Drawing.Size(91, 24);
this.uninstallButton.TabIndex = 10002; this.uninstallButton.TabIndex = 10003;
this.uninstallButton.Text = "Uninstall"; this.uninstallButton.Text = "Uninstall";
this.uninstallButton.UseVisualStyleBackColor = true; this.uninstallButton.UseVisualStyleBackColor = true;
this.uninstallButton.Click += new System.EventHandler(this.OnUninstall); this.uninstallButton.Click += new System.EventHandler(this.OnUninstall);
@ -275,7 +324,7 @@ namespace CreamInstaller
this.progressLabelDLCs.Location = new System.Drawing.Point(12, 281); this.progressLabelDLCs.Location = new System.Drawing.Point(12, 281);
this.progressLabelDLCs.Name = "progressLabelDLCs"; this.progressLabelDLCs.Name = "progressLabelDLCs";
this.progressLabelDLCs.Size = new System.Drawing.Size(560, 12); this.progressLabelDLCs.Size = new System.Drawing.Size(560, 12);
this.progressLabelDLCs.TabIndex = 10004; this.progressLabelDLCs.TabIndex = 12;
this.progressLabelDLCs.Text = "Remaining DLC (2): 123456, 654321"; this.progressLabelDLCs.Text = "Remaining DLC (2): 123456, 654321";
// //
// sortCheckBox // sortCheckBox
@ -287,10 +336,19 @@ namespace CreamInstaller
this.sortCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0); this.sortCheckBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.sortCheckBox.Name = "sortCheckBox"; this.sortCheckBox.Name = "sortCheckBox";
this.sortCheckBox.Size = new System.Drawing.Size(104, 20); this.sortCheckBox.Size = new System.Drawing.Size(104, 20);
this.sortCheckBox.TabIndex = 1; this.sortCheckBox.TabIndex = 10001;
this.sortCheckBox.Text = "Sort By Name"; this.sortCheckBox.Text = "Sort By Name";
this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged); this.sortCheckBox.CheckedChanged += new System.EventHandler(this.OnSortCheckBoxChanged);
// //
// contextMenuStrip
//
this.contextMenuStrip.AllowMerge = false;
this.contextMenuStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.contextMenuStrip.Name = "contextMenuStrip";
this.contextMenuStrip.ShowItemToolTips = false;
this.contextMenuStrip.Size = new System.Drawing.Size(181, 26);
this.contextMenuStrip.TabStop = true;
//
// SelectForm // SelectForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
@ -319,8 +377,8 @@ namespace CreamInstaller
this.Load += new System.EventHandler(this.OnLoad); this.Load += new System.EventHandler(this.OnLoad);
this.groupBox1.ResumeLayout(false); this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout(); this.groupBox1.PerformLayout();
this.flowLayoutPanel4.ResumeLayout(false);
this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
this.flowLayoutPanel2.ResumeLayout(false); this.flowLayoutPanel2.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -338,7 +396,7 @@ namespace CreamInstaller
private System.Windows.Forms.CheckBox allCheckBox; private System.Windows.Forms.CheckBox allCheckBox;
private Button scanButton; private Button scanButton;
private Label noneFoundLabel; private Label noneFoundLabel;
private CreamInstaller.Components.CustomTreeView selectionTreeView; private Components.CustomTreeView selectionTreeView;
private CheckBox blockedGamesCheckBox; private CheckBox blockedGamesCheckBox;
private Button blockProtectedHelpButton; private Button blockProtectedHelpButton;
private FlowLayoutPanel flowLayoutPanel1; private FlowLayoutPanel flowLayoutPanel1;
@ -347,6 +405,10 @@ namespace CreamInstaller
private Label progressLabelGames; private Label progressLabelGames;
private Label progressLabelDLCs; private Label progressLabelDLCs;
private CheckBox sortCheckBox; private CheckBox sortCheckBox;
private FlowLayoutPanel flowLayoutPanel3;
private ContextMenuStrip contextMenuStrip;
private FlowLayoutPanel flowLayoutPanel4;
private CheckBox koaloaderAllCheckBox;
} }
} }

View file

@ -31,10 +31,10 @@ internal partial class SelectForm : CustomForm
Text = Program.ApplicationName; Text = Program.ApplicationName;
} }
private static void UpdateRemaining(Label label, List<string> list, string descriptor) => private static void UpdateRemaining(Label label, SynchronizedCollection<string> list, string descriptor) =>
label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : ""; label.Text = list.Any() ? $"Remaining {descriptor} ({list.Count}): " + string.Join(", ", list).Replace("&", "&&") : "";
private readonly List<string> RemainingGames = new(); private readonly SynchronizedCollection<string> RemainingGames = new();
private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, RemainingGames, "games"); private void UpdateRemainingGames() => UpdateRemaining(progressLabelGames, RemainingGames, "games");
private void AddToRemainingGames(string gameName) private void AddToRemainingGames(string gameName)
{ {
@ -53,13 +53,12 @@ internal partial class SelectForm : CustomForm
Program.Invoke(progressLabelGames, delegate Program.Invoke(progressLabelGames, delegate
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
if (RemainingGames.Contains(gameName)) RemainingGames.Remove(gameName);
_ = RemainingGames.Remove(gameName);
UpdateRemainingGames(); UpdateRemainingGames();
}); });
} }
private readonly List<string> RemainingDLCs = new(); private readonly SynchronizedCollection<string> RemainingDLCs = new();
private void UpdateRemainingDLCs() => UpdateRemaining(progressLabelDLCs, RemainingDLCs, "DLCs"); private void UpdateRemainingDLCs() => UpdateRemaining(progressLabelDLCs, RemainingDLCs, "DLCs");
private void AddToRemainingDLCs(string dlcId) private void AddToRemainingDLCs(string dlcId)
{ {
@ -78,8 +77,7 @@ internal partial class SelectForm : CustomForm
Program.Invoke(progressLabelDLCs, delegate Program.Invoke(progressLabelDLCs, delegate
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
if (RemainingDLCs.Contains(dlcId)) RemainingDLCs.Remove(dlcId);
_ = RemainingDLCs.Remove(dlcId);
UpdateRemainingDLCs(); UpdateRemainingDLCs();
}); });
} }
@ -92,13 +90,13 @@ internal partial class SelectForm : CustomForm
void AddToRemainingGames(string gameName) void AddToRemainingGames(string gameName)
{ {
this.AddToRemainingGames(gameName); this.AddToRemainingGames(gameName);
progress.Report(-++TotalGameCount); progress.Report(-Interlocked.Increment(ref TotalGameCount));
progress.Report(CompleteGameCount); progress.Report(CompleteGameCount);
} }
void RemoveFromRemainingGames(string gameName) void RemoveFromRemainingGames(string gameName)
{ {
this.RemoveFromRemainingGames(gameName); this.RemoveFromRemainingGames(gameName);
progress.Report(++CompleteGameCount); progress.Report(Interlocked.Increment(ref CompleteGameCount));
} }
if (Program.Canceled) return; if (Program.Canceled) return;
List<TreeNode> treeNodes = TreeNodes; List<TreeNode> treeNodes = TreeNodes;
@ -119,6 +117,7 @@ internal partial class SelectForm : CustomForm
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Paradox, "PL"); ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Paradox, "PL");
selection ??= new(); selection ??= new();
if (allCheckBox.Checked) selection.Enabled = true; if (allCheckBox.Checked) selection.Enabled = true;
if (koaloaderAllCheckBox.Checked) selection.Koaloader = true;
selection.Id = "PL"; selection.Id = "PL";
selection.Name = "Paradox Launcher"; selection.Name = "Paradox Launcher";
selection.RootDirectory = ParadoxLauncher.InstallPath; selection.RootDirectory = ParadoxLauncher.InstallPath;
@ -135,17 +134,17 @@ internal partial class SelectForm : CustomForm
_ = selectionTreeView.Nodes.Add(programNode); _ = selectionTreeView.Nodes.Add(programNode);
} }
} }
int totalGames = 0, gamesChecked = 0; int steamGamesToCheck;
if (ProgramsToScan.Any(c => c.platform is Platform.Steam)) 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();
totalGames = steamGames.Count; steamGamesToCheck = steamGames.Count;
foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames) foreach ((string appId, string name, string branch, int buildId, string gameDirectory) in steamGames)
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
if (Program.IsGameBlocked(name, gameDirectory) || !ProgramsToScan.Any(c => c.platform is Platform.Steam && c.id == appId)) if (Program.IsGameBlocked(name, gameDirectory) || !ProgramsToScan.Any(c => c.platform is Platform.Steam && c.id == appId))
{ {
gamesChecked++; Interlocked.Decrement(ref steamGamesToCheck);
continue; continue;
} }
AddToRemainingGames(name); AddToRemainingGames(name);
@ -155,12 +154,12 @@ internal partial class SelectForm : CustomForm
List<string> dllDirectories = await SteamLibrary.GetDllDirectoriesFromGameDirectory(gameDirectory); List<string> dllDirectories = await SteamLibrary.GetDllDirectoriesFromGameDirectory(gameDirectory);
if (dllDirectories is null) if (dllDirectories is null)
{ {
gamesChecked++; Interlocked.Decrement(ref steamGamesToCheck);
RemoveFromRemainingGames(name); RemoveFromRemainingGames(name);
return; return;
} }
AppData appData = await SteamStore.QueryStoreAPI(appId); AppData appData = await SteamStore.QueryStoreAPI(appId);
gamesChecked++; Interlocked.Decrement(ref steamGamesToCheck);
VProperty appInfo = await SteamCMD.GetAppInfo(appId, branch, buildId); VProperty appInfo = await SteamCMD.GetAppInfo(appId, branch, buildId);
if (appData is null && appInfo is null) if (appData is null && appInfo is null)
{ {
@ -183,8 +182,8 @@ internal partial class SelectForm : CustomForm
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
do // give games steam store api limit priority do // give games steam store api limit priority
Thread.Sleep(100); Thread.Sleep(200);
while (!Program.Canceled && gamesChecked < totalGames); while (!Program.Canceled && steamGamesToCheck > 0);
if (Program.Canceled) return; if (Program.Canceled) return;
string dlcName = null; string dlcName = null;
string dlcIcon = null; string dlcIcon = null;
@ -228,9 +227,11 @@ internal partial class SelectForm : CustomForm
if (Program.Canceled) return; if (Program.Canceled) return;
await task; await task;
} }
steamGamesToCheck = 0;
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Steam, appId) ?? new(); ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Steam, appId) ?? new();
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
if (koaloaderAllCheckBox.Checked) selection.Koaloader = true;
selection.Id = appId; selection.Id = appId;
selection.Name = appData?.name ?? name; selection.Name = appData?.name ?? name;
selection.RootDirectory = gameDirectory; selection.RootDirectory = gameDirectory;
@ -338,6 +339,7 @@ internal partial class SelectForm : CustomForm
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) ?? new(); ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Epic, @namespace) ?? new();
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
if (koaloaderAllCheckBox.Checked) selection.Koaloader = true;
selection.Id = @namespace; selection.Id = @namespace;
selection.Name = name; selection.Name = name;
selection.RootDirectory = directory; selection.RootDirectory = directory;
@ -424,6 +426,7 @@ internal partial class SelectForm : CustomForm
ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) ?? new(); ProgramSelection selection = ProgramSelection.FromPlatformId(Platform.Ubisoft, gameId) ?? new();
selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any(); selection.Enabled = allCheckBox.Checked || selection.SelectedDlc.Any() || selection.ExtraSelectedDlc.Any();
if (koaloaderAllCheckBox.Checked) selection.Koaloader = true;
selection.Id = gameId; selection.Id = gameId;
selection.Name = name; selection.Name = name;
selection.RootDirectory = gameDirectory; selection.RootDirectory = gameDirectory;
@ -454,7 +457,7 @@ internal partial class SelectForm : CustomForm
if (Program.Canceled) return; if (Program.Canceled) return;
await task; await task;
} }
gamesChecked = totalGames; steamGamesToCheck = 0;
} }
private List<(Platform platform, string id, string name)> ProgramsToScan; private List<(Platform platform, string id, string name)> ProgramsToScan;
@ -467,6 +470,7 @@ internal partial class SelectForm : CustomForm
scanButton.Enabled = false; scanButton.Enabled = false;
noneFoundLabel.Visible = false; noneFoundLabel.Visible = false;
allCheckBox.Enabled = false; allCheckBox.Enabled = false;
koaloaderAllCheckBox.Enabled = false;
installButton.Enabled = false; installButton.Enabled = false;
uninstallButton.Enabled = installButton.Enabled; uninstallButton.Enabled = installButton.Enabled;
selectionTreeView.Enabled = false; selectionTreeView.Enabled = false;
@ -540,6 +544,7 @@ internal partial class SelectForm : CustomForm
HideProgressBar(); HideProgressBar();
selectionTreeView.Enabled = ProgramSelection.All.Any(); selectionTreeView.Enabled = ProgramSelection.All.Any();
allCheckBox.Enabled = selectionTreeView.Enabled; allCheckBox.Enabled = selectionTreeView.Enabled;
koaloaderAllCheckBox.Enabled = selectionTreeView.Enabled;
noneFoundLabel.Visible = !selectionTreeView.Enabled; noneFoundLabel.Visible = !selectionTreeView.Enabled;
installButton.Enabled = ProgramSelection.AllEnabled.Any(); installButton.Enabled = ProgramSelection.AllEnabled.Any();
uninstallButton.Enabled = installButton.Enabled; uninstallButton.Enabled = installButton.Enabled;
@ -644,6 +649,165 @@ internal partial class SelectForm : CustomForm
+ progressBar.Size.Height); + progressBar.Size.Height);
} }
internal void OnNodeRightClick(TreeNode node, Point location)
{
contextMenuStrip.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));
contextMenuStrip.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<ContextMenuItem> 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",
new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON))));
}
if (File.Exists(appInfoVDF))
queries.Add(new ContextMenuItem("Open SteamCMD Query", "Notepad",
new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoVDF))));
if (queries.Any())
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
foreach (ContextMenuItem query in queries)
contextMenuStrip.Items.Add(query);
contextMenuStrip.Items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt",
new EventHandler((sender, e) =>
{
try
{
File.Delete(appInfoVDF);
}
catch { }
try
{
File.Delete(appInfoJSON);
}
catch { }
try
{
File.Delete(cooldown);
}
catch { }
OnLoad(forceScan: true);
})));
}
}
if (selection is not null)
{
if (id == "PL")
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Repair", "Command Prompt",
new EventHandler(async (sender, e) => await ParadoxLauncher.Repair(this, selection))));
}
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory))));
List<string> directories = selection.ExecutableDirectories.ToList();
int executables = 0;
foreach (string directory in directories)
{
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Executable Directory #{++executables}", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(directory))));
}
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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Epic Online Services Directory #{++epic}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer",
new EventHandler((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)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id))));
}
if (selection is not null)
{
if (selection.Platform is Platform.Steam)
{
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))));
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIconUrl), "Steam Community",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id))));
}
if (selection.Platform is Platform.Epic)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" + id))));
contextMenuStrip.Items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))));
}
if (selection.Platform is Platform.Ubisoft)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
#pragma warning disable CA1308 // Normalize strings to uppercase
contextMenuStrip.Items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
new EventHandler((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)
{
contextMenuStrip.Items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.WebsiteUrl)),
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.WebsiteUrl))));
}
contextMenuStrip.Show(selectionTreeView, location);
contextMenuStrip.Refresh();
}
private void OnLoad(object sender, EventArgs _) private void OnLoad(object sender, EventArgs _)
{ {
retry: retry:
@ -651,161 +815,6 @@ internal partial class SelectForm : CustomForm
{ {
HideProgressBar(); HideProgressBar();
selectionTreeView.AfterCheck += OnTreeViewNodeCheckedChanged; selectionTreeView.AfterCheck += OnTreeViewNodeCheckedChanged;
selectionTreeView.NodeMouseClick += (sender, e) =>
{
TreeNode node = e.Node;
if (node is null || !node.Bounds.Contains(e.Location) || e.Button != MouseButtons.Right || e.Clicks != 1)
return;
ContextMenuStrip contextMenuStrip = new();
selectionTreeView.SelectedNode = node;
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));
contextMenuStrip.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<ContextMenuItem> 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",
new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoJSON))));
}
if (File.Exists(appInfoVDF))
queries.Add(new ContextMenuItem("Open SteamCMD Query", "Notepad",
new EventHandler((sender, e) => Diagnostics.OpenFileInNotepad(appInfoVDF))));
if (queries.Any())
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
foreach (ContextMenuItem query in queries)
contextMenuStrip.Items.Add(query);
contextMenuStrip.Items.Add(new ContextMenuItem("Refresh Queries", "Command Prompt",
new EventHandler((sender, e) =>
{
try
{
File.Delete(appInfoVDF);
}
catch { }
try
{
File.Delete(appInfoJSON);
}
catch { }
try
{
File.Delete(cooldown);
}
catch { }
OnLoad(forceScan: true);
})));
}
}
if (selection is not null)
{
if (id == "PL")
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Repair", "Command Prompt",
new EventHandler(async (sender, e) => await ParadoxLauncher.Repair(this, selection))));
}
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open Root Directory", "File Explorer",
new EventHandler((sender, e) => Diagnostics.OpenDirectoryInFileExplorer(selection.RootDirectory))));
List<string> 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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Steamworks Directory #{++steam}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Epic Online Services Directory #{++epic}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Uplay R1 Directory #{++r1}", "File Explorer",
new EventHandler((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))
contextMenuStrip.Items.Add(new ContextMenuItem($"Open Uplay R2 Directory #{++r2}", "File Explorer",
new EventHandler((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)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open SteamDB", "SteamDB",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamdb.info/app/" + id))));
}
if (selection is not null)
{
if (selection.Platform is Platform.Steam)
{
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Store", "Steam Store",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))));
contextMenuStrip.Items.Add(new ContextMenuItem("Open Steam Community", ("Sub_" + id, selection.SubIconUrl), "Steam Community",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + id))));
}
if (selection.Platform is Platform.Epic)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(new ContextMenuItem("Open ScreamDB", "ScreamDB",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser("https://scream-db.web.app/offers/" + id))));
contextMenuStrip.Items.Add(new ContextMenuItem("Open Epic Games Store", "Epic Games",
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.ProductUrl))));
}
if (selection.Platform is Platform.Ubisoft)
{
contextMenuStrip.Items.Add(new ToolStripSeparator());
#pragma warning disable CA1308 // Normalize strings to uppercase
contextMenuStrip.Items.Add(new ContextMenuItem("Open Ubisoft Store", "Ubisoft Store",
new EventHandler((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)
{
contextMenuStrip.Items.Add(new ContextMenuItem("Open Official Website", ("Web_" + id, IconGrabber.GetDomainFaviconUrl(selection.WebsiteUrl)),
new EventHandler((sender, e) => Diagnostics.OpenUrlInInternetBrowser(selection.WebsiteUrl))));
}
contextMenuStrip.Show(selectionTreeView, e.Location);
};
OnLoad(forceProvideChoices: true); OnLoad(forceProvideChoices: true);
} }
catch (Exception e) catch (Exception e)
@ -850,19 +859,39 @@ internal partial class SelectForm : CustomForm
private void OnAllCheckBoxChanged(object sender, EventArgs e) private void OnAllCheckBoxChanged(object sender, EventArgs e)
{ {
bool shouldCheck = false; bool shouldCheck = false;
TreeNodes.ForEach(node => foreach (TreeNode node in TreeNodes)
{ if (node.Parent is null && !node.Checked)
if (node.Parent is null)
{ {
if (!node.Checked) shouldCheck = true; shouldCheck = true;
if (node.Checked != shouldCheck) break;
{
node.Checked = shouldCheck;
OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse));
}
} }
}); foreach (TreeNode node in TreeNodes)
if (node.Parent is null && node.Checked != shouldCheck)
{
node.Checked = shouldCheck;
OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse));
}
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = shouldCheck; allCheckBox.Checked = shouldCheck;
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
}
internal CheckBox KoaloaderAllCheckBox() => koaloaderAllCheckBox;
internal void OnKoaloaderAllCheckBoxChanged(object sender, EventArgs e)
{
bool shouldCheck = false;
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
if (!selection.Koaloader)
{
shouldCheck = true;
break;
}
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
selection.Koaloader = shouldCheck;
selectionTreeView.Invalidate();
koaloaderAllCheckBox.CheckedChanged -= OnKoaloaderAllCheckBoxChanged;
koaloaderAllCheckBox.Checked = shouldCheck;
koaloaderAllCheckBox.CheckedChanged += OnKoaloaderAllCheckBoxChanged;
} }
private void OnBlockProtectedGamesCheckBoxChanged(object sender, EventArgs e) private void OnBlockProtectedGamesCheckBoxChanged(object sender, EventArgs e)

View file

@ -57,4 +57,7 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root> </root>

View file

@ -27,7 +27,8 @@ public enum DlcType
internal class ProgramSelection internal class ProgramSelection
{ {
internal bool Enabled; internal bool Enabled;
internal bool Koaloader = true; internal bool Koaloader;
internal string KoaloaderProxy = "Koaloader.version_64.version.dll";
internal Platform Platform; internal Platform Platform;
internal string Id = "0"; internal string Id = "0";

View file

@ -34,6 +34,29 @@ internal static class Koaloader
("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker64.dll") ("Uplay R2 Unlocker", "UplayR2Unlocker32.dll"), ("Uplay R2 Unlocker", "UplayR2Unlocker64.dll")
}; };
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
{
directory.GetKoaloaderComponents(out _, out string config);
SortedList<string, string> targets = new(PlatformIdComparer.String);
SortedList<string, string> modules = new(PlatformIdComparer.String);
if (targets.Any() || modules.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Koaloader configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
WriteConfig(writer, targets, modules, installForm);
writer.Flush();
writer.Close();
}
else if (File.Exists(config))
{
File.Delete(config);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
internal static void WriteConfig(StreamWriter writer, SortedList<string, string> targets, SortedList<string, string> modules, InstallForm installForm = null) internal static void WriteConfig(StreamWriter writer, SortedList<string, string> targets, SortedList<string, string> modules, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
@ -76,7 +99,7 @@ internal static class Koaloader
writer.WriteLine("}"); writer.WriteLine("}");
} }
internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) => await Task.Run(() => internal static async Task Uninstall(string directory, InstallForm installForm = null, bool deleteConfig = true) => await Task.Run(async () =>
{ {
directory.GetKoaloaderComponents(out List<string> proxies, out string config); directory.GetKoaloaderComponents(out List<string> proxies, out string config);
foreach (string proxy in proxies.Where(proxy => File.Exists(proxy) && proxy.IsResourceFile(Resources.ResourceIdentifier.Koaloader))) foreach (string proxy in proxies.Where(proxy => File.Exists(proxy) && proxy.IsResourceFile(Resources.ResourceIdentifier.Koaloader)))
@ -99,13 +122,20 @@ internal static class Koaloader
if (installForm is not null) if (installForm is not null)
installForm.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Deleted configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: 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);
}); });
internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() => internal static async Task Install(string directory, ProgramSelection selection, InstallForm installForm = null, bool generateConfig = true) => await Task.Run(() =>
{ {
directory.GetKoaloaderComponents(out List<string> proxies, out string config); directory.GetKoaloaderComponents(out List<string> proxies, out string config);
string path = directory + @"\version.dll"; string proxy = selection.KoaloaderProxy;
"Koaloader.version_64.version.dll".Write(path); proxy = proxy[(proxy.IndexOf('.') + 1)..];
proxy = proxy[(proxy.IndexOf('.') + 1)..];
string path = directory + @"\" + proxy;
selection.KoaloaderProxy.Write(path);
if (installForm is not null) if (installForm is not null)
installForm.UpdateUser($"Wrote Koaloader: {Path.GetFileName(path)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote Koaloader: {Path.GetFileName(path)}", InstallationLog.Action, info: false);
if (selection.Platform is Platform.Steam or Platform.Paradox) if (selection.Platform is Platform.Steam or Platform.Paradox)
@ -133,6 +163,8 @@ internal static class Koaloader
if (did32 && did64) if (did32 && did64)
break; break;
} }
if (did32 || did64)
SmokeAPI.CheckConfig(directory, selection, installForm);
} }
if (selection.Platform is Platform.Epic or Platform.Paradox) if (selection.Platform is Platform.Epic or Platform.Paradox)
{ {
@ -159,6 +191,8 @@ internal static class Koaloader
if (did32 && did64) if (did32 && did64)
break; break;
} }
if (did32 || did64)
ScreamAPI.CheckConfig(directory, selection, installForm);
} }
if (selection.Platform is Platform.Ubisoft) if (selection.Platform is Platform.Ubisoft)
{ {
@ -202,27 +236,12 @@ internal static class Koaloader
if (did32r1 && did64r1 && did32r2 && did64r2) if (did32r1 && did64r1 && did32r2 && did64r2)
break; break;
} }
if (did32r1 || did64r1)
UplayR1.CheckConfig(directory, selection, installForm);
if (did32r2 || did64r2)
UplayR2.CheckConfig(directory, selection, installForm);
} }
if (generateConfig) if (generateConfig)
{ CheckConfig(directory, selection, installForm);
SortedList<string, string> targets = new(PlatformIdComparer.String);
SortedList<string, string> modules = new(PlatformIdComparer.String);
if (targets.Any() || modules.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Koaloader configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
WriteConfig(writer, targets, modules, installForm);
writer.Flush();
writer.Close();
}
else if (File.Exists(config))
{
File.Delete(config);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
}); });
} }

View file

@ -25,6 +25,36 @@ internal static class ScreamAPI
config = directory + @"\ScreamAPI.json"; config = directory + @"\ScreamAPI.json";
} }
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
{
directory.GetScreamApiComponents(out _, out _, out _, out _, out string config);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideCatalogItems = selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
overrideCatalogItems = overrideCatalogItems.Except(extraDlc);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements = selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in selection.ExtraSelectedDlc)
entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement));
if (overrideCatalogItems.Any() || entitlements.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideCatalogItems, SortedList<string, (DlcType type, string name, string icon)> entitlements, InstallForm installForm = null) internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideCatalogItems, SortedList<string, (DlcType type, string name, string icon)> entitlements, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
@ -137,32 +167,6 @@ internal static class ScreamAPI
installForm.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote ScreamAPI: {Path.GetFileName(api64)}", InstallationLog.Action, info: false);
} }
if (generateConfig) if (generateConfig)
{ CheckConfig(directory, selection, installForm);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideCatalogItems = selection.AllDlc.Where(pair => pair.Value.type is DlcType.EpicCatalogItem).Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
overrideCatalogItems = overrideCatalogItems.Except(extraDlc);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> entitlements = selection.SelectedDlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> _dlc) in selection.ExtraSelectedDlc)
entitlements = entitlements.Concat(_dlc.Where(pair => pair.Value.type == DlcType.EpicEntitlement));
if (overrideCatalogItems.Any() || entitlements.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating ScreamAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
}); });
} }

View file

@ -26,6 +26,41 @@ internal static class SmokeAPI
cache = directory + @"\SmokeAPI.cache.json"; cache = directory + @"\SmokeAPI.cache.json";
} }
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
{
directory.GetSmokeApiComponents(out _, out _, out _, out _, out string config, out _);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
overrideDlc = overrideDlc.Except(extraDlc);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> injectDlc = new List<KeyValuePair<string, (DlcType type, string name, string icon)>>();
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<string, (DlcType type, string name, string icon)> 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));
}
if (overrideDlc.Any() || injectDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideDlc, SortedList<string, (DlcType type, string name, string icon)> injectDlc, InstallForm installForm = null) internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> overrideDlc, SortedList<string, (DlcType type, string name, string icon)> injectDlc, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
@ -146,37 +181,6 @@ internal static class SmokeAPI
installForm.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote SmokeAPI: {Path.GetFileName(api64)}", InstallationLog.Action, info: false);
} }
if (generateConfig) if (generateConfig)
{ CheckConfig(directory, selection, installForm);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> overrideDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
overrideDlc = overrideDlc.Except(extraDlc);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> injectDlc = new List<KeyValuePair<string, (DlcType type, string name, string icon)>>();
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<string, (DlcType type, string name, string icon)> 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));
}
if (overrideDlc.Any() || injectDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating SmokeAPI configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
}); });
} }

View file

@ -25,6 +25,30 @@ internal static class UplayR1
config = directory + @"\UplayR1Unlocker.jsonc"; config = directory + @"\UplayR1Unlocker.jsonc";
} }
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
{
directory.GetUplayR1Components(out _, out _, out _, out _, out string config);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
blacklistDlc = blacklistDlc.Except(extraDlc);
if (blacklistDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc, InstallForm installForm = null) internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
@ -113,26 +137,6 @@ internal static class UplayR1
installForm.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote Uplay R1 Unlocker: {Path.GetFileName(api64)}", InstallationLog.Action, info: false);
} }
if (generateConfig) if (generateConfig)
{ CheckConfig(directory, selection, installForm);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
blacklistDlc = blacklistDlc.Except(extraDlc);
if (blacklistDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Uplay R1 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
}); });
} }

View file

@ -27,6 +27,30 @@ internal static class UplayR2
config = directory + @"\UplayR2Unlocker.jsonc"; config = directory + @"\UplayR2Unlocker.jsonc";
} }
internal static void CheckConfig(string directory, ProgramSelection selection, InstallForm installForm = null)
{
directory.GetUplayR2Components(out _, out _, out _, out _, out _, out _, out string config);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
blacklistDlc = blacklistDlc.Except(extraDlc);
if (blacklistDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc, InstallForm installForm = null) internal static void WriteConfig(StreamWriter writer, SortedList<string, (DlcType type, string name, string icon)> blacklistDlc, InstallForm installForm = null)
{ {
writer.WriteLine("{"); writer.WriteLine("{");
@ -121,26 +145,6 @@ internal static class UplayR2
installForm.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", InstallationLog.Action, info: false); installForm.UpdateUser($"Wrote Uplay R2 Unlocker: {Path.GetFileName(api)}", InstallationLog.Action, info: false);
} }
if (generateConfig) if (generateConfig)
{ CheckConfig(directory, selection, installForm);
IEnumerable<KeyValuePair<string, (DlcType type, string name, string icon)>> blacklistDlc = selection.AllDlc.Except(selection.SelectedDlc);
foreach ((string id, string name, SortedList<string, (DlcType type, string name, string icon)> extraDlc) in selection.ExtraSelectedDlc)
blacklistDlc = blacklistDlc.Except(extraDlc);
if (blacklistDlc.Any())
{
if (installForm is not null)
installForm.UpdateUser("Generating Uplay R2 Unlocker configuration for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(config).Close();
StreamWriter writer = new(config, true, Encoding.UTF8);
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);
if (installForm is not null)
installForm.UpdateUser($"Deleted unnecessary configuration: {Path.GetFileName(config)}", InstallationLog.Action, info: false);
}
}
}); });
} }