diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs index a6222bcb9c..368b86e655 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs @@ -30,10 +30,12 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext protected bool IsResolving; //this is to avoid circular dependency lookup. private AssemblyManager _assemblyManager; public bool IsTemplateMode { get; set; } + public bool IsDisposed { get; private set; } public MemoryFileAssemblyContextLoader(AssemblyManager assemblyManager) : base(isCollectible: true) { this._assemblyManager = assemblyManager; + this.IsDisposed = false; base.Unloading += OnUnload; } @@ -157,11 +159,11 @@ public AssemblyLoadingSuccessState CompileAndLoadScriptAssembly( if (externMetadataReferences is not null) metadataReferences.AddRange(externMetadataReferences); - // build metadata refs from global where not an in-memory compiled assembly and not the same assembly as supplied. - metadataReferences.AddRange(AppDomain.CurrentDomain.GetAssemblies() + // build metadata refs from default where not an in-memory compiled assembly and not the same assembly as supplied. + metadataReferences.AddRange(AssemblyLoadContext.Default.Assemblies .Where(a => { - if (a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")) + if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit")) return false; if (a.FullName is null) return true; @@ -172,7 +174,28 @@ public AssemblyLoadingSuccessState CompileAndLoadScriptAssembly( .Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit"))) .Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference) ).ToList()); - + + // build metadata refs from ACL assemblies from files/disk. + foreach (AssemblyManager.LoadedACL loadedAcl in _assemblyManager.GetAllLoadedACLs()) + { + if(loadedAcl.Acl.IsTemplateMode || loadedAcl.Acl.IsDisposed) + continue; + metadataReferences.AddRange(loadedAcl.Acl.Assemblies + .Where(a => + { + if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit")) + return false; + if (a.FullName is null) + return true; + return !externAssemblyNames.Contains(a.FullName); // exclude duplicates + }) + .Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference) + .Union(externAssemblyRefs // add custom supplied assemblies + .Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit"))) + .Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference) + ).ToList()); + } + // build metadata refs from in-memory images foreach (var loadedAcl in _assemblyManager.GetAllLoadedACLs()) { @@ -252,7 +275,8 @@ protected override Assembly Load(AssemblyName assemblyName) //try resolve against other loaded alcs foreach (var loadedAcL in _assemblyManager.GetAllLoadedACLs()) { - if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode) continue; + if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed) + continue; try { @@ -285,5 +309,6 @@ private void OnUnload(AssemblyLoadContext alc) CompiledAssemblyImage = null; _dependencyResolvers.Clear(); base.Unloading -= OnUnload; + this.IsDisposed = true; } }