From 635982c525368fa2e9162726852948db878e12ae Mon Sep 17 00:00:00 2001 From: suchmememanyskill <38142618+suchmememanyskill@users.noreply.github.com> Date: Sun, 23 Jun 2024 00:04:44 +0200 Subject: [PATCH] Add post install script to Remote --- LauncherGamePlugin/Forms/FormValidator.cs | 52 +++++++++++++++++++ RemoteDownloaderPlugin/Game/OnlineGame.cs | 50 ++++++++++++++++-- .../Gui/AddOrEditEmuProfileGui.cs | 26 +++++++++- RemoteDownloaderPlugin/Store.cs | 4 ++ 4 files changed, 127 insertions(+), 5 deletions(-) diff --git a/LauncherGamePlugin/Forms/FormValidator.cs b/LauncherGamePlugin/Forms/FormValidator.cs index 65bc199..d99cf56 100644 --- a/LauncherGamePlugin/Forms/FormValidator.cs +++ b/LauncherGamePlugin/Forms/FormValidator.cs @@ -49,6 +49,46 @@ public void Validate(FormEntry entry) } } +public class MultiContainsValidation : IFormValidator +{ + private string[] _contians; + + public MultiContainsValidation(params string[] contains) + { + _contians = contains; + } + + public void Validate(FormEntry entry) + { + if (_contians.All(contains => !entry.Value.Contains(contains))) + throw new Exception($"{Utils.OnlyLetters(entry.Name)} does not contain one of the following: {_contians}"); + } +} + +public class WhenNotEmptyValidation : IFormValidator +{ + private IEnumerable _validators; + + public WhenNotEmptyValidation(IEnumerable validators) + { + _validators = validators; + } + + public void Validate(FormEntry entry) + { + if (string.IsNullOrWhiteSpace(entry.Value)) + { + entry.Value = string.Empty; + return; + } + + foreach (var validator in _validators) + { + validator.Validate(entry); + } + } +} + public static class FormEntryExtensions { public static FormEntry NotEmpty(this FormEntry formEntry) @@ -68,4 +108,16 @@ public static FormEntry Contains(this FormEntry formEntry, string contains) formEntry.Validators.Add(new ContainsValidation(contains)); return formEntry; } + + public static FormEntry Contains(this FormEntry formEntry, string[] contains) + { + formEntry.Validators.Add(new MultiContainsValidation(contains)); + return formEntry; + } + + public static FormEntry WhenNotEmpty(this FormEntry formEntry, params IFormValidator[] entries) + { + formEntry.Validators.Add(new WhenNotEmptyValidation(entries)); + return formEntry; + } } \ No newline at end of file diff --git a/RemoteDownloaderPlugin/Game/OnlineGame.cs b/RemoteDownloaderPlugin/Game/OnlineGame.cs index 52cb785..a39bc69 100644 --- a/RemoteDownloaderPlugin/Game/OnlineGame.cs +++ b/RemoteDownloaderPlugin/Game/OnlineGame.cs @@ -1,8 +1,10 @@ -using LauncherGamePlugin; +using System.Diagnostics; +using LauncherGamePlugin; using LauncherGamePlugin.Enums; using LauncherGamePlugin.Extensions; using LauncherGamePlugin.Forms; using LauncherGamePlugin.Interfaces; +using LauncherGamePlugin.Launcher; namespace RemoteDownloaderPlugin.Game; @@ -79,8 +81,8 @@ public async Task Download() OnUpdate?.Invoke(); return; } - - _plugin.Storage.Data.Games.Add(new() + + var installedContent = new InstalledGameContent() { Id = Game.Id, Name = Game.Name, @@ -91,9 +93,49 @@ public async Task Download() Images = Game.Images, InstalledContent = _download.InstalledEntries, BasePath = _download.BasePath - }); + }; + + var gamePath = Path.Join(installedContent.BasePath, installedContent.Filename); + var gameDir = Path.Join(installedContent.BasePath, installedContent.Id); + + _plugin.Storage.Data.Games.Add(installedContent); _plugin.Storage.Save(); + + var emuProfile = _plugin.Storage.Data.EmuProfiles.FirstOrDefault(x => x.Platform == Game.Platform); + + if (emuProfile != null && !string.IsNullOrWhiteSpace(emuProfile.PostInstallScriptPath) && + File.Exists(emuProfile.PostInstallScriptPath)) + { + var args = emuProfile.PostInstallScriptArgs; + + if (string.IsNullOrWhiteSpace(args)) + { + args = string.Empty; + } + else + { + args = args.Replace("{EXEC}", $"\"{gamePath}\"").Replace("{DIR}", $"\"{gameDir}\""); + } + + var workDir = emuProfile.PostInstallScriptWorkingDirectory; + + if (string.IsNullOrWhiteSpace(workDir) || !Directory.Exists(workDir)) + { + workDir = Path.GetDirectoryName(emuProfile.PostInstallScriptPath); + } + + _download.Line1 = "Running post install script..."; + _download.InvokeOnUpdate(); + Process process = new(); + + process.StartInfo.FileName = emuProfile.PostInstallScriptPath; + process.StartInfo.WorkingDirectory = workDir; + process.StartInfo.Arguments = args; + process.Start(); + await process.WaitForExitAsync(); + } + _plugin.App.ReloadGames(); _download = null; OnUpdate?.Invoke(); diff --git a/RemoteDownloaderPlugin/Gui/AddOrEditEmuProfileGui.cs b/RemoteDownloaderPlugin/Gui/AddOrEditEmuProfileGui.cs index 9f097f9..e47f1ca 100644 --- a/RemoteDownloaderPlugin/Gui/AddOrEditEmuProfileGui.cs +++ b/RemoteDownloaderPlugin/Gui/AddOrEditEmuProfileGui.cs @@ -11,6 +11,9 @@ public class AddOrEditEmuProfileGui private string _path; private string _args; private string _workDir; + private string _postInstallScriptPath; + private string _postInstallScriptArgs; + private string _postInstallScriptWorkDir; private readonly bool _addOrUpdate; public AddOrEditEmuProfileGui(IApp app, Plugin instance) @@ -22,6 +25,9 @@ public AddOrEditEmuProfileGui(IApp app, Plugin instance) _path = ""; _args = ""; _workDir = ""; + _postInstallScriptPath = ""; + _postInstallScriptArgs = ""; + _postInstallScriptWorkDir = ""; _addOrUpdate = false; } @@ -32,6 +38,9 @@ public AddOrEditEmuProfileGui(IApp app, Plugin instance, EmuProfile profile) _path = profile.ExecPath; _args = profile.CliArgs; _workDir = profile.WorkingDirectory; + _postInstallScriptPath = profile.PostInstallScriptPath ?? string.Empty; + _postInstallScriptArgs = profile.PostInstallScriptArgs ?? string.Empty; + _postInstallScriptWorkDir = profile.PostInstallScriptWorkingDirectory ?? string.Empty; _addOrUpdate = true; } @@ -44,6 +53,12 @@ public void ShowGui() Form.FilePicker("Executable Path:", _path).NotEmpty().Exists(), Form.TextInput("CLI Args:", _args).NotEmpty().Contains("{EXEC}"), Form.FolderPicker("Working Directory:", _workDir).NotEmpty().Exists(), + Form.Separator(), + Form.FilePicker("Post Install Script Path:", _postInstallScriptPath).WhenNotEmpty(new ExistsValidation()), + Form.TextInput("Post Install Script Args:", _postInstallScriptArgs).WhenNotEmpty(new MultiContainsValidation("{EXEC}", "{DIR}")), + Form.FolderPicker("Post Install Script Work Directory:", _postInstallScriptWorkDir).WhenNotEmpty(new ExistsValidation()), + Form.Separator(), + Form.TextBox("Supported arguments:\n- {EXEC}: Path to base game binary\n- {DIR}: Path to directory with updates/dlcs/extras"), }; if (_addOrUpdate) @@ -94,6 +109,9 @@ public void Process(Form form) _path = form.GetValue("Executable Path:"); _args = form.GetValue("CLI Args:"); _workDir = form.GetValue("Working Directory:"); + _postInstallScriptPath = form.GetValue("Post Install Script Path:"); + _postInstallScriptArgs = form.GetValue("Post Install Script Args:"); + _postInstallScriptWorkDir = form.GetValue("Post Install Script Work Directory:"); EmuProfile? existingProfile = _instance.Storage.Data.EmuProfiles.FirstOrDefault(x => x.Platform == _platform); if (existingProfile == null) @@ -103,7 +121,10 @@ public void Process(Form form) Platform = _platform, ExecPath = _path, CliArgs = _args, - WorkingDirectory = _workDir + WorkingDirectory = _workDir, + PostInstallScriptPath = _postInstallScriptPath, + PostInstallScriptArgs = _postInstallScriptArgs, + PostInstallScriptWorkingDirectory = _postInstallScriptWorkDir, }); } else @@ -111,6 +132,9 @@ public void Process(Form form) existingProfile.CliArgs = _args; existingProfile.ExecPath = _path; existingProfile.WorkingDirectory = _workDir; + existingProfile.PostInstallScriptPath = _postInstallScriptPath; + existingProfile.PostInstallScriptArgs = _postInstallScriptArgs; + existingProfile.PostInstallScriptWorkingDirectory = _postInstallScriptWorkDir; } _instance.Storage.Save(); diff --git a/RemoteDownloaderPlugin/Store.cs b/RemoteDownloaderPlugin/Store.cs index a31414e..82dae78 100644 --- a/RemoteDownloaderPlugin/Store.cs +++ b/RemoteDownloaderPlugin/Store.cs @@ -107,6 +107,10 @@ public class EmuProfile public string ExecPath { get; set; } public string WorkingDirectory { get; set; } = ""; public string CliArgs { get; set; } = ""; + + public string? PostInstallScriptPath { get; set; } + public string? PostInstallScriptArgs { get; set; } + public string? PostInstallScriptWorkingDirectory { get; set; } } public class InstalledGameContent