diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml
new file mode 100644
index 0000000..4e7b9bb
--- /dev/null
+++ b/.github/workflows/autobuild.yml
@@ -0,0 +1,38 @@
+name: Autobuild
+
+on:
+ push:
+ branches: [ main ]
+ tags:
+ - '*'
+ workflow_dispatch:
+ pull_request:
+ types: [ main ]
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '8.0.x'
+
+ - name: Restore dependencies
+ run: dotnet restore CreamInstaller.sln
+
+ - name: Build Release
+ run: dotnet build CreamInstaller.sln --configuration Release --no-restore
+
+ - name: Publish single-file
+ run: dotnet publish CreamInstaller.sln -c Release -r win-x64 -p:PublishSingleFile=true --self-contained true --output ./publish
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: CreamInstaller-release
+ path: ./publish/CreamInstaller.exe
diff --git a/CreamInstaller/Components/CustomForm.cs b/CreamInstaller/Components/CustomForm.cs
index d36e628..06b4d2e 100644
--- a/CreamInstaller/Components/CustomForm.cs
+++ b/CreamInstaller/Components/CustomForm.cs
@@ -52,7 +52,7 @@ internal class CustomForm : Form
"Automatically finds all installed Steam, Epic and Ubisoft games with their respective DLC-related DLL locations on the user's computer,\n"
+ "parses SteamCMD, Steam Store and Epic Games Store for user-selected games' DLCs, then provides a very simple graphical interface\n"
+ "utilizing the gathered information for the maintenance of DLC unlockers.\n\n"
- + $"The program utilizes the latest version of [CreamAPI](https://cs.rin.ru/forum/viewtopic.php?f=29&t=70576) by [deadmau5](https://cs.rin.ru/forum/viewtopic.php?f=29&t=70576). It also utilizes the latest versions of [Koaloader]({acidicoala}/Koaloader), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1\n"
+ + $"The program utilizes the latest version of [CreamAPI](https://cs.rin.ru/forum/viewtopic.php?f=29&t=70576) by [deadmau5](https://cs.rin.ru/forum/viewtopic.php?f=29&t=70576). It also utilizes the latest versions of [SmokeAPI]({acidicoala}/SmokeAPI), [Koaloader]({acidicoala}/Koaloader), [ScreamAPI]({acidicoala}/ScreamAPI), [Uplay R1\n"
+ $"Unlocker]({acidicoala}/UplayR1Unlocker) and [Uplay R2 Unlocker]({acidicoala}/UplayR2Unlocker), all by [acidicoala]({acidicoala}). All unlockers are downloaded and embedded into the program itself; no further\n"
+ "downloads necessary on your part!\n\n"
+ "USAGE:\n" + " 1. Choose which programs and/or games the program should scan for DLC.\n"
diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj
index ed83620..315106f 100644
--- a/CreamInstaller/CreamInstaller.csproj
+++ b/CreamInstaller/CreamInstaller.csproj
@@ -4,7 +4,7 @@
net8.0-windows10.0.22621.0
True
Resources\program.ico
- 5.0.1.0
+ 5.0.1.1
2021, pointfeev (https://github.com/pointfeev)
CreamInstaller
Automatic DLC Unlocker Installer & Configuration Generator
diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs
index 31fdc20..44a5566 100644
--- a/CreamInstaller/Forms/InstallForm.cs
+++ b/CreamInstaller/Forms/InstallForm.cs
@@ -68,6 +68,9 @@ internal sealed partial class InstallForm : CustomForm
bool useCreamApiProxy = selection.UseProxy && !Program.UseSmokeAPI &&
(selection.Platform is Platform.Steam || selection.Platform is Platform.Paradox &&
selection.ExtraSelections.Any(s => s.Platform is Platform.Steam));
+ bool useSmokeApiProxy = selection.UseProxy && Program.UseSmokeAPI &&
+ (selection.Platform is Platform.Steam || selection.Platform is Platform.Paradox &&
+ selection.ExtraSelections.Any(s => s.Platform is Platform.Steam));
UpdateUser(
$"{(uninstalling ? "Uninstalling" : "Installing")}" + $" {(uninstalling ? "from" : "for")} " +
@@ -84,7 +87,7 @@ internal sealed partial class InstallForm : CustomForm
if (Program.Canceled)
return;
- directory.GetKoaloaderComponents(out string old_config, out string config);
+ directory.GetKoaloaderComponents(out string old_config, out string config, out _);
if (directory.GetKoaloaderProxies().Any(proxy =>
proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|| directory != selection.RootDirectory &&
@@ -97,19 +100,36 @@ internal sealed partial class InstallForm : CustomForm
await Koaloader.Uninstall(directory, selection.RootDirectory, this);
}
- directory.GetCreamApiComponents(out _, out _, out _, out _, out config);
- if (directory.GetCreamApiProxies().Any(proxy =>
- proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
- proxy.IsResourceFile(ResourceIdentifier.Steamworks64))))
+ if (!Program.UseSmokeAPI)
{
- UpdateUser(
- "Uninstalling CreamAPI in proxy mode from " + selection.Name +
- $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation);
- await CreamAPI.ProxyUninstall(directory, this);
+ directory.GetCreamApiComponents(out _, out _, out _, out _, out config);
+ if (directory.GetCreamApiProxies().Any(proxy =>
+ proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
+ proxy.IsResourceFile(ResourceIdentifier.Steamworks64))))
+ {
+ UpdateUser(
+ "Uninstalling CreamAPI in proxy mode from " + selection.Name +
+ $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation);
+ await CreamAPI.ProxyUninstall(directory, this);
+ }
+ }
+ else
+ {
+ directory.GetSmokeApiComponents(out _, out _, out _, out _, out old_config, out config, out _,
+ out _, out _);
+ if (directory.GetSmokeApiProxies().Any(proxy =>
+ proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
+ proxy.IsResourceFile(ResourceIdentifier.Steamworks64))))
+ {
+ UpdateUser(
+ "Uninstalling SmokeAPI in proxy mode from " + selection.Name +
+ $" in incorrect directory \"{directory}\" . . . ", LogTextBox.Operation);
+ await SmokeAPI.ProxyUninstall(directory, this);
+ }
}
}
- if (uninstalling || !useKoaloader || !useCreamApiProxy)
+ if (uninstalling || !useKoaloader || !useCreamApiProxy || !useSmokeApiProxy)
foreach ((string directory, _) in selection.ExecutableDirectories)
{
if (Program.Canceled)
@@ -117,7 +137,7 @@ internal sealed partial class InstallForm : CustomForm
if (uninstalling || !useKoaloader)
{
- directory.GetKoaloaderComponents(out string old_config, out string config);
+ directory.GetKoaloaderComponents(out string old_config, out string config, out _);
if (directory.GetKoaloaderProxies().Any(proxy =>
proxy.FileExists() && proxy.IsResourceFile(ResourceIdentifier.Koaloader))
|| Koaloader.AutoLoadDLLs.Any(pair => (directory + @"\" + pair.dll).FileExists()) ||
@@ -130,23 +150,44 @@ internal sealed partial class InstallForm : CustomForm
}
}
- if (uninstalling || !useCreamApiProxy)
+ if (!Program.UseSmokeAPI)
{
- directory.GetCreamApiComponents(out _, out _, out _, out _, out string config);
- if (directory.GetCreamApiProxies().Any(proxy =>
- proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
- proxy.IsResourceFile(ResourceIdentifier.Steamworks64))) ||
- config.FileExists())
+ if (uninstalling || !useCreamApiProxy)
{
- UpdateUser(
- "Uninstalling CreamAPI in proxy mode from " + selection.Name +
- $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
- await CreamAPI.ProxyUninstall(directory, this);
+ directory.GetCreamApiComponents(out _, out _, out _, out _, out string config);
+ if (directory.GetCreamApiProxies().Any(proxy =>
+ proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
+ proxy.IsResourceFile(ResourceIdentifier.Steamworks64))) ||
+ config.FileExists())
+ {
+ UpdateUser(
+ "Uninstalling CreamAPI in proxy mode from " + selection.Name +
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
+ await CreamAPI.ProxyUninstall(directory, this);
+ }
+ }
+ }
+ else
+ {
+ if (uninstalling || !useSmokeApiProxy)
+ {
+ directory.GetSmokeApiComponents(out _, out _, out _, out _, out string old_config, out string config, out _,
+ out _, out _);
+ if (directory.GetSmokeApiProxies().Any(proxy =>
+ proxy.FileExists() && (proxy.IsResourceFile(ResourceIdentifier.Steamworks32) ||
+ proxy.IsResourceFile(ResourceIdentifier.Steamworks64))) ||
+ config.FileExists())
+ {
+ UpdateUser(
+ "Uninstalling SmokeAPI in proxy mode from " + selection.Name +
+ $" in directory \"{directory}\" . . . ", LogTextBox.Operation);
+ await SmokeAPI.ProxyUninstall(directory, this);
+ }
}
}
}
- bool uninstallingForProxy = uninstalling || useKoaloader || useCreamApiProxy;
+ bool uninstallingForProxy = uninstalling || useKoaloader || useCreamApiProxy || useSmokeApiProxy;
int count = selection.DllDirectories.Count, cur = 0;
foreach (string directory in selection.DllDirectories)
{
@@ -199,7 +240,7 @@ internal sealed partial class InstallForm : CustomForm
if (selection.Platform is Platform.Epic or Platform.Paradox)
{
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64,
- out string api64_o, out string config, out string log);
+ out string api64_o, out string old_config, out string config, out string old_log, out string log);
if (uninstallingForProxy
? api32_o.FileExists() || api64_o.FileExists() || config.FileExists() || log.FileExists()
: api32.FileExists() || api64.FileExists())
@@ -253,13 +294,13 @@ internal sealed partial class InstallForm : CustomForm
UpdateProgress(++cur / count * 100);
}
- if ((useCreamApiProxy || useKoaloader) && !uninstalling)
+ if ((useCreamApiProxy || useSmokeApiProxy || useKoaloader) && !uninstalling)
foreach ((string directory, BinaryType binaryType) in selection.ExecutableDirectories)
{
if (Program.Canceled)
return;
- if (useCreamApiProxy)
+ if (useCreamApiProxy && !Program.UseSmokeAPI)
{
UpdateUser(
"Installing CreamAPI in proxy mode for " + selection.Name +
@@ -267,6 +308,14 @@ internal sealed partial class InstallForm : CustomForm
LogTextBox.Operation);
await CreamAPI.ProxyInstall(directory, binaryType, selection, this);
}
+ else if (useSmokeApiProxy && Program.UseSmokeAPI)
+ {
+ UpdateUser(
+ "Installing SmokeAPI in proxy mode for " + selection.Name +
+ $" in directory \"{directory}\" . . . ",
+ LogTextBox.Operation);
+ await SmokeAPI.ProxyInstall(directory, binaryType, selection, this);
+ }
else if (useKoaloader)
{
UpdateUser("Installing Koaloader for " + selection.Name + $" in directory \"{directory}\" . . . ",
diff --git a/CreamInstaller/Forms/SelectForm.Designer.cs b/CreamInstaller/Forms/SelectForm.Designer.cs
index 6f018d1..4671df6 100644
--- a/CreamInstaller/Forms/SelectForm.Designer.cs
+++ b/CreamInstaller/Forms/SelectForm.Designer.cs
@@ -1,8 +1,8 @@
-using System.ComponentModel;
+using CreamInstaller.Components;
+using CreamInstaller.Resources;
+using System.ComponentModel;
using System.Windows.Forms;
-using CreamInstaller.Components;
-
namespace CreamInstaller.Forms
{
partial class SelectForm
@@ -28,6 +28,9 @@ namespace CreamInstaller.Forms
blockedGamesFlowPanel = new FlowLayoutPanel();
blockedGamesCheckBox = new CheckBox();
blockProtectedHelpButton = new Button();
+ useSmokeAPILayoutPanel = new FlowLayoutPanel();
+ useSmokeAPICheckBox = new CheckBox();
+ useSmokeAPIHelpButton = new Button();
allCheckBoxLayoutPanel = new FlowLayoutPanel();
allCheckBox = new CheckBox();
progressBar = new ProgressBar();
@@ -45,6 +48,7 @@ namespace CreamInstaller.Forms
programsGroupBox.SuspendLayout();
proxyFlowPanel.SuspendLayout();
blockedGamesFlowPanel.SuspendLayout();
+ useSmokeAPILayoutPanel.SuspendLayout();
allCheckBoxLayoutPanel.SuspendLayout();
saveFlowPanel.SuspendLayout();
SuspendLayout();
@@ -84,6 +88,7 @@ namespace CreamInstaller.Forms
programsGroupBox.Controls.Add(proxyFlowPanel);
programsGroupBox.Controls.Add(noneFoundLabel);
programsGroupBox.Controls.Add(blockedGamesFlowPanel);
+ programsGroupBox.Controls.Add(useSmokeAPILayoutPanel);
programsGroupBox.Controls.Add(allCheckBoxLayoutPanel);
programsGroupBox.Controls.Add(selectionTreeView);
programsGroupBox.Location = new System.Drawing.Point(12, 12);
@@ -172,6 +177,48 @@ namespace CreamInstaller.Forms
blockProtectedHelpButton.UseVisualStyleBackColor = true;
blockProtectedHelpButton.Click += OnBlockProtectedGamesHelpButtonClicked;
//
+ // useSmokeAPILayoutPanel
+ //
+ useSmokeAPILayoutPanel.Anchor = AnchorStyles.Top;
+ useSmokeAPILayoutPanel.AutoSize = true;
+ useSmokeAPILayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
+ useSmokeAPILayoutPanel.Controls.Add(useSmokeAPICheckBox);
+ useSmokeAPILayoutPanel.Controls.Add(useSmokeAPIHelpButton);
+ useSmokeAPILayoutPanel.Location = new System.Drawing.Point(338, -1);
+ useSmokeAPILayoutPanel.Margin = new Padding(0);
+ useSmokeAPILayoutPanel.Name = "useSmokeAPILayoutPanel";
+ useSmokeAPILayoutPanel.Size = new System.Drawing.Size(124, 19);
+ useSmokeAPILayoutPanel.TabIndex = 1006;
+ useSmokeAPILayoutPanel.WrapContents = false;
+ //
+ // useSmokeAPICheckBox
+ //
+ useSmokeAPICheckBox.AutoSize = true;
+ useSmokeAPICheckBox.Checked = true;
+ useSmokeAPICheckBox.CheckState = CheckState.Checked;
+ useSmokeAPICheckBox.Enabled = false;
+ useSmokeAPICheckBox.Location = new System.Drawing.Point(2, 0);
+ useSmokeAPICheckBox.Margin = new Padding(2, 0, 0, 0);
+ useSmokeAPICheckBox.Name = "useSmokeAPICheckBox";
+ useSmokeAPICheckBox.Size = new System.Drawing.Size(102, 19);
+ useSmokeAPICheckBox.TabIndex = 1;
+ useSmokeAPICheckBox.Text = "Use SmokeAPI";
+ useSmokeAPICheckBox.UseVisualStyleBackColor = true;
+ useSmokeAPICheckBox.CheckedChanged += OnUseSmokeAPICheckBoxChanged;
+ //
+ // useSmokeAPIHelpButton
+ //
+ useSmokeAPIHelpButton.Enabled = false;
+ useSmokeAPIHelpButton.Font = new System.Drawing.Font("Segoe UI", 7F);
+ useSmokeAPIHelpButton.Location = new System.Drawing.Point(104, 0);
+ useSmokeAPIHelpButton.Margin = new Padding(0, 0, 1, 0);
+ useSmokeAPIHelpButton.Name = "useSmokeAPIHelpButton";
+ useSmokeAPIHelpButton.Size = new System.Drawing.Size(19, 19);
+ useSmokeAPIHelpButton.TabIndex = 2;
+ useSmokeAPIHelpButton.Text = "?";
+ useSmokeAPIHelpButton.UseVisualStyleBackColor = true;
+ useSmokeAPIHelpButton.Click += OnUseSmokeAPIHelpButtonClicked;
+ //
// allCheckBoxLayoutPanel
//
allCheckBoxLayoutPanel.Anchor = AnchorStyles.Top | AnchorStyles.Right;
@@ -182,7 +229,7 @@ namespace CreamInstaller.Forms
allCheckBoxLayoutPanel.Margin = new Padding(0);
allCheckBoxLayoutPanel.Name = "allCheckBoxLayoutPanel";
allCheckBoxLayoutPanel.Size = new System.Drawing.Size(42, 19);
- allCheckBoxLayoutPanel.TabIndex = 1006;
+ allCheckBoxLayoutPanel.TabIndex = 1007;
allCheckBoxLayoutPanel.WrapContents = false;
//
// allCheckBox
@@ -404,7 +451,10 @@ namespace CreamInstaller.Forms
private CustomTreeView selectionTreeView;
private CheckBox blockedGamesCheckBox;
private Button blockProtectedHelpButton;
+ private CheckBox useSmokeAPICheckBox;
+ private Button useSmokeAPIHelpButton;
private FlowLayoutPanel blockedGamesFlowPanel;
+ private FlowLayoutPanel useSmokeAPILayoutPanel;
private FlowLayoutPanel allCheckBoxLayoutPanel;
private Button uninstallButton;
private Label progressLabelGames;
diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs
index bdbbb1b..9ba24f5 100644
--- a/CreamInstaller/Forms/SelectForm.cs
+++ b/CreamInstaller/Forms/SelectForm.cs
@@ -548,6 +548,8 @@ internal sealed partial class SelectForm : CustomForm
Program.Canceled = false;
blockedGamesCheckBox.Enabled = false;
blockProtectedHelpButton.Enabled = false;
+ useSmokeAPICheckBox.Enabled = false;
+ useSmokeAPIHelpButton.Enabled = false;
cancelButton.Enabled = true;
scanButton.Enabled = false;
noneFoundLabel.Visible = false;
@@ -694,6 +696,8 @@ internal sealed partial class SelectForm : CustomForm
scanButton.Enabled = true;
blockedGamesCheckBox.Enabled = true;
blockProtectedHelpButton.Enabled = true;
+ useSmokeAPICheckBox.Enabled = true;
+ useSmokeAPIHelpButton.Enabled = true;
}
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
@@ -887,8 +891,8 @@ internal sealed partial class SelectForm : CustomForm
foreach (string directory in directories)
{
directory.GetScreamApiComponents(out string api32, out string api32_o, out string api64,
- out string api64_o, out string config,
- out string log);
+ out string api64_o, out string old_config, out string config,
+ out string old_log, out string log);
if (api32.FileExists() || api32_o.FileExists() || api64.FileExists() || api64_o.FileExists() ||
config.FileExists() || log.FileExists())
_ = items.Add(new ContextMenuItem($"Open EOS Directory #{++epic}", "File Explorer",
@@ -1206,6 +1210,20 @@ internal sealed partial class SelectForm : CustomForm
: blockedDirectoryExceptions),
customFormText: "Block Protected Games");
}
+ private void OnUseSmokeAPICheckBoxChanged(object sender, EventArgs e)
+ {
+ Program.UseSmokeAPI = useSmokeAPICheckBox.Checked;
+ OnLoad(forceProvideChoices: false);
+ }
+
+ private void OnUseSmokeAPIHelpButtonClicked(object sender, EventArgs e)
+ {
+ using DialogForm form = new(this);
+ _ = form.Show(SystemIcons.Information,
+ "InTest restore SmokeAPI in app. May be unstable."
+ + "\n\nIf some games don't launch with it - try disable and reinstall unlock",
+ customFormText: "Use SmokeAPI");
+ }
private void OnSortCheckBoxChanged(object sender, EventArgs e)
=> selectionTreeView.TreeViewNodeSorter =
diff --git a/CreamInstaller/Forms/SelectForm.resx b/CreamInstaller/Forms/SelectForm.resx
index 00c232e..a50cd1b 100644
--- a/CreamInstaller/Forms/SelectForm.resx
+++ b/CreamInstaller/Forms/SelectForm.resx
@@ -1,7 +1,7 @@