From f640ceaee46efca6c074cb4837933a1a5288d7c7 Mon Sep 17 00:00:00 2001 From: pointfeev Date: Sun, 28 Nov 2021 17:14:32 -0500 Subject: [PATCH] Fix encoding, word wrapping, DLC sorting by appid --- CreamInstaller/Classes/ExceptionHandler.cs | 2 +- CreamInstaller/Classes/ProgramSelection.cs | 34 ++++++-------------- CreamInstaller/Classes/SteamCMD.cs | 18 +++++++---- CreamInstaller/CreamInstaller.csproj | 2 +- CreamInstaller/Forms/InstallForm.Designer.cs | 1 - CreamInstaller/Forms/InstallForm.cs | 19 +++++------ CreamInstaller/Forms/MainForm.cs | 6 ++-- CreamInstaller/Forms/SelectForm.cs | 32 +++++++++--------- 8 files changed, 53 insertions(+), 61 deletions(-) diff --git a/CreamInstaller/Classes/ExceptionHandler.cs b/CreamInstaller/Classes/ExceptionHandler.cs index 3dd3dfc..7b5e7f9 100644 --- a/CreamInstaller/Classes/ExceptionHandler.cs +++ b/CreamInstaller/Classes/ExceptionHandler.cs @@ -18,7 +18,7 @@ namespace CreamInstaller string line = stackTrace[i]; if (!(line is null)) { - output += "\n " + line.Substring(line.IndexOf("at")); + output += "\n " + line[line.IndexOf("at")..]; } } } diff --git a/CreamInstaller/Classes/ProgramSelection.cs b/CreamInstaller/Classes/ProgramSelection.cs index b82373f..6f10530 100644 --- a/CreamInstaller/Classes/ProgramSelection.cs +++ b/CreamInstaller/Classes/ProgramSelection.cs @@ -16,9 +16,9 @@ namespace CreamInstaller public VProperty AppInfo = null; - public List> AllSteamDlc = new(); - public List> SelectedSteamDlc = new(); - public List>>> ExtraSteamAppIdDlc = new(); + public readonly SortedList AllSteamDlc = new(); + public readonly SortedList SelectedSteamDlc = new(); + public readonly List>> ExtraSteamAppIdDlc = new(); public bool AreSteamApiDllsLocked { @@ -34,20 +34,13 @@ namespace CreamInstaller } } - private void Toggle(Tuple dlcApp, bool enabled) - { - if (enabled) - { - if (!SelectedSteamDlc.Contains(dlcApp)) SelectedSteamDlc.Add(dlcApp); - } - else SelectedSteamDlc.Remove(dlcApp); - } + private void Toggle(KeyValuePair dlcApp, bool enabled) => SelectedSteamDlc[dlcApp.Key] = enabled ? dlcApp.Value : null; public void ToggleDlc(string dlcName, bool enabled) { - foreach (Tuple dlcApp in AllSteamDlc) + foreach (KeyValuePair dlcApp in AllSteamDlc) { - if (dlcApp.Item2 == dlcName) + if (dlcApp.Value == dlcName) { Toggle(dlcApp, enabled); break; @@ -59,7 +52,7 @@ namespace CreamInstaller public void ToggleAllDlc(bool enabled) { if (!enabled) SelectedSteamDlc.Clear(); - else foreach (Tuple dlcApp in AllSteamDlc) Toggle(dlcApp, enabled); + else foreach (KeyValuePair dlcApp in AllSteamDlc) Toggle(dlcApp, enabled); Enabled = SelectedSteamDlc.Any(); } @@ -73,18 +66,11 @@ namespace CreamInstaller public static ProgramSelection FromName(string displayName) => AllSafe.Find(s => s.Name == displayName); - public static Tuple GetDlc(string displayName) + public static KeyValuePair? GetDlc(string displayName) { foreach (ProgramSelection selection in AllSafe) - { - foreach (Tuple app in selection.AllSteamDlc) - { - if (app.Item2 == displayName) - { - return app; - } - } - } + foreach (KeyValuePair app in selection.AllSteamDlc) + if (app.Value == displayName) return app; return null; } } diff --git a/CreamInstaller/Classes/SteamCMD.cs b/CreamInstaller/Classes/SteamCMD.cs index 2acff60..6034f0b 100644 --- a/CreamInstaller/Classes/SteamCMD.cs +++ b/CreamInstaller/Classes/SteamCMD.cs @@ -7,6 +7,7 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Net; +using System.Text; using System.Windows.Forms; namespace CreamInstaller @@ -20,6 +21,8 @@ namespace CreamInstaller public static readonly string AppCachePath = DirectoryPath + @"\appcache"; public static readonly string AppCacheAppInfoPath = AppCachePath + @"\appinfo.vdf"; public static readonly string AppInfoPath = DirectoryPath + @"\appinfo"; + + public static readonly Version MinimumAppInfoVersion = Version.Parse("2.0.3.2"); public static readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt"; public static bool Run(string command, out string output) @@ -34,7 +37,10 @@ namespace CreamInstaller RedirectStandardError = true, UseShellExecute = false, Arguments = command, - CreateNoWindow = true + CreateNoWindow = true, + StandardInputEncoding = Encoding.UTF8, + StandardOutputEncoding = Encoding.UTF8, + StandardErrorEncoding = Encoding.UTF8 }; using (Process process = Process.Start(processStartInfo)) { @@ -58,11 +64,11 @@ namespace CreamInstaller File.Delete(ArchivePath); } if (File.Exists(AppCacheAppInfoPath)) File.Delete(AppCacheAppInfoPath); - if (!File.Exists(AppInfoVersionPath) || !Version.TryParse(File.ReadAllText(AppInfoVersionPath), out Version version) || version < Version.Parse("2.0.2.0")) + if (!File.Exists(AppInfoVersionPath) || !Version.TryParse(File.ReadAllText(AppInfoVersionPath, Encoding.UTF8), out Version version) || version < MinimumAppInfoVersion) { if (Directory.Exists(AppInfoPath)) Directory.Delete(AppInfoPath, true); Directory.CreateDirectory(AppInfoPath); - File.WriteAllText(AppInfoVersionPath, Application.ProductVersion); + File.WriteAllText(AppInfoVersionPath, Application.ProductVersion, Encoding.UTF8); } if (!File.Exists(DllPath)) Run($@"+quit", out _); } @@ -75,7 +81,7 @@ namespace CreamInstaller string appUpdatePath = $@"{AppInfoPath}\{appId}"; string appUpdateFile = $@"{appUpdatePath}\appinfo.txt"; restart: - if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile); + 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", out _); @@ -84,8 +90,8 @@ namespace CreamInstaller int closeBracket = output.LastIndexOf("}"); if (openBracket != -1 && closeBracket != -1) { - output = $"\"{appId}\"\n" + output.Substring(openBracket, 1 + closeBracket - openBracket); - File.WriteAllText(appUpdateFile, output); + output = $"\"{appId}\"\n" + output[openBracket..(1 + closeBracket)]; + File.WriteAllText(appUpdateFile, output, Encoding.UTF8); } } if (Program.Canceled || output is null) return false; diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index 00715d1..d067de8 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -5,7 +5,7 @@ true Resources\ini.ico true - 2.0.3.0 + 2.0.3.2 Resources\ini.ico 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. diff --git a/CreamInstaller/Forms/InstallForm.Designer.cs b/CreamInstaller/Forms/InstallForm.Designer.cs index 5f15509..1b60138 100644 --- a/CreamInstaller/Forms/InstallForm.Designer.cs +++ b/CreamInstaller/Forms/InstallForm.Designer.cs @@ -106,7 +106,6 @@ namespace CreamInstaller this.logTextBox.TabIndex = 4; this.logTextBox.TabStop = false; this.logTextBox.Text = ""; - this.logTextBox.WordWrap = false; // // reselectButton // diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs index efc24bd..4c530be 100644 --- a/CreamInstaller/Forms/InstallForm.cs +++ b/CreamInstaller/Forms/InstallForm.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -82,7 +83,7 @@ namespace CreamInstaller UpdateUser("Generating CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); string cApi = directory + @"\cream_api.ini"; File.Create(cApi).Close(); - StreamWriter writer = File.AppendText(cApi); + StreamWriter writer = new(cApi, true, Encoding.UTF8); writer.WriteLine("; " + Application.CompanyName + " v" + Application.ProductVersion); if (selection.SteamAppId > 0) { @@ -93,13 +94,13 @@ namespace CreamInstaller writer.WriteLine(); writer.WriteLine("[dlc]"); UpdateUser($"Added game to cream_api.ini with appid {selection.SteamAppId} ({selection.Name})", InstallationLog.Resource); - foreach (Tuple dlcApp in selection.SelectedSteamDlc) + foreach (KeyValuePair dlcApp in selection.SelectedSteamDlc) { - writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}"); - UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", InstallationLog.Resource); + writer.WriteLine($"{dlcApp.Key} = {dlcApp.Value}"); + UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource); } } - foreach (Tuple>> extraAppDlc in selection.ExtraSteamAppIdDlc) + foreach (Tuple> extraAppDlc in selection.ExtraSteamAppIdDlc) { writer.WriteLine(); writer.WriteLine("[steam]"); @@ -107,15 +108,15 @@ namespace CreamInstaller writer.WriteLine(); writer.WriteLine("[dlc]"); UpdateUser($"Added game to cream_api.ini with appid {extraAppDlc.Item1} ({extraAppDlc.Item2})", InstallationLog.Resource); - foreach (Tuple dlcApp in extraAppDlc.Item3) + foreach (KeyValuePair dlcApp in extraAppDlc.Item3) { - writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}"); - UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", InstallationLog.Resource); + writer.WriteLine($"{dlcApp.Key} = {dlcApp.Value}"); + UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource); } } writer.Flush(); writer.Close(); - await Task.Run(() => Thread.Sleep(0)); // to keep the text box control from glitching + await Task.Run(() => Thread.Sleep(10)); // to keep the text box control from glitching UpdateProgress(++cur / count * 100); } UpdateProgress(100); diff --git a/CreamInstaller/Forms/MainForm.cs b/CreamInstaller/Forms/MainForm.cs index 5e8f880..b87ed5c 100644 --- a/CreamInstaller/Forms/MainForm.cs +++ b/CreamInstaller/Forms/MainForm.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using System.Net.Http; +using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Web; using System.Windows.Forms; namespace CreamInstaller @@ -107,7 +109,7 @@ namespace CreamInstaller using HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); using Stream stream = await response.Content.ReadAsStreamAsync(); - using StreamReader reader = new(stream); + using StreamReader reader = new(stream, Encoding.UTF8); HtmlAgilityPack.HtmlDocument document = new(); document.LoadHtml(reader.ReadToEnd()); foreach (HtmlNode node in document.DocumentNode.SelectNodes("//div[@data-test-selector='body-content']/ul/li")) @@ -115,7 +117,7 @@ namespace CreamInstaller changelogTreeView.Invoke((MethodInvoker)delegate { TreeNode change = new(); - change.Text = $"{node.InnerText}"; + change.Text = $"{HttpUtility.HtmlDecode(node.InnerText)}"; root.Nodes.Add(change); root.Expand(); }); diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs index 008dc03..f158ffd 100644 --- a/CreamInstaller/Forms/SelectForm.cs +++ b/CreamInstaller/Forms/SelectForm.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using System.Windows.Forms; @@ -43,7 +44,7 @@ namespace CreamInstaller string libraryFolders = libraryFolder + @"\libraryfolders.vdf"; if (File.Exists(libraryFolders)) { - dynamic property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders)); + dynamic property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders, Encoding.UTF8)); foreach (dynamic _property in property.Value) { if (int.TryParse(_property.Key, out int _)) @@ -94,7 +95,7 @@ namespace CreamInstaller { try { - dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory)); + dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory, Encoding.UTF8)); string _appid = property.Value.appid.ToString(); string installdir = property.Value.installdir.ToString(); string name = property.Value.name.ToString(); @@ -144,7 +145,7 @@ namespace CreamInstaller if (Directory.Exists(directory + @"\EasyAntiCheat")) continue; // BattlEye in DayZ detects DLL changes, but not in Arma3? if (name != "Arma 3" && Directory.Exists(directory + @"\BattlEye")) continue; - Task task = new(() => + Task task = Task.Run(() => { if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List dllDirectories)) return; VProperty appInfo = null; @@ -158,7 +159,7 @@ namespace CreamInstaller foreach (int id in dlcIds) { if (Program.Canceled) return; - Task task = new(() => + Task task = Task.Run(() => { if (Program.Canceled) return; string dlcName = null; @@ -166,12 +167,12 @@ namespace CreamInstaller if (Program.Canceled) return; if (string.IsNullOrWhiteSpace(dlcName)) return; dlc[id] = dlcName; + progress.Report(++cur); }); dlcTasks.Add(task); RunningTasks.Add(task); - task.Start(); - progress.Report(-RunningTasks.Count); } + progress.Report(-RunningTasks.Count); } else if (name != "Paradox Launcher") return; if (Program.Canceled) return; @@ -189,7 +190,6 @@ namespace CreamInstaller foreach (Task task in dlcTasks.ToList()) { if (Program.Canceled) return; - progress.Report(cur++); task.Wait(); } if (Program.Canceled) return; @@ -210,27 +210,25 @@ namespace CreamInstaller else foreach (KeyValuePair dlcApp in dlc.ToList()) { if (Program.Canceled || programNode is null) return; - Tuple app = new(dlcApp.Key, dlcApp.Value); - TreeNode dlcNode = treeNodes.Find(s => s.Text == app.Item2) ?? new(); - dlcNode.Text = app.Item2; - dlcNode.Checked = selection.SelectedSteamDlc.Contains(app); + TreeNode dlcNode = treeNodes.Find(s => s.Text == dlcApp.Value) ?? new(); + dlcNode.Text = dlcApp.Value; + dlcNode.Checked = selection.SelectedSteamDlc.Contains(dlcApp); dlcNode.Remove(); programNode.Nodes.Add(dlcNode); treeNodes.Remove(dlcNode); treeNodes.Add(dlcNode); - if (!selection.AllSteamDlc.Contains(app)) selection.AllSteamDlc.Add(app); + selection.AllSteamDlc[dlcApp.Key] = dlcApp.Value; } }); + progress.Report(++cur); }); RunningTasks.Add(task); - task.Start(); } progress.Report(-RunningTasks.Count); progress.Report(cur); foreach (Task task in RunningTasks.ToList()) { if (Program.Canceled) return; - progress.Report(cur++); task.Wait(); } progress.Report(RunningTasks.Count); @@ -346,8 +344,8 @@ namespace CreamInstaller if (e.Button == MouseButtons.Right) { ProgramSelection selection = ProgramSelection.FromName(e.Node.Text); - Tuple dlc = ProgramSelection.GetDlc(e.Node.Text); - int appId = selection?.SteamAppId ?? dlc?.Item1 ?? 0; + KeyValuePair? dlc = ProgramSelection.GetDlc(e.Node.Text); + int appId = selection?.SteamAppId ?? dlc?.Key ?? 0; if (appId > 0) Process.Start(new ProcessStartInfo { FileName = "https://steamdb.info/app/" + appId, @@ -372,7 +370,7 @@ namespace CreamInstaller paradoxLauncher ??= ProgramSelection.FromName("Paradox Launcher"); if (!(paradoxLauncher is null)) { - paradoxLauncher.ExtraSteamAppIdDlc = new(); + paradoxLauncher.ExtraSteamAppIdDlc.Clear(); foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled) { if (selection.Name == paradoxLauncher.Name) continue;