installation

This commit is contained in:
pointfeev 2021-11-05 22:37:54 -04:00
parent 93b535ab29
commit d17007e65a
No known key found for this signature in database
GPG key ID: AA14DC36C4D7D13C
9 changed files with 203 additions and 149 deletions

View file

@ -9,7 +9,7 @@
<Version>2.0.0.0</Version>
<PackageIcon>ini.ico</PackageIcon>
<PackageIconUrl />
<Description>Automatically downloads and installs CreamAPI files for programs/games.</Description>
<Description>Automatically generates and installs CreamAPI files for programs/games.</Description>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
@ -20,7 +20,7 @@
<PackageTags>steam, dlc</PackageTags>
<AssemblyName>CreamInstaller</AssemblyName>
<Company>CreamInstaller</Company>
<Product>CreamAPI Downloader &amp; Installer</Product>
<Product>CreamAPI Generator &amp; Installer</Product>
<Authors>pointfeev</Authors>
<PackageId>pointfeev.creaminstaller</PackageId>
<StartupObject>CreamInstaller.Program</StartupObject>
@ -32,6 +32,19 @@
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="steam_api.dll" />
<None Remove="steam_api64.dll" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="steam_api64.dll" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="steam_api.dll" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
<PackageReference Include="Onova" Version="2.6.2" />

View file

@ -2,8 +2,9 @@
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CreamInstaller
@ -27,7 +28,7 @@ namespace CreamInstaller
public 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;
}
@ -40,125 +41,96 @@ namespace CreamInstaller
{
logTextBox.AppendText(Environment.NewLine, color);
}
logTextBox.AppendText(userInfoLabel.Text, color);
}
}
private void OperateFor(ProgramSelection selection)
private async Task OperateFor(ProgramSelection selection)
{
UpdateProgress(0);
UpdateUser("Downloading CreamAPI files for " + selection.DisplayName + " . . . ", LogColor.Operation);
UpdateUser($"Downloaded archive: {Program.OutputFile}", LogColor.Resource);
UpdateUser("Searching for CreamAPI files in downloaded archive . . . ", LogColor.Operation);
string resourcePath = null;
List<ZipArchiveEntry> resources = new List<ZipArchiveEntry>();
Program.OutputArchive = ZipFile.OpenRead(Program.OutputFile);
int currentEntryCount = 0;
foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries)
{
currentEntryCount++;
if (entry.Name == "steam_api64.dll")
{
resourcePath = Path.GetDirectoryName(entry.FullName);
UpdateUser("Got CreamAPI file path: " + resourcePath, LogColor.Resource);
}
UpdateProgress(currentEntryCount / (Program.OutputArchive.Entries.Count * 2) * 100);
}
foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries)
{
currentEntryCount++;
if (!string.IsNullOrEmpty(entry.Name) && Path.GetDirectoryName(entry.FullName) == resourcePath)
{
resources.Add(entry);
UpdateUser("Found CreamAPI file: " + entry.Name, LogColor.Resource);
}
UpdateProgress(currentEntryCount / (Program.OutputArchive.Entries.Count * 2) * 100);
}
if (resources.Count < 1)
{
throw new CustomMessageException($"Unable to find CreamAPI files in downloaded archive: {Program.OutputFile}");
}
if (!Program.IsProgramRunningDialog(this, selection))
{
throw new OperationCanceledException();
}
UpdateUser("Installing CreamAPI files for " + selection.DisplayName + " . . . ", LogColor.Operation);
int currentFileCount = 0;
int count = selection.SteamApiDllDirectories.Count;
int cur = 0;
foreach (string directory in selection.SteamApiDllDirectories)
{
Dictionary<string, string> changesToRevert = new();
foreach (ZipArchiveEntry entry in resources)
UpdateUser("Installing CreamAPI for " + selection.DisplayName + $" in directory \"{directory}\" . . . ", LogColor.Operation);
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException();
string api = directory + @"\steam_api.dll";
string api_o = directory + @"\steam_api_o.dll";
if (File.Exists(api) && !File.Exists(api_o))
{
currentFileCount++;
string file = directory + "\\" + entry.Name;
if (File.Exists(file))
{
string backup = file + Program.BackupFileExtension;
File.Copy(file, backup, true);
changesToRevert.Add(file, backup);
}
else
{
changesToRevert.Add(file, string.Empty);
}
try
{
entry.ExtractToFile(file, true);
}
catch
{
foreach (KeyValuePair<string, string> keyValuePair in changesToRevert)
{
file = keyValuePair.Key;
string backup = keyValuePair.Value;
if (string.IsNullOrEmpty(backup))
{
File.Delete(file);
UpdateUser("Deleted CreamAPI file: " + file, LogColor.Warning);
}
else if (file.IsFilePathLocked())
{
File.Delete(backup);
}
else
{
File.Move(backup, file, true);
UpdateUser("Reversed changes to Steam API file: " + file, LogColor.Warning);
}
}
throw new CustomMessageException($"Unable to overwrite Steam API file: {file}");
}
UpdateUser("Installed file: " + file, LogColor.Resource);
UpdateProgress(currentFileCount / (resources.Count * selection.SteamApiDllDirectories.Count) * 100);
File.Move(api, api_o);
UpdateUser($"Renamed file: {api} -> steam_api_o.dll", LogColor.Resource);
}
foreach (KeyValuePair<string, string> keyValuePair in changesToRevert)
if (File.Exists(api_o))
{
string file = keyValuePair.Key;
string backup = keyValuePair.Value;
if (!string.IsNullOrEmpty(backup))
Resources.WriteResourceToFile("steam_api.dll", api);
UpdateUser($"Wrote resource to file: {api}", LogColor.Resource);
}
string api64 = directory + @"\steam_api64.dll";
string api64_o = directory + @"\steam_api64_o.dll";
if (File.Exists(api64) && !File.Exists(api64_o))
{
File.Move(api64, api64_o);
UpdateUser($"Renamed file: {api64} -> steam_api64_o.dll", LogColor.Resource);
}
if (File.Exists(api64_o))
{
Resources.WriteResourceToFile("steam_api64.dll", api64);
UpdateUser($"Wrote resource to file: {api64}", LogColor.Resource);
}
string cApi = directory + @"\cream_api.ini";
File.Create(cApi).Close();
StreamWriter writer = File.AppendText(cApi);
writer.WriteLine(";Created with CreamInstaller by pointfeev#4538");
if (selection.SteamAppId > 0)
{
writer.WriteLine();
writer.WriteLine("[steam]");
writer.WriteLine($"appid = {selection.SteamAppId}");
writer.WriteLine();
writer.WriteLine("[dlc]");
UpdateUser($"Added game to cream_api.ini with appid {selection.SteamAppId} ({selection.DisplayName})", LogColor.Resource);
foreach (Tuple<int, string> dlcApp in selection.SelectedSteamDlc)
{
File.Delete(backup);
writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}");
UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", LogColor.Resource);
}
}
foreach (Tuple<int, string, List<Tuple<int, string>>> extraAppDlc in selection.ExtraSteamAppIdDlc)
{
writer.WriteLine();
writer.WriteLine("[steam]");
writer.WriteLine($"appid = {extraAppDlc.Item1}");
writer.WriteLine();
writer.WriteLine("[dlc]");
UpdateUser($"Added game to cream_api.ini with appid {extraAppDlc.Item1} ({extraAppDlc.Item2})", LogColor.Resource);
foreach (Tuple<int, string> dlcApp in extraAppDlc.Item3)
{
writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}");
UpdateUser($"Added DLC to cream_api.ini with appid {dlcApp.Item1} ({dlcApp.Item2})", LogColor.Resource);
}
}
writer.Flush();
writer.Close();
await Task.Run(() => Thread.Sleep(0)); // to keep the text box control from glitching
UpdateProgress(++cur / count * 100);
}
UpdateProgress(100);
}
private void Operate()
private async Task Operate()
{
OperationsCount = Program.ProgramSelections.ToList().FindAll(selection => selection.Enabled).Count;
OperationsCount = ProgramSelection.AllSafeEnabled.Count;
CompleteOperationsCount = 0;
foreach (ProgramSelection selection in Program.ProgramSelections.ToList())
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
{
if (!selection.Enabled) continue;
if (!Program.IsProgramRunningDialog(this, selection)) throw new OperationCanceledException();
try
{
OperateFor(selection);
await OperateFor(selection);
UpdateUser($"Operation succeeded for {selection.DisplayName}.", LogColor.Success);
selection.Toggle(false);
selection.Enabled = false;
}
catch (Exception exception)
{
@ -167,7 +139,7 @@ namespace CreamInstaller
++CompleteOperationsCount;
}
Program.Cleanup();
List<ProgramSelection> FailedSelections = Program.ProgramSelections.ToList().FindAll(selection => selection.Enabled);
List<ProgramSelection> FailedSelections = ProgramSelection.AllSafeEnabled;
if (FailedSelections.Any())
{
if (FailedSelections.Count == 1)
@ -181,9 +153,9 @@ namespace CreamInstaller
}
}
private readonly int ProgramCount = Program.ProgramSelections.ToList().FindAll(selection => selection.Enabled).Count;
private readonly int ProgramCount = ProgramSelection.AllSafeEnabled.Count;
private void Start()
private async void Start()
{
acceptButton.Enabled = false;
retryButton.Enabled = false;
@ -192,12 +164,12 @@ namespace CreamInstaller
userProgressBar.Value = userProgressBar.Minimum;
try
{
Operate();
UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s).", LogColor.Success);
await Operate();
UpdateUser("CreamAPI successfully installed for " + ProgramCount + " program(s).", LogColor.Success);
}
catch (Exception exception)
{
UpdateUser("CreamAPI download and/or installation failed: " + exception.ToString(), LogColor.Error);
UpdateUser("CreamAPI installation failed: " + exception.ToString(), LogColor.Error);
retryButton.Enabled = true;
}
userProgressBar.Value = userProgressBar.Maximum;

View file

@ -12,7 +12,7 @@ namespace CreamInstaller
{
public static class Program
{
public static readonly string ApplicationName = "CreamInstaller v" + Application.ProductVersion + ": CreamAPI Downloader & Installer";
public static readonly string ApplicationName = Application.CompanyName + " v" + Application.ProductVersion + ": " + Application.ProductName;
public static readonly Assembly EntryAssembly = Assembly.GetEntryAssembly();
public static readonly Process CurrentProcess = Process.GetCurrentProcess();
public static readonly string CurrentProcessFilePath = CurrentProcess.MainModule.FileName;
@ -36,7 +36,7 @@ namespace CreamInstaller
public static bool IsProgramRunningDialog(Form form, ProgramSelection selection)
{
if (selection.IsProgramRunning)
if (selection.AreSteamApiDllsLocked)
{
if (new DialogForm(form).Show(ApplicationName, SystemIcons.Error,
$"ERROR: {selection.DisplayName} is currently running!" +
@ -55,6 +55,7 @@ namespace CreamInstaller
public static bool IsFilePathLocked(this string filePath)
{
if (!File.Exists(filePath)) return false;
bool Locked = false;
try
{

View file

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
namespace CreamInstaller
{
@ -12,21 +14,54 @@ namespace CreamInstaller
public int SteamAppId;
public List<string> SteamApiDllDirectories;
public bool IsProgramRunning
public Dictionary<string, string> AppInfo = new();
public List<Tuple<int, string>> AllSteamDlc = new();
public List<Tuple<int, string>> SelectedSteamDlc = new();
public List<Tuple<int, string, List<Tuple<int, string>>>> ExtraSteamAppIdDlc = new();
public bool AreSteamApiDllsLocked
{
get
{
foreach (string directory in SteamApiDllDirectories)
{
string file = directory + "\\steam_api64.dll";
if (file.IsFilePathLocked()) return true;
string api = directory + @"\steam_api.dll";
string api64 = directory + @"\steam_api64.dll";
if (api.IsFilePathLocked() || api64.IsFilePathLocked()) return true;
}
return false;
}
}
public ProgramSelection() => Program.ProgramSelections.Add(this);
public void ToggleDlc(string dlcName, bool Enabled)
{
foreach (Tuple<int, string> dlcApp in AllSteamDlc)
{
if (dlcApp.Item2 == dlcName)
{
if (Enabled)
{
if (!SelectedSteamDlc.Contains(dlcApp))
{
SelectedSteamDlc.Add(dlcApp);
}
}
else SelectedSteamDlc.Remove(dlcApp);
return;
}
}
}
public void Toggle(bool Enabled) => this.Enabled = Enabled;
public ProgramSelection() => All.Add(this);
public static List<ProgramSelection> All => Program.ProgramSelections;
public static List<ProgramSelection> AllSafe => All.ToList();
public static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled);
public static ProgramSelection FromIdentifier(string identifier) => AllSafe.Find(s => s.Identifier == identifier);
public static ProgramSelection FromDisplayName(string displayName) => AllSafe.Find(s => s.DisplayName == displayName);
}
}

View file

@ -0,0 +1,15 @@
using System.IO;
using System.Reflection;
namespace CreamInstaller
{
public static class Resources
{
public static void WriteResourceToFile(string resourceName, string filePath)
{
using Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("CreamInstaller." + resourceName);
using FileStream file = new(filePath, FileMode.Create, FileAccess.Write);
resource.CopyTo(file);
}
}
}

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -47,8 +48,8 @@ namespace CreamInstaller
{
steamApiDllDirectories = new();
if (Program.Canceled) return false;
string api = gameDirectory + "\\steam_api.dll";
string api64 = gameDirectory + "\\steam_api64.dll";
string api = gameDirectory + @"\steam_api.dll";
string api64 = gameDirectory + @"\steam_api64.dll";
if (File.Exists(api) || File.Exists(api64)) steamApiDllDirectories.Add(gameDirectory);
foreach (string _directory in Directory.GetDirectories(gameDirectory))
{
@ -138,17 +139,17 @@ namespace CreamInstaller
if (!(appInfo is null) && appInfo.TryGetValue("listofdlc", out list))
{
if (Program.Canceled) return;
string[] nums = Regex.Replace(list, "[^0-9,]+", "").Split(",");
List<int> ids = new();
foreach (string s in nums)
{
if (Program.Canceled) return;
ids.Add(int.Parse(s));
}
Task task = new(() =>
{
try
{
string[] nums = list.Split(",");
List<int> ids = new();
foreach (string s in nums)
{
if (Program.Canceled) return;
ids.Add(int.Parse(s));
}
foreach (int id in ids)
{
if (Program.Canceled) return;
@ -156,7 +157,7 @@ namespace CreamInstaller
Dictionary<string, string> dlcAppInfo = null;
if (SteamCMD.GetAppInfo(id, out dlcAppInfo)) dlcAppInfo.TryGetValue("name", out dlcName);
if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(dlcName)) continue;
if (string.IsNullOrWhiteSpace(dlcName)) dlcName = "Unknown DLC";
dlc.Add(new Tuple<int, string>(id, dlcName));
}
}
@ -170,17 +171,19 @@ namespace CreamInstaller
else if (identifier != "Paradox Launcher") return;
if (Program.Canceled) return;
if (string.IsNullOrWhiteSpace(identifier)) return;
string displayName = identifier;
if (!(appInfo is null)) appInfo.TryGetValue("name", out displayName);
if (string.IsNullOrWhiteSpace(displayName)) return;
if (string.IsNullOrWhiteSpace(displayName)) displayName = "Unknown Game";
if (Program.Canceled) return;
ProgramSelection selection = Program.ProgramSelections.Find(s => s.Identifier == identifier) ?? new();
ProgramSelection selection = ProgramSelection.FromIdentifier(identifier) ?? new();
selection.Identifier = identifier;
selection.DisplayName = displayName;
selection.RootDirectory = rootDirectory;
selection.SteamAppId = steamAppId;
selection.SteamApiDllDirectories = steamApiDllDirectories;
selection.AppInfo = appInfo;
foreach (Task task in dlcTasks.ToList())
{
@ -207,6 +210,8 @@ namespace CreamInstaller
programNode.Nodes.Add(dlcNode);
treeNodes.Remove(dlcNode);
treeNodes.Add(dlcNode);
selection.AllSteamDlc.Add(dlcApp);
selection.SelectedSteamDlc.Add(dlcApp);
}
});
}
@ -273,11 +278,11 @@ namespace CreamInstaller
label2.Text = "Gathering your CreamAPI-applicable games and their DLCs . . . ";
await Task.Run(() => GetCreamApiApplicablePrograms(iProgress));
Program.ProgramSelections.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory)));
Program.ProgramSelections.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
ProgramSelection.All.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory)));
ProgramSelection.All.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
foreach (TreeNode treeNode in treeNodes)
{
if (treeNode.Parent is null && !Program.ProgramSelections.Any(selection => selection.DisplayName == treeNode.Text))
if (treeNode.Parent is null && ProgramSelection.FromDisplayName(treeNode.Text) is null)
{
treeNode.Remove();
}
@ -288,13 +293,13 @@ namespace CreamInstaller
label2.Visible = false;
progressBar1.Visible = false;
if (Program.ProgramSelections.Any())
if (ProgramSelection.All.Any())
{
allCheckBox.Enabled = true;
treeView1.CheckBoxes = true;
treeView1.ExpandAll();
treeNodes.ForEach(node => node.Checked = true);
if (Program.ProgramSelections.Any(selection => selection.Enabled))
if (ProgramSelection.AllSafeEnabled.Any())
{
acceptButton.Enabled = true;
}
@ -310,20 +315,22 @@ namespace CreamInstaller
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
{
ProgramSelection selection = Program.ProgramSelections.ToList().Find(selection => selection.DisplayName == e.Node.Text);
ProgramSelection selection = ProgramSelection.FromDisplayName(e.Node.Text);
if (selection is null)
{
selection = ProgramSelection.FromDisplayName(e.Node.Parent.Text);
treeView1.AfterCheck -= OnTreeViewNodeCheckedChanged;
e.Node.Parent.Checked = e.Node.Parent.Nodes.Cast<TreeNode>().ToList().Any(treeNode => treeNode.Checked);
treeView1.AfterCheck += OnTreeViewNodeCheckedChanged;
selection.ToggleDlc(e.Node.Text, e.Node.Checked);
}
else
{
selection.Toggle(e.Node.Checked);
selection.Enabled = e.Node.Checked;
treeView1.AfterCheck -= OnTreeViewNodeCheckedChanged;
e.Node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = e.Node.Checked);
treeView1.AfterCheck += OnTreeViewNodeCheckedChanged;
acceptButton.Enabled = Program.ProgramSelections.ToList().Any(selection => selection.Enabled);
acceptButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = treeNodes.TrueForAll(treeNode => treeNode.Checked);
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
@ -339,9 +346,9 @@ namespace CreamInstaller
private void OnAccept(object sender, EventArgs e)
{
if (Program.ProgramSelections.Count > 0)
if (ProgramSelection.All.Count > 0)
{
foreach (ProgramSelection selection in Program.ProgramSelections.ToList())
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
{
if (!Program.IsProgramRunningDialog(this, selection))
{
@ -349,16 +356,28 @@ namespace CreamInstaller
}
}
ProgramSelection paradoxLauncher = ProgramSelection.FromIdentifier("Paradox Launcher");
if (!(paradoxLauncher is null))
{
paradoxLauncher.ExtraSteamAppIdDlc = new();
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
{
if (selection.Identifier == paradoxLauncher.Identifier) continue;
if (!selection.AppInfo.TryGetValue("publisher", out string publisher) || publisher != "Paradox Interactive") continue;
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.DisplayName, selection.SelectedSteamDlc));
}
}
Hide();
InstallForm installForm = new InstallForm(this);
installForm.ShowDialog();
if (installForm.Reselecting)
{
//foreach (TreeNode treeNode in treeNodes)
//{
// treeNode.Checked = !treeNode.Checked;
// treeNode.Checked = !treeNode.Checked; // to fire checked event
//}
foreach (TreeNode treeNode in treeNodes)
{
treeNode.Checked = !treeNode.Checked;
treeNode.Checked = !treeNode.Checked; // to fire checked event
}
int X = installForm.Location.X + installForm.Size.Width / 2 - Size.Width / 2;
int Y = installForm.Location.Y + installForm.Size.Height / 2 - Size.Height / 2;
Location = new Point(X, Y);

View file

@ -13,7 +13,7 @@ namespace CreamInstaller
public static string FilePath = DirectoryPath + @"\steamcmd.exe";
public static string ArchivePath = DirectoryPath + @"\steamcmd.zip";
public static string DllPath = DirectoryPath + @"\steamclient.dll";
public static string AppUpdatePath = DirectoryPath + @"\appupdate";
public static string AppInfoCachePath = DirectoryPath + @"\appinfocache";
public static bool Run(string command, out string output)
{
@ -57,17 +57,16 @@ namespace CreamInstaller
{
appInfo = new();
if (Program.Canceled) return false;
string output = null;
string appUpdatePath = $@"{AppUpdatePath}\{steamAppId}";
string output;
string appUpdatePath = $@"{AppInfoCachePath}\{steamAppId}";
string appUpdateFile = $@"{appUpdatePath}\appinfo.txt";
if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile);
else
{
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {steamAppId} +force_install_dir {appUpdatePath} +app_update 4 +quit", out _);
if (Program.Canceled) return false;
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {steamAppId} +quit", out output);
File.WriteAllText(appUpdateFile, output);
}
//if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile);
//else
//{
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {steamAppId} +force_install_dir {appUpdatePath} +app_update 4 +quit", out _);
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {steamAppId} +quit", out output);
File.WriteAllText(appUpdateFile, output);
//}
if (Program.Canceled || output is null) return false;
foreach (string s in output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
{

Binary file not shown.

Binary file not shown.