Fix encoding, word wrapping, DLC sorting by appid

This commit is contained in:
pointfeev 2021-11-28 17:14:32 -05:00
parent fd22d12b9f
commit f640ceaee4
No known key found for this signature in database
GPG key ID: AA14DC36C4D7D13C
8 changed files with 53 additions and 61 deletions

View file

@ -18,7 +18,7 @@ namespace CreamInstaller
string line = stackTrace[i]; string line = stackTrace[i];
if (!(line is null)) if (!(line is null))
{ {
output += "\n " + line.Substring(line.IndexOf("at")); output += "\n " + line[line.IndexOf("at")..];
} }
} }
} }

View file

@ -16,9 +16,9 @@ namespace CreamInstaller
public VProperty AppInfo = null; public VProperty AppInfo = null;
public List<Tuple<int, string>> AllSteamDlc = new(); public readonly SortedList<int, string> AllSteamDlc = new();
public List<Tuple<int, string>> SelectedSteamDlc = new(); public readonly SortedList<int, string> SelectedSteamDlc = new();
public List<Tuple<int, string, List<Tuple<int, string>>>> ExtraSteamAppIdDlc = new(); public readonly List<Tuple<int, string, SortedList<int, string>>> ExtraSteamAppIdDlc = new();
public bool AreSteamApiDllsLocked public bool AreSteamApiDllsLocked
{ {
@ -34,20 +34,13 @@ namespace CreamInstaller
} }
} }
private void Toggle(Tuple<int, string> dlcApp, bool enabled) private void Toggle(KeyValuePair<int, string> dlcApp, bool enabled) => SelectedSteamDlc[dlcApp.Key] = enabled ? dlcApp.Value : null;
{
if (enabled)
{
if (!SelectedSteamDlc.Contains(dlcApp)) SelectedSteamDlc.Add(dlcApp);
}
else SelectedSteamDlc.Remove(dlcApp);
}
public void ToggleDlc(string dlcName, bool enabled) public void ToggleDlc(string dlcName, bool enabled)
{ {
foreach (Tuple<int, string> dlcApp in AllSteamDlc) foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc)
{ {
if (dlcApp.Item2 == dlcName) if (dlcApp.Value == dlcName)
{ {
Toggle(dlcApp, enabled); Toggle(dlcApp, enabled);
break; break;
@ -59,7 +52,7 @@ namespace CreamInstaller
public void ToggleAllDlc(bool enabled) public void ToggleAllDlc(bool enabled)
{ {
if (!enabled) SelectedSteamDlc.Clear(); if (!enabled) SelectedSteamDlc.Clear();
else foreach (Tuple<int, string> dlcApp in AllSteamDlc) Toggle(dlcApp, enabled); else foreach (KeyValuePair<int, string> dlcApp in AllSteamDlc) Toggle(dlcApp, enabled);
Enabled = SelectedSteamDlc.Any(); Enabled = SelectedSteamDlc.Any();
} }
@ -73,18 +66,11 @@ namespace CreamInstaller
public static ProgramSelection FromName(string displayName) => AllSafe.Find(s => s.Name == displayName); public static ProgramSelection FromName(string displayName) => AllSafe.Find(s => s.Name == displayName);
public static Tuple<int, string> GetDlc(string displayName) public static KeyValuePair<int, string>? GetDlc(string displayName)
{ {
foreach (ProgramSelection selection in AllSafe) foreach (ProgramSelection selection in AllSafe)
{ foreach (KeyValuePair<int, string> app in selection.AllSteamDlc)
foreach (Tuple<int, string> app in selection.AllSteamDlc) if (app.Value == displayName) return app;
{
if (app.Item2 == displayName)
{
return app;
}
}
}
return null; return null;
} }
} }

View file

@ -7,6 +7,7 @@ using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
namespace CreamInstaller namespace CreamInstaller
@ -20,6 +21,8 @@ namespace CreamInstaller
public static readonly string AppCachePath = DirectoryPath + @"\appcache"; public static readonly string AppCachePath = DirectoryPath + @"\appcache";
public static readonly string AppCacheAppInfoPath = AppCachePath + @"\appinfo.vdf"; public static readonly string AppCacheAppInfoPath = AppCachePath + @"\appinfo.vdf";
public static readonly string AppInfoPath = DirectoryPath + @"\appinfo"; 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 readonly string AppInfoVersionPath = AppInfoPath + @"\version.txt";
public static bool Run(string command, out string output) public static bool Run(string command, out string output)
@ -34,7 +37,10 @@ namespace CreamInstaller
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
Arguments = command, Arguments = command,
CreateNoWindow = true CreateNoWindow = true,
StandardInputEncoding = Encoding.UTF8,
StandardOutputEncoding = Encoding.UTF8,
StandardErrorEncoding = Encoding.UTF8
}; };
using (Process process = Process.Start(processStartInfo)) using (Process process = Process.Start(processStartInfo))
{ {
@ -58,11 +64,11 @@ namespace CreamInstaller
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), 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); if (Directory.Exists(AppInfoPath)) Directory.Delete(AppInfoPath, true);
Directory.CreateDirectory(AppInfoPath); Directory.CreateDirectory(AppInfoPath);
File.WriteAllText(AppInfoVersionPath, Application.ProductVersion); File.WriteAllText(AppInfoVersionPath, Application.ProductVersion, Encoding.UTF8);
} }
if (!File.Exists(DllPath)) Run($@"+quit", out _); if (!File.Exists(DllPath)) Run($@"+quit", out _);
} }
@ -75,7 +81,7 @@ namespace CreamInstaller
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); 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 _);
@ -84,8 +90,8 @@ namespace CreamInstaller
int closeBracket = output.LastIndexOf("}"); int closeBracket = output.LastIndexOf("}");
if (openBracket != -1 && closeBracket != -1) if (openBracket != -1 && closeBracket != -1)
{ {
output = $"\"{appId}\"\n" + output.Substring(openBracket, 1 + closeBracket - openBracket); output = $"\"{appId}\"\n" + output[openBracket..(1 + closeBracket)];
File.WriteAllText(appUpdateFile, output); File.WriteAllText(appUpdateFile, output, Encoding.UTF8);
} }
} }
if (Program.Canceled || output is null) return false; if (Program.Canceled || output is null) return false;

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.3.0</Version> <Version>2.0.3.2</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

@ -106,7 +106,6 @@ namespace CreamInstaller
this.logTextBox.TabIndex = 4; this.logTextBox.TabIndex = 4;
this.logTextBox.TabStop = false; this.logTextBox.TabStop = false;
this.logTextBox.Text = ""; this.logTextBox.Text = "";
this.logTextBox.WordWrap = false;
// //
// reselectButton // reselectButton
// //

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -82,7 +83,7 @@ namespace CreamInstaller
UpdateUser("Generating CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation); UpdateUser("Generating CreamAPI for " + selection.Name + $" in directory \"{directory}\" . . . ", InstallationLog.Operation);
string cApi = directory + @"\cream_api.ini"; string cApi = directory + @"\cream_api.ini";
File.Create(cApi).Close(); File.Create(cApi).Close();
StreamWriter writer = File.AppendText(cApi); StreamWriter writer = new(cApi, true, Encoding.UTF8);
writer.WriteLine("; " + Application.CompanyName + " v" + Application.ProductVersion); writer.WriteLine("; " + Application.CompanyName + " v" + Application.ProductVersion);
if (selection.SteamAppId > 0) if (selection.SteamAppId > 0)
{ {
@ -93,13 +94,13 @@ namespace CreamInstaller
writer.WriteLine(); writer.WriteLine();
writer.WriteLine("[dlc]"); writer.WriteLine("[dlc]");
UpdateUser($"Added game to cream_api.ini with appid {selection.SteamAppId} ({selection.Name})", InstallationLog.Resource); UpdateUser($"Added game to cream_api.ini with appid {selection.SteamAppId} ({selection.Name})", InstallationLog.Resource);
foreach (Tuple<int, string> dlcApp in selection.SelectedSteamDlc) foreach (KeyValuePair<int, string> dlcApp in selection.SelectedSteamDlc)
{ {
writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}"); writer.WriteLine($"{dlcApp.Key} = {dlcApp.Value}");
UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", InstallationLog.Resource); UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource);
} }
} }
foreach (Tuple<int, string, List<Tuple<int, string>>> extraAppDlc in selection.ExtraSteamAppIdDlc) foreach (Tuple<int, string, SortedList<int, string>> extraAppDlc in selection.ExtraSteamAppIdDlc)
{ {
writer.WriteLine(); writer.WriteLine();
writer.WriteLine("[steam]"); writer.WriteLine("[steam]");
@ -107,15 +108,15 @@ namespace CreamInstaller
writer.WriteLine(); writer.WriteLine();
writer.WriteLine("[dlc]"); writer.WriteLine("[dlc]");
UpdateUser($"Added game to cream_api.ini with appid {extraAppDlc.Item1} ({extraAppDlc.Item2})", InstallationLog.Resource); UpdateUser($"Added game to cream_api.ini with appid {extraAppDlc.Item1} ({extraAppDlc.Item2})", InstallationLog.Resource);
foreach (Tuple<int, string> dlcApp in extraAppDlc.Item3) foreach (KeyValuePair<int, string> dlcApp in extraAppDlc.Item3)
{ {
writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}"); writer.WriteLine($"{dlcApp.Key} = {dlcApp.Value}");
UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", InstallationLog.Resource); UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Key} ({dlcApp.Value})", InstallationLog.Resource);
} }
} }
writer.Flush(); writer.Flush();
writer.Close(); 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(++cur / count * 100);
} }
UpdateProgress(100); UpdateProgress(100);

View file

@ -7,8 +7,10 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms; using System.Windows.Forms;
namespace CreamInstaller namespace CreamInstaller
@ -107,7 +109,7 @@ namespace CreamInstaller
using HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); using HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
using Stream stream = await response.Content.ReadAsStreamAsync(); using Stream stream = await response.Content.ReadAsStreamAsync();
using StreamReader reader = new(stream); using StreamReader reader = new(stream, Encoding.UTF8);
HtmlAgilityPack.HtmlDocument document = new(); HtmlAgilityPack.HtmlDocument document = new();
document.LoadHtml(reader.ReadToEnd()); document.LoadHtml(reader.ReadToEnd());
foreach (HtmlNode node in document.DocumentNode.SelectNodes("//div[@data-test-selector='body-content']/ul/li")) 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 changelogTreeView.Invoke((MethodInvoker)delegate
{ {
TreeNode change = new(); TreeNode change = new();
change.Text = $"{node.InnerText}"; change.Text = $"{HttpUtility.HtmlDecode(node.InnerText)}";
root.Nodes.Add(change); root.Nodes.Add(change);
root.Expand(); root.Expand();
}); });

View file

@ -8,6 +8,7 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -43,7 +44,7 @@ namespace CreamInstaller
string libraryFolders = libraryFolder + @"\libraryfolders.vdf"; string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
if (File.Exists(libraryFolders)) 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) foreach (dynamic _property in property.Value)
{ {
if (int.TryParse(_property.Key, out int _)) if (int.TryParse(_property.Key, out int _))
@ -94,7 +95,7 @@ namespace CreamInstaller
{ {
try try
{ {
dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory)); dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory, Encoding.UTF8));
string _appid = property.Value.appid.ToString(); string _appid = property.Value.appid.ToString();
string installdir = property.Value.installdir.ToString(); string installdir = property.Value.installdir.ToString();
string name = property.Value.name.ToString(); string name = property.Value.name.ToString();
@ -144,7 +145,7 @@ namespace CreamInstaller
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 = new(() => 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;
@ -158,7 +159,7 @@ namespace CreamInstaller
foreach (int id in dlcIds) foreach (int id in dlcIds)
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
Task task = new(() => Task task = Task.Run(() =>
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
string dlcName = null; string dlcName = null;
@ -166,12 +167,12 @@ namespace CreamInstaller
if (Program.Canceled) return; if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(dlcName)) return; if (string.IsNullOrWhiteSpace(dlcName)) return;
dlc[id] = dlcName; dlc[id] = dlcName;
progress.Report(++cur);
}); });
dlcTasks.Add(task); dlcTasks.Add(task);
RunningTasks.Add(task); RunningTasks.Add(task);
task.Start();
progress.Report(-RunningTasks.Count);
} }
progress.Report(-RunningTasks.Count);
} }
else if (name != "Paradox Launcher") return; else if (name != "Paradox Launcher") return;
if (Program.Canceled) return; if (Program.Canceled) return;
@ -189,7 +190,6 @@ namespace CreamInstaller
foreach (Task task in dlcTasks.ToList()) foreach (Task task in dlcTasks.ToList())
{ {
if (Program.Canceled) return; if (Program.Canceled) return;
progress.Report(cur++);
task.Wait(); task.Wait();
} }
if (Program.Canceled) return; if (Program.Canceled) return;
@ -210,27 +210,25 @@ namespace CreamInstaller
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;
Tuple<int, string> app = new(dlcApp.Key, dlcApp.Value); TreeNode dlcNode = treeNodes.Find(s => s.Text == dlcApp.Value) ?? new();
TreeNode dlcNode = treeNodes.Find(s => s.Text == app.Item2) ?? new(); dlcNode.Text = dlcApp.Value;
dlcNode.Text = app.Item2; dlcNode.Checked = selection.SelectedSteamDlc.Contains(dlcApp);
dlcNode.Checked = selection.SelectedSteamDlc.Contains(app);
dlcNode.Remove(); dlcNode.Remove();
programNode.Nodes.Add(dlcNode); programNode.Nodes.Add(dlcNode);
treeNodes.Remove(dlcNode); treeNodes.Remove(dlcNode);
treeNodes.Add(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); RunningTasks.Add(task);
task.Start();
} }
progress.Report(-RunningTasks.Count); progress.Report(-RunningTasks.Count);
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;
progress.Report(cur++);
task.Wait(); task.Wait();
} }
progress.Report(RunningTasks.Count); progress.Report(RunningTasks.Count);
@ -346,8 +344,8 @@ namespace CreamInstaller
if (e.Button == MouseButtons.Right) if (e.Button == MouseButtons.Right)
{ {
ProgramSelection selection = ProgramSelection.FromName(e.Node.Text); ProgramSelection selection = ProgramSelection.FromName(e.Node.Text);
Tuple<int, string> dlc = ProgramSelection.GetDlc(e.Node.Text); KeyValuePair<int, string>? dlc = ProgramSelection.GetDlc(e.Node.Text);
int appId = selection?.SteamAppId ?? dlc?.Item1 ?? 0; int appId = selection?.SteamAppId ?? dlc?.Key ?? 0;
if (appId > 0) Process.Start(new ProcessStartInfo if (appId > 0) Process.Start(new ProcessStartInfo
{ {
FileName = "https://steamdb.info/app/" + appId, FileName = "https://steamdb.info/app/" + appId,
@ -372,7 +370,7 @@ namespace CreamInstaller
paradoxLauncher ??= ProgramSelection.FromName("Paradox Launcher"); paradoxLauncher ??= ProgramSelection.FromName("Paradox Launcher");
if (!(paradoxLauncher is null)) if (!(paradoxLauncher is null))
{ {
paradoxLauncher.ExtraSteamAppIdDlc = new(); 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) continue;