proper game gathering, depot dlcs, appinfo caching
This commit is contained in:
parent
b11e5e9fcb
commit
351847727b
6 changed files with 195 additions and 178 deletions
|
@ -52,7 +52,7 @@ namespace CreamInstaller
|
|||
int cur = 0;
|
||||
foreach (string directory in selection.SteamApiDllDirectories)
|
||||
{
|
||||
UpdateUser("Installing CreamAPI for " + selection.DisplayName + $" in directory \"{directory}\" . . . ", LogColor.Operation);
|
||||
UpdateUser("Installing CreamAPI for " + selection.Name + $" 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";
|
||||
|
@ -89,7 +89,7 @@ namespace CreamInstaller
|
|||
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);
|
||||
UpdateUser($"Added game to cream_api.ini with appid {selection.SteamAppId} ({selection.Name})", LogColor.Resource);
|
||||
foreach (Tuple<int, string> dlcApp in selection.SelectedSteamDlc)
|
||||
{
|
||||
writer.WriteLine($"{dlcApp.Item1} = {dlcApp.Item2}");
|
||||
|
@ -129,12 +129,12 @@ namespace CreamInstaller
|
|||
try
|
||||
{
|
||||
await OperateFor(selection);
|
||||
UpdateUser($"Operation succeeded for {selection.DisplayName}.", LogColor.Success);
|
||||
UpdateUser($"Operation succeeded for {selection.Name}.", LogColor.Success);
|
||||
selection.Enabled = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
UpdateUser($"Operation failed for {selection.DisplayName}: " + exception.ToString(), LogColor.Error);
|
||||
UpdateUser($"Operation failed for {selection.Name}: " + exception.ToString(), LogColor.Error);
|
||||
}
|
||||
++CompleteOperationsCount;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ namespace CreamInstaller
|
|||
{
|
||||
if (FailedSelections.Count == 1)
|
||||
{
|
||||
throw new CustomMessageException($"Operation failed for {FailedSelections.First().DisplayName}.");
|
||||
throw new CustomMessageException($"Operation failed for {FailedSelections.First().Name}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace CreamInstaller
|
|||
if (selection.AreSteamApiDllsLocked)
|
||||
{
|
||||
if (new DialogForm(form).Show(ApplicationName, SystemIcons.Error,
|
||||
$"ERROR: {selection.DisplayName} is currently running!" +
|
||||
$"ERROR: {selection.Name} is currently running!" +
|
||||
"\n\nPlease close the program/game to continue . . . ",
|
||||
"Retry", "Cancel") == DialogResult.OK)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Gameloop.Vdf.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -8,13 +9,13 @@ namespace CreamInstaller
|
|||
{
|
||||
public bool Enabled = true;
|
||||
|
||||
public string Identifier;
|
||||
public string DisplayName;
|
||||
public string Name;
|
||||
public string RootDirectory;
|
||||
public int SteamAppId;
|
||||
public List<string> SteamApiDllDirectories;
|
||||
|
||||
public Dictionary<string, string> AppInfo = new();
|
||||
public VProperty AppInfo = null;
|
||||
|
||||
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();
|
||||
|
@ -47,9 +48,10 @@ namespace CreamInstaller
|
|||
}
|
||||
}
|
||||
else SelectedSteamDlc.Remove(dlcApp);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!SelectedSteamDlc.Any()) this.Enabled = false;
|
||||
}
|
||||
|
||||
public ProgramSelection() => All.Add(this);
|
||||
|
@ -60,8 +62,6 @@ namespace CreamInstaller
|
|||
|
||||
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);
|
||||
public static ProgramSelection FromName(string displayName) => AllSafe.Find(s => s.Name == displayName);
|
||||
}
|
||||
}
|
4
CreamInstaller/SelectForm.Designer.cs
generated
4
CreamInstaller/SelectForm.Designer.cs
generated
|
@ -108,11 +108,11 @@ namespace CreamInstaller
|
|||
this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.treeView1.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.treeView1.CheckBoxes = true;
|
||||
this.treeView1.Location = new System.Drawing.Point(6, 22);
|
||||
this.treeView1.Name = "treeView1";
|
||||
this.treeView1.ShowPlusMinus = false;
|
||||
this.treeView1.ShowRootLines = false;
|
||||
this.treeView1.Size = new System.Drawing.Size(448, 208);
|
||||
this.treeView1.TabIndex = 1001;
|
||||
//
|
||||
|
|
|
@ -6,7 +6,6 @@ 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;
|
||||
|
||||
|
@ -32,63 +31,70 @@ namespace CreamInstaller
|
|||
if (steamInstallPath == null) steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
|
||||
if (steamInstallPath != null)
|
||||
{
|
||||
string mainLibraryFolder = steamInstallPath + "\\steamapps\\common";
|
||||
gameDirectories.Add(mainLibraryFolder);
|
||||
string libraryFolders = steamInstallPath + "\\steamapps\\libraryfolders.vdf";
|
||||
VProperty property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders));
|
||||
foreach (VProperty _property in property.Value)
|
||||
if (int.TryParse(_property.Key, out _) && Directory.Exists(_property.Value.ToString()))
|
||||
gameDirectories.Add(_property.Value.ToString());
|
||||
string libraryFolder = steamInstallPath + @"\steamapps";
|
||||
gameDirectories.Add(libraryFolder);
|
||||
string libraryFolders = libraryFolder + @"\libraryfolders.vdf";
|
||||
dynamic property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders));
|
||||
foreach (dynamic _property in property.Value)
|
||||
{
|
||||
if (int.TryParse(_property.Key, out int _))
|
||||
{
|
||||
string path = _property.Value.path.ToString() + @"\steamapps";
|
||||
if (string.IsNullOrWhiteSpace(path)) continue;
|
||||
if (!gameDirectories.Contains(path)) gameDirectories.Add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return gameDirectories;
|
||||
}
|
||||
}
|
||||
|
||||
private bool GetSteamApiDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> steamApiDllDirectories)
|
||||
private bool GetDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> dllDirectories)
|
||||
{
|
||||
steamApiDllDirectories = new();
|
||||
dllDirectories = new();
|
||||
if (Program.Canceled) return false;
|
||||
string api = gameDirectory + @"\steam_api.dll";
|
||||
string api64 = gameDirectory + @"\steam_api64.dll";
|
||||
if (File.Exists(api) || File.Exists(api64)) steamApiDllDirectories.Add(gameDirectory);
|
||||
if (File.Exists(api) || File.Exists(api64)) dllDirectories.Add(gameDirectory);
|
||||
foreach (string _directory in Directory.GetDirectories(gameDirectory))
|
||||
{
|
||||
if (Program.Canceled) return false;
|
||||
try
|
||||
{
|
||||
if (GetSteamApiDllDirectoriesFromGameDirectory(_directory, out List<string> _steamApiDllDirectories))
|
||||
steamApiDllDirectories.AddRange(_steamApiDllDirectories);
|
||||
if (GetDllDirectoriesFromGameDirectory(_directory, out List<string> _dllDirectories))
|
||||
dllDirectories.AddRange(_dllDirectories);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
if (!steamApiDllDirectories.Any()) return false;
|
||||
if (!dllDirectories.Any()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool GetSteamAppIdFromGameDirectory(string gameDirectory, out int appId)
|
||||
private bool GetGamesFromLibraryDirectory(string libraryDirectory, out List<Tuple<int, string, int, string>> games)
|
||||
{
|
||||
appId = 0;
|
||||
games = new();
|
||||
if (Program.Canceled) return false;
|
||||
string file = gameDirectory + "\\steam_appid.txt";
|
||||
if (File.Exists(file) && int.TryParse(File.ReadAllText(file), out appId)) return true;
|
||||
foreach (string _directory in Directory.GetDirectories(gameDirectory))
|
||||
foreach (string directory in Directory.GetFiles(libraryDirectory))
|
||||
{
|
||||
if (Program.Canceled) return false;
|
||||
if (GetSteamAppIdFromGameDirectory(_directory, out appId)) return true;
|
||||
if (Path.GetExtension(directory) == ".acf")
|
||||
{
|
||||
dynamic property = VdfConvert.Deserialize(File.ReadAllText(directory));
|
||||
string _appid = property.Value.appid.ToString();
|
||||
string installdir = property.Value.installdir.ToString();
|
||||
string name = property.Value.name.ToString();
|
||||
string _buildid = property.Value.buildid.ToString();
|
||||
if (string.IsNullOrWhiteSpace(_appid)
|
||||
|| string.IsNullOrWhiteSpace(installdir)
|
||||
|| string.IsNullOrWhiteSpace(name)
|
||||
|| string.IsNullOrWhiteSpace(_buildid)) continue;
|
||||
string gameDirectory = libraryDirectory + @"\common\" + installdir;
|
||||
if (!int.TryParse(_appid, out int appid)) continue;
|
||||
if (!int.TryParse(_buildid, out int buildid)) continue;
|
||||
games.Add(new(appid, name, buildid, gameDirectory));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool GetGameDirectoriesFromLibraryDirectory(string libraryDirectory, out List<string> gameDirectories)
|
||||
{
|
||||
gameDirectories = new();
|
||||
if (Program.Canceled) return false;
|
||||
foreach (string _directory in Directory.GetDirectories(libraryDirectory))
|
||||
{
|
||||
if (Program.Canceled) return false;
|
||||
if (Directory.Exists(_directory)) gameDirectories.Add(_directory);
|
||||
}
|
||||
if (!gameDirectories.Any()) return false;
|
||||
if (!games.Any()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -102,120 +108,121 @@ namespace CreamInstaller
|
|||
{
|
||||
int cur = 0;
|
||||
if (Program.Canceled) return;
|
||||
List<Tuple<string, string>> applicablePrograms = new();
|
||||
List<Tuple<int, string, int, string>> applicablePrograms = new();
|
||||
string launcherRootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
|
||||
if (Directory.Exists(launcherRootDirectory)) applicablePrograms.Add(new Tuple<string, string>("Paradox Launcher", launcherRootDirectory));
|
||||
if (Directory.Exists(launcherRootDirectory)) applicablePrograms.Add(new(0, "Paradox Launcher", 0, launcherRootDirectory));
|
||||
foreach (string libraryDirectory in GameLibraryDirectories)
|
||||
if (GetGameDirectoriesFromLibraryDirectory(libraryDirectory, out List<string> gameDirectories))
|
||||
foreach (string gameDirectory in gameDirectories)
|
||||
applicablePrograms.Add(new Tuple<string, string>(Path.GetFileName(gameDirectory) ?? "unknown_" + applicablePrograms.Count, gameDirectory));
|
||||
if (GetGamesFromLibraryDirectory(libraryDirectory, out List<Tuple<int, string, int, string>> games))
|
||||
foreach (Tuple<int, string, int, string> game in games)
|
||||
applicablePrograms.Add(game);
|
||||
RunningTasks = new();
|
||||
foreach (Tuple<string, string> program in applicablePrograms)
|
||||
foreach (Tuple<int, string, int, string> program in applicablePrograms)
|
||||
{
|
||||
string identifier = program.Item1;
|
||||
string rootDirectory = program.Item2;
|
||||
int appId = program.Item1;
|
||||
string name = program.Item2;
|
||||
int buildId = program.Item3;
|
||||
string directory = program.Item4;
|
||||
if (Program.Canceled) return;
|
||||
if (Directory.Exists(directory + @"\EasyAntiCheat")) continue;
|
||||
Task task = new(() =>
|
||||
{
|
||||
try
|
||||
if (Program.Canceled || !GetDllDirectoriesFromGameDirectory(directory, out List<string> dllDirectories)) return;
|
||||
VProperty appInfo = null;
|
||||
if (Program.Canceled || (name != "Paradox Launcher" && !SteamCMD.GetAppInfo(appId, buildId, out appInfo))) return;
|
||||
List<Tuple<int, string>> dlc = null;
|
||||
if (!DLC.TryGetValue(appId, out dlc))
|
||||
{
|
||||
int steamAppId = 0;
|
||||
if (Program.Canceled
|
||||
|| (identifier != "Paradox Launcher" && !GetSteamAppIdFromGameDirectory(rootDirectory, out steamAppId))
|
||||
|| !GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory, out List<string> steamApiDllDirectories))
|
||||
return;
|
||||
|
||||
Dictionary<string, string> appInfo = null;
|
||||
if (Program.Canceled || (identifier != "Paradox Launcher" && !SteamCMD.GetAppInfo(steamAppId, out appInfo))) return;
|
||||
string list = null;
|
||||
List<Tuple<int, string>> dlc = null;
|
||||
if (!DLC.TryGetValue(steamAppId, out dlc))
|
||||
dlc = new();
|
||||
DLC.Add(appId, dlc);
|
||||
}
|
||||
if (Program.Canceled) return;
|
||||
List<Task> dlcTasks = new();
|
||||
List<int> dlcIds = new();
|
||||
if (!(appInfo is null))
|
||||
{
|
||||
try
|
||||
{
|
||||
dlc = new();
|
||||
DLC.Add(steamAppId, dlc);
|
||||
if (!(appInfo.Value["extended"] is null))
|
||||
foreach (VProperty property in appInfo.Value["extended"])
|
||||
if (property.Key.ToString() == "listofdlc")
|
||||
foreach (string id in property.Value.ToString().Split(","))
|
||||
if (!dlcIds.Contains(int.Parse(id)))
|
||||
dlcIds.Add(int.Parse(id));
|
||||
}
|
||||
if (Program.Canceled) return;
|
||||
List<Task> dlcTasks = new();
|
||||
if (!(appInfo is null) && appInfo.TryGetValue("listofdlc", out list))
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
if (!(appInfo.Value["depots"] is null))
|
||||
foreach (VProperty _property in appInfo.Value["depots"])
|
||||
if (int.TryParse(_property.Key.ToString(), out int _))
|
||||
if (int.TryParse(_property.Value?["dlcappid"]?.ToString(), out int appid) && !dlcIds.Contains(appid))
|
||||
dlcIds.Add(appid);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
if (!(dlcIds is null) && dlcIds.Count > 0)
|
||||
{
|
||||
foreach (int id in dlcIds)
|
||||
{
|
||||
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
|
||||
{
|
||||
foreach (int id in ids)
|
||||
{
|
||||
if (Program.Canceled) return;
|
||||
string dlcName = null;
|
||||
Dictionary<string, string> dlcAppInfo = null;
|
||||
if (SteamCMD.GetAppInfo(id, out dlcAppInfo)) dlcAppInfo.TryGetValue("name", out dlcName);
|
||||
if (Program.Canceled) return;
|
||||
if (string.IsNullOrWhiteSpace(dlcName)) dlcName = "Unknown DLC";
|
||||
dlc.Add(new Tuple<int, string>(id, dlcName));
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
if (Program.Canceled) return;
|
||||
string dlcName = null;
|
||||
VProperty dlcAppInfo = null;
|
||||
if (SteamCMD.GetAppInfo(id, 0, out dlcAppInfo)) try { dlcName = dlcAppInfo?.Value?["common"]?["name"]?.ToString(); } catch { }
|
||||
if (Program.Canceled) return;
|
||||
if (string.IsNullOrWhiteSpace(dlcName)) dlcName = $"Unnamed DLC ({id})";
|
||||
dlc.Add(new Tuple<int, string>(id, dlcName));
|
||||
});
|
||||
dlcTasks.Add(task);
|
||||
RunningTasks.Add(task);
|
||||
task.Start();
|
||||
progress.Report(-RunningTasks.Count);
|
||||
}
|
||||
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)) displayName = "Unknown Game";
|
||||
if (Program.Canceled) return;
|
||||
|
||||
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())
|
||||
{
|
||||
if (Program.Canceled) return;
|
||||
progress.Report(cur++);
|
||||
task.Wait();
|
||||
}
|
||||
if (Program.Canceled) return;
|
||||
treeView1.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
if (Program.Canceled) return;
|
||||
TreeNode programNode = treeNodes.Find(s => s.Text == displayName) ?? new();
|
||||
programNode.Text = displayName;
|
||||
programNode.Remove();
|
||||
treeView1.Nodes.Add(programNode);
|
||||
treeNodes.Remove(programNode);
|
||||
treeNodes.Add(programNode);
|
||||
foreach (Tuple<int, string> dlcApp in dlc.ToList())
|
||||
{
|
||||
if (Program.Canceled || programNode is null) return;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Text == dlcApp.Item2) ?? new();
|
||||
dlcNode.Text = dlcApp.Item2;
|
||||
dlcNode.Remove();
|
||||
programNode.Nodes.Add(dlcNode);
|
||||
treeNodes.Remove(dlcNode);
|
||||
treeNodes.Add(dlcNode);
|
||||
selection.AllSteamDlc.Add(dlcApp);
|
||||
selection.SelectedSteamDlc.Add(dlcApp);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
else if (name != "Paradox Launcher") return;
|
||||
if (Program.Canceled) return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name)) return;
|
||||
if (Program.Canceled) return;
|
||||
|
||||
ProgramSelection selection = ProgramSelection.FromName(name) ?? new();
|
||||
selection.Name = name;
|
||||
selection.RootDirectory = directory;
|
||||
selection.SteamAppId = appId;
|
||||
selection.SteamApiDllDirectories = dllDirectories;
|
||||
selection.AppInfo = appInfo;
|
||||
|
||||
foreach (Task task in dlcTasks.ToList())
|
||||
{
|
||||
if (Program.Canceled) return;
|
||||
progress.Report(cur++);
|
||||
task.Wait();
|
||||
}
|
||||
if (Program.Canceled) return;
|
||||
treeView1.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
if (Program.Canceled) return;
|
||||
TreeNode programNode = treeNodes.Find(s => s.Text == name) ?? new();
|
||||
programNode.Text = name;
|
||||
programNode.Remove();
|
||||
treeView1.Nodes.Add(programNode);
|
||||
treeNodes.Remove(programNode);
|
||||
treeNodes.Add(programNode);
|
||||
foreach (Tuple<int, string> dlcApp in dlc.ToList())
|
||||
{
|
||||
if (Program.Canceled || programNode is null) return;
|
||||
TreeNode dlcNode = treeNodes.Find(s => s.Text == dlcApp.Item2) ?? new();
|
||||
dlcNode.Text = dlcApp.Item2;
|
||||
dlcNode.Remove();
|
||||
programNode.Nodes.Add(dlcNode);
|
||||
treeNodes.Remove(dlcNode);
|
||||
treeNodes.Add(dlcNode);
|
||||
selection.AllSteamDlc.Add(dlcApp);
|
||||
selection.SelectedSteamDlc.Add(dlcApp);
|
||||
}
|
||||
});
|
||||
});
|
||||
RunningTasks.Add(task);
|
||||
task.Start();
|
||||
|
@ -282,7 +289,7 @@ namespace CreamInstaller
|
|||
ProgramSelection.All.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
|
||||
foreach (TreeNode treeNode in treeNodes)
|
||||
{
|
||||
if (treeNode.Parent is null && ProgramSelection.FromDisplayName(treeNode.Text) is null)
|
||||
if (treeNode.Parent is null && ProgramSelection.FromName(treeNode.Text) is null)
|
||||
{
|
||||
treeNode.Remove();
|
||||
}
|
||||
|
@ -297,7 +304,6 @@ namespace CreamInstaller
|
|||
{
|
||||
allCheckBox.Enabled = true;
|
||||
treeView1.CheckBoxes = true;
|
||||
treeView1.ExpandAll();
|
||||
treeNodes.ForEach(node => node.Checked = true);
|
||||
if (ProgramSelection.AllSafeEnabled.Any())
|
||||
{
|
||||
|
@ -315,10 +321,10 @@ namespace CreamInstaller
|
|||
|
||||
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
ProgramSelection selection = ProgramSelection.FromDisplayName(e.Node.Text);
|
||||
ProgramSelection selection = ProgramSelection.FromName(e.Node.Text);
|
||||
if (selection is null)
|
||||
{
|
||||
selection = ProgramSelection.FromDisplayName(e.Node.Parent.Text);
|
||||
selection = ProgramSelection.FromName(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;
|
||||
|
@ -339,30 +345,29 @@ namespace CreamInstaller
|
|||
|
||||
private void OnLoad(object sender, EventArgs e)
|
||||
{
|
||||
treeView1.BeforeCollapse += (sender, e) => e.Cancel = true;
|
||||
treeView1.AfterCheck += OnTreeViewNodeCheckedChanged;
|
||||
OnLoad();
|
||||
}
|
||||
|
||||
private static bool ParadoxLauncherDlcDialog(Form form)
|
||||
{
|
||||
ProgramSelection paradoxLauncher = ProgramSelection.FromIdentifier("Paradox Launcher");
|
||||
ProgramSelection paradoxLauncher = ProgramSelection.FromName("Paradox Launcher");
|
||||
if (!(paradoxLauncher is null) && paradoxLauncher.Enabled)
|
||||
{
|
||||
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));
|
||||
if (selection.Name == paradoxLauncher.Name) continue;
|
||||
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
||||
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc));
|
||||
}
|
||||
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
||||
{
|
||||
foreach (ProgramSelection selection in ProgramSelection.AllSafe)
|
||||
{
|
||||
if (selection.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.AllSteamDlc));
|
||||
if (selection.Name == paradoxLauncher.Name) continue;
|
||||
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") continue;
|
||||
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc));
|
||||
}
|
||||
}
|
||||
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Gameloop.Vdf;
|
||||
using Gameloop.Vdf.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
@ -53,37 +54,48 @@ namespace CreamInstaller
|
|||
if (!File.Exists(DllPath)) Run($@"+quit", out _);
|
||||
}
|
||||
|
||||
public static bool GetAppInfo(int steamAppId, out Dictionary<string, string> appInfo)
|
||||
private static Dictionary<int, int> retries = new();
|
||||
|
||||
public static bool GetAppInfo(int appId, int buildId, out VProperty appInfo)
|
||||
{
|
||||
appInfo = new();
|
||||
appInfo = null;
|
||||
if (Program.Canceled) return false;
|
||||
string output;
|
||||
string appUpdatePath = $@"{AppInfoCachePath}\{steamAppId}";
|
||||
string appUpdatePath = $@"{AppInfoCachePath}\{appId}";
|
||||
string appUpdateFile = $@"{appUpdatePath}\appinfo.txt";
|
||||
// need a fast way to make sure the cached info is up-to-date and correct
|
||||
//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))
|
||||
if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile);
|
||||
else
|
||||
{
|
||||
if (Program.Canceled) return false;
|
||||
int first = s.IndexOf("\"");
|
||||
int second = 1 + first + s.Substring(first + 1).IndexOf("\"");
|
||||
int third = 1 + second + s.Substring(second + 1).IndexOf("\"");
|
||||
int fourth = 1 + third + s.Substring(third + 1).IndexOf("\"");
|
||||
if (first > -1 && second > 0 && third > 0 && fourth > 0)
|
||||
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} +quit", out output);
|
||||
int openBracket = output.IndexOf("{");
|
||||
int closeBracket = output.LastIndexOf("}");
|
||||
output = $"\"{appId}\"\n" + output.Substring(openBracket, 1 + closeBracket - openBracket);
|
||||
File.WriteAllText(appUpdateFile, output);
|
||||
}
|
||||
if (Program.Canceled || output is null) return false;
|
||||
appInfo = VdfConvert.Deserialize(output);
|
||||
try
|
||||
{
|
||||
VToken type = appInfo?.Value?["common"]?["type"];
|
||||
if (type is null || type.ToString() == "Game")
|
||||
{
|
||||
string a = s.Substring(first + 1, Math.Max(second - first - 1, 0));
|
||||
string b = s.Substring(third + 1, Math.Max(fourth - third - 1, 0));
|
||||
if (string.IsNullOrWhiteSpace(a) || string.IsNullOrWhiteSpace(b)) continue;
|
||||
if (!appInfo.TryGetValue(a, out _)) appInfo.Add(a, b);
|
||||
string buildid = appInfo.Value["depots"]?["public"]?["buildid"]?.ToString();
|
||||
buildid = buildid ?? appInfo.Value["depots"]?["branches"]?["public"]?["buildid"]?.ToString();
|
||||
if (type is null || int.Parse(buildid) < buildId
|
||||
|| appInfo.Value["extended"] is null
|
||||
|| appInfo.Value["depots"] is null)
|
||||
{
|
||||
if (retries.TryGetValue(appId, out int count)) retries[appId] = ++count;
|
||||
else retries.Add(appId, 1);
|
||||
if (count > 3) return false;
|
||||
File.Delete(appUpdateFile);
|
||||
bool success = GetAppInfo(appId, buildId, out appInfo);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue