initial framework for v2.0
This commit is contained in:
parent
d24ba494de
commit
f5ba69f380
8 changed files with 271 additions and 296 deletions
|
@ -6,7 +6,7 @@
|
|||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>ini.ico</ApplicationIcon>
|
||||
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
||||
<Version>1.0.6.4</Version>
|
||||
<Version>2.0.0.0</Version>
|
||||
<PackageIcon>ini.ico</PackageIcon>
|
||||
<PackageIconUrl />
|
||||
<Description>Automatically downloads and installs CreamAPI files for programs/games.</Description>
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
||||
<PackageReference Include="MegaApiClient" Version="1.9.0" />
|
||||
<PackageReference Include="koskit.SteamCmdFluentApi" Version="1.0.4" />
|
||||
<PackageReference Include="Onova" Version="2.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ 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
|
||||
|
@ -47,33 +45,10 @@ namespace CreamInstaller
|
|||
}
|
||||
}
|
||||
|
||||
private async Task OperateFor(ProgramSelection selection)
|
||||
private void OperateFor(ProgramSelection selection)
|
||||
{
|
||||
UpdateProgress(0);
|
||||
UpdateUser("Downloading CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation);
|
||||
Program.OutputFile = selection.ProgramDirectory + "\\" + selection.DownloadNode.Name;
|
||||
if (File.Exists(Program.OutputFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(Program.OutputFile);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new CustomMessageException($"Unable to delete old archive file: {Program.OutputFile}");
|
||||
}
|
||||
}
|
||||
Progress<double> progress = new Progress<double>(delegate (double progress)
|
||||
{
|
||||
if (!Program.Canceled)
|
||||
{
|
||||
UpdateUser($"Downloading CreamAPI files for {selection.ProgramName} . . . {(int)progress}%", LogColor.Operation, log: false);
|
||||
UpdateProgress((int)progress);
|
||||
}
|
||||
});
|
||||
Program.CancellationTokenSource = new CancellationTokenSource();
|
||||
Program.OutputTask = Program.MegaApiClient.DownloadFileAsync(selection.DownloadNode, Program.OutputFile, progress, Program.CancellationTokenSource.Token);
|
||||
await Program.OutputTask;
|
||||
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;
|
||||
|
@ -88,7 +63,7 @@ namespace CreamInstaller
|
|||
resourcePath = Path.GetDirectoryName(entry.FullName);
|
||||
UpdateUser("Got CreamAPI file path: " + resourcePath, LogColor.Resource);
|
||||
}
|
||||
UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100);
|
||||
UpdateProgress(currentEntryCount / (Program.OutputArchive.Entries.Count * 2) * 100);
|
||||
}
|
||||
foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries)
|
||||
{
|
||||
|
@ -98,7 +73,7 @@ namespace CreamInstaller
|
|||
resources.Add(entry);
|
||||
UpdateUser("Found CreamAPI file: " + entry.Name, LogColor.Resource);
|
||||
}
|
||||
UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100);
|
||||
UpdateProgress(currentEntryCount / (Program.OutputArchive.Entries.Count * 2) * 100);
|
||||
}
|
||||
if (resources.Count < 1)
|
||||
{
|
||||
|
@ -108,7 +83,7 @@ namespace CreamInstaller
|
|||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
UpdateUser("Installing CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation);
|
||||
UpdateUser("Installing CreamAPI files for " + selection.DisplayName + " . . . ", LogColor.Operation);
|
||||
int currentFileCount = 0;
|
||||
foreach (string directory in selection.SteamApiDllDirectories)
|
||||
{
|
||||
|
@ -155,7 +130,7 @@ namespace CreamInstaller
|
|||
throw new CustomMessageException($"Unable to overwrite Steam API file: {file}");
|
||||
}
|
||||
UpdateUser("Installed file: " + file, LogColor.Resource);
|
||||
UpdateProgress((currentFileCount / (resources.Count * selection.SteamApiDllDirectories.Count)) * 100);
|
||||
UpdateProgress(currentFileCount / (resources.Count * selection.SteamApiDllDirectories.Count) * 100);
|
||||
}
|
||||
foreach (KeyValuePair<string, string> keyValuePair in changesToRevert)
|
||||
{
|
||||
|
@ -170,22 +145,15 @@ namespace CreamInstaller
|
|||
UpdateProgress(100);
|
||||
}
|
||||
|
||||
private async Task Operate()
|
||||
private void Operate()
|
||||
{
|
||||
OperationsCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
||||
CompleteOperationsCount = 0;
|
||||
|
||||
foreach (ProgramSelection selection in Program.ProgramSelections.ToList())
|
||||
{
|
||||
if (Program.Canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!selection.Enabled) { continue; }
|
||||
|
||||
Program.Cleanup(cancel: false, logout: false);
|
||||
|
||||
if (!Program.IsProgramRunningDialog(this, selection))
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
|
@ -193,27 +161,26 @@ namespace CreamInstaller
|
|||
|
||||
try
|
||||
{
|
||||
await OperateFor(selection);
|
||||
|
||||
UpdateUser($"Operation succeeded for {selection.ProgramName}.", LogColor.Success);
|
||||
OperateFor(selection);
|
||||
UpdateUser($"Operation succeeded for {selection.DisplayName}.", LogColor.Success);
|
||||
selection.Toggle(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
UpdateUser($"Operation failed for {selection.ProgramName}: " + exception.ToString(), LogColor.Error);
|
||||
UpdateUser($"Operation failed for {selection.DisplayName}: " + exception.ToString(), LogColor.Error);
|
||||
}
|
||||
|
||||
++CompleteOperationsCount;
|
||||
}
|
||||
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
|
||||
List<ProgramSelection> FailedSelections = Program.ProgramSelections.FindAll(selection => selection.Enabled);
|
||||
if (FailedSelections.Any())
|
||||
{
|
||||
if (FailedSelections.Count == 1)
|
||||
{
|
||||
throw new CustomMessageException($"Operation failed for {FailedSelections.First().ProgramName}.");
|
||||
throw new CustomMessageException($"Operation failed for {FailedSelections.First().DisplayName}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -224,9 +191,8 @@ namespace CreamInstaller
|
|||
|
||||
private readonly int ProgramCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
||||
|
||||
private async void Start()
|
||||
private void Start()
|
||||
{
|
||||
Program.Canceled = false;
|
||||
acceptButton.Enabled = false;
|
||||
retryButton.Enabled = false;
|
||||
cancelButton.Enabled = true;
|
||||
|
@ -234,7 +200,7 @@ namespace CreamInstaller
|
|||
userProgressBar.Value = userProgressBar.Minimum;
|
||||
try
|
||||
{
|
||||
await Operate();
|
||||
Operate();
|
||||
UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s).", LogColor.Success);
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
@ -257,24 +223,24 @@ namespace CreamInstaller
|
|||
|
||||
private void OnAccept(object sender, EventArgs e)
|
||||
{
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnRetry(object sender, EventArgs e)
|
||||
{
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
Start();
|
||||
}
|
||||
|
||||
private void OnCancel(object sender, EventArgs e)
|
||||
{
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
}
|
||||
|
||||
private void OnReselect(object sender, EventArgs e)
|
||||
{
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
Reselecting = true;
|
||||
Close();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using CG.Web.MegaApiClient;
|
||||
using Onova;
|
||||
using Onova;
|
||||
using Onova.Models;
|
||||
using Onova.Services;
|
||||
using System;
|
||||
|
@ -94,31 +93,6 @@ namespace CreamInstaller
|
|||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
Program.MegaApiClient = new MegaApiClient();
|
||||
void Login()
|
||||
{
|
||||
try
|
||||
{
|
||||
Program.MegaApiClient.Login();
|
||||
}
|
||||
catch (ApiException)
|
||||
{
|
||||
if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Error,
|
||||
$"ERROR: Failed logging into MEGA!" +
|
||||
"\n\nMEGA is likely offline, please try again later . . .",
|
||||
"Retry", "Cancel") == DialogResult.OK)
|
||||
{
|
||||
Login();
|
||||
}
|
||||
else
|
||||
{
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Login();
|
||||
|
||||
OnLoad();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using CG.Web.MegaApiClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
@ -7,21 +6,18 @@ using System.IO;
|
|||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CreamInstaller
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static string ApplicationName = "CreamInstaller v" + Application.ProductVersion + ": CreamAPI Downloader & Installer";
|
||||
|
||||
public static Assembly EntryAssembly = Assembly.GetEntryAssembly();
|
||||
public static Process CurrentProcess = Process.GetCurrentProcess();
|
||||
public static string CurrentProcessFilePath = CurrentProcess.MainModule.FileName;
|
||||
public static string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\"));
|
||||
|
||||
public static string BackupFileExtension = ".creaminstaller.backup";
|
||||
public static readonly string ApplicationName = "CreamInstaller v" + Application.ProductVersion + ": CreamAPI Downloader & Installer";
|
||||
public static readonly Assembly EntryAssembly = Assembly.GetEntryAssembly();
|
||||
public static readonly Process CurrentProcess = Process.GetCurrentProcess();
|
||||
public static readonly string CurrentProcessFilePath = CurrentProcess.MainModule.FileName;
|
||||
public static readonly string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\"));
|
||||
public static readonly string BackupFileExtension = ".creaminstaller.backup";
|
||||
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
|
@ -43,7 +39,7 @@ namespace CreamInstaller
|
|||
if (selection.IsProgramRunning)
|
||||
{
|
||||
if (new DialogForm(form).Show(ApplicationName, SystemIcons.Error,
|
||||
$"ERROR: {selection.ProgramName} is currently running!" +
|
||||
$"ERROR: {selection.DisplayName} is currently running!" +
|
||||
"\n\nPlease close the program/game to continue . . . ",
|
||||
"Retry", "Cancel") == DialogResult.OK)
|
||||
{
|
||||
|
@ -77,66 +73,15 @@ namespace CreamInstaller
|
|||
public static List<ProgramSelection> ProgramSelections = new();
|
||||
|
||||
public static bool Canceled = false;
|
||||
public static MegaApiClient MegaApiClient;
|
||||
public static ZipArchive OutputArchive;
|
||||
public static CancellationTokenSource CancellationTokenSource;
|
||||
public static Task OutputTask;
|
||||
public static string OutputFile;
|
||||
public static string OutputFile = null; // placeholder, won't exist in new system
|
||||
public static ZipArchive OutputArchive = null; // placeholder, won't exist in new system
|
||||
|
||||
public static void Cleanup(bool cancel = true, bool logout = true)
|
||||
public static void Cleanup(bool cancel = true)
|
||||
{
|
||||
Canceled = cancel;
|
||||
if (OutputArchive != null || CancellationTokenSource != null || OutputTask != null || OutputFile != null)
|
||||
{
|
||||
InstallForm?.UpdateUser("Cleaning up . . . ", LogColor.Cleanup);
|
||||
}
|
||||
if (OutputArchive != null)
|
||||
{
|
||||
OutputArchive.Dispose();
|
||||
OutputArchive = null;
|
||||
}
|
||||
if (CancellationTokenSource != null)
|
||||
{
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
if (OutputTask != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
OutputTask.Wait();
|
||||
}
|
||||
catch (AggregateException) { }
|
||||
OutputTask.Dispose();
|
||||
OutputTask = null;
|
||||
}
|
||||
if (CancellationTokenSource != null)
|
||||
{
|
||||
CancellationTokenSource.Dispose();
|
||||
CancellationTokenSource = null;
|
||||
}
|
||||
if (OutputFile != null && File.Exists(OutputFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(OutputFile);
|
||||
InstallForm?.UpdateUser($"Deleted archive: {OutputFile}", LogColor.Cleanup);
|
||||
}
|
||||
catch
|
||||
{
|
||||
InstallForm?.UpdateUser($"WARNING: Failed to clean up archive: {OutputFile}", LogColor.Warning);
|
||||
}
|
||||
OutputFile = null;
|
||||
}
|
||||
if (logout && MegaApiClient != null && MegaApiClient.IsLoggedIn)
|
||||
{
|
||||
InstallForm?.UpdateUser("Logging out of MEGA . . . ", LogColor.Cleanup);
|
||||
MegaApiClient.Logout();
|
||||
}
|
||||
SteamCMD.Kill();
|
||||
}
|
||||
|
||||
private static void OnApplicationExit(object s, EventArgs e)
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
private static void OnApplicationExit(object s, EventArgs e) => Cleanup();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using CG.Web.MegaApiClient;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CreamInstaller
|
||||
{
|
||||
|
@ -7,10 +6,11 @@ namespace CreamInstaller
|
|||
{
|
||||
public bool Enabled = true;
|
||||
|
||||
public string ProgramName;
|
||||
public string ProgramDirectory;
|
||||
public string Name;
|
||||
public string DisplayName;
|
||||
public string RootDirectory;
|
||||
public int SteamAppId;
|
||||
public List<string> SteamApiDllDirectories;
|
||||
public INode DownloadNode;
|
||||
|
||||
public bool IsProgramRunning
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"profiles": {
|
||||
"MEGA": {
|
||||
"CreamInstaller": {
|
||||
"commandName": "Project",
|
||||
"nativeDebugging": false
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using CG.Web.MegaApiClient;
|
||||
using Gameloop.Vdf;
|
||||
using Gameloop.Vdf;
|
||||
using Gameloop.Vdf.Linq;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
|
@ -7,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
@ -27,12 +27,9 @@ namespace CreamInstaller
|
|||
get
|
||||
{
|
||||
List<string> gameDirectories = new List<string>();
|
||||
if (Program.Canceled) { return gameDirectories; }
|
||||
if (Program.Canceled) return gameDirectories;
|
||||
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)
|
||||
{
|
||||
string mainLibraryFolder = steamInstallPath + "\\steamapps\\common";
|
||||
|
@ -40,160 +37,157 @@ namespace CreamInstaller
|
|||
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 _))
|
||||
{
|
||||
if (int.TryParse(_property.Key, out _) && Directory.Exists(_property.Value.ToString()))
|
||||
gameDirectories.Add(_property.Value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return gameDirectories;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetSteamApiDllDirectoriesFromGameDirectory(string gameDirectory, List<string> steamApiDllDirectories = null)
|
||||
private bool GetSteamApiDllDirectoriesFromGameDirectory(string gameDirectory, out List<string> steamApiDllDirectories)
|
||||
{
|
||||
if (Program.Canceled) { return null; }
|
||||
if (steamApiDllDirectories is null)
|
||||
{
|
||||
steamApiDllDirectories = new();
|
||||
}
|
||||
string file = gameDirectory + "\\steam_api64.dll";
|
||||
if (File.Exists(file))
|
||||
{
|
||||
steamApiDllDirectories.Add(gameDirectory);
|
||||
}
|
||||
steamApiDllDirectories = 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);
|
||||
foreach (string _directory in Directory.GetDirectories(gameDirectory))
|
||||
{
|
||||
if (Program.Canceled) { return null; }
|
||||
GetSteamApiDllDirectoriesFromGameDirectory(_directory, steamApiDllDirectories);
|
||||
if (Program.Canceled) return false;
|
||||
try
|
||||
{
|
||||
if (GetSteamApiDllDirectoriesFromGameDirectory(_directory, out List<string> _steamApiDllDirectories))
|
||||
steamApiDllDirectories.AddRange(_steamApiDllDirectories);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
if (!steamApiDllDirectories.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return steamApiDllDirectories;
|
||||
if (!steamApiDllDirectories.Any()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GetGameDirectoryFromLibraryDirectory(string gameName, string libraryDirectory)
|
||||
private bool GetSteamAppIdFromGameDirectory(string gameDirectory, out int appId)
|
||||
{
|
||||
if (Program.Canceled) { return null; }
|
||||
if (Path.GetFileName(libraryDirectory) == gameName)
|
||||
appId = 0;
|
||||
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))
|
||||
{
|
||||
return libraryDirectory;
|
||||
if (Program.Canceled) return false;
|
||||
if (GetSteamAppIdFromGameDirectory(_directory, out appId)) return true;
|
||||
}
|
||||
try
|
||||
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))
|
||||
{
|
||||
foreach (string _directory in Directory.GetDirectories(libraryDirectory))
|
||||
{
|
||||
if (Program.Canceled) { return null; }
|
||||
string dir = GetGameDirectoryFromLibraryDirectory(gameName, _directory);
|
||||
if (dir != null)
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
if (Program.Canceled) return false;
|
||||
if (Directory.Exists(_directory)) gameDirectories.Add(_directory);
|
||||
}
|
||||
catch { }
|
||||
return null;
|
||||
if (!gameDirectories.Any()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly List<CheckBox> checkBoxes = new();
|
||||
|
||||
private readonly Dictionary<int, string> dlc = new();
|
||||
|
||||
[DllImport("kernel32")]
|
||||
private static extern bool AllocConsole();
|
||||
|
||||
private void GetCreamApiApplicablePrograms(IProgress<int> progress)
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
int maxProgress = 0;
|
||||
IEnumerable<INode> fileNodes = Program.MegaApiClient.GetNodesFromLink(new Uri("https://mega.nz/folder/45YBwIxZ#fsZNZZu9twY2PVLgrB86fA"));
|
||||
foreach (INode node in fileNodes)
|
||||
if (Program.Canceled) return;
|
||||
List<Tuple<string, 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));
|
||||
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));
|
||||
List<Task> tasks = new();
|
||||
foreach (Tuple<string, string> program in applicablePrograms)
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
if (node.Type == NodeType.Directory && node.Name != "CreamAPI" && node.Name != "Outdated")
|
||||
string name = program.Item1;
|
||||
string rootDirectory = program.Item2;
|
||||
if (Program.Canceled) return;
|
||||
Task task = new Task(() =>
|
||||
{
|
||||
++maxProgress;
|
||||
}
|
||||
}
|
||||
progress.Report(maxProgress);
|
||||
int curProgress = 0;
|
||||
progress.Report(curProgress);
|
||||
foreach (INode node in fileNodes)
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
if (node.Type == NodeType.Directory && node.Name != "CreamAPI" && node.Name != "Outdated")
|
||||
{
|
||||
progress.Report(++curProgress);
|
||||
if (Program.ProgramSelections.Any(selection => selection.ProgramName == node.Name)) { continue; }
|
||||
string rootDirectory = null;
|
||||
List<string> directories = null;
|
||||
if (node.Name == "Paradox Launcher")
|
||||
int steamAppId = 0;
|
||||
if (Program.Canceled || Program.ProgramSelections.Any(s => s.Name == name)
|
||||
|| (name != "Paradox Launcher" && !GetSteamAppIdFromGameDirectory(rootDirectory, out steamAppId))
|
||||
|| !GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory, out List<string> steamApiDllDirectories))
|
||||
return;
|
||||
|
||||
Dictionary<string, string> appInfo = null;
|
||||
if (Program.Canceled || (name != "Paradox Launcher" && !SteamCMD.GetAppInfo(steamAppId, out appInfo))) return;
|
||||
string list = null;
|
||||
if (!(appInfo is null) && appInfo.TryGetValue("listofdlc", out list))
|
||||
{
|
||||
rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
|
||||
if (Directory.Exists(rootDirectory))
|
||||
if (Program.Canceled) return;
|
||||
string[] nums = list.Split(",");
|
||||
List<int> ids = new();
|
||||
foreach (string s in nums) ids.Add(int.Parse(s));
|
||||
foreach (int id in ids)
|
||||
{
|
||||
directories = GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory);
|
||||
if (Program.Canceled) return;
|
||||
string dlcName = null;
|
||||
Dictionary<string, string> dlcAppInfo = null;
|
||||
//if (SteamCMD.GetAppInfo(id, out dlcAppInfo)) dlcAppInfo.TryGetValue("name", out dlcName);
|
||||
dlc.Add(id, dlcName);
|
||||
Console.WriteLine(id + " = " + dlcName);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (name != "Paradox Launcher") return;
|
||||
|
||||
ProgramSelection selection = new();
|
||||
selection.Name = name;
|
||||
string displayName = name;
|
||||
if (!(appInfo is null)) appInfo.TryGetValue("name", out displayName);
|
||||
selection.DisplayName = displayName;
|
||||
selection.RootDirectory = rootDirectory;
|
||||
selection.SteamAppId = steamAppId;
|
||||
selection.SteamApiDllDirectories = steamApiDllDirectories;
|
||||
|
||||
flowLayoutPanel1.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
foreach (string libraryDirectory in GameLibraryDirectories)
|
||||
CheckBox checkBox = new();
|
||||
checkBoxes.Add(checkBox);
|
||||
checkBox.AutoSize = true;
|
||||
checkBox.Parent = flowLayoutPanel1;
|
||||
checkBox.Text = selection.DisplayName;
|
||||
checkBox.Checked = true;
|
||||
checkBox.Enabled = false;
|
||||
checkBox.TabStop = true;
|
||||
checkBox.TabIndex = 1 + checkBoxes.Count;
|
||||
|
||||
checkBox.CheckedChanged += (sender, e) =>
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
rootDirectory = GetGameDirectoryFromLibraryDirectory(node.Name, libraryDirectory);
|
||||
if (Directory.Exists(rootDirectory))
|
||||
{
|
||||
directories = GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(directories is null))
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
flowLayoutPanel1.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
if (Program.Canceled) { return; }
|
||||
|
||||
INode downloadNode = null;
|
||||
foreach (INode _node in fileNodes)
|
||||
{
|
||||
if (_node.Type == NodeType.File && _node.ParentId == node.Id)
|
||||
{
|
||||
downloadNode = _node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadNode is null) return;
|
||||
ProgramSelection selection = new();
|
||||
selection.DownloadNode = downloadNode;
|
||||
selection.ProgramName = node.Name;
|
||||
selection.ProgramDirectory = rootDirectory;
|
||||
selection.SteamApiDllDirectories = new();
|
||||
selection.SteamApiDllDirectories.AddRange(directories);
|
||||
|
||||
CheckBox checkBox = new();
|
||||
checkBoxes.Add(checkBox);
|
||||
checkBox.AutoSize = true;
|
||||
checkBox.Parent = flowLayoutPanel1;
|
||||
checkBox.Text = node.Name;
|
||||
checkBox.Checked = true;
|
||||
checkBox.Enabled = false;
|
||||
checkBox.TabStop = true;
|
||||
checkBox.TabIndex = 1 + checkBoxes.Count;
|
||||
|
||||
checkBox.CheckedChanged += (sender, e) =>
|
||||
{
|
||||
selection.Toggle(checkBox.Checked);
|
||||
acceptButton.Enabled = Program.ProgramSelections.Any(selection => selection.Enabled);
|
||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||
allCheckBox.Checked = checkBoxes.TrueForAll(checkBox => checkBox.Checked);
|
||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
selection.Toggle(checkBox.Checked);
|
||||
acceptButton.Enabled = Program.ProgramSelections.Any(selection => selection.Enabled);
|
||||
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
|
||||
allCheckBox.Checked = checkBoxes.TrueForAll(checkBox => checkBox.Checked);
|
||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||
};
|
||||
});
|
||||
});
|
||||
tasks.Add(task);
|
||||
task.Start();
|
||||
}
|
||||
progress.Report(maxProgress);
|
||||
int max = tasks.Count;
|
||||
progress.Report(max);
|
||||
int cur = 0;
|
||||
progress.Report(cur);
|
||||
foreach (Task task in tasks)
|
||||
{
|
||||
progress.Report(cur++);
|
||||
task.Wait();
|
||||
}
|
||||
progress.Report(max);
|
||||
}
|
||||
|
||||
private async void OnLoad()
|
||||
|
@ -211,29 +205,48 @@ namespace CreamInstaller
|
|||
progressBar1.Value = 0;
|
||||
groupBox1.Size = new Size(groupBox1.Size.Width, groupBox1.Size.Height - 44);
|
||||
|
||||
label2.Text = "Scanning for CreamAPI-applicable programs on your computer . . . ";
|
||||
AllocConsole();
|
||||
|
||||
bool setup = true;
|
||||
int maxProgress = 0;
|
||||
Progress<int> progress = new();
|
||||
IProgress<int> iProgress = progress;
|
||||
progress.ProgressChanged += (sender, _progress) =>
|
||||
{
|
||||
if (maxProgress == 0)
|
||||
{
|
||||
maxProgress = _progress;
|
||||
}
|
||||
if (maxProgress == 0) maxProgress = _progress;
|
||||
else
|
||||
{
|
||||
int p = (int)((float)(_progress / (float)maxProgress) * 100);
|
||||
label2.Text = "Scanning for CreamAPI-applicable programs on your computer . . . " + p + "% (" + _progress + "/" + maxProgress + ")";
|
||||
int p = Math.Max(Math.Min((int)((float)(_progress / (float)maxProgress) * 100), 100), 0);
|
||||
if (setup) label2.Text = "Setting up SteamCMD . . . " + p + "% (" + _progress + "/" + maxProgress + ")";
|
||||
else label2.Text = "Scanning for CreamAPI-applicable programs on your computer . . . " + p + "% (" + _progress + "/" + maxProgress + ")";
|
||||
progressBar1.Value = p;
|
||||
}
|
||||
};
|
||||
await Task.Run(() => GetCreamApiApplicablePrograms(progress));
|
||||
|
||||
int max = 1660; // not exact, number varies
|
||||
iProgress.Report(max);
|
||||
int cur = 0;
|
||||
iProgress.Report(cur);
|
||||
label2.Text = "Setting up SteamCMD . . . ";
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(SteamCMD.DirectoryPath);
|
||||
watcher.Changed += (sender, e) => iProgress.Report(++cur);
|
||||
watcher.Filter = "*";
|
||||
watcher.IncludeSubdirectories = true;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
await Task.Run(() => SteamCMD.Setup());
|
||||
watcher.Dispose();
|
||||
Clipboard.SetText(cur.ToString());
|
||||
|
||||
maxProgress = 0;
|
||||
setup = false;
|
||||
label2.Text = "Scanning for CreamAPI-applicable programs on your computer . . . ";
|
||||
await Task.Run(() => GetCreamApiApplicablePrograms(iProgress));
|
||||
|
||||
Program.ProgramSelections.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory)));
|
||||
Program.ProgramSelections.RemoveAll(selection => !Directory.Exists(selection.ProgramDirectory) || !selection.SteamApiDllDirectories.Any());
|
||||
Program.ProgramSelections.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
|
||||
foreach (CheckBox checkBox in checkBoxes)
|
||||
{
|
||||
if (!Program.ProgramSelections.Any(selection => selection.ProgramName == checkBox.Text))
|
||||
if (!Program.ProgramSelections.Any(selection => selection.DisplayName == checkBox.Text))
|
||||
{
|
||||
checkBox.Dispose();
|
||||
}
|
||||
|
@ -289,8 +302,8 @@ namespace CreamInstaller
|
|||
checkBox.Checked = !checkBox.Checked;
|
||||
checkBox.Checked = !checkBox.Checked; // to fire CheckChanged
|
||||
}
|
||||
int X = (installForm.Location.X + installForm.Size.Width / 2) - Size.Width / 2;
|
||||
int Y = (installForm.Location.Y + installForm.Size.Height / 2) - Size.Height / 2;
|
||||
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);
|
||||
Show();
|
||||
}
|
||||
|
@ -308,7 +321,7 @@ namespace CreamInstaller
|
|||
|
||||
private void OnCancel(object sender, EventArgs e)
|
||||
{
|
||||
Program.Cleanup(logout: false);
|
||||
Program.Cleanup();
|
||||
}
|
||||
|
||||
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
||||
|
|
77
CreamInstaller/SteamCMD.cs
Normal file
77
CreamInstaller/SteamCMD.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
using SteamCmdFluentApi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
|
||||
namespace CreamInstaller
|
||||
{
|
||||
public static class SteamCMD
|
||||
{
|
||||
public static string DirectoryPath = Path.GetTempPath() + "CreamInstaller";
|
||||
public static string FilePath = DirectoryPath + "\\steamcmd.exe";
|
||||
public static string ArchivePath = DirectoryPath + "\\steamcmd.zip";
|
||||
public static string DllPath = DirectoryPath + "\\steamclient.dll";
|
||||
|
||||
private static SteamCmd current = null;
|
||||
|
||||
public static SteamCmd Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (current is null) current = SteamCmd.WithExecutable(FilePath);
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Setup()
|
||||
{
|
||||
Kill();
|
||||
if (!Directory.Exists(DirectoryPath)) Directory.CreateDirectory(DirectoryPath);
|
||||
if (!File.Exists(FilePath))
|
||||
{
|
||||
using (WebClient webClient = new WebClient()) webClient.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", ArchivePath);
|
||||
ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath);
|
||||
File.Delete(ArchivePath);
|
||||
}
|
||||
if (!File.Exists(DllPath)) Current.TryToExecuteCommand($@"+login anonymous +app_info_update 1 +quit", out _);
|
||||
}
|
||||
|
||||
public static bool GetAppInfo(int steamAppId, out Dictionary<string, string> appInfo)
|
||||
{
|
||||
appInfo = new();
|
||||
if (Program.Canceled) return false;
|
||||
// need to find a way to request app info, currently it won't work from the command line like below
|
||||
bool success = Current.TryToExecuteCommand($@"+login anonymous +app_info_update 1 +app_info_request {steamAppId} +app_info_print {steamAppId} +quit", out string output);
|
||||
if (!success) return false;
|
||||
foreach (string s in output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Kill()
|
||||
{
|
||||
foreach (Process process in Process.GetProcessesByName("steamcmd")) { process.Kill(); process.WaitForExit(); }
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
Kill();
|
||||
if (Directory.Exists(DirectoryPath)) Directory.Delete(DirectoryPath, true);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue