ok now it works
This commit is contained in:
@@ -1,38 +1,71 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using CringePlugins.Config;
|
||||
using CringePlugins.Resolver;
|
||||
using CringePlugins.Splash;
|
||||
using NLog;
|
||||
using NuGet;
|
||||
using NuGet.Deps;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace CringePlugins.Loader;
|
||||
|
||||
public class PluginsLifetime
|
||||
public class PluginsLifetime : ILoadingStage
|
||||
{
|
||||
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly ImmutableArray<PluginInstance> _plugins;
|
||||
public string Name => "Loading Plugins";
|
||||
|
||||
public PluginsLifetime()
|
||||
{
|
||||
var dir = Directory.CreateDirectory(Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CringeLauncher", "plugins"));
|
||||
private ImmutableArray<PluginInstance> _plugins = [];
|
||||
private readonly DirectoryInfo _dir = Directory.CreateDirectory(Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CringeLauncher"));
|
||||
private readonly NuGetFramework _runtimeFramework = NuGetFramework.ParseFolder("net8.0-windows");
|
||||
|
||||
var plugins = ImmutableArray<PluginInstance>.Empty.ToBuilder();
|
||||
public async ValueTask Load(ISplashProgress progress)
|
||||
{
|
||||
progress.DefineStepsCount(6);
|
||||
|
||||
foreach (var directory in dir.EnumerateDirectories())
|
||||
progress.Report("Discovering local plugins");
|
||||
|
||||
DiscoverLocalPlugins(_dir.CreateSubdirectory("plugins"));
|
||||
|
||||
progress.Report("Loading config");
|
||||
|
||||
PackagesConfig? packagesConfig = null;
|
||||
var configPath = Path.Join(_dir.FullName, "packages.json");
|
||||
if (File.Exists(configPath))
|
||||
await using (var stream = File.OpenRead(configPath))
|
||||
packagesConfig = JsonSerializer.Deserialize<PackagesConfig>(stream, NuGetClient.SerializerOptions)!;
|
||||
|
||||
if (packagesConfig == null)
|
||||
{
|
||||
var files = directory.GetFiles("*.dll");
|
||||
|
||||
if (files.Length != 1) continue;
|
||||
|
||||
try
|
||||
{
|
||||
plugins.Add(new PluginInstance(files[0].FullName));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Failed to load plugin {PluginPath}", files[0].FullName);
|
||||
}
|
||||
packagesConfig = PackagesConfig.Default;
|
||||
await using var stream = File.Create(configPath);
|
||||
await JsonSerializer.SerializeAsync(stream, packagesConfig, NuGetClient.SerializerOptions);
|
||||
}
|
||||
|
||||
_plugins = plugins.ToImmutable();
|
||||
progress.Report("Resolving packages");
|
||||
|
||||
var sourceMapping = new PackageSourceMapping(packagesConfig.Sources);
|
||||
var resolver = new PackageResolver(_runtimeFramework, packagesConfig.Packages, sourceMapping);
|
||||
|
||||
var packages = await resolver.ResolveAsync();
|
||||
|
||||
progress.Report("Downloading packages");
|
||||
|
||||
var cachedPackages = await resolver.DownloadPackagesAsync(_dir.CreateSubdirectory("cache"), packages, progress);
|
||||
|
||||
progress.Report("Loading plugins");
|
||||
|
||||
await LoadPlugins(cachedPackages, sourceMapping);
|
||||
|
||||
progress.Report("Registering plugins");
|
||||
|
||||
RegisterLifetime();
|
||||
}
|
||||
|
||||
private void RegisterLifetime()
|
||||
{
|
||||
foreach (var instance in _plugins)
|
||||
{
|
||||
try
|
||||
@@ -46,4 +79,56 @@ public class PluginsLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadPlugins(IReadOnlySet<CachedPackage> packages, PackageSourceMapping sourceMapping)
|
||||
{
|
||||
var plugins = _plugins.ToBuilder();
|
||||
|
||||
foreach (var package in packages)
|
||||
{
|
||||
var dir = Path.Join(package.Directory.FullName, "lib", package.ResolvedFramework.GetShortFolderName());
|
||||
|
||||
await using (var stream = File.Create(Path.Join(dir, $"{package.Package.Id}.deps.json")))
|
||||
await DependencyManifestUtility.WriteDependencyManifestAsync(stream, package.Entry, _runtimeFramework,
|
||||
sourceMapping,
|
||||
dependency =>
|
||||
packages.First(b => b.Package.Id.Equals(dependency.Id, StringComparison.OrdinalIgnoreCase))
|
||||
.Package
|
||||
.Version);
|
||||
|
||||
LoadComponent(plugins, Path.Join(dir, $"{package.Package.Id}.dll"));
|
||||
}
|
||||
|
||||
_plugins = plugins.ToImmutable();
|
||||
}
|
||||
|
||||
private void DiscoverLocalPlugins(DirectoryInfo dir)
|
||||
{
|
||||
var plugins = ImmutableArray<PluginInstance>.Empty.ToBuilder();
|
||||
|
||||
foreach (var directory in dir.EnumerateDirectories())
|
||||
{
|
||||
var files = directory.GetFiles("*.deps.json");
|
||||
|
||||
if (files.Length != 1) continue;
|
||||
|
||||
var path = files[0].FullName[..^".deps.json".Length] + ".dll";
|
||||
|
||||
LoadComponent(plugins, path);
|
||||
}
|
||||
|
||||
_plugins = plugins.ToImmutable();
|
||||
}
|
||||
|
||||
private static void LoadComponent(ImmutableArray<PluginInstance>.Builder plugins, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
plugins.Add(new PluginInstance(path));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Failed to load plugin {PluginPath}", path);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user