- Massive refactoring and asynchronous fixes
- Disabled file operations from displaying in the install info label, and they now only display in the log
- Disabled selection validation, as previous issues warranting it have since been fixed
This commit is contained in:
pointfeev 2022-01-22 01:47:09 -05:00
parent 70f009abb5
commit 5024cd2194
12 changed files with 414 additions and 580 deletions

219
.editorconfig Normal file
View file

@ -0,0 +1,219 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = true
dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:suggestion
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:suggestion
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# Expression-level preferences
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
# Field preferences
dotnet_style_readonly_field = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
# New line preferences
dotnet_style_allow_multiple_blank_lines_experimental = false:suggestion
dotnet_style_allow_statement_immediately_after_block_experimental = true:suggestion
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:suggestion
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:suggestion
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:suggestion
csharp_style_expression_bodied_constructors = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_lambdas = true:suggestion
csharp_style_expression_bodied_local_functions = true:suggestion
csharp_style_expression_bodied_methods = true:suggestion
csharp_style_expression_bodied_operators = true:suggestion
csharp_style_expression_bodied_properties = true:suggestion
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true:suggestion
csharp_style_prefer_switch_expression = true
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Modifier preferences
csharp_prefer_static_local_function = true
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
# Code-block preferences
csharp_prefer_braces = false:suggestion
csharp_prefer_simple_using_statement = true
csharp_style_namespace_declarations = file_scoped:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_deconstructed_variable_declaration = true
csharp_style_implicit_object_creation_when_type_is_apparent = true
csharp_style_inlined_variable_declaration = true
csharp_style_pattern_local_over_anonymous_function = true
csharp_style_prefer_index_operator = true
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_range_operator = true
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = unused_local_variable:suggestion
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:suggestion
# New line preferences
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:suggestion
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
csharp_style_allow_embedded_statements_on_same_line_experimental = true:suggestion
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

View file

@ -53,14 +53,8 @@ namespace CreamInstaller
private readonly string message;
public override string Message => message ?? "CustomMessageException";
public override string ToString()
{
return Message;
}
public override string ToString() => Message;
internal CustomMessageException(string message)
{
this.message = message;
}
internal CustomMessageException(string message) => this.message = message;
}
}

View file

@ -1,9 +1,10 @@
using Gameloop.Vdf.Linq;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Gameloop.Vdf.Linq;
namespace CreamInstaller
{
internal class ProgramSelection
@ -81,10 +82,7 @@ namespace CreamInstaller
Enabled = SelectedSteamDlc.Any();
}
internal ProgramSelection()
{
All.Add(this);
}
internal ProgramSelection() => All.Add(this);
internal void Validate()
{
@ -95,10 +93,7 @@ namespace CreamInstaller
}
}
internal static void ValidateAll()
{
All.ForEach(selection => selection.Validate());
}
internal static void ValidateAll() => All.ForEach(selection => selection.Validate());
internal static List<ProgramSelection> All => Program.ProgramSelections;
@ -106,10 +101,7 @@ namespace CreamInstaller
internal static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled);
internal static ProgramSelection FromAppId(int appId)
{
return AllSafe.Find(s => s.SteamAppId == appId);
}
internal static ProgramSelection FromAppId(int appId) => AllSafe.Find(s => s.SteamAppId == appId);
internal static KeyValuePair<int, string>? GetDlcFromAppId(int appId)
{

View file

@ -1,6 +1,4 @@
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -11,6 +9,9 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
namespace CreamInstaller
{
internal static class SteamCMD
@ -26,12 +27,9 @@ namespace CreamInstaller
internal static readonly Version MinimumAppInfoVersion = Version.Parse("2.0.3.2");
internal static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
internal static string Run(string command)
internal static async Task<string> Run(string command) => await Task.Run(() =>
{
if (Program.Canceled)
{
return "";
}
if (Program.Canceled) return "";
List<string> logs = new();
ProcessStartInfo processStartInfo = new()
{
@ -55,7 +53,7 @@ namespace CreamInstaller
process.WaitForExit();
}
return string.Join("\r\n", logs);
}
});
internal static async Task Setup()
{
@ -67,56 +65,34 @@ namespace CreamInstaller
byte[] file = await httpClient.GetByteArrayAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip");
file.Write(ArchivePath);
}
ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath);
File.Delete(ArchivePath);
}
if (File.Exists(AppCacheAppInfoPath))
{
File.Delete(AppCacheAppInfoPath);
}
if (File.Exists(AppCacheAppInfoPath)) File.Delete(AppCacheAppInfoPath);
if (!File.Exists(AppInfoVersionPath) || !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version) || version < MinimumAppInfoVersion)
{
if (Directory.Exists(AppInfoPath))
{
Directory.Delete(AppInfoPath, true);
}
if (Directory.Exists(AppInfoPath)) Directory.Delete(AppInfoPath, true);
Directory.CreateDirectory(AppInfoPath);
File.WriteAllText(AppInfoVersionPath, Application.ProductVersion, Encoding.UTF8);
}
if (!File.Exists(DllPath))
{
Run($@"+quit");
}
if (!File.Exists(DllPath)) await Run($@"+quit");
}
internal static bool GetAppInfo(int appId, out VProperty appInfo, string branch = "public", int buildId = 0)
internal static async Task<VProperty> GetAppInfo(int appId, string branch = "public", int buildId = 0)
{
appInfo = null;
if (Program.Canceled)
{
return false;
}
VProperty appInfo = null;
if (Program.Canceled) return null;
string output;
string appUpdatePath = $@"{AppInfoPath}\{appId}";
string appUpdateFile = $@"{appUpdatePath}\appinfo.txt";
restart:
if (Program.Canceled)
{
return false;
}
if (Program.Canceled) return null;
if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile))
{
output = File.ReadAllText(appUpdateFile, Encoding.UTF8);
}
else
{
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +force_install_dir {appUpdatePath} +app_update 4 +quit");
output = Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +quit");
await Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +force_install_dir {appUpdatePath} +app_update 4 +quit");
output = await Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +quit");
int openBracket = output.IndexOf("{");
int closeBracket = output.LastIndexOf("}");
if (openBracket != -1 && closeBracket != -1)
@ -125,11 +101,7 @@ namespace CreamInstaller
File.WriteAllText(appUpdateFile, output, Encoding.UTF8);
}
}
if (Program.Canceled || output is null)
{
return false;
}
if (Program.Canceled || output is null) return null;
try { appInfo = VdfConvert.Deserialize(output); }
catch
{
@ -139,85 +111,46 @@ namespace CreamInstaller
goto restart;
}
}
if (appInfo.Value is VValue)
{
goto restart;
}
if (appInfo.Value is VValue) goto restart;
if (appInfo is null || (appInfo.Value is not VValue && appInfo.Value.Children().ToList().Count == 0))
{
return true;
}
return appInfo;
VToken type = appInfo.Value is VValue ? null : appInfo.Value?["common"]?["type"];
if (type is null || type.ToString() == "Game")
{
string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString();
if (buildid is null && type is not null)
{
return true;
}
if (buildid is null && type is not null) return appInfo;
if (type is null || int.Parse(buildid) < buildId)
{
foreach (int id in ParseDlcAppIds(appInfo))
List<int> dlcAppIds = await ParseDlcAppIds(appInfo);
foreach (int id in dlcAppIds)
{
string dlcAppUpdatePath = $@"{AppInfoPath}\{id}";
if (Directory.Exists(dlcAppUpdatePath))
{
Directory.Delete(dlcAppUpdatePath, true);
}
}
if (Directory.Exists(appUpdatePath))
{
Directory.Delete(appUpdatePath, true);
if (Directory.Exists(dlcAppUpdatePath)) Directory.Delete(dlcAppUpdatePath, true);
}
if (Directory.Exists(appUpdatePath)) Directory.Delete(appUpdatePath, true);
goto restart;
}
}
return true;
return appInfo;
}
internal static List<int> ParseDlcAppIds(VProperty appInfo)
internal static async Task<List<int>> ParseDlcAppIds(VProperty appInfo) => await Task.Run(() =>
{
List<int> dlcIds = new();
if (appInfo is not VProperty)
{
return dlcIds;
}
if (appInfo is not VProperty) return dlcIds;
if (appInfo.Value["extended"] is not null)
{
foreach (VProperty property in appInfo.Value["extended"])
{
if (property.Key.ToString() == "listofdlc")
{
foreach (string id in property.Value.ToString().Split(","))
{
if (!dlcIds.Contains(int.Parse(id)))
{
dlcIds.Add(int.Parse(id));
}
}
}
}
}
if (appInfo.Value["depots"] is not null)
{
foreach (VProperty _property in appInfo.Value["depots"])
{
if (int.TryParse(_property.Key.ToString(), out int _))
{
if (int.TryParse(_property.Value?["dlcappid"]?.ToString(), out int appid) && !dlcIds.Contains(appid))
{
dlcIds.Add(appid);
}
}
}
}
return dlcIds;
}
});
internal static async Task Kill()
{
@ -227,10 +160,7 @@ namespace CreamInstaller
process.Kill();
tasks.Add(Task.Run(() => process.WaitForExit()));
}
foreach (Task task in tasks)
{
await task;
}
foreach (Task task in tasks) await task;
}
internal static void Dispose()

View file

@ -5,7 +5,7 @@
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Version>2.2.1.1</Version>
<Version>2.2.2.0</Version>
<PackageIcon>Resources\ini.ico</PackageIcon>
<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>

View file

@ -4,15 +4,9 @@ namespace CreamInstaller
{
internal class CustomForm : Form
{
internal CustomForm() : base()
{
Icon = Properties.Resources.Icon;
}
internal CustomForm() : base() => Icon = Properties.Resources.Icon;
internal CustomForm(IWin32Window owner) : this()
{
Owner = owner as Form;
}
internal CustomForm(IWin32Window owner) : this() => Owner = owner as Form;
protected override CreateParams CreateParams // Double buffering for all controls
{

View file

@ -5,10 +5,7 @@ namespace CreamInstaller
{
internal partial class DialogForm : CustomForm
{
internal DialogForm(IWin32Window owner) : base(owner)
{
InitializeComponent();
}
internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
internal DialogResult Show(string formName, Icon descriptionIcon, string descriptionText, string acceptButtonText, string cancelButtonText = null)
{
@ -21,10 +18,7 @@ namespace CreamInstaller
cancelButton.Enabled = false;
cancelButton.Visible = false;
}
else
{
cancelButton.Text = cancelButtonText;
}
else cancelButton.Text = cancelButtonText;
return ShowDialog();
}
}

View file

@ -51,6 +51,7 @@ namespace CreamInstaller
//
this.userInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.userInfoLabel.AutoEllipsis = true;
this.userInfoLabel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.userInfoLabel.Location = new System.Drawing.Point(12, 9);
this.userInfoLabel.Name = "userInfoLabel";

View file

@ -30,23 +30,17 @@ namespace CreamInstaller
internal void UpdateProgress(int progress)
{
int value = (int)((float)(CompleteOperationsCount / (float)OperationsCount) * 100) + (progress / OperationsCount);
if (value < userProgressBar.Value)
{
return;
}
if (value < userProgressBar.Value) return;
userProgressBar.Value = value;
}
internal async Task UpdateUser(string text, Color color, bool log = true)
internal async Task UpdateUser(string text, Color color, bool info = true, bool log = true)
{
userInfoLabel.Text = text;
if (info) userInfoLabel.Text = text;
if (log && !logTextBox.IsDisposed)
{
if (logTextBox.Text.Length > 0)
{
logTextBox.AppendText(Environment.NewLine, color);
}
logTextBox.AppendText(userInfoLabel.Text, color);
if (logTextBox.Text.Length > 0) logTextBox.AppendText(Environment.NewLine, color);
logTextBox.AppendText(text, color);
}
await Task.Run(() => Thread.Sleep(1)); // to keep the text box control from glitching
}
@ -59,11 +53,11 @@ namespace CreamInstaller
writer.WriteLine($"appid = {steamAppId}");
writer.WriteLine();
writer.WriteLine("[dlc]");
await UpdateUser($"Added game to cream_api.ini with appid {steamAppId} ({name})", InstallationLog.Resource);
await UpdateUser($"Added game to cream_api.ini with appid {steamAppId} ({name})", InstallationLog.Resource, info: false);
foreach (KeyValuePair<int, string> dlcApp in steamDlcApps)
{
writer.WriteLine($"{dlcApp.Key} = {dlcApp.Value}");
await UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource);
await UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource, info: false);
}
}
@ -91,25 +85,25 @@ namespace CreamInstaller
if (File.Exists(api))
{
File.Delete(api);
await UpdateUser($"Deleted file: {Path.GetFileName(api)}", InstallationLog.Resource);
await UpdateUser($"Deleted file: {Path.GetFileName(api)}", InstallationLog.Resource, info: false);
}
File.Move(api_o, api);
await UpdateUser($"Renamed file: {Path.GetFileName(api_o)} -> {Path.GetFileName(api)}", InstallationLog.Resource);
await UpdateUser($"Renamed file: {Path.GetFileName(api_o)} -> {Path.GetFileName(api)}", InstallationLog.Resource, info: false);
}
if (File.Exists(api64_o))
{
if (File.Exists(api64))
{
File.Delete(api64);
await UpdateUser($"Deleted file: {Path.GetFileName(api64)}", InstallationLog.Resource);
await UpdateUser($"Deleted file: {Path.GetFileName(api64)}", InstallationLog.Resource, info: false);
}
File.Move(api64_o, api64);
await UpdateUser($"Renamed file: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", InstallationLog.Resource);
await UpdateUser($"Renamed file: {Path.GetFileName(api64_o)} -> {Path.GetFileName(api64)}", InstallationLog.Resource, info: false);
}
if (File.Exists(cApi))
{
File.Delete(cApi);
await UpdateUser($"Deleted file: {Path.GetFileName(cApi)}", InstallationLog.Resource);
await UpdateUser($"Deleted file: {Path.GetFileName(cApi)}", InstallationLog.Resource, info: false);
}
}
else
@ -117,22 +111,22 @@ namespace CreamInstaller
if (File.Exists(api) && !File.Exists(api_o))
{
File.Move(api, api_o);
await UpdateUser($"Renamed file: {Path.GetFileName(api)} -> {Path.GetFileName(api_o)}", InstallationLog.Resource);
await UpdateUser($"Renamed file: {Path.GetFileName(api)} -> {Path.GetFileName(api_o)}", InstallationLog.Resource, info: false);
}
if (File.Exists(api_o))
{
Properties.Resources.API.Write(api);
await UpdateUser($"Wrote resource to file: {Path.GetFileName(api)}", InstallationLog.Resource);
await UpdateUser($"Wrote resource to file: {Path.GetFileName(api)}", InstallationLog.Resource, info: false);
}
if (File.Exists(api64) && !File.Exists(api64_o))
{
File.Move(api64, api64_o);
await UpdateUser($"Renamed file: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", InstallationLog.Resource);
await UpdateUser($"Renamed file: {Path.GetFileName(api64)} -> {Path.GetFileName(api64_o)}", InstallationLog.Resource, info: false);
}
if (File.Exists(api64_o))
{
Properties.Resources.API64.Write(api64);
await UpdateUser($"Wrote resource to file: {Path.GetFileName(api64)}", InstallationLog.Resource);
await UpdateUser($"Wrote resource to file: {Path.GetFileName(api64)}", InstallationLog.Resource, info: false);
}
await UpdateUser("Generating CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
File.Create(cApi).Close();
@ -161,10 +155,7 @@ namespace CreamInstaller
CompleteOperationsCount = 0;
foreach (ProgramSelection selection in programSelections)
{
if (!Program.IsProgramRunningDialog(this, selection))
{
throw new OperationCanceledException();
}
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException();
try
{
await OperateFor(selection);
@ -180,16 +171,8 @@ namespace CreamInstaller
await Program.Cleanup();
List<ProgramSelection> FailedSelections = ProgramSelection.AllSafeEnabled;
if (FailedSelections.Any())
{
if (FailedSelections.Count == 1)
{
throw new CustomMessageException($"Operation failed for {FailedSelections.First().Name}.");
}
else
{
throw new CustomMessageException($"Operation failed for {FailedSelections.Count} programs.");
}
}
if (FailedSelections.Count == 1) throw new CustomMessageException($"Operation failed for {FailedSelections.First().Name}.");
else throw new CustomMessageException($"Operation failed for {FailedSelections.Count} programs.");
}
private readonly int ProgramCount = ProgramSelection.AllSafeEnabled.Count;
@ -228,10 +211,7 @@ namespace CreamInstaller
}
catch (Exception e)
{
if (ExceptionHandler.OutputException(e))
{
goto retry;
}
if (ExceptionHandler.OutputException(e)) goto retry;
Close();
}
}
@ -248,10 +228,7 @@ namespace CreamInstaller
Start();
}
private void OnCancel(object sender, EventArgs e)
{
Program.Cleanup().Wait();
}
private void OnCancel(object sender, EventArgs e) => Program.Cleanup().Wait();
private void OnReselect(object sender, EventArgs e)
{

View file

@ -1,8 +1,4 @@
using HtmlAgilityPack;
using Onova;
using Onova.Models;
using Onova.Services;
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
@ -13,6 +9,12 @@ using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using HtmlAgilityPack;
using Onova;
using Onova.Models;
using Onova.Services;
namespace CreamInstaller
{
internal partial class MainForm : CustomForm
@ -33,7 +35,6 @@ namespace CreamInstaller
cancellationTokenSource.Dispose();
cancellationTokenSource = null;
}
Hide();
new SelectForm(this).ShowDialog();
Close();
@ -93,7 +94,6 @@ namespace CreamInstaller
changelogTreeView.Visible = true;
Version currentVersion = new(Application.ProductVersion);
foreach (Version version in versions)
{
if (version > currentVersion && !changelogTreeView.Nodes.ContainsKey(version.ToString()))
{
TreeNode root = new($"v{version}");
@ -128,7 +128,6 @@ namespace CreamInstaller
}
});
}
}
}
}
@ -139,7 +138,6 @@ namespace CreamInstaller
{
string FileName = Path.GetFileName(Program.CurrentProcessFilePath);
if (FileName != "CreamInstaller.exe")
{
if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Warning,
"WARNING: CreamInstaller.exe was renamed!" +
"\n\nThis will cause unwanted behavior when updating the program!",
@ -148,24 +146,16 @@ namespace CreamInstaller
Application.Exit();
return;
}
}
OnLoad();
}
catch (Exception e)
{
if (ExceptionHandler.OutputException(e))
{
goto retry;
}
if (ExceptionHandler.OutputException(e)) goto retry;
Close();
}
}
private void OnIgnore(object sender, EventArgs e)
{
StartProgram();
}
private void OnIgnore(object sender, EventArgs e) => StartProgram();
private async void OnUpdate(object sender, EventArgs e)
{
@ -200,10 +190,7 @@ namespace CreamInstaller
Application.Exit();
return;
}
else
{
OnLoad();
}
else OnLoad();
}
private void OnUpdateCancel(object sender, EventArgs e)

View file

@ -1,7 +1,4 @@
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
using Microsoft.Win32;
using System;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -13,6 +10,11 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
using Microsoft.Win32;
namespace CreamInstaller
{
internal partial class SelectForm : CustomForm
@ -24,118 +26,74 @@ namespace CreamInstaller
Program.SelectForm = this;
}
private static List<string> GameLibraryDirectories
private static async Task<List<string>> GameLibraryDirectories() => await Task.Run(() =>
{
get
List<string> gameDirectories = new();
if (Program.Canceled) return gameDirectories;
string steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Valve\\Steam", "InstallPath", null) as string;
steamInstallPath ??= Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
if (steamInstallPath != null && Directory.Exists(steamInstallPath))
{
List<string> gameDirectories = new();
if (Program.Canceled)
string libraryFolder = steamInstallPath + @"\steamapps";
if (Directory.Exists(libraryFolder))
{
return gameDirectories;
}
string steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Valve\\Steam", "InstallPath", null) as string;
if (steamInstallPath == null)
{
steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
}
if (steamInstallPath != null && Directory.Exists(steamInstallPath))
{
string libraryFolder = steamInstallPath + @"\steamapps";
if (Directory.Exists(libraryFolder))
gameDirectories.Add(libraryFolder);
try
{
gameDirectories.Add(libraryFolder);
try
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
if (File.Exists(libraryFolders))
{
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
if (File.Exists(libraryFolders))
{
dynamic property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders, Encoding.UTF8));
foreach (dynamic _property in property.Value)
dynamic property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders, Encoding.UTF8)).Value;
foreach (dynamic _property in property)
if (int.TryParse(_property.Key, out int _))
{
if (int.TryParse(_property.Key, out int _))
{
string path = _property.Value.path.ToString() + @"\steamapps";
if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path))
{
continue;
}
if (!gameDirectories.Contains(path))
{
gameDirectories.Add(path);
}
}
string path = _property.Value.path.ToString() + @"\steamapps";
if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path)) continue;
if (!gameDirectories.Contains(path)) gameDirectories.Add(path);
}
}
}
catch { }
}
catch { }
}
return gameDirectories;
}
}
return gameDirectories;
});
private static bool GetDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> dllDirectories)
private static async Task<List<string>> GetDllDirectoriesFromGameDirectory(string gameDirectory) => await Task.Run(async () =>
{
dllDirectories = new();
if (Program.Canceled || !Directory.Exists(gameDirectory))
{
return false;
}
List<string> dllDirectories = new();
if (Program.Canceled || !Directory.Exists(gameDirectory)) return null;
string api = gameDirectory + @"\steam_api.dll";
string api64 = gameDirectory + @"\steam_api64.dll";
if (File.Exists(api) || File.Exists(api64))
if (File.Exists(api) || File.Exists(api64)) dllDirectories.Add(gameDirectory);
string[] directories = Directory.GetDirectories(gameDirectory);
foreach (string _directory in directories)
{
dllDirectories.Add(gameDirectory);
}
foreach (string _directory in Directory.GetDirectories(gameDirectory))
{
if (Program.Canceled)
{
return false;
}
if (Program.Canceled) return null;
try
{
if (GetDllDirectoriesFromGameDirectory(_directory, out List<string> _dllDirectories))
{
dllDirectories.AddRange(_dllDirectories);
}
List<string> moreDllDirectories = await GetDllDirectoriesFromGameDirectory(_directory);
if (moreDllDirectories is not null) dllDirectories.AddRange(moreDllDirectories);
}
catch { }
}
if (!dllDirectories.Any())
{
return false;
}
if (!dllDirectories.Any()) return null;
return dllDirectories;
});
return true;
}
private static bool GetGamesFromLibraryDirectory(string libraryDirectory, out List<Tuple<int, string, string, int, string>> games)
private static async Task<List<Tuple<int, string, string, int, string>>> GetGamesFromLibraryDirectory(string libraryDirectory) => await Task.Run(() =>
{
games = new();
if (Program.Canceled || !Directory.Exists(libraryDirectory))
List<Tuple<int, string, string, int, string>> games = new();
if (Program.Canceled || !Directory.Exists(libraryDirectory)) return null;
string[] files = Directory.GetFiles(libraryDirectory);
foreach (string file in files)
{
return false;
}
foreach (string directory in Directory.GetFiles(libraryDirectory))
{
if (Program.Canceled)
{
return false;
}
if (Path.GetExtension(directory) == ".acf")
if (Program.Canceled) return null;
if (Path.GetExtension(file) == ".acf")
{
try
{
dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory, Encoding.UTF8));
dynamic property = VdfConvert.Deserialize(File.ReadAllText(file, Encoding.UTF8));
string _appid = property.Value.appid.ToString();
string installdir = property.Value.installdir.ToString();
string name = property.Value.name.ToString();
@ -144,39 +102,20 @@ namespace CreamInstaller
|| string.IsNullOrWhiteSpace(installdir)
|| string.IsNullOrWhiteSpace(name)
|| string.IsNullOrWhiteSpace(_buildid))
{
continue;
}
string branch = property.Value.UserConfig?.betakey?.ToString();
if (string.IsNullOrWhiteSpace(branch))
{
branch = "public";
}
if (string.IsNullOrWhiteSpace(branch)) branch = "public";
string gameDirectory = libraryDirectory + @"\common\" + installdir;
if (!int.TryParse(_appid, out int appid))
{
continue;
}
if (!int.TryParse(_buildid, out int buildid))
{
continue;
}
if (!int.TryParse(_appid, out int appid)) continue;
if (!int.TryParse(_buildid, out int buildid)) continue;
games.Add(new(appid, name, branch, buildid, gameDirectory));
}
catch { }
}
}
if (!games.Any())
{
return false;
}
return true;
}
if (!games.Any()) return null;
return games;
});
internal List<TreeNode> TreeNodes => GatherTreeNodes(selectionTreeView.Nodes);
private List<TreeNode> GatherTreeNodes(TreeNodeCollection nodeCollection)
@ -194,30 +133,21 @@ namespace CreamInstaller
private async Task GetCreamApiApplicablePrograms(IProgress<int> progress)
{
int cur = 0;
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
List<Tuple<int, string, string, int, string>> applicablePrograms = new();
string launcherRootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
if (Directory.Exists(launcherRootDirectory))
{
applicablePrograms.Add(new(0, "Paradox Launcher", "", 0, launcherRootDirectory));
}
foreach (string libraryDirectory in GameLibraryDirectories)
List<string> gameLibraryDirectories = await GameLibraryDirectories();
foreach (string libraryDirectory in gameLibraryDirectories)
{
if (GetGamesFromLibraryDirectory(libraryDirectory, out List<Tuple<int, string, string, int, string>> games))
{
List<Tuple<int, string, string, int, string>> games = await GetGamesFromLibraryDirectory(libraryDirectory);
if (games is not null)
foreach (Tuple<int, string, string, int, string> game in games)
{
applicablePrograms.Add(game);
}
}
}
int cur = 0;
RunningTasks.Clear();
foreach (Tuple<int, string, string, int, string> program in applicablePrograms)
{
@ -227,23 +157,14 @@ namespace CreamInstaller
int buildId = program.Item4;
string directory = program.Item5;
ProgramSelection selection = ProgramSelection.FromAppId(appId);
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
if (Program.BlockProtectedGames)
{
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)
@ -254,59 +175,32 @@ namespace CreamInstaller
continue;
}
}
Task task = Task.Run(async () =>
RunningTasks.Add(Task.Run(async () =>
{
if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List<string> dllDirectories))
{
return;
}
if (Program.Canceled) return;
List<string> dllDirectories = await GetDllDirectoriesFromGameDirectory(directory);
if (dllDirectories is null) return;
VProperty appInfo = null;
if (Program.Canceled || (appId > 0 && !SteamCMD.GetAppInfo(appId, out appInfo, branch, buildId)))
{
return;
}
if (Program.Canceled)
{
return;
}
if (appId > 0) appInfo = await SteamCMD.GetAppInfo(appId, branch, buildId);
if (appId > 0 && appInfo is null) return;
if (Program.Canceled) return;
ConcurrentDictionary<int, string> dlc = new();
List<Task> dlcTasks = new();
List<int> dlcIds = SteamCMD.ParseDlcAppIds(appInfo);
List<int> dlcIds = await SteamCMD.ParseDlcAppIds(appInfo);
if (dlcIds.Count > 0)
{
foreach (int id in dlcIds)
{
if (Program.Canceled)
if (Program.Canceled) return;
Task task = Task.Run(async () =>
{
return;
}
Task task = Task.Run(() =>
{
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
string dlcName = null;
if (SteamCMD.GetAppInfo(id, out VProperty dlcAppInfo))
{
VProperty dlcAppInfo = await SteamCMD.GetAppInfo(id);
if (dlcAppInfo is not null)
dlcName = dlcAppInfo?.Value?["common"]?["name"]?.ToString();
}
if (Program.Canceled)
{
return;
}
if (string.IsNullOrWhiteSpace(dlcName))
{
return; //dlcName = "Unknown DLC";
}
if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(dlcName)) return; //dlcName = "Unknown DLC";
dlc[id] = /*$"[{id}] " +*/ dlcName;
progress.Report(++cur);
});
@ -315,20 +209,9 @@ namespace CreamInstaller
}
progress.Report(-RunningTasks.Count);
}
else if (appId > 0)
{
return;
}
if (Program.Canceled)
{
return;
}
if (string.IsNullOrWhiteSpace(name))
{
return;
}
else if (appId > 0) return;
if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(name)) return;
selection ??= new();
selection.Usable = true;
@ -337,31 +220,17 @@ namespace CreamInstaller
selection.SteamAppId = appId;
selection.SteamApiDllDirectories = dllDirectories;
selection.AppInfo = appInfo;
if (allCheckBox.Checked)
{
selection.Enabled = true;
}
if (allCheckBox.Checked) selection.Enabled = true;
foreach (Task task in dlcTasks.ToList())
foreach (Task task in dlcTasks)
{
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
await task;
}
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
selectionTreeView.Invoke((MethodInvoker)delegate
{
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
TreeNode programNode = TreeNodes.Find(s => s.Name == "" + appId) ?? new();
programNode.Name = "" + appId;
programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name;
@ -374,19 +243,11 @@ namespace CreamInstaller
}
else
{
foreach (KeyValuePair<int, string> dlcApp in dlc.ToList())
foreach (KeyValuePair<int, string> dlcApp in dlc)
{
if (Program.Canceled || programNode is null)
{
return;
}
if (Program.Canceled || programNode is null) return;
selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value;
if (allCheckBox.Checked)
{
selection.SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
}
if (allCheckBox.Checked) selection.SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
TreeNode dlcNode = TreeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new();
dlcNode.Name = "" + dlcApp.Key;
dlcNode.Text = dlcApp.Value;
@ -397,17 +258,13 @@ namespace CreamInstaller
}
});
progress.Report(++cur);
});
RunningTasks.Add(task);
}));
}
progress.Report(-RunningTasks.Count);
progress.Report(cur);
foreach (Task task in RunningTasks.ToList())
{
if (Program.Canceled)
{
return;
}
if (Program.Canceled) return;
await task;
}
progress.Report(RunningTasks.Count);
@ -428,7 +285,6 @@ namespace CreamInstaller
installButton.Enabled = false;
uninstallButton.Enabled = installButton.Enabled;
selectionTreeView.Enabled = false;
progressLabel.Visible = true;
progressBar1.Visible = true;
progressBar1.Value = 0;
@ -441,44 +297,20 @@ namespace CreamInstaller
IProgress<int> iProgress = progress;
progress.ProgressChanged += (sender, _progress) =>
{
if (_progress < 0)
{
maxProgress = -_progress;
}
else
{
curProgress = _progress;
}
if (_progress < 0) maxProgress = -_progress;
else curProgress = _progress;
int p = Math.Max(Math.Min((int)((float)(curProgress / (float)maxProgress) * 100), 100), 0);
if (validating)
{
progressLabel.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})";
}
else if (setup)
{
progressLabel.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
}
else
{
progressLabel.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
}
if (validating) progressLabel.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})";
else if (setup) progressLabel.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
else progressLabel.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
progressBar1.Value = p;
};
iProgress.Report(-1660); // not exact, number varies
int cur = 0;
iProgress.Report(cur);
if (!validating)
{
progressLabel.Text = "Setting up SteamCMD . . . ";
}
if (!Directory.Exists(SteamCMD.DirectoryPath))
{
Directory.CreateDirectory(SteamCMD.DirectoryPath);
}
if (!validating) progressLabel.Text = "Setting up SteamCMD . . . ";
if (!Directory.Exists(SteamCMD.DirectoryPath)) Directory.CreateDirectory(SteamCMD.DirectoryPath);
FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
watcher.Changed += (sender, e) => iProgress.Report(++cur);
@ -489,60 +321,42 @@ namespace CreamInstaller
watcher.Dispose();
setup = false;
if (!validating)
{
progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
}
if (!validating) progressLabel.Text = "Gathering and caching your applicable games and their DLCs . . . ";
await GetCreamApiApplicablePrograms(iProgress);
ProgramSelection.ValidateAll();
TreeNodes.ForEach(node =>
{
if (node.Parent is null && ProgramSelection.FromAppId(int.Parse(node.Name)) is null)
{
node.Remove();
}
if (node.Parent is null && ProgramSelection.FromAppId(int.Parse(node.Name)) is null) node.Remove();
});
progressBar1.Value = 100;
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height + 44);
progressLabel.Visible = false;
progressBar1.Visible = false;
selectionTreeView.Enabled = ProgramSelection.All.Any();
allCheckBox.Enabled = selectionTreeView.Enabled;
noneFoundLabel.Visible = !selectionTreeView.Enabled;
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
uninstallButton.Enabled = installButton.Enabled;
cancelButton.Enabled = false;
scanButton.Enabled = true;
blockedGamesCheckBox.Enabled = true;
blockProtectedHelpButton.Enabled = true;
progressLabel.Text = "Validating . . . ";
if (!validating && !Program.Canceled)
{
OnLoad(true);
}
//if (!validating && !Program.Canceled) OnLoad(true);
}
catch (Exception e)
{
if (ExceptionHandler.OutputException(e))
{
goto retry;
}
if (ExceptionHandler.OutputException(e)) goto retry;
Close();
}
}
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.Unknown)
{
return;
}
if (e.Action == TreeViewAction.Unknown) return;
TreeNode node = e.Node;
if (node is not null)
{
@ -563,10 +377,7 @@ namespace CreamInstaller
selection.ToggleAllDlc(node.Checked);
node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = node.Checked);
}
else
{
selection.Enabled = node.Checked;
}
else selection.Enabled = node.Checked;
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = TreeNodes.TrueForAll(treeNode => treeNode.Checked);
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
@ -593,18 +404,13 @@ namespace CreamInstaller
selectionTreeView.NodeMouseClick += (sender, e) =>
{
TreeNode node = e.Node;
if (e.Button == MouseButtons.Right && node.Bounds.Contains(e.Location))
{
string appId = node.Name;
if (appId != "0")
string appId = node.Name;
if (e.Button == MouseButtons.Right && node.Bounds.Contains(e.Location) && appId != "0")
Process.Start(new ProcessStartInfo
{
Process.Start(new ProcessStartInfo
{
FileName = "https://steamdb.info/app/" + appId,
UseShellExecute = true
});
}
}
FileName = "https://steamdb.info/app/" + appId,
UseShellExecute = true
});
};
OnLoad();
}
@ -617,31 +423,17 @@ namespace CreamInstaller
paradoxLauncher.ExtraSteamAppIdDlc.Clear();
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
{
if (selection.Name == paradoxLauncher.Name)
{
continue;
}
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive")
{
continue;
}
if (selection.Name == paradoxLauncher.Name) continue;
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc));
}
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
{
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
{
if (selection.Name == paradoxLauncher.Name)
{
continue;
}
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive")
{
continue;
}
if (selection.Name == paradoxLauncher.Name) continue;
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc));
}
}
}
}
@ -657,9 +449,7 @@ namespace CreamInstaller
$"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!",
"Ignore", "Cancel") == DialogResult.OK)
{
return false;
}
return true;
}
}
@ -671,16 +461,8 @@ namespace CreamInstaller
if (ProgramSelection.All.Any())
{
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
{
if (!Program.IsProgramRunningDialog(this, selection))
{
return;
}
}
if (ParadoxLauncherDlcDialog(this))
{
return;
}
if (!Program.IsProgramRunningDialog(this, selection)) return;
if (ParadoxLauncherDlcDialog(this)) return;
Hide();
InstallForm installForm = new(this, uninstall);
installForm.ShowDialog();
@ -690,27 +472,13 @@ namespace CreamInstaller
Show();
OnLoad();
}
else
{
Close();
}
else Close();
}
}
private void OnInstall(object sender, EventArgs e)
{
OnAccept(false);
}
private void OnUninstall(object sender, EventArgs e)
{
OnAccept(true);
}
private void OnScan(object sender, EventArgs e)
{
OnLoad();
}
private void OnInstall(object sender, EventArgs e) => OnAccept(false);
private void OnUninstall(object sender, EventArgs e) => OnAccept(true);
private void OnScan(object sender, EventArgs e) => OnLoad();
private void OnCancel(object sender, EventArgs e)
{
@ -728,10 +496,7 @@ namespace CreamInstaller
{
if (node.Parent is null)
{
if (!node.Checked)
{
shouldCheck = true;
}
if (!node.Checked) shouldCheck = true;
if (node.Checked != shouldCheck)
{
node.Checked = shouldCheck;
@ -753,19 +518,13 @@ namespace CreamInstaller
{
string blockedGames = "";
foreach (string name in Program.ProtectedGameNames)
{
blockedGames += helpButtonListPrefix + name;
}
string blockedDirectories = "";
foreach (string path in Program.ProtectedGameDirectories)
{
blockedDirectories += helpButtonListPrefix + path;
}
string blockedDirectoryExceptions = "";
foreach (string name in Program.ProtectedGameDirectoryExceptions)
{
blockedDirectoryExceptions += helpButtonListPrefix + name;
}
new DialogForm(this).Show(blockedGamesCheckBox.Text, SystemIcons.Information,
"Blocks the program from caching and displaying games protected by DLL checks," +
"\nanti-cheats, or that are confirmed not to be working with CreamAPI." +

View file

@ -41,11 +41,7 @@ namespace CreamInstaller
}
catch (Exception e)
{
if (ExceptionHandler.OutputException(e))
{
goto retry;
}
if (ExceptionHandler.OutputException(e)) goto retry;
Application.Exit();
return;
}
@ -61,14 +57,9 @@ namespace CreamInstaller
$"ERROR: {selection.Name} is currently running!" +
"\n\nPlease close the program/game to continue . . . ",
"Retry", "Cancel") == DialogResult.OK)
{
return IsProgramRunningDialog(form, selection);
}
}
else
{
return true;
}
else return true;
return false;
}
@ -86,17 +77,13 @@ namespace CreamInstaller
internal static List<ProgramSelection> ProgramSelections = new();
internal static bool Canceled = false;
internal static async Task Cleanup(bool cancel = true)
{
Canceled = cancel;
await SteamCMD.Kill();
}
private static void OnApplicationExit(object s, EventArgs e)
{
Cleanup().Wait();
}
private static void OnApplicationExit(object s, EventArgs e) => Cleanup().Wait();
internal static void InheritLocation(this Form form, Form fromForm)
{