From c25bf3bb3d092af40a14376e9a2b8658f64f442d Mon Sep 17 00:00:00 2001 From: pas2704 Date: Sat, 9 Nov 2024 18:23:40 -0500 Subject: [PATCH] Implement Migration of PluginLoader configs (UI is temporary atm) Add profiles to Config Error handling for package resolution Remove debug code from wndproc hook --- CringeLauncher/ImGuiHandler.cs | 6 +- CringeLauncher/Launcher.cs | 2 +- CringeLauncher/Patches/RenderHookPatch.cs | 2 +- .../Compatability/PluginLoaderConfig.cs | 70 +++++++++++++++++++ .../Compatability/PluginLoaderProfile.cs | 12 ++++ CringePlugins/Config/PackagesConfig.cs | 4 +- CringePlugins/Loader/PluginsLifetime.cs | 4 +- CringePlugins/Resolver/PackageResolver.cs | 14 +++- CringePlugins/Ui/PluginListComponent.cs | 28 ++++++-- 9 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 CringePlugins/Compatability/PluginLoaderConfig.cs create mode 100644 CringePlugins/Compatability/PluginLoaderProfile.cs diff --git a/CringeLauncher/ImGuiHandler.cs b/CringeLauncher/ImGuiHandler.cs index a400cdb..9590dcf 100644 --- a/CringeLauncher/ImGuiHandler.cs +++ b/CringeLauncher/ImGuiHandler.cs @@ -45,7 +45,7 @@ internal class ImGuiHandler : IDisposable _init = true; } - public void HookWindow(HWND windowHandle) + public static void HookWindow(HWND windowHandle) { _wndproc = PInvoke.GetWindowLongPtr(windowHandle, WINDOW_LONG_PTR_INDEX.GWL_WNDPROC); @@ -96,8 +96,8 @@ internal class ImGuiHandler : IDisposable var blockMessage = (msg is >= 256 and <= 265 && io.WantTextInput) || (msg is >= 512 and <= 526 && io.WantCaptureMouse); - if (!blockMessage) - Console.WriteLine($"{msg} - M:{io.WantCaptureMouse}, K:{io.WantTextInput}"); + /*if (!blockMessage) + Console.WriteLine($"{msg} - M:{io.WantCaptureMouse}, K:{io.WantTextInput}");*/ return blockMessage ? hookResult : CallWindowProc(_wndproc, hWnd, msg, wParam, lParam); } diff --git a/CringeLauncher/Launcher.cs b/CringeLauncher/Launcher.cs index 5710331..27b78ba 100644 --- a/CringeLauncher/Launcher.cs +++ b/CringeLauncher/Launcher.cs @@ -73,7 +73,7 @@ public class Launcher : ICorePlugin var splash = new Splash(); - splash.DefineStage(_lifetime = new PluginsLifetime()); + splash.DefineStage(_lifetime = new PluginsLifetime(Path.GetDirectoryName(args[0])!)); InitTexts(); SpaceEngineersGame.SetupBasicGameInfo(); diff --git a/CringeLauncher/Patches/RenderHookPatch.cs b/CringeLauncher/Patches/RenderHookPatch.cs index 42e5d1b..db33386 100644 --- a/CringeLauncher/Patches/RenderHookPatch.cs +++ b/CringeLauncher/Patches/RenderHookPatch.cs @@ -19,6 +19,6 @@ public class RenderHookPatch [HarmonyPostfix, HarmonyPatch(typeof(MyGameForm), "OnLoad")] private static void LoadPostfix(MyGameForm __instance) { - ImGuiHandler.Instance?.HookWindow((HWND)__instance.Handle); + ImGuiHandler.HookWindow((HWND)__instance.Handle); } } \ No newline at end of file diff --git a/CringePlugins/Compatability/PluginLoaderConfig.cs b/CringePlugins/Compatability/PluginLoaderConfig.cs new file mode 100644 index 0000000..c65f373 --- /dev/null +++ b/CringePlugins/Compatability/PluginLoaderConfig.cs @@ -0,0 +1,70 @@ +using CringePlugins.Config; +using CringePlugins.Resolver; +using NuGet.Versioning; +using System.Collections.Immutable; +using System.Xml.Serialization; + +namespace CringePlugins.Compatability; + +[XmlType("PluginConfig")] +public class PluginLoaderConfig +{ + [XmlArrayItem("Id")] + public string[] Plugins { get; set; } = []; + + [XmlArrayItem("Profile")] + public PluginLoaderProfile[] Profiles { get; set; } = []; + + public PackagesConfig Migrate(PackagesConfig old) + { + var pluginsBuilder = ImmutableArray.CreateBuilder(); + var defaultVersion = new NuGetVersion(1, 0, 0); + foreach (var plugin in Plugins) + { + if (!IsValidId(plugin)) + continue; + + pluginsBuilder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}", + new(defaultVersion))); + } + + var profiles = new Dictionary>(); + foreach (var profile in Profiles) + { + var builder = ImmutableArray.CreateBuilder(); + foreach (var plugin in profile.Plugins) + { + if (!IsValidId(plugin)) + continue; + + builder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}", + new(defaultVersion))); + } + + profiles[profile.Name] = builder.ToImmutable(); + } + + return old with + { + Packages = pluginsBuilder.ToImmutableArray(), + Profiles = profiles + }; + } + + private static bool IsValidId(string pluginId) + { + var count = 0; + foreach (var c in pluginId) + { + if (c != '/') + continue; + + count++; + + if (count > 1) + return false; + } + + return count == 1; + } +} diff --git a/CringePlugins/Compatability/PluginLoaderProfile.cs b/CringePlugins/Compatability/PluginLoaderProfile.cs new file mode 100644 index 0000000..1d37fa9 --- /dev/null +++ b/CringePlugins/Compatability/PluginLoaderProfile.cs @@ -0,0 +1,12 @@ +using System.Xml.Serialization; + +namespace CringePlugins.Compatability; + +//https://github.com/sepluginloader/PluginLoader/blob/main/PluginLoader/Profile.cs +[XmlType("Profile")] +public class PluginLoaderProfile +{ + public string Key { get; set; } = ""; + public string Name { get; set; } = ""; + public string[] Plugins { get; set; } = []; +} diff --git a/CringePlugins/Config/PackagesConfig.cs b/CringePlugins/Config/PackagesConfig.cs index 8993649..0488aa5 100644 --- a/CringePlugins/Config/PackagesConfig.cs +++ b/CringePlugins/Config/PackagesConfig.cs @@ -5,10 +5,10 @@ using NuGet.Models; namespace CringePlugins.Config; -public record PackagesConfig(ImmutableArray Sources, ImmutableArray Packages) +public record PackagesConfig(ImmutableArray Sources, ImmutableArray Packages, Dictionary> Profiles) { public static PackagesConfig Default { get; } = new([ new("zznty", @"^SpaceEngineersDedicated\.ReferenceAssemblies$|^ImGui\.NET\.DirectX$|^NuGet$|^Cringe.+$|^SharedCringe$|^Plugin.+$", "https://ng.zznty.ru/v3/index.json"), new("nuget.org", string.Empty, "https://api.nuget.org/v3/index.json") - ], []); + ], [], []); //todo: default profile with recommended plugins? } \ No newline at end of file diff --git a/CringePlugins/Loader/PluginsLifetime.cs b/CringePlugins/Loader/PluginsLifetime.cs index 20b2fd6..cba0316 100644 --- a/CringePlugins/Loader/PluginsLifetime.cs +++ b/CringePlugins/Loader/PluginsLifetime.cs @@ -15,7 +15,7 @@ using SharedCringe.Loader; namespace CringePlugins.Loader; -public class PluginsLifetime : ILoadingStage +public class PluginsLifetime(string gameFolder) : ILoadingStage { public static ImmutableArray Contexts { get; private set; } = []; @@ -65,7 +65,7 @@ public class PluginsLifetime : ILoadingStage await LoadPlugins(cachedPackages, sourceMapping, packagesConfig); - RenderHandler.Current.RegisterComponent(new PluginListComponent(packagesConfig, sourceMapping, configPath, _plugins)); + RenderHandler.Current.RegisterComponent(new PluginListComponent(packagesConfig, sourceMapping, configPath, gameFolder, _plugins)); } public void RegisterLifetime() diff --git a/CringePlugins/Resolver/PackageResolver.cs b/CringePlugins/Resolver/PackageResolver.cs index 297ee6b..29cc0bb 100644 --- a/CringePlugins/Resolver/PackageResolver.cs +++ b/CringePlugins/Resolver/PackageResolver.cs @@ -1,5 +1,6 @@ using System.Collections.Immutable; using System.IO.Compression; +using NLog; using NuGet; using NuGet.Frameworks; using NuGet.Models; @@ -9,6 +10,7 @@ namespace CringePlugins.Resolver; public class PackageResolver(NuGetFramework runtimeFramework, ImmutableArray references, PackageSourceMapping packageSources) { + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); public async Task> ResolveAsync() { var order = 0; @@ -18,7 +20,17 @@ public class PackageResolver(NuGetFramework runtimeFramework, ImmutableArray page.Items!.Where(b => b.CatalogEntry.PackageTypes is ["CringePlugin"])) diff --git a/CringePlugins/Ui/PluginListComponent.cs b/CringePlugins/Ui/PluginListComponent.cs index bd18104..f50d0fe 100644 --- a/CringePlugins/Ui/PluginListComponent.cs +++ b/CringePlugins/Ui/PluginListComponent.cs @@ -1,7 +1,9 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Text.Json; +using System.Xml.Serialization; using CringePlugins.Abstractions; +using CringePlugins.Compatability; using CringePlugins.Config; using CringePlugins.Loader; using CringePlugins.Resolver; @@ -33,16 +35,18 @@ internal class PluginListComponent : IRenderComponent private readonly PackageSourceMapping _sourceMapping; private ImmutableHashSet? _selectedSources; private readonly string _configPath; + private readonly string _gameFolder; private readonly ImmutableArray _plugins; private (SearchResultEntry entry, NuGetClient client)? _selected; private (PackageSource source, int index)? _selectedSource; - public PluginListComponent(PackagesConfig packagesConfig, PackageSourceMapping sourceMapping, string configPath, + public PluginListComponent(PackagesConfig packagesConfig, PackageSourceMapping sourceMapping, string configPath, string gameFolder, ImmutableArray plugins) { _packagesConfig = packagesConfig; _sourceMapping = sourceMapping; _configPath = configPath; + _gameFolder = gameFolder; _plugins = plugins; _packages = packagesConfig.Packages.ToImmutableDictionary(b => b.Id, b => b.Range, StringComparer.OrdinalIgnoreCase); @@ -251,8 +255,20 @@ internal class PluginListComponent : IRenderComponent if (BeginTabItem("Settings")) { - //todo - Text("Todo"); + var oldConfigPath = Path.Join(_gameFolder, "Plugins", "config.xml"); + if (File.Exists(oldConfigPath) && Button("Migrate PluginLoader Config")) + { + var configSerializer = new XmlSerializer(typeof(PluginLoaderConfig)); + using var fs = File.OpenRead(oldConfigPath); + + if (configSerializer.Deserialize(fs) is PluginLoaderConfig oldConfig) + { + _packagesConfig = oldConfig.Migrate(_packagesConfig); + + + Save(false); + } + } EndTabItem(); } @@ -481,15 +497,15 @@ internal class PluginListComponent : IRenderComponent _searchResults = builder.ToImmutable(); } - private void Save() + private void Save(bool keepPackages = true) { _changed = true; using var stream = File.Create(_configPath); - JsonSerializer.Serialize(stream, _packagesConfig with + JsonSerializer.Serialize(stream, keepPackages ? _packagesConfig with { Packages = [.._packages.Select(b => new PackageReference(b.Key, b.Value))] - }, NuGetClient.SerializerOptions); + } : _packagesConfig, NuGetClient.SerializerOptions); } } \ No newline at end of file