Code cleanup and rebuild/republish on Visual Studio 2022
This commit is contained in:
pointfeev 2021-12-25 19:46:24 -06:00
parent 730c7093e7
commit 3a325aeaa2
9 changed files with 503 additions and 99 deletions

View file

@ -7,7 +7,11 @@ namespace CreamInstaller
{ {
public static bool OutputException(Exception e) public static bool OutputException(Exception e)
{ {
while (!(e.InnerException is null)) e = e.InnerException; while (!(e.InnerException is null))
{
e = e.InnerException;
}
string output = ""; string output = "";
string[] stackTrace = e.StackTrace?.Split('\n'); string[] stackTrace = e.StackTrace?.Split('\n');
if (!(stackTrace is null) && stackTrace.Length > 0) if (!(stackTrace is null) && stackTrace.Length > 0)
@ -25,7 +29,11 @@ namespace CreamInstaller
string[] messageLines = e.Message?.Split('\n'); string[] messageLines = e.Message?.Split('\n');
if (!(messageLines is null) && messageLines.Length > 0) if (!(messageLines is null) && messageLines.Length > 0)
{ {
if (output.Length > 0) output += "\n\n"; if (output.Length > 0)
{
output += "\n\n";
}
output += "MESSAGE\n"; output += "MESSAGE\n";
for (int i = 0; i < messageLines.Length; i++) for (int i = 0; i < messageLines.Length; i++)
{ {
@ -42,10 +50,13 @@ namespace CreamInstaller
public class CustomMessageException : Exception public class CustomMessageException : Exception
{ {
private string message; private readonly string message;
public override string Message => message ?? "CustomMessageException"; public override string Message => message ?? "CustomMessageException";
public override string ToString() => Message; public override string ToString()
{
return Message;
}
public CustomMessageException(string message) public CustomMessageException(string message)
{ {

View file

@ -28,7 +28,10 @@ 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()) return true; if (api.IsFilePathLocked() || api64.IsFilePathLocked())
{
return true;
}
} }
return false; return false;
} }
@ -36,8 +39,14 @@ namespace CreamInstaller
private void Toggle(KeyValuePair<int, string> dlcApp, bool enabled) private void Toggle(KeyValuePair<int, string> dlcApp, bool enabled)
{ {
if (enabled) SelectedSteamDlc[dlcApp.Key] = dlcApp.Value; if (enabled)
else SelectedSteamDlc.Remove(dlcApp.Key); {
SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
}
else
{
SelectedSteamDlc.Remove(dlcApp.Key);
}
} }
public void ToggleDlc(int dlcAppId, bool enabled) public void ToggleDlc(int dlcAppId, bool enabled)
@ -55,12 +64,25 @@ namespace CreamInstaller
public void ToggleAllDlc(bool enabled) public void ToggleAllDlc(bool enabled)
{ {
if (!enabled) SelectedSteamDlc.Clear(); if (!enabled)
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();
} }
public ProgramSelection() => All.Add(this); public ProgramSelection()
{
All.Add(this);
}
public static List<ProgramSelection> All => Program.ProgramSelections; public static List<ProgramSelection> All => Program.ProgramSelections;
@ -68,13 +90,24 @@ namespace CreamInstaller
public static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled); public static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled);
public static ProgramSelection FromAppId(int appId) => AllSafe.Find(s => s.SteamAppId == appId); public static ProgramSelection FromAppId(int appId)
{
return AllSafe.Find(s => s.SteamAppId == appId);
}
public static KeyValuePair<int, string>? GetDlcFromAppId(int appId) public static KeyValuePair<int, string>? GetDlcFromAppId(int appId)
{ {
foreach (ProgramSelection selection in AllSafe) foreach (ProgramSelection selection in AllSafe)
{
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;
} }
} }

View file

@ -59,29 +59,51 @@ namespace CreamInstaller
Kill(); Kill();
if (!File.Exists(FilePath)) if (!File.Exists(FilePath))
{ {
using (WebClient webClient = new()) webClient.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", ArchivePath); using (WebClient webClient = new())
{
webClient.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", ArchivePath);
}
ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath); ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath);
File.Delete(ArchivePath); 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 (!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); Directory.CreateDirectory(AppInfoPath);
File.WriteAllText(AppInfoVersionPath, Application.ProductVersion, Encoding.UTF8); File.WriteAllText(AppInfoVersionPath, Application.ProductVersion, Encoding.UTF8);
} }
if (!File.Exists(DllPath)) Run($@"+quit", out _); if (!File.Exists(DllPath))
{
Run($@"+quit", out _);
}
} }
public static bool GetAppInfo(int appId, out VProperty appInfo, string branch = "public", int buildId = 0) public static bool GetAppInfo(int appId, out VProperty appInfo, string branch = "public", int buildId = 0)
{ {
appInfo = null; appInfo = null;
if (Program.Canceled) return false; if (Program.Canceled)
{
return false;
}
string output; string output;
string appUpdatePath = $@"{AppInfoPath}\{appId}"; string appUpdatePath = $@"{AppInfoPath}\{appId}";
string appUpdateFile = $@"{appUpdatePath}\appinfo.txt"; string appUpdateFile = $@"{appUpdatePath}\appinfo.txt";
restart: restart:
if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile, Encoding.UTF8); if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile))
{
output = File.ReadAllText(appUpdateFile, Encoding.UTF8);
}
else else
{ {
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +force_install_dir {appUpdatePath} +app_update 4 +quit", out _); Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +force_install_dir {appUpdatePath} +app_update 4 +quit", out _);
@ -94,7 +116,11 @@ namespace CreamInstaller
File.WriteAllText(appUpdateFile, output, Encoding.UTF8); File.WriteAllText(appUpdateFile, output, Encoding.UTF8);
} }
} }
if (Program.Canceled || output is null) return false; if (Program.Canceled || output is null)
{
return false;
}
try { appInfo = VdfConvert.Deserialize(output); } try { appInfo = VdfConvert.Deserialize(output); }
catch catch
{ {
@ -104,21 +130,40 @@ namespace CreamInstaller
goto restart; goto restart;
} }
} }
if (appInfo.Value is VValue) goto restart; if (appInfo.Value is VValue)
if (appInfo is null || (!(appInfo.Value is VValue) && appInfo.Value.Children().ToList().Count == 0)) return true; {
goto restart;
}
if (appInfo is null || (!(appInfo.Value is VValue) && appInfo.Value.Children().ToList().Count == 0))
{
return true;
}
VToken type = appInfo.Value is VValue ? null : appInfo.Value?["common"]?["type"]; VToken type = appInfo.Value is VValue ? null : appInfo.Value?["common"]?["type"];
if (type is null || type.ToString() == "Game") if (type is null || type.ToString() == "Game")
{ {
string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString(); string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString();
if (buildid is null && !(type is null)) return true; if (buildid is null && !(type is null))
{
return true;
}
if (type is null || int.Parse(buildid) < buildId) if (type is null || int.Parse(buildid) < buildId)
{ {
foreach (int id in ParseDlcAppIds(appInfo)) foreach (int id in ParseDlcAppIds(appInfo))
{ {
string dlcAppUpdatePath = $@"{AppInfoPath}\{id}"; string dlcAppUpdatePath = $@"{AppInfoPath}\{id}";
if (Directory.Exists(dlcAppUpdatePath)) Directory.Delete(dlcAppUpdatePath, true); if (Directory.Exists(dlcAppUpdatePath))
{
Directory.Delete(dlcAppUpdatePath, true);
}
} }
if (Directory.Exists(appUpdatePath)) Directory.Delete(appUpdatePath, true); if (Directory.Exists(appUpdatePath))
{
Directory.Delete(appUpdatePath, true);
}
goto restart; goto restart;
} }
} }
@ -128,30 +173,60 @@ namespace CreamInstaller
public static List<int> ParseDlcAppIds(VProperty appInfo) public static List<int> ParseDlcAppIds(VProperty appInfo)
{ {
List<int> dlcIds = new(); List<int> dlcIds = new();
if (!(appInfo is VProperty)) return dlcIds; if (!(appInfo is VProperty))
{
return dlcIds;
}
if (!(appInfo.Value["extended"] is null)) if (!(appInfo.Value["extended"] is null))
{
foreach (VProperty property in appInfo.Value["extended"]) foreach (VProperty property in appInfo.Value["extended"])
{
if (property.Key.ToString() == "listofdlc") if (property.Key.ToString() == "listofdlc")
{
foreach (string id in property.Value.ToString().Split(",")) foreach (string id in property.Value.ToString().Split(","))
{
if (!dlcIds.Contains(int.Parse(id))) if (!dlcIds.Contains(int.Parse(id)))
{
dlcIds.Add(int.Parse(id)); dlcIds.Add(int.Parse(id));
}
}
}
}
}
if (!(appInfo.Value["depots"] is null)) if (!(appInfo.Value["depots"] is null))
{
foreach (VProperty _property in appInfo.Value["depots"]) foreach (VProperty _property in appInfo.Value["depots"])
{
if (int.TryParse(_property.Key.ToString(), out int _)) if (int.TryParse(_property.Key.ToString(), out int _))
{
if (int.TryParse(_property.Value?["dlcappid"]?.ToString(), out int appid) && !dlcIds.Contains(appid)) if (int.TryParse(_property.Value?["dlcappid"]?.ToString(), out int appid) && !dlcIds.Contains(appid))
{
dlcIds.Add(appid); dlcIds.Add(appid);
}
}
}
}
return dlcIds; return dlcIds;
} }
public static void Kill() public static void Kill()
{ {
foreach (Process process in Process.GetProcessesByName("steamcmd")) process.Kill(); foreach (Process process in Process.GetProcessesByName("steamcmd"))
{
process.Kill();
}
} }
public static void Dispose() public static void Dispose()
{ {
Kill(); Kill();
if (Directory.Exists(DirectoryPath)) Directory.Delete(DirectoryPath, true); if (Directory.Exists(DirectoryPath))
{
Directory.Delete(DirectoryPath, true);
}
} }
} }
} }

View file

@ -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.0.4.0</Version> <Version>2.0.4.1</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>

View file

@ -9,8 +9,14 @@ namespace CreamInstaller
{ {
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
if (m.Msg == 0x203) m.Result = IntPtr.Zero; if (m.Msg == 0x203)
else base.WndProc(ref m); {
m.Result = IntPtr.Zero;
}
else
{
base.WndProc(ref m);
}
} }
public CustomTreeView() : base() public CustomTreeView() : base()
@ -27,17 +33,27 @@ namespace CreamInstaller
private void DrawTreeNode(object sender, DrawTreeNodeEventArgs e) private void DrawTreeNode(object sender, DrawTreeNodeEventArgs e)
{ {
if (!e.Node.IsVisible) return; if (!e.Node.IsVisible)
{
return;
}
e.Graphics.FillRectangle(new SolidBrush(BackColor), e.Bounds); e.Graphics.FillRectangle(new SolidBrush(BackColor), e.Bounds);
int startX = e.Bounds.X + (e.Node.Parent is null ? 22 : 41); int startX = e.Bounds.X + (e.Node.Parent is null ? 22 : 41);
int startY = e.Bounds.Y; int startY = e.Bounds.Y;
if (e.Node.Parent is null && e.Node.Nodes.Count > 0) if (e.Node.Parent is null && e.Node.Nodes.Count > 0)
{
if (e.Node.IsExpanded) if (e.Node.IsExpanded)
{
openedGlyphRenderer.DrawBackground(e.Graphics, new(e.Bounds.X + startX / 2 - 8, startY, 16, 16)); openedGlyphRenderer.DrawBackground(e.Graphics, new(e.Bounds.X + startX / 2 - 8, startY, 16, 16));
}
else else
{
closedGlyphRenderer.DrawBackground(e.Graphics, new(e.Bounds.X + startX / 2 - 8, startY, 16, 16)); closedGlyphRenderer.DrawBackground(e.Graphics, new(e.Bounds.X + startX / 2 - 8, startY, 16, 16));
}
}
CheckBoxState checkBoxState = e.Node.TreeView.Enabled CheckBoxState checkBoxState = e.Node.TreeView.Enabled
? (e.Node.Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal) ? (e.Node.Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal)

View file

@ -30,7 +30,11 @@ namespace CreamInstaller
public void UpdateProgress(int progress) public void UpdateProgress(int progress)
{ {
int value = (int)((float)(CompleteOperationsCount / (float)OperationsCount) * 100) + (progress / OperationsCount); int value = (int)((float)(CompleteOperationsCount / (float)OperationsCount) * 100) + (progress / OperationsCount);
if (value < userProgressBar.Value) return; if (value < userProgressBar.Value)
{
return;
}
userProgressBar.Value = value; userProgressBar.Value = value;
} }
@ -55,7 +59,11 @@ namespace CreamInstaller
foreach (string directory in selection.SteamApiDllDirectories) foreach (string directory in selection.SteamApiDllDirectories)
{ {
UpdateUser("Installing CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); UpdateUser("Installing CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException(); if (!Program.IsProgramRunningDialog(this, selection))
{
throw new OperationCanceledException();
}
string api = directory + @"\steam_api.dll"; string api = directory + @"\steam_api.dll";
string api_o = directory + @"\steam_api_o.dll"; string api_o = directory + @"\steam_api_o.dll";
if (File.Exists(api) && !File.Exists(api_o)) if (File.Exists(api) && !File.Exists(api_o))
@ -128,8 +136,16 @@ namespace CreamInstaller
CompleteOperationsCount = 0; CompleteOperationsCount = 0;
foreach (ProgramSelection selection in ProgramSelection.AllSafe) foreach (ProgramSelection selection in ProgramSelection.AllSafe)
{ {
if (!selection.Enabled) continue; if (!selection.Enabled)
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException(); {
continue;
}
if (!Program.IsProgramRunningDialog(this, selection))
{
throw new OperationCanceledException();
}
try try
{ {
await OperateFor(selection); await OperateFor(selection);
@ -193,7 +209,11 @@ namespace CreamInstaller
} }
catch (Exception e) catch (Exception e)
{ {
if (ExceptionHandler.OutputException(e)) goto retry; if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Close(); Close();
} }
} }

View file

@ -154,7 +154,11 @@ namespace CreamInstaller
} }
catch (Exception e) catch (Exception e)
{ {
if (ExceptionHandler.OutputException(e)) goto retry; if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Close(); Close();
} }
} }

View file

@ -31,9 +31,17 @@ namespace CreamInstaller
get get
{ {
List<string> gameDirectories = new(); List<string> gameDirectories = new();
if (Program.Canceled) return gameDirectories; if (Program.Canceled)
{
return gameDirectories;
}
string steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Valve\\Steam", "InstallPath", null) as string; 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)
{
steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
}
if (steamInstallPath != null && Directory.Exists(steamInstallPath)) if (steamInstallPath != null && Directory.Exists(steamInstallPath))
{ {
string libraryFolder = steamInstallPath + @"\steamapps"; string libraryFolder = steamInstallPath + @"\steamapps";
@ -51,8 +59,15 @@ namespace CreamInstaller
if (int.TryParse(_property.Key, out int _)) if (int.TryParse(_property.Key, out int _))
{ {
string path = _property.Value.path.ToString() + @"\steamapps"; string path = _property.Value.path.ToString() + @"\steamapps";
if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path)) continue; if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(path))
if (!gameDirectories.Contains(path)) gameDirectories.Add(path); {
continue;
}
if (!gameDirectories.Contains(path))
{
gameDirectories.Add(path);
}
} }
} }
} }
@ -67,31 +82,57 @@ namespace CreamInstaller
private static bool GetDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> dllDirectories) private static bool GetDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> dllDirectories)
{ {
dllDirectories = new(); dllDirectories = new();
if (Program.Canceled || !Directory.Exists(gameDirectory)) return false; if (Program.Canceled || !Directory.Exists(gameDirectory))
{
return false;
}
string api = gameDirectory + @"\steam_api.dll"; string api = gameDirectory + @"\steam_api.dll";
string api64 = gameDirectory + @"\steam_api64.dll"; string api64 = gameDirectory + @"\steam_api64.dll";
if (File.Exists(api) || File.Exists(api64)) dllDirectories.Add(gameDirectory); if (File.Exists(api) || File.Exists(api64))
{
dllDirectories.Add(gameDirectory);
}
foreach (string _directory in Directory.GetDirectories(gameDirectory)) foreach (string _directory in Directory.GetDirectories(gameDirectory))
{ {
if (Program.Canceled) return false; if (Program.Canceled)
{
return false;
}
try try
{ {
if (GetDllDirectoriesFromGameDirectory(_directory, out List<string> _dllDirectories)) if (GetDllDirectoriesFromGameDirectory(_directory, out List<string> _dllDirectories))
{
dllDirectories.AddRange(_dllDirectories); dllDirectories.AddRange(_dllDirectories);
}
} }
catch { } catch { }
} }
if (!dllDirectories.Any()) return false; if (!dllDirectories.Any())
{
return false;
}
return true; return true;
} }
private static bool GetGamesFromLibraryDirectory(string libraryDirectory, out List<Tuple<int, string, string, int, string>> games) private static bool GetGamesFromLibraryDirectory(string libraryDirectory, out List<Tuple<int, string, string, int, string>> games)
{ {
games = new(); games = new();
if (Program.Canceled || !Directory.Exists(libraryDirectory)) return false; if (Program.Canceled || !Directory.Exists(libraryDirectory))
{
return false;
}
foreach (string directory in Directory.GetFiles(libraryDirectory)) foreach (string directory in Directory.GetFiles(libraryDirectory))
{ {
if (Program.Canceled) return false; if (Program.Canceled)
{
return false;
}
if (Path.GetExtension(directory) == ".acf") if (Path.GetExtension(directory) == ".acf")
{ {
try try
@ -104,18 +145,38 @@ namespace CreamInstaller
if (string.IsNullOrWhiteSpace(_appid) if (string.IsNullOrWhiteSpace(_appid)
|| string.IsNullOrWhiteSpace(installdir) || string.IsNullOrWhiteSpace(installdir)
|| string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(name)
|| string.IsNullOrWhiteSpace(_buildid)) continue; || string.IsNullOrWhiteSpace(_buildid))
{
continue;
}
string branch = property.Value.UserConfig?.betakey?.ToString(); string branch = property.Value.UserConfig?.betakey?.ToString();
if (string.IsNullOrWhiteSpace(branch)) branch = "public"; if (string.IsNullOrWhiteSpace(branch))
{
branch = "public";
}
string gameDirectory = libraryDirectory + @"\common\" + installdir; string gameDirectory = libraryDirectory + @"\common\" + installdir;
if (!int.TryParse(_appid, out int appid)) continue; if (!int.TryParse(_appid, out int appid))
if (!int.TryParse(_buildid, out int buildid)) continue; {
continue;
}
if (!int.TryParse(_buildid, out int buildid))
{
continue;
}
games.Add(new(appid, name, branch, buildid, gameDirectory)); games.Add(new(appid, name, branch, buildid, gameDirectory));
} }
catch { } catch { }
} }
} }
if (!games.Any()) return false; if (!games.Any())
{
return false;
}
return true; return true;
} }
@ -125,14 +186,29 @@ namespace CreamInstaller
private void GetCreamApiApplicablePrograms(IProgress<int> progress) private void GetCreamApiApplicablePrograms(IProgress<int> progress)
{ {
int cur = 0; int cur = 0;
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
List<Tuple<int, string, string, int, string>> applicablePrograms = new(); List<Tuple<int, string, string, int, string>> applicablePrograms = new();
string launcherRootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive"; string launcherRootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
if (Directory.Exists(launcherRootDirectory)) applicablePrograms.Add(new(0, "Paradox Launcher", "", 0, launcherRootDirectory)); if (Directory.Exists(launcherRootDirectory))
{
applicablePrograms.Add(new(0, "Paradox Launcher", "", 0, launcherRootDirectory));
}
foreach (string libraryDirectory in GameLibraryDirectories) foreach (string libraryDirectory in GameLibraryDirectories)
{
if (GetGamesFromLibraryDirectory(libraryDirectory, out List<Tuple<int, string, string, int, string>> games)) if (GetGamesFromLibraryDirectory(libraryDirectory, out List<Tuple<int, string, string, int, string>> games))
{
foreach (Tuple<int, string, string, int, string> game in games) foreach (Tuple<int, string, string, int, string> game in games)
{
applicablePrograms.Add(game); applicablePrograms.Add(game);
}
}
}
RunningTasks.Clear(); RunningTasks.Clear();
foreach (Tuple<int, string, string, int, string> program in applicablePrograms) foreach (Tuple<int, string, string, int, string> program in applicablePrograms)
{ {
@ -141,17 +217,39 @@ namespace CreamInstaller
string branch = program.Item3; string branch = program.Item3;
int buildId = program.Item4; int buildId = program.Item4;
string directory = program.Item5; string directory = program.Item5;
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
// EasyAntiCheat detects DLL changes, so skip those games // EasyAntiCheat detects DLL changes, so skip those games
if (Directory.Exists(directory + @"\EasyAntiCheat")) continue; if (Directory.Exists(directory + @"\EasyAntiCheat"))
{
continue;
}
// BattlEye in DayZ detects DLL changes, but not in Arma3? // BattlEye in DayZ detects DLL changes, but not in Arma3?
if (name != "Arma 3" && Directory.Exists(directory + @"\BattlEye")) continue; if (name != "Arma 3" && Directory.Exists(directory + @"\BattlEye"))
{
continue;
}
Task task = Task.Run(() => Task task = Task.Run(() =>
{ {
if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List<string> dllDirectories)) return; if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List<string> dllDirectories))
{
return;
}
VProperty appInfo = null; VProperty appInfo = null;
if (Program.Canceled || (appId > 0 && !SteamCMD.GetAppInfo(appId, out appInfo, branch, buildId))) return; if (Program.Canceled || (appId > 0 && !SteamCMD.GetAppInfo(appId, out appInfo, branch, buildId)))
if (Program.Canceled) return; {
return;
}
if (Program.Canceled)
{
return;
}
ConcurrentDictionary<int, string> dlc = new(); ConcurrentDictionary<int, string> dlc = new();
List<Task> dlcTasks = new(); List<Task> dlcTasks = new();
List<int> dlcIds = SteamCMD.ParseDlcAppIds(appInfo); List<int> dlcIds = SteamCMD.ParseDlcAppIds(appInfo);
@ -159,14 +257,34 @@ namespace CreamInstaller
{ {
foreach (int id in dlcIds) foreach (int id in dlcIds)
{ {
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
Task task = Task.Run(() => Task task = Task.Run(() =>
{ {
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
string dlcName = null; string dlcName = null;
if (SteamCMD.GetAppInfo(id, out VProperty dlcAppInfo)) dlcName = dlcAppInfo?.Value?["common"]?["name"]?.ToString(); if (SteamCMD.GetAppInfo(id, out VProperty dlcAppInfo))
if (Program.Canceled) return; {
if (string.IsNullOrWhiteSpace(dlcName)) return; //dlcName = "Unknown DLC"; dlcName = dlcAppInfo?.Value?["common"]?["name"]?.ToString();
}
if (Program.Canceled)
{
return;
}
if (string.IsNullOrWhiteSpace(dlcName))
{
return; //dlcName = "Unknown DLC";
}
dlc[id] = /*$"[{id}] " +*/ dlcName; dlc[id] = /*$"[{id}] " +*/ dlcName;
progress.Report(++cur); progress.Report(++cur);
}); });
@ -175,9 +293,20 @@ namespace CreamInstaller
} }
progress.Report(-RunningTasks.Count); progress.Report(-RunningTasks.Count);
} }
else if (appId > 0) return; else if (appId > 0)
if (Program.Canceled) return; {
if (string.IsNullOrWhiteSpace(name)) return; return;
}
if (Program.Canceled)
{
return;
}
if (string.IsNullOrWhiteSpace(name))
{
return;
}
ProgramSelection selection = ProgramSelection.FromAppId(appId) ?? new(); ProgramSelection selection = ProgramSelection.FromAppId(appId) ?? new();
selection.Name = name; selection.Name = name;
@ -188,13 +317,25 @@ namespace CreamInstaller
foreach (Task task in dlcTasks.ToList()) foreach (Task task in dlcTasks.ToList())
{ {
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
task.Wait(); task.Wait();
} }
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
treeView1.Invoke((MethodInvoker)delegate treeView1.Invoke((MethodInvoker)delegate
{ {
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
TreeNode programNode = treeNodes.Find(s => s.Name == "" + appId) ?? new(); TreeNode programNode = treeNodes.Find(s => s.Name == "" + appId) ?? new();
programNode.Name = "" + appId; programNode.Name = "" + appId;
programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name; programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name;
@ -207,9 +348,15 @@ namespace CreamInstaller
{ {
// maybe add game and/or dlc choice here? // maybe add game and/or dlc choice here?
} }
else foreach (KeyValuePair<int, string> dlcApp in dlc.ToList()) else
{
foreach (KeyValuePair<int, string> dlcApp in dlc.ToList())
{ {
if (Program.Canceled || programNode is null) return; if (Program.Canceled || programNode is null)
{
return;
}
TreeNode dlcNode = treeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new(); TreeNode dlcNode = treeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new();
dlcNode.Name = "" + dlcApp.Key; dlcNode.Name = "" + dlcApp.Key;
dlcNode.Text = dlcApp.Value; dlcNode.Text = dlcApp.Value;
@ -220,6 +367,7 @@ namespace CreamInstaller
treeNodes.Add(dlcNode); treeNodes.Add(dlcNode);
selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value; selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value;
} }
}
}); });
progress.Report(++cur); progress.Report(++cur);
}); });
@ -229,7 +377,11 @@ namespace CreamInstaller
progress.Report(cur); progress.Report(cur);
foreach (Task task in RunningTasks.ToList()) foreach (Task task in RunningTasks.ToList())
{ {
if (Program.Canceled) return; if (Program.Canceled)
{
return;
}
task.Wait(); task.Wait();
} }
progress.Report(RunningTasks.Count); progress.Report(RunningTasks.Count);
@ -257,20 +409,45 @@ namespace CreamInstaller
IProgress<int> iProgress = progress; IProgress<int> iProgress = progress;
progress.ProgressChanged += (sender, _progress) => progress.ProgressChanged += (sender, _progress) =>
{ {
if (_progress < 0) maxProgress = -_progress; if (_progress < 0)
else curProgress = _progress; {
maxProgress = -_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) label2.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})"; if (validating)
else if (setup) label2.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})"; {
else label2.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})"; label2.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})";
}
else if (setup)
{
label2.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
}
else
{
label2.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) label2.Text = "Setting up SteamCMD . . . "; if (!validating)
if (!Directory.Exists(SteamCMD.DirectoryPath)) Directory.CreateDirectory(SteamCMD.DirectoryPath); {
label2.Text = "Setting up SteamCMD . . . ";
}
if (!Directory.Exists(SteamCMD.DirectoryPath))
{
Directory.CreateDirectory(SteamCMD.DirectoryPath);
}
FileSystemWatcher watcher = new(SteamCMD.DirectoryPath); FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
watcher.Changed += (sender, e) => iProgress.Report(++cur); watcher.Changed += (sender, e) => iProgress.Report(++cur);
watcher.Filter = "*"; watcher.Filter = "*";
@ -280,13 +457,21 @@ namespace CreamInstaller
watcher.Dispose(); watcher.Dispose();
setup = false; setup = false;
if (!validating) label2.Text = "Gathering and caching your applicable games and their DLCs . . . "; if (!validating)
{
label2.Text = "Gathering and caching your applicable games and their DLCs . . . ";
}
await Task.Run(() => GetCreamApiApplicablePrograms(iProgress)); await Task.Run(() => GetCreamApiApplicablePrograms(iProgress));
ProgramSelection.All.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory))); ProgramSelection.All.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory)));
ProgramSelection.All.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any()); ProgramSelection.All.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
foreach (TreeNode treeNode in treeNodes) foreach (TreeNode treeNode in treeNodes)
{
if (treeNode.Parent is null && ProgramSelection.FromAppId(int.Parse(treeNode.Name)) is null) if (treeNode.Parent is null && ProgramSelection.FromAppId(int.Parse(treeNode.Name)) is null)
{
treeNode.Remove(); treeNode.Remove();
}
}
//SetMinimumSizeFromTreeView(); //SetMinimumSizeFromTreeView();
progressBar1.Value = 100; progressBar1.Value = 100;
@ -303,7 +488,10 @@ namespace CreamInstaller
scanButton.Enabled = true; scanButton.Enabled = true;
label2.Text = "Validating . . . "; label2.Text = "Validating . . . ";
if (!validating && !Program.Canceled) OnLoad(true); if (!validating && !Program.Canceled)
{
OnLoad(true);
}
} }
/*private const int GWL_STYLE = -16; /*private const int GWL_STYLE = -16;
@ -337,7 +525,11 @@ namespace CreamInstaller
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e) private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
{ {
if (e.Action == TreeViewAction.Unknown) return; if (e.Action == TreeViewAction.Unknown)
{
return;
}
ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(e.Node.Name)); ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(e.Node.Name));
if (selection is null) if (selection is null)
{ {
@ -351,7 +543,11 @@ namespace CreamInstaller
selection.ToggleAllDlc(e.Node.Checked); selection.ToggleAllDlc(e.Node.Checked);
e.Node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = e.Node.Checked); e.Node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = e.Node.Checked);
} }
else selection.Enabled = e.Node.Checked; else
{
selection.Enabled = e.Node.Checked;
}
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged; allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = treeNodes.TrueForAll(treeNode => treeNode.Checked); allCheckBox.Checked = treeNodes.TrueForAll(treeNode => treeNode.Checked);
allCheckBox.CheckedChanged += OnAllCheckBoxChanged; allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
@ -380,11 +576,14 @@ namespace CreamInstaller
ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(e.Node.Name)); ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(e.Node.Name));
KeyValuePair<int, string>? dlc = ProgramSelection.GetDlcFromAppId(int.Parse(e.Node.Name)); KeyValuePair<int, string>? dlc = ProgramSelection.GetDlcFromAppId(int.Parse(e.Node.Name));
int appId = selection?.SteamAppId ?? dlc?.Key ?? 0; int appId = selection?.SteamAppId ?? dlc?.Key ?? 0;
if (appId > 0) Process.Start(new ProcessStartInfo if (appId > 0)
{ {
FileName = "https://steamdb.info/app/" + appId, Process.Start(new ProcessStartInfo
UseShellExecute = true {
}); FileName = "https://steamdb.info/app/" + appId,
UseShellExecute = true
});
}
} }
}; };
retry: retry:
@ -394,7 +593,11 @@ namespace CreamInstaller
} }
catch (Exception e) catch (Exception e)
{ {
if (ExceptionHandler.OutputException(e)) goto retry; if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Close(); Close();
} }
} }
@ -407,16 +610,32 @@ namespace CreamInstaller
paradoxLauncher.ExtraSteamAppIdDlc.Clear(); paradoxLauncher.ExtraSteamAppIdDlc.Clear();
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled) foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
{ {
if (selection.Name == paradoxLauncher.Name) continue; if (selection.Name == paradoxLauncher.Name)
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue; {
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.AllSafe)
{ {
if (selection.Name == paradoxLauncher.Name) continue; if (selection.Name == paradoxLauncher.Name)
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue; {
continue;
}
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive")
{
continue;
}
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc)); paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc));
} }
} }
@ -449,16 +668,31 @@ namespace CreamInstaller
if (ProgramSelection.All.Count > 0) if (ProgramSelection.All.Count > 0)
{ {
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled) 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(); Hide();
InstallForm installForm = new(this); InstallForm installForm = new(this);
installForm.ShowDialog(); installForm.ShowDialog();
if (installForm.Reselecting) if (installForm.Reselecting)
{ {
foreach (TreeNode treeNode in treeNodes) foreach (TreeNode treeNode in treeNodes)
{
if (!(treeNode.Parent is null) || int.Parse(treeNode.Name) == 0) if (!(treeNode.Parent is null) || int.Parse(treeNode.Name) == 0)
{
OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse)); OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse));
}
}
this.InheritLocation(installForm); this.InheritLocation(installForm);
Show(); Show();
} }
@ -486,7 +720,11 @@ namespace CreamInstaller
{ {
if (treeNode.Parent is null) if (treeNode.Parent is null)
{ {
if (!treeNode.Checked) shouldCheck = true; if (!treeNode.Checked)
{
shouldCheck = true;
}
treeNode.Checked = shouldCheck; treeNode.Checked = shouldCheck;
OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse)); OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse));
} }

View file

@ -35,7 +35,11 @@ namespace CreamInstaller
} }
catch (Exception e) catch (Exception e)
{ {
if (ExceptionHandler.OutputException(e)) goto retry; if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Application.Exit(); Application.Exit();
return; return;
} }
@ -83,7 +87,10 @@ namespace CreamInstaller
SteamCMD.Kill(); SteamCMD.Kill();
} }
private static void OnApplicationExit(object s, EventArgs e) => Cleanup(); private static void OnApplicationExit(object s, EventArgs e)
{
Cleanup();
}
internal static void InheritLocation(this Form form, Form fromForm) internal static void InheritLocation(this Form form, Form fromForm)
{ {