From 26ac37ed468391efb3c3ee00ae3eca21e98d5783 Mon Sep 17 00:00:00 2001 From: Maplewheels Date: Sat, 21 Mar 2026 21:45:41 -0400 Subject: [PATCH] Added fallback native assembly resolver. --- .../LuaCs/_Plugins/IAssemblyLoaderService.cs | 4 ++ .../_Services/LuaScriptManagementService.cs | 5 +- .../_Services/PluginManagementService.cs | 56 ++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/IAssemblyLoaderService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/IAssemblyLoaderService.cs index 8a6115bc1..00cc5042b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/IAssemblyLoaderService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/IAssemblyLoaderService.cs @@ -44,6 +44,10 @@ public interface IAssemblyLoaderService : IService /// Guid Id { get; } /// + /// The owner content package. + /// + ContentPackage OwnerPackage { get; } + /// /// Indicates that the assemblies in this load context are metadata references only and not /// intended for execution. /// diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs index 502021b23..ccae1545c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/LuaScriptManagementService.cs @@ -116,7 +116,8 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService, commands.RegisterCommand("cl_toggleluadebug", "Toggles the MoonSharp Debug Server.", (string[] args) => { - int port = 41912; + DebugConsole.Log($"This command is currently not implemented. Please open a github issue if you need this feature."); + /*int port = 41912; if (args.Length > 0) { @@ -124,7 +125,7 @@ class LuaScriptManagementService : ILuaScriptManagementService, ILuaDataService, } throw new NotImplementedException(); - //GameMain.LuaCs.ToggleDebugger(port); + //GameMain.LuaCs.ToggleDebugger(port);*/ }); #elif SERVER diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs index db7d40f17..2cbb1a657 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Loader; using System.Text; using System.Threading; @@ -201,6 +202,7 @@ public class PluginManagementService : IAssemblyManagementService private readonly ConcurrentDictionary _pluginPackageLookup = new(); private readonly ConcurrentDictionary> _pluginInstances = new(); private readonly ConditionalWeakTable _unloadingAssemblyLoaders = new(); + private readonly ConcurrentBag _loadedNativeLibraries = new(); private readonly AsyncReaderWriterLock _operationsLock = new(); private ServiceContainer _pluginInjectorContainer; @@ -638,10 +640,39 @@ public class PluginManagementService : IAssemblyManagementService return sourceCode.Replace("GameMain.LuaCs", "LuaCsSetup.Instance"); } - private IntPtr OnAssemblyLoaderResolvingUnmanaged(Assembly arg1, string arg2) + private IntPtr OnAssemblyLoaderResolvingUnmanaged(Assembly callerAssembly, string targetAssemblyName) { - // TODO: Implement extern assembly lookup for Native/Unmanaged Assemblies. - throw new NotImplementedException(); + Guard.IsNull(callerAssembly, nameof(callerAssembly)); + Guard.IsNullOrWhiteSpace(targetAssemblyName, nameof(targetAssemblyName)); + + if (AssemblyLoadContext.GetLoadContext(callerAssembly) is not IAssemblyLoaderService loaderService) + { + return IntPtr.Zero; + } + + var targetDirectory = Path.GetFullPath(loaderService.OwnerPackage.Dir); + if (!targetAssemblyName.TrimEnd().EndsWith(".dll")) + { + targetAssemblyName += ".dll"; + } + + var res = _storageService.FindFilesInPackage(loaderService.OwnerPackage, string.Empty, targetAssemblyName, true); + + if (res.IsFailed || !res.Value.Any()) + { + return IntPtr.Zero; + } + + foreach (var path in res.Value) + { + if (System.Runtime.InteropServices.NativeLibrary.TryLoad(path, out IntPtr asmPtr)) + { + _loadedNativeLibraries.Add(asmPtr); + return asmPtr; + } + } + + return IntPtr.Zero; } private Assembly OnAssemblyLoaderResolvingManaged(IAssemblyLoaderService requestingLoader, AssemblyName searchName) @@ -745,6 +776,25 @@ public class PluginManagementService : IAssemblyManagementService }, 3.0f); #endif + // clear native libraries + if (_loadedNativeLibraries.Any()) + { + foreach (var ptr in _loadedNativeLibraries) + { + try + { + System.Runtime.InteropServices.NativeLibrary.Free(ptr); + } + catch + { + // ignored + continue; + } + } + + _loadedNativeLibraries.Clear(); + } + return results; }