MinecraftConsoles/Minecraft.Server.FourKit/PluginLoadContext.cs
UniPM 50ab3597d0
Allowing plugins to be used as dependencies to other plugins (#16)
* fuck everything i did blegh

* better exception tracking for plugins

* Update PluginLoadContext.Load to return existing instances (basically, make plugin api references possible)

* Update docs to help with plugin dependencies

---------

Co-authored-by: UniPM <zoc6x8voc@mozmail.com>
2026-05-06 17:38:05 -05:00

54 lines
1.6 KiB
C#

using Minecraft.Server.FourKit.Plugin;
using System.Reflection;
using System.Runtime.Loader;
namespace Minecraft.Server.FourKit;
internal sealed class PluginLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
private readonly string _pluginDirectory;
public PluginLoadContext(string pluginPath)
: base(isCollectible: false)
{
_pluginDirectory = Path.GetDirectoryName(Path.GetFullPath(pluginPath))!;
_resolver = new AssemblyDependencyResolver(pluginPath);
}
protected override Assembly? Load(AssemblyName assemblyName)
{
if (assemblyName.Name == typeof(ServerPlugin).Assembly.GetName().Name)
return typeof(ServerPlugin).Assembly;
foreach (var alc in AssemblyLoadContext.All)
{
var existing = alc.Assemblies
.FirstOrDefault(a => a.GetName().Name == assemblyName.Name);
if (existing != null) return existing;
}
string? path = _resolver.ResolveAssemblyToPath(assemblyName);
if (path != null)
return LoadFromAssemblyPath(path);
if (assemblyName.Name != null)
{
string fallback = Path.Combine(_pluginDirectory, assemblyName.Name + ".dll");
if (File.Exists(fallback))
return LoadFromAssemblyPath(fallback);
}
return null;
}
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
string? path = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (path != null)
return LoadUnmanagedDllFromPath(path);
return IntPtr.Zero;
}
}