v2.2.3.0
- Minor refactoring - Updated HtmlAgilityPack dependency - Replaced node right click with a beefy context menu with ICONS :O - Small improvements to selection node display - Fixed selections sometimes being prematurely removed - Enabled selections will now be saved and restored after installation
This commit is contained in:
parent
af556628de
commit
f151a1ba2a
7 changed files with 195 additions and 107 deletions
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Gameloop.Vdf.Linq;
|
using Gameloop.Vdf.Linq;
|
||||||
|
|
||||||
|
@ -12,9 +14,42 @@ namespace CreamInstaller
|
||||||
internal bool Enabled = false;
|
internal bool Enabled = false;
|
||||||
internal bool Usable = true;
|
internal bool Usable = true;
|
||||||
|
|
||||||
internal string Name;
|
internal int SteamAppId = 0;
|
||||||
|
internal string Name = "Program";
|
||||||
|
|
||||||
|
internal Image Icon;
|
||||||
|
private string iconPath;
|
||||||
|
internal string IconPath
|
||||||
|
{
|
||||||
|
get => iconPath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
iconPath = value;
|
||||||
|
Task.Run(async () => Icon = await Program.GetImageFromUrl(iconPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal string IconStaticID
|
||||||
|
{
|
||||||
|
set => IconPath = $"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/{SteamAppId}/{value}.jpg";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Image ClientIcon;
|
||||||
|
private string clientIconPath;
|
||||||
|
internal string ClientIconPath
|
||||||
|
{
|
||||||
|
get => clientIconPath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
clientIconPath = value;
|
||||||
|
Task.Run(async () => ClientIcon = await Program.GetImageFromUrl(clientIconPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal string ClientIconStaticID
|
||||||
|
{
|
||||||
|
set => ClientIconPath = $"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/{SteamAppId}/{value}.ico";
|
||||||
|
}
|
||||||
|
|
||||||
internal string RootDirectory;
|
internal string RootDirectory;
|
||||||
internal int SteamAppId;
|
|
||||||
internal List<string> SteamApiDllDirectories;
|
internal List<string> SteamApiDllDirectories;
|
||||||
|
|
||||||
internal VProperty AppInfo = null;
|
internal VProperty AppInfo = null;
|
||||||
|
@ -31,10 +66,7 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
string api = directory + @"\steam_api.dll";
|
string api = directory + @"\steam_api.dll";
|
||||||
string api64 = directory + @"\steam_api64.dll";
|
string api64 = directory + @"\steam_api64.dll";
|
||||||
if (api.IsFilePathLocked() || api64.IsFilePathLocked())
|
if (api.IsFilePathLocked() || api64.IsFilePathLocked()) return true;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -42,43 +74,25 @@ namespace CreamInstaller
|
||||||
|
|
||||||
private void Toggle(KeyValuePair<int, string> dlcApp, bool enabled)
|
private void Toggle(KeyValuePair<int, string> dlcApp, bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (enabled) SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
|
||||||
{
|
else SelectedSteamDlc.Remove(dlcApp.Key);
|
||||||
SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SelectedSteamDlc.Remove(dlcApp.Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ToggleDlc(int dlcAppId, bool enabled)
|
internal void ToggleDlc(int dlcAppId, bool enabled)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc)
|
foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc)
|
||||||
{
|
|
||||||
if (dlcApp.Key == dlcAppId)
|
if (dlcApp.Key == dlcAppId)
|
||||||
{
|
{
|
||||||
Toggle(dlcApp, enabled);
|
Toggle(dlcApp, enabled);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Enabled = SelectedSteamDlc.Any();
|
Enabled = SelectedSteamDlc.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ToggleAllDlc(bool enabled)
|
internal void ToggleAllDlc(bool enabled)
|
||||||
{
|
{
|
||||||
if (!enabled)
|
if (!enabled) SelectedSteamDlc.Clear();
|
||||||
{
|
else foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc) Toggle(dlcApp, enabled);
|
||||||
SelectedSteamDlc.Clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc)
|
|
||||||
{
|
|
||||||
Toggle(dlcApp, enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enabled = SelectedSteamDlc.Any();
|
Enabled = SelectedSteamDlc.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,36 +100,37 @@ namespace CreamInstaller
|
||||||
|
|
||||||
internal void Validate()
|
internal void Validate()
|
||||||
{
|
{
|
||||||
SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory));
|
if (Program.BlockProtectedGames && Program.IsGameBlocked(Name, RootDirectory))
|
||||||
if (!Directory.Exists(RootDirectory) || !SteamApiDllDirectories.Any())
|
|
||||||
{
|
{
|
||||||
All.Remove(this);
|
All.Remove(this);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (!Directory.Exists(RootDirectory))
|
||||||
|
{
|
||||||
|
All.Remove(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory));
|
||||||
|
if (!SteamApiDllDirectories.Any()) All.Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ValidateAll() => All.ForEach(selection => selection.Validate());
|
internal static void ValidateAll() => AllSafe.ForEach(selection => selection.Validate());
|
||||||
|
|
||||||
internal static List<ProgramSelection> All => Program.ProgramSelections;
|
internal static List<ProgramSelection> All => Program.ProgramSelections;
|
||||||
|
|
||||||
internal static List<ProgramSelection> AllSafe => All.FindAll(s => s.Usable);
|
internal static List<ProgramSelection> AllSafe => All.ToList();
|
||||||
|
|
||||||
internal static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled);
|
internal static List<ProgramSelection> AllUsable => All.FindAll(s => s.Usable);
|
||||||
|
|
||||||
internal static ProgramSelection FromAppId(int appId) => AllSafe.Find(s => s.SteamAppId == appId);
|
internal static List<ProgramSelection> AllUsableEnabled => AllUsable.FindAll(s => s.Enabled);
|
||||||
|
|
||||||
|
internal static ProgramSelection FromAppId(int appId) => AllUsable.Find(s => s.SteamAppId == appId);
|
||||||
|
|
||||||
internal static KeyValuePair<int, string>? GetDlcFromAppId(int appId)
|
internal static KeyValuePair<int, string>? GetDlcFromAppId(int appId)
|
||||||
{
|
{
|
||||||
foreach (ProgramSelection selection in AllSafe)
|
foreach (ProgramSelection selection in AllUsable)
|
||||||
{
|
|
||||||
foreach (KeyValuePair<int, string> app in selection.AllSteamDlc)
|
foreach (KeyValuePair<int, string> app in selection.AllSteamDlc)
|
||||||
{
|
if (app.Key == appId) return app;
|
||||||
if (app.Key == appId)
|
|
||||||
{
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
|
||||||
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
||||||
<Version>2.2.2.0</Version>
|
<Version>2.2.3.0</Version>
|
||||||
<PackageIcon>Resources\ini.ico</PackageIcon>
|
<PackageIcon>Resources\ini.ico</PackageIcon>
|
||||||
<PackageIconUrl />
|
<PackageIconUrl />
|
||||||
<Description>Automatically generates and installs CreamAPI files for Steam games on the user's computer. It can also generate and install CreamAPI for the Paradox Launcher should the user select a Paradox Interactive game.</Description>
|
<Description>Automatically generates and installs CreamAPI files for Steam games on the user's computer. It can also generate and install CreamAPI for the Paradox Launcher should the user select a Paradox Interactive game.</Description>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.38" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.40" />
|
||||||
<PackageReference Include="Onova" Version="2.6.2" />
|
<PackageReference Include="Onova" Version="2.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -150,9 +150,10 @@ namespace CreamInstaller
|
||||||
|
|
||||||
private async Task Operate()
|
private async Task Operate()
|
||||||
{
|
{
|
||||||
List<ProgramSelection> programSelections = ProgramSelection.AllSafeEnabled;
|
List<ProgramSelection> programSelections = ProgramSelection.AllUsableEnabled;
|
||||||
OperationsCount = programSelections.Count;
|
OperationsCount = programSelections.Count;
|
||||||
CompleteOperationsCount = 0;
|
CompleteOperationsCount = 0;
|
||||||
|
List<ProgramSelection> disabledSelections = new();
|
||||||
foreach (ProgramSelection selection in programSelections)
|
foreach (ProgramSelection selection in programSelections)
|
||||||
{
|
{
|
||||||
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException();
|
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException();
|
||||||
|
@ -161,6 +162,7 @@ namespace CreamInstaller
|
||||||
await OperateFor(selection);
|
await OperateFor(selection);
|
||||||
await UpdateUser($"Operation succeeded for {selection.Name}.", InstallationLog.Success);
|
await UpdateUser($"Operation succeeded for {selection.Name}.", InstallationLog.Success);
|
||||||
selection.Enabled = false;
|
selection.Enabled = false;
|
||||||
|
disabledSelections.Add(selection);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
|
@ -169,13 +171,14 @@ namespace CreamInstaller
|
||||||
++CompleteOperationsCount;
|
++CompleteOperationsCount;
|
||||||
}
|
}
|
||||||
await Program.Cleanup();
|
await Program.Cleanup();
|
||||||
List<ProgramSelection> FailedSelections = ProgramSelection.AllSafeEnabled;
|
List<ProgramSelection> FailedSelections = ProgramSelection.AllUsableEnabled;
|
||||||
if (FailedSelections.Any())
|
if (FailedSelections.Any())
|
||||||
if (FailedSelections.Count == 1) throw new CustomMessageException($"Operation failed for {FailedSelections.First().Name}.");
|
if (FailedSelections.Count == 1) throw new CustomMessageException($"Operation failed for {FailedSelections.First().Name}.");
|
||||||
else throw new CustomMessageException($"Operation failed for {FailedSelections.Count} programs.");
|
else throw new CustomMessageException($"Operation failed for {FailedSelections.Count} programs.");
|
||||||
|
foreach (ProgramSelection selection in disabledSelections) selection.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly int ProgramCount = ProgramSelection.AllSafeEnabled.Count;
|
private readonly int ProgramCount = ProgramSelection.AllUsableEnabled.Count;
|
||||||
|
|
||||||
private async void Start()
|
private async void Start()
|
||||||
{
|
{
|
||||||
|
|
13
CreamInstaller/Forms/SelectForm.Designer.cs
generated
13
CreamInstaller/Forms/SelectForm.Designer.cs
generated
|
@ -31,6 +31,7 @@ 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();
|
||||||
|
@ -46,6 +47,7 @@ namespace CreamInstaller
|
||||||
this.progressLabel = new System.Windows.Forms.Label();
|
this.progressLabel = new System.Windows.Forms.Label();
|
||||||
this.scanButton = new System.Windows.Forms.Button();
|
this.scanButton = new System.Windows.Forms.Button();
|
||||||
this.uninstallButton = new System.Windows.Forms.Button();
|
this.uninstallButton = new System.Windows.Forms.Button();
|
||||||
|
this.nodeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
this.groupBox1.SuspendLayout();
|
this.groupBox1.SuspendLayout();
|
||||||
this.flowLayoutPanel1.SuspendLayout();
|
this.flowLayoutPanel1.SuspendLayout();
|
||||||
this.flowLayoutPanel2.SuspendLayout();
|
this.flowLayoutPanel2.SuspendLayout();
|
||||||
|
@ -166,7 +168,6 @@ namespace CreamInstaller
|
||||||
this.selectionTreeView.CheckBoxes = true;
|
this.selectionTreeView.CheckBoxes = true;
|
||||||
this.selectionTreeView.Enabled = false;
|
this.selectionTreeView.Enabled = false;
|
||||||
this.selectionTreeView.FullRowSelect = true;
|
this.selectionTreeView.FullRowSelect = true;
|
||||||
this.selectionTreeView.HotTracking = true;
|
|
||||||
this.selectionTreeView.Location = new System.Drawing.Point(6, 22);
|
this.selectionTreeView.Location = new System.Drawing.Point(6, 22);
|
||||||
this.selectionTreeView.Name = "selectionTreeView";
|
this.selectionTreeView.Name = "selectionTreeView";
|
||||||
this.selectionTreeView.Size = new System.Drawing.Size(548, 280);
|
this.selectionTreeView.Size = new System.Drawing.Size(548, 280);
|
||||||
|
@ -206,12 +207,12 @@ namespace CreamInstaller
|
||||||
this.progressBar1.Size = new System.Drawing.Size(560, 23);
|
this.progressBar1.Size = new System.Drawing.Size(560, 23);
|
||||||
this.progressBar1.TabIndex = 9;
|
this.progressBar1.TabIndex = 9;
|
||||||
//
|
//
|
||||||
// label2
|
// progressLabel
|
||||||
//
|
//
|
||||||
this.progressLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
this.progressLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.progressLabel.Location = new System.Drawing.Point(12, 279);
|
this.progressLabel.Location = new System.Drawing.Point(12, 279);
|
||||||
this.progressLabel.Name = "label2";
|
this.progressLabel.Name = "progressLabel";
|
||||||
this.progressLabel.Size = new System.Drawing.Size(760, 15);
|
this.progressLabel.Size = new System.Drawing.Size(760, 15);
|
||||||
this.progressLabel.TabIndex = 10;
|
this.progressLabel.TabIndex = 10;
|
||||||
this.progressLabel.Text = "Loading . . .";
|
this.progressLabel.Text = "Loading . . .";
|
||||||
|
@ -242,6 +243,11 @@ namespace CreamInstaller
|
||||||
this.uninstallButton.UseVisualStyleBackColor = true;
|
this.uninstallButton.UseVisualStyleBackColor = true;
|
||||||
this.uninstallButton.Click += new System.EventHandler(this.OnUninstall);
|
this.uninstallButton.Click += new System.EventHandler(this.OnUninstall);
|
||||||
//
|
//
|
||||||
|
// nodeContextMenu
|
||||||
|
//
|
||||||
|
this.nodeContextMenu.Name = "nodeContextMenu";
|
||||||
|
this.nodeContextMenu.Size = new System.Drawing.Size(61, 4);
|
||||||
|
//
|
||||||
// SelectForm
|
// SelectForm
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
|
@ -290,6 +296,7 @@ namespace CreamInstaller
|
||||||
private FlowLayoutPanel flowLayoutPanel1;
|
private FlowLayoutPanel flowLayoutPanel1;
|
||||||
private FlowLayoutPanel flowLayoutPanel2;
|
private FlowLayoutPanel flowLayoutPanel2;
|
||||||
private Button uninstallButton;
|
private Button uninstallButton;
|
||||||
|
private ContextMenuStrip nodeContextMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -157,24 +156,9 @@ namespace CreamInstaller
|
||||||
int buildId = program.Item4;
|
int buildId = program.Item4;
|
||||||
string directory = program.Item5;
|
string directory = program.Item5;
|
||||||
ProgramSelection selection = ProgramSelection.FromAppId(appId);
|
ProgramSelection selection = ProgramSelection.FromAppId(appId);
|
||||||
|
if (selection is not null) selection.Validate();
|
||||||
if (Program.Canceled) return;
|
if (Program.Canceled) return;
|
||||||
if (Program.BlockProtectedGames)
|
if (Program.BlockProtectedGames && Program.IsGameBlocked(name, directory)) continue;
|
||||||
{
|
|
||||||
bool blockedGame = Program.ProtectedGameNames.Contains(name);
|
|
||||||
if (!Program.ProtectedGameDirectoryExceptions.Contains(name))
|
|
||||||
foreach (string path in Program.ProtectedGameDirectories)
|
|
||||||
if (Directory.Exists(directory + path))
|
|
||||||
blockedGame = true;
|
|
||||||
if (blockedGame)
|
|
||||||
{
|
|
||||||
if (selection is not null)
|
|
||||||
{
|
|
||||||
selection.Enabled = false;
|
|
||||||
selection.Usable = false;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RunningTasks.Add(Task.Run(async () =>
|
RunningTasks.Add(Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (Program.Canceled) return;
|
if (Program.Canceled) return;
|
||||||
|
@ -215,11 +199,20 @@ namespace CreamInstaller
|
||||||
|
|
||||||
selection ??= new();
|
selection ??= new();
|
||||||
selection.Usable = true;
|
selection.Usable = true;
|
||||||
|
selection.SteamAppId = appId;
|
||||||
selection.Name = name;
|
selection.Name = name;
|
||||||
selection.RootDirectory = directory;
|
selection.RootDirectory = directory;
|
||||||
selection.SteamAppId = appId;
|
|
||||||
selection.SteamApiDllDirectories = dllDirectories;
|
selection.SteamApiDllDirectories = dllDirectories;
|
||||||
selection.AppInfo = appInfo;
|
selection.AppInfo = appInfo;
|
||||||
|
if (selection.Icon is null)
|
||||||
|
{
|
||||||
|
if (appId == 0) selection.Icon = Program.GetFileIconImage(directory + @"\launcher\bootstrapper-v2.exe");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selection.IconStaticID = appInfo?.Value?["common"]?["icon"]?.ToString();
|
||||||
|
selection.ClientIconStaticID = appInfo?.Value?["common"]?["clienticon"]?.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (allCheckBox.Checked) selection.Enabled = true;
|
if (allCheckBox.Checked) selection.Enabled = true;
|
||||||
|
|
||||||
foreach (Task task in dlcTasks)
|
foreach (Task task in dlcTasks)
|
||||||
|
@ -270,7 +263,7 @@ namespace CreamInstaller
|
||||||
progress.Report(RunningTasks.Count);
|
progress.Report(RunningTasks.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnLoad(bool validating = false)
|
private async void OnLoad()
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
|
@ -300,16 +293,15 @@ namespace CreamInstaller
|
||||||
if (_progress < 0) maxProgress = -_progress;
|
if (_progress < 0) maxProgress = -_progress;
|
||||||
else curProgress = _progress;
|
else curProgress = _progress;
|
||||||
int p = Math.Max(Math.Min((int)((float)(curProgress / (float)maxProgress) * 100), 100), 0);
|
int p = Math.Max(Math.Min((int)((float)(curProgress / (float)maxProgress) * 100), 100), 0);
|
||||||
if (validating) progressLabel.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})";
|
progressLabel.Text = setup ? $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})"
|
||||||
else if (setup) progressLabel.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
|
: $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
|
||||||
else progressLabel.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
|
|
||||||
progressBar1.Value = p;
|
progressBar1.Value = p;
|
||||||
};
|
};
|
||||||
|
|
||||||
iProgress.Report(-1660); // not exact, number varies
|
iProgress.Report(-1660); // not exact, number varies
|
||||||
int cur = 0;
|
int cur = 0;
|
||||||
iProgress.Report(cur);
|
iProgress.Report(cur);
|
||||||
if (!validating) progressLabel.Text = "Setting up SteamCMD . . . ";
|
progressLabel.Text = "Setting up SteamCMD . . . ";
|
||||||
if (!Directory.Exists(SteamCMD.DirectoryPath)) Directory.CreateDirectory(SteamCMD.DirectoryPath);
|
if (!Directory.Exists(SteamCMD.DirectoryPath)) Directory.CreateDirectory(SteamCMD.DirectoryPath);
|
||||||
|
|
||||||
FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
|
FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
|
||||||
|
@ -321,14 +313,13 @@ namespace CreamInstaller
|
||||||
watcher.Dispose();
|
watcher.Dispose();
|
||||||
|
|
||||||
setup = false;
|
setup = false;
|
||||||
if (!validating) progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
|
progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
|
||||||
|
|
||||||
await GetCreamApiApplicablePrograms(iProgress);
|
|
||||||
ProgramSelection.ValidateAll();
|
ProgramSelection.ValidateAll();
|
||||||
TreeNodes.ForEach(node =>
|
TreeNodes.ForEach(node =>
|
||||||
{
|
{
|
||||||
if (node.Parent is null && ProgramSelection.FromAppId(int.Parse(node.Name)) is null) node.Remove();
|
if (!int.TryParse(node.Name, out int appId) || node.Parent is null && ProgramSelection.FromAppId(appId) is null) node.Remove();
|
||||||
});
|
});
|
||||||
|
await GetCreamApiApplicablePrograms(iProgress);
|
||||||
|
|
||||||
progressBar1.Value = 100;
|
progressBar1.Value = 100;
|
||||||
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height + 44);
|
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height + 44);
|
||||||
|
@ -337,15 +328,12 @@ namespace CreamInstaller
|
||||||
selectionTreeView.Enabled = ProgramSelection.All.Any();
|
selectionTreeView.Enabled = ProgramSelection.All.Any();
|
||||||
allCheckBox.Enabled = selectionTreeView.Enabled;
|
allCheckBox.Enabled = selectionTreeView.Enabled;
|
||||||
noneFoundLabel.Visible = !selectionTreeView.Enabled;
|
noneFoundLabel.Visible = !selectionTreeView.Enabled;
|
||||||
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
|
installButton.Enabled = ProgramSelection.AllUsableEnabled.Any();
|
||||||
uninstallButton.Enabled = installButton.Enabled;
|
uninstallButton.Enabled = installButton.Enabled;
|
||||||
cancelButton.Enabled = false;
|
cancelButton.Enabled = false;
|
||||||
scanButton.Enabled = true;
|
scanButton.Enabled = true;
|
||||||
blockedGamesCheckBox.Enabled = true;
|
blockedGamesCheckBox.Enabled = true;
|
||||||
blockProtectedHelpButton.Enabled = true;
|
blockProtectedHelpButton.Enabled = true;
|
||||||
|
|
||||||
progressLabel.Text = "Validating . . . ";
|
|
||||||
//if (!validating && !Program.Canceled) OnLoad(true);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -383,7 +371,7 @@ namespace CreamInstaller
|
||||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
|
installButton.Enabled = ProgramSelection.AllUsableEnabled.Any();
|
||||||
uninstallButton.Enabled = installButton.Enabled;
|
uninstallButton.Enabled = installButton.Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,9 +379,9 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
public int Compare(object a, object b)
|
public int Compare(object a, object b)
|
||||||
{
|
{
|
||||||
TreeNode A = a as TreeNode;
|
if (!int.TryParse((a as TreeNode).Name, out int A)) return 1;
|
||||||
TreeNode B = b as TreeNode;
|
if (!int.TryParse((b as TreeNode).Name, out int B)) return 0;
|
||||||
return int.Parse(A.Name) > int.Parse(B.Name) ? 1 : 0;
|
return A > B ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,16 +389,54 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
selectionTreeView.TreeViewNodeSorter = new TreeNodeSorter();
|
selectionTreeView.TreeViewNodeSorter = new TreeNodeSorter();
|
||||||
selectionTreeView.AfterCheck += OnTreeViewNodeCheckedChanged;
|
selectionTreeView.AfterCheck += OnTreeViewNodeCheckedChanged;
|
||||||
|
Dictionary<string, Image> images = new();
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
images["File Explorer"] = Program.GetFileExplorerImage();
|
||||||
|
images["SteamDB"] = await Program.GetImageFromUrl("https://steamdb.info/favicon.ico");
|
||||||
|
images["Steam Store"] = await Program.GetImageFromUrl("https://store.steampowered.com/favicon.ico");
|
||||||
|
images["Steam Community"] = await Program.GetImageFromUrl("https://steamcommunity.com/favicon.ico");
|
||||||
|
});
|
||||||
|
Image Image(string identifier) => images.GetValueOrDefault(identifier, null);
|
||||||
selectionTreeView.NodeMouseClick += (sender, e) =>
|
selectionTreeView.NodeMouseClick += (sender, e) =>
|
||||||
{
|
{
|
||||||
TreeNode node = e.Node;
|
TreeNode node = e.Node;
|
||||||
string appId = node.Name;
|
TreeNode parentNode = node.Parent;
|
||||||
if (e.Button == MouseButtons.Right && node.Bounds.Contains(e.Location) && appId != "0")
|
if (!int.TryParse(node.Name, out int appId)) return;
|
||||||
Process.Start(new ProcessStartInfo
|
ProgramSelection selection = ProgramSelection.FromAppId(appId);
|
||||||
|
if (e.Button == MouseButtons.Right && node.Bounds.Contains(e.Location))
|
||||||
|
{
|
||||||
|
selectionTreeView.SelectedNode = node;
|
||||||
|
nodeContextMenu.Items.Clear();
|
||||||
|
if (selection is not null)
|
||||||
{
|
{
|
||||||
FileName = "https://steamdb.info/app/" + appId,
|
nodeContextMenu.Items.Add(new ToolStripMenuItem(selection.Name, selection.Icon));
|
||||||
UseShellExecute = true
|
nodeContextMenu.Items.Add(new ToolStripSeparator());
|
||||||
});
|
nodeContextMenu.Items.Add(new ToolStripMenuItem("Open Root Directory", Image("File Explorer"),
|
||||||
|
new EventHandler((sender, e) => Program.OpenDirectoryInFileExplorer(selection.RootDirectory))));
|
||||||
|
for (int i = 0; i < selection.SteamApiDllDirectories.Count; i++)
|
||||||
|
{
|
||||||
|
string directory = selection.SteamApiDllDirectories[i];
|
||||||
|
nodeContextMenu.Items.Add(new ToolStripMenuItem($"Open Steamworks Directory ({i + 1})", Image("File Explorer"),
|
||||||
|
new EventHandler((sender, e) => Program.OpenDirectoryInFileExplorer(directory))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeContextMenu.Items.Add(new ToolStripMenuItem(node.Text));
|
||||||
|
nodeContextMenu.Items.Add(new ToolStripSeparator());
|
||||||
|
}
|
||||||
|
if (appId != 0)
|
||||||
|
{
|
||||||
|
nodeContextMenu.Items.Add(new ToolStripMenuItem("Open SteamDB", Image("SteamDB"),
|
||||||
|
new EventHandler((sender, e) => Program.OpenUrlInInternetBrowser("https://steamdb.info/app/" + appId))));
|
||||||
|
nodeContextMenu.Items.Add(new ToolStripMenuItem("Open Steam Store", Image("Steam Store"),
|
||||||
|
new EventHandler((sender, e) => Program.OpenUrlInInternetBrowser("https://store.steampowered.com/app/" + appId))));
|
||||||
|
if (selection is not null) nodeContextMenu.Items.Add(new ToolStripMenuItem("Open Steam Community", selection.ClientIcon ?? Image("Steam Community"),
|
||||||
|
new EventHandler((sender, e) => Program.OpenUrlInInternetBrowser("https://steamcommunity.com/app/" + appId))));
|
||||||
|
}
|
||||||
|
nodeContextMenu.Show(selectionTreeView, e.Location);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
OnLoad();
|
OnLoad();
|
||||||
}
|
}
|
||||||
|
@ -421,14 +447,14 @@ namespace CreamInstaller
|
||||||
if (paradoxLauncher is not null)
|
if (paradoxLauncher is not null)
|
||||||
{
|
{
|
||||||
paradoxLauncher.ExtraSteamAppIdDlc.Clear();
|
paradoxLauncher.ExtraSteamAppIdDlc.Clear();
|
||||||
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
|
foreach (ProgramSelection selection in ProgramSelection.AllUsableEnabled)
|
||||||
{
|
{
|
||||||
if (selection.Name == paradoxLauncher.Name) continue;
|
if (selection.Name == paradoxLauncher.Name) continue;
|
||||||
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
||||||
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc));
|
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc));
|
||||||
}
|
}
|
||||||
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
||||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
foreach (ProgramSelection selection in ProgramSelection.AllUsable)
|
||||||
{
|
{
|
||||||
if (selection.Name == paradoxLauncher.Name) continue;
|
if (selection.Name == paradoxLauncher.Name) continue;
|
||||||
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
||||||
|
@ -445,12 +471,10 @@ namespace CreamInstaller
|
||||||
PopulateParadoxLauncherDlc(paradoxLauncher);
|
PopulateParadoxLauncherDlc(paradoxLauncher);
|
||||||
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
||||||
{
|
{
|
||||||
if (new DialogForm(form).Show(Program.ApplicationName, SystemIcons.Warning,
|
return new DialogForm(form).Show(Program.ApplicationName, SystemIcons.Warning,
|
||||||
$"WARNING: There are no installed games with DLC that can be added to the Paradox Launcher!" +
|
$"WARNING: There are no installed games with DLC that can be added to the Paradox Launcher!" +
|
||||||
"\n\nInstalling CreamAPI for the Paradox Launcher is pointless, since no DLC will be added to the configuration!",
|
"\n\nInstalling CreamAPI for the Paradox Launcher is pointless, since no DLC will be added to the configuration!",
|
||||||
"Ignore", "Cancel") == DialogResult.OK)
|
"Ignore", "Cancel") != DialogResult.OK;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -460,7 +484,7 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
if (ProgramSelection.All.Any())
|
if (ProgramSelection.All.Any())
|
||||||
{
|
{
|
||||||
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
|
foreach (ProgramSelection selection in ProgramSelection.AllUsableEnabled)
|
||||||
if (!Program.IsProgramRunningDialog(this, selection)) return;
|
if (!Program.IsProgramRunningDialog(this, selection)) return;
|
||||||
if (ParadoxLauncherDlcDialog(this)) return;
|
if (ParadoxLauncherDlcDialog(this)) return;
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -483,10 +507,7 @@ namespace CreamInstaller
|
||||||
private void OnCancel(object sender, EventArgs e)
|
private void OnCancel(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
progressLabel.Text = "Cancelling . . . ";
|
progressLabel.Text = "Cancelling . . . ";
|
||||||
Task.Run(async () =>
|
Task.Run(async () => await Program.Cleanup());
|
||||||
{
|
|
||||||
await Program.Cleanup();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
||||||
|
|
|
@ -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="nodeContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
</root>
|
</root>
|
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -24,6 +26,15 @@ namespace CreamInstaller
|
||||||
internal static readonly string[] ProtectedGameDirectories = { @"\EasyAntiCheat", @"\BattlEye" }; // DLL detections
|
internal static readonly string[] ProtectedGameDirectories = { @"\EasyAntiCheat", @"\BattlEye" }; // DLL detections
|
||||||
internal static readonly string[] ProtectedGameDirectoryExceptions = { "Arma 3" }; // Arma 3's BattlEye doesn't detect DLL changes?
|
internal static readonly string[] ProtectedGameDirectoryExceptions = { "Arma 3" }; // Arma 3's BattlEye doesn't detect DLL changes?
|
||||||
|
|
||||||
|
internal static bool IsGameBlocked(string name, string directory)
|
||||||
|
{
|
||||||
|
if (ProtectedGameNames.Contains(name)) return true;
|
||||||
|
if (!ProtectedGameDirectoryExceptions.Contains(name))
|
||||||
|
foreach (string path in ProtectedGameDirectories)
|
||||||
|
if (Directory.Exists(directory + path)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
private static void Main()
|
private static void Main()
|
||||||
{
|
{
|
||||||
|
@ -49,6 +60,34 @@ namespace CreamInstaller
|
||||||
mutex.Close();
|
mutex.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static async Task<Image> GetImageFromUrl(string url)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpClient httpClient = new();
|
||||||
|
httpClient.DefaultRequestHeaders.Add("user-agent", "CreamInstaller");
|
||||||
|
return new Bitmap(await httpClient.GetStreamAsync(url));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Image GetFileIconImage(string path) => File.Exists(path) ? Icon.ExtractAssociatedIcon(path).ToBitmap() : null;
|
||||||
|
|
||||||
|
internal static Image GetFileExplorerImage() => GetFileIconImage(Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\explorer.exe");
|
||||||
|
|
||||||
internal static bool IsProgramRunningDialog(Form form, ProgramSelection selection)
|
internal static bool IsProgramRunningDialog(Form form, ProgramSelection selection)
|
||||||
{
|
{
|
||||||
if (selection.AreSteamApiDllsLocked)
|
if (selection.AreSteamApiDllsLocked)
|
||||||
|
|
Loading…
Reference in a new issue