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>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>ini.ico</ApplicationIcon>
|
<ApplicationIcon>ini.ico</ApplicationIcon>
|
||||||
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
||||||
<Version>1.0.6.4</Version>
|
<Version>2.0.0.0</Version>
|
||||||
<PackageIcon>ini.ico</PackageIcon>
|
<PackageIcon>ini.ico</PackageIcon>
|
||||||
<PackageIconUrl />
|
<PackageIconUrl />
|
||||||
<Description>Automatically downloads and installs CreamAPI files for programs/games.</Description>
|
<Description>Automatically downloads and installs CreamAPI files for programs/games.</Description>
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
<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" />
|
<PackageReference Include="Onova" Version="2.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace CreamInstaller
|
namespace CreamInstaller
|
||||||
|
@ -47,33 +45,10 @@ namespace CreamInstaller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OperateFor(ProgramSelection selection)
|
private void OperateFor(ProgramSelection selection)
|
||||||
{
|
{
|
||||||
UpdateProgress(0);
|
UpdateProgress(0);
|
||||||
UpdateUser("Downloading CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation);
|
UpdateUser("Downloading CreamAPI files for " + selection.DisplayName + " . . . ", 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($"Downloaded archive: {Program.OutputFile}", LogColor.Resource);
|
UpdateUser($"Downloaded archive: {Program.OutputFile}", LogColor.Resource);
|
||||||
UpdateUser("Searching for CreamAPI files in downloaded archive . . . ", LogColor.Operation);
|
UpdateUser("Searching for CreamAPI files in downloaded archive . . . ", LogColor.Operation);
|
||||||
string resourcePath = null;
|
string resourcePath = null;
|
||||||
|
@ -88,7 +63,7 @@ namespace CreamInstaller
|
||||||
resourcePath = Path.GetDirectoryName(entry.FullName);
|
resourcePath = Path.GetDirectoryName(entry.FullName);
|
||||||
UpdateUser("Got CreamAPI file path: " + resourcePath, LogColor.Resource);
|
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)
|
foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries)
|
||||||
{
|
{
|
||||||
|
@ -98,7 +73,7 @@ namespace CreamInstaller
|
||||||
resources.Add(entry);
|
resources.Add(entry);
|
||||||
UpdateUser("Found CreamAPI file: " + entry.Name, LogColor.Resource);
|
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)
|
if (resources.Count < 1)
|
||||||
{
|
{
|
||||||
|
@ -108,7 +83,7 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
throw new OperationCanceledException();
|
throw new OperationCanceledException();
|
||||||
}
|
}
|
||||||
UpdateUser("Installing CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation);
|
UpdateUser("Installing CreamAPI files for " + selection.DisplayName + " . . . ", LogColor.Operation);
|
||||||
int currentFileCount = 0;
|
int currentFileCount = 0;
|
||||||
foreach (string directory in selection.SteamApiDllDirectories)
|
foreach (string directory in selection.SteamApiDllDirectories)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +130,7 @@ namespace CreamInstaller
|
||||||
throw new CustomMessageException($"Unable to overwrite Steam API file: {file}");
|
throw new CustomMessageException($"Unable to overwrite Steam API file: {file}");
|
||||||
}
|
}
|
||||||
UpdateUser("Installed file: " + file, LogColor.Resource);
|
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)
|
foreach (KeyValuePair<string, string> keyValuePair in changesToRevert)
|
||||||
{
|
{
|
||||||
|
@ -170,22 +145,15 @@ namespace CreamInstaller
|
||||||
UpdateProgress(100);
|
UpdateProgress(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Operate()
|
private void Operate()
|
||||||
{
|
{
|
||||||
OperationsCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
OperationsCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
||||||
CompleteOperationsCount = 0;
|
CompleteOperationsCount = 0;
|
||||||
|
|
||||||
foreach (ProgramSelection selection in Program.ProgramSelections.ToList())
|
foreach (ProgramSelection selection in Program.ProgramSelections.ToList())
|
||||||
{
|
{
|
||||||
if (Program.Canceled)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selection.Enabled) { continue; }
|
if (!selection.Enabled) { continue; }
|
||||||
|
|
||||||
Program.Cleanup(cancel: false, logout: false);
|
|
||||||
|
|
||||||
if (!Program.IsProgramRunningDialog(this, selection))
|
if (!Program.IsProgramRunningDialog(this, selection))
|
||||||
{
|
{
|
||||||
throw new OperationCanceledException();
|
throw new OperationCanceledException();
|
||||||
|
@ -193,27 +161,26 @@ namespace CreamInstaller
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await OperateFor(selection);
|
OperateFor(selection);
|
||||||
|
UpdateUser($"Operation succeeded for {selection.DisplayName}.", LogColor.Success);
|
||||||
UpdateUser($"Operation succeeded for {selection.ProgramName}.", LogColor.Success);
|
|
||||||
selection.Toggle(false);
|
selection.Toggle(false);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
UpdateUser($"Operation failed for {selection.ProgramName}: " + exception.ToString(), LogColor.Error);
|
UpdateUser($"Operation failed for {selection.DisplayName}: " + exception.ToString(), LogColor.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
++CompleteOperationsCount;
|
++CompleteOperationsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
|
|
||||||
List<ProgramSelection> FailedSelections = Program.ProgramSelections.FindAll(selection => selection.Enabled);
|
List<ProgramSelection> FailedSelections = Program.ProgramSelections.FindAll(selection => selection.Enabled);
|
||||||
if (FailedSelections.Any())
|
if (FailedSelections.Any())
|
||||||
{
|
{
|
||||||
if (FailedSelections.Count == 1)
|
if (FailedSelections.Count == 1)
|
||||||
{
|
{
|
||||||
throw new CustomMessageException($"Operation failed for {FailedSelections.First().ProgramName}.");
|
throw new CustomMessageException($"Operation failed for {FailedSelections.First().DisplayName}.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -224,9 +191,8 @@ namespace CreamInstaller
|
||||||
|
|
||||||
private readonly int ProgramCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
private readonly int ProgramCount = Program.ProgramSelections.FindAll(selection => selection.Enabled).Count;
|
||||||
|
|
||||||
private async void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
Program.Canceled = false;
|
|
||||||
acceptButton.Enabled = false;
|
acceptButton.Enabled = false;
|
||||||
retryButton.Enabled = false;
|
retryButton.Enabled = false;
|
||||||
cancelButton.Enabled = true;
|
cancelButton.Enabled = true;
|
||||||
|
@ -234,7 +200,7 @@ namespace CreamInstaller
|
||||||
userProgressBar.Value = userProgressBar.Minimum;
|
userProgressBar.Value = userProgressBar.Minimum;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Operate();
|
Operate();
|
||||||
UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s).", LogColor.Success);
|
UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s).", LogColor.Success);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
|
@ -257,24 +223,24 @@ namespace CreamInstaller
|
||||||
|
|
||||||
private void OnAccept(object sender, EventArgs e)
|
private void OnAccept(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRetry(object sender, EventArgs e)
|
private void OnRetry(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCancel(object sender, EventArgs e)
|
private void OnCancel(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnReselect(object sender, EventArgs e)
|
private void OnReselect(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
Reselecting = true;
|
Reselecting = true;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using CG.Web.MegaApiClient;
|
using Onova;
|
||||||
using Onova;
|
|
||||||
using Onova.Models;
|
using Onova.Models;
|
||||||
using Onova.Services;
|
using Onova.Services;
|
||||||
using System;
|
using System;
|
||||||
|
@ -94,31 +93,6 @@ namespace CreamInstaller
|
||||||
Environment.Exit(0);
|
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();
|
OnLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using CG.Web.MegaApiClient;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
@ -7,21 +6,18 @@ using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace CreamInstaller
|
namespace CreamInstaller
|
||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static string ApplicationName = "CreamInstaller v" + Application.ProductVersion + ": CreamAPI Downloader & Installer";
|
public static readonly string ApplicationName = "CreamInstaller v" + Application.ProductVersion + ": CreamAPI Downloader & Installer";
|
||||||
|
public static readonly Assembly EntryAssembly = Assembly.GetEntryAssembly();
|
||||||
public static Assembly EntryAssembly = Assembly.GetEntryAssembly();
|
public static readonly Process CurrentProcess = Process.GetCurrentProcess();
|
||||||
public static Process CurrentProcess = Process.GetCurrentProcess();
|
public static readonly string CurrentProcessFilePath = CurrentProcess.MainModule.FileName;
|
||||||
public static string CurrentProcessFilePath = CurrentProcess.MainModule.FileName;
|
public static readonly string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\"));
|
||||||
public static string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\"));
|
public static readonly string BackupFileExtension = ".creaminstaller.backup";
|
||||||
|
|
||||||
public static string BackupFileExtension = ".creaminstaller.backup";
|
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
private static void Main()
|
private static void Main()
|
||||||
|
@ -43,7 +39,7 @@ namespace CreamInstaller
|
||||||
if (selection.IsProgramRunning)
|
if (selection.IsProgramRunning)
|
||||||
{
|
{
|
||||||
if (new DialogForm(form).Show(ApplicationName, SystemIcons.Error,
|
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 . . . ",
|
"\n\nPlease close the program/game to continue . . . ",
|
||||||
"Retry", "Cancel") == DialogResult.OK)
|
"Retry", "Cancel") == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
@ -77,66 +73,15 @@ namespace CreamInstaller
|
||||||
public static List<ProgramSelection> ProgramSelections = new();
|
public static List<ProgramSelection> ProgramSelections = new();
|
||||||
|
|
||||||
public static bool Canceled = false;
|
public static bool Canceled = false;
|
||||||
public static MegaApiClient MegaApiClient;
|
public static string OutputFile = null; // placeholder, won't exist in new system
|
||||||
public static ZipArchive OutputArchive;
|
public static ZipArchive OutputArchive = null; // placeholder, won't exist in new system
|
||||||
public static CancellationTokenSource CancellationTokenSource;
|
|
||||||
public static Task OutputTask;
|
|
||||||
public static string OutputFile;
|
|
||||||
|
|
||||||
public static void Cleanup(bool cancel = true, bool logout = true)
|
public static void Cleanup(bool cancel = true)
|
||||||
{
|
{
|
||||||
Canceled = cancel;
|
Canceled = cancel;
|
||||||
if (OutputArchive != null || CancellationTokenSource != null || OutputTask != null || OutputFile != null)
|
SteamCMD.Kill();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnApplicationExit(object s, EventArgs e)
|
private static void OnApplicationExit(object s, EventArgs e) => Cleanup();
|
||||||
{
|
|
||||||
Cleanup();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
using CG.Web.MegaApiClient;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace CreamInstaller
|
namespace CreamInstaller
|
||||||
{
|
{
|
||||||
|
@ -7,10 +6,11 @@ namespace CreamInstaller
|
||||||
{
|
{
|
||||||
public bool Enabled = true;
|
public bool Enabled = true;
|
||||||
|
|
||||||
public string ProgramName;
|
public string Name;
|
||||||
public string ProgramDirectory;
|
public string DisplayName;
|
||||||
|
public string RootDirectory;
|
||||||
|
public int SteamAppId;
|
||||||
public List<string> SteamApiDllDirectories;
|
public List<string> SteamApiDllDirectories;
|
||||||
public INode DownloadNode;
|
|
||||||
|
|
||||||
public bool IsProgramRunning
|
public bool IsProgramRunning
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"MEGA": {
|
"CreamInstaller": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"nativeDebugging": false
|
"nativeDebugging": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using CG.Web.MegaApiClient;
|
using Gameloop.Vdf;
|
||||||
using Gameloop.Vdf;
|
|
||||||
using Gameloop.Vdf.Linq;
|
using Gameloop.Vdf.Linq;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
|
@ -7,6 +6,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.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
@ -27,12 +27,9 @@ namespace CreamInstaller
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
List<string> gameDirectories = new List<string>();
|
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;
|
string steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Valve\\Steam", "InstallPath", null) as string;
|
||||||
if (steamInstallPath == null)
|
if (steamInstallPath == null) steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
|
||||||
{
|
|
||||||
steamInstallPath = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Valve\\Steam", "InstallPath", null) as string;
|
|
||||||
}
|
|
||||||
if (steamInstallPath != null)
|
if (steamInstallPath != null)
|
||||||
{
|
{
|
||||||
string mainLibraryFolder = steamInstallPath + "\\steamapps\\common";
|
string mainLibraryFolder = steamInstallPath + "\\steamapps\\common";
|
||||||
|
@ -40,142 +37,129 @@ namespace CreamInstaller
|
||||||
string libraryFolders = steamInstallPath + "\\steamapps\\libraryfolders.vdf";
|
string libraryFolders = steamInstallPath + "\\steamapps\\libraryfolders.vdf";
|
||||||
VProperty property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders));
|
VProperty property = VdfConvert.Deserialize(File.ReadAllText(libraryFolders));
|
||||||
foreach (VProperty _property in property.Value)
|
foreach (VProperty _property in property.Value)
|
||||||
{
|
if (int.TryParse(_property.Key, out _) && Directory.Exists(_property.Value.ToString()))
|
||||||
if (int.TryParse(_property.Key, out _))
|
|
||||||
{
|
|
||||||
gameDirectories.Add(_property.Value.ToString());
|
gameDirectories.Add(_property.Value.ToString());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return gameDirectories;
|
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();
|
steamApiDllDirectories = new();
|
||||||
}
|
if (Program.Canceled) return false;
|
||||||
string file = gameDirectory + "\\steam_api64.dll";
|
string api = "";//gameDirectory + "\\steam_api.dll";
|
||||||
if (File.Exists(file))
|
string api64 = gameDirectory + "\\steam_api64.dll";
|
||||||
{
|
if (File.Exists(api) || File.Exists(api64)) steamApiDllDirectories.Add(gameDirectory);
|
||||||
steamApiDllDirectories.Add(gameDirectory);
|
|
||||||
}
|
|
||||||
foreach (string _directory in Directory.GetDirectories(gameDirectory))
|
foreach (string _directory in Directory.GetDirectories(gameDirectory))
|
||||||
{
|
{
|
||||||
if (Program.Canceled) { return null; }
|
if (Program.Canceled) return false;
|
||||||
GetSteamApiDllDirectoriesFromGameDirectory(_directory, steamApiDllDirectories);
|
|
||||||
}
|
|
||||||
if (!steamApiDllDirectories.Any())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return steamApiDllDirectories;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetGameDirectoryFromLibraryDirectory(string gameName, string libraryDirectory)
|
|
||||||
{
|
|
||||||
if (Program.Canceled) { return null; }
|
|
||||||
if (Path.GetFileName(libraryDirectory) == gameName)
|
|
||||||
{
|
|
||||||
return libraryDirectory;
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (string _directory in Directory.GetDirectories(libraryDirectory))
|
if (GetSteamApiDllDirectoriesFromGameDirectory(_directory, out List<string> _steamApiDllDirectories))
|
||||||
{
|
steamApiDllDirectories.AddRange(_steamApiDllDirectories);
|
||||||
if (Program.Canceled) { return null; }
|
|
||||||
string dir = GetGameDirectoryFromLibraryDirectory(gameName, _directory);
|
|
||||||
if (dir != null)
|
|
||||||
{
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return null;
|
}
|
||||||
|
if (!steamApiDllDirectories.Any()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool GetSteamAppIdFromGameDirectory(string gameDirectory, out int appId)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
if (Program.Canceled) return false;
|
||||||
|
if (GetSteamAppIdFromGameDirectory(_directory, out appId)) return true;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<CheckBox> checkBoxes = new();
|
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)
|
private void GetCreamApiApplicablePrograms(IProgress<int> progress)
|
||||||
{
|
{
|
||||||
if (Program.Canceled) { return; }
|
if (Program.Canceled) return;
|
||||||
int maxProgress = 0;
|
List<Tuple<string, string>> applicablePrograms = new();
|
||||||
IEnumerable<INode> fileNodes = Program.MegaApiClient.GetNodesFromLink(new Uri("https://mega.nz/folder/45YBwIxZ#fsZNZZu9twY2PVLgrB86fA"));
|
string launcherRootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
|
||||||
foreach (INode node in fileNodes)
|
if (Directory.Exists(launcherRootDirectory)) applicablePrograms.Add(new Tuple<string, string>("Paradox Launcher", launcherRootDirectory));
|
||||||
{
|
|
||||||
if (Program.Canceled) { return; }
|
|
||||||
if (node.Type == NodeType.Directory && node.Name != "CreamAPI" && node.Name != "Outdated")
|
|
||||||
{
|
|
||||||
++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")
|
|
||||||
{
|
|
||||||
rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Programs\\Paradox Interactive";
|
|
||||||
if (Directory.Exists(rootDirectory))
|
|
||||||
{
|
|
||||||
directories = GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (string libraryDirectory in GameLibraryDirectories)
|
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; }
|
string name = program.Item1;
|
||||||
rootDirectory = GetGameDirectoryFromLibraryDirectory(node.Name, libraryDirectory);
|
string rootDirectory = program.Item2;
|
||||||
if (Directory.Exists(rootDirectory))
|
if (Program.Canceled) return;
|
||||||
|
Task task = new Task(() =>
|
||||||
{
|
{
|
||||||
directories = GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory);
|
int steamAppId = 0;
|
||||||
break;
|
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))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 if (name != "Paradox Launcher") return;
|
||||||
if (!(directories is null))
|
|
||||||
{
|
ProgramSelection selection = new();
|
||||||
if (Program.Canceled) { return; }
|
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
|
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();
|
CheckBox checkBox = new();
|
||||||
checkBoxes.Add(checkBox);
|
checkBoxes.Add(checkBox);
|
||||||
checkBox.AutoSize = true;
|
checkBox.AutoSize = true;
|
||||||
checkBox.Parent = flowLayoutPanel1;
|
checkBox.Parent = flowLayoutPanel1;
|
||||||
checkBox.Text = node.Name;
|
checkBox.Text = selection.DisplayName;
|
||||||
checkBox.Checked = true;
|
checkBox.Checked = true;
|
||||||
checkBox.Enabled = false;
|
checkBox.Enabled = false;
|
||||||
checkBox.TabStop = true;
|
checkBox.TabStop = true;
|
||||||
|
@ -190,10 +174,20 @@ namespace CreamInstaller
|
||||||
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
tasks.Add(task);
|
||||||
|
task.Start();
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
progress.Report(maxProgress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnLoad()
|
private async void OnLoad()
|
||||||
|
@ -211,29 +205,48 @@ namespace CreamInstaller
|
||||||
progressBar1.Value = 0;
|
progressBar1.Value = 0;
|
||||||
groupBox1.Size = new Size(groupBox1.Size.Width, groupBox1.Size.Height - 44);
|
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;
|
int maxProgress = 0;
|
||||||
Progress<int> progress = new();
|
Progress<int> progress = new();
|
||||||
|
IProgress<int> iProgress = progress;
|
||||||
progress.ProgressChanged += (sender, _progress) =>
|
progress.ProgressChanged += (sender, _progress) =>
|
||||||
{
|
{
|
||||||
if (maxProgress == 0)
|
if (maxProgress == 0) maxProgress = _progress;
|
||||||
{
|
|
||||||
maxProgress = _progress;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int p = (int)((float)(_progress / (float)maxProgress) * 100);
|
int p = Math.Max(Math.Min((int)((float)(_progress / (float)maxProgress) * 100), 100), 0);
|
||||||
label2.Text = "Scanning for CreamAPI-applicable programs on your computer . . . " + p + "% (" + _progress + "/" + maxProgress + ")";
|
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;
|
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.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)
|
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();
|
checkBox.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -289,8 +302,8 @@ namespace CreamInstaller
|
||||||
checkBox.Checked = !checkBox.Checked;
|
checkBox.Checked = !checkBox.Checked;
|
||||||
checkBox.Checked = !checkBox.Checked; // to fire CheckChanged
|
checkBox.Checked = !checkBox.Checked; // to fire CheckChanged
|
||||||
}
|
}
|
||||||
int X = (installForm.Location.X + installForm.Size.Width / 2) - Size.Width / 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;
|
int Y = installForm.Location.Y + installForm.Size.Height / 2 - Size.Height / 2;
|
||||||
Location = new Point(X, Y);
|
Location = new Point(X, Y);
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
@ -308,7 +321,7 @@ namespace CreamInstaller
|
||||||
|
|
||||||
private void OnCancel(object sender, EventArgs e)
|
private void OnCancel(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Program.Cleanup(logout: false);
|
Program.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAllCheckBoxChanged(object sender, EventArgs e)
|
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