diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs
index 566276687..352485437 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/AssemblyManager.cs
@@ -352,13 +352,25 @@ public class AssemblyManager
{
OpsLockLoaded.ExitReadLock();
}
-
}
#endregion
#region InternalAPI
+ ///
+ /// [Unsafe] Warning: only for use in nested threading functions. Requires care to manage access.
+ /// Does not make any guarantees about the state of the ACL after the list has been returned.
+ ///
+ ///
+ [MethodImpl(MethodImplOptions.Synchronized | MethodImplOptions.NoInlining)]
+ internal ImmutableList UnsafeGetAllLoadedACLs()
+ {
+ if (LoadedACLs.IsEmpty)
+ return ImmutableList.Empty;
+ return LoadedACLs.Select(kvp => kvp.Value).ToImmutableList();
+ }
+
///
/// Used by content package and plugin management to stop unloading of a given ACL until all plugins have gracefully closed.
///
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs
index a92f0ea38..77de3a722 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs
@@ -295,15 +295,16 @@ public sealed class CsPackageManager : IDisposable
_assemblyManager.OnAssemblyUnloading += AssemblyManagerOnAssemblyUnloading;
// log error if some ACLs are still unloading (some assembly is still in use)
+ _assemblyManager.FinalizeDispose(); //Update lists
if (_assemblyManager.IsCurrentlyUnloading)
{
ModUtils.Logging.PrintWarning($"WARNING: Some mods from a previous session (lobby) are still loaded! This may result in undefined behaviour!\nIf you notice any odd behaviour that only occurs after multiple lobbies, please restart your game.");
+ ModUtils.Logging.PrintWarning($"The below ACLs are still unloading:");
foreach (var wkref in _assemblyManager.StillUnloadingACLs)
{
- ModUtils.Logging.PrintWarning($"The below ACL is still unloading:");
if (wkref.TryGetTarget(out var tgt))
{
- ModUtils.Logging.PrintWarning($"ACL Name: {tgt.Name}");
+ ModUtils.Logging.PrintWarning($"ACL Name: {tgt.FriendlyName}");
foreach (Assembly assembly in tgt.Assemblies)
{
ModUtils.Logging.PrintWarning($"-- Assembly: {assembly.GetName()}");
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs
index 94e3edd74..e99bdfe2d 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs
@@ -280,20 +280,33 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
}
//try resolve against other loaded alcs
- foreach (var loadedAcL in _assemblyManager.GetAllLoadedACLs())
+ ImmutableList list;
+ try
{
- if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed)
- continue;
+ list = _assemblyManager.UnsafeGetAllLoadedACLs();
+ }
+ catch
+ {
+ list = ImmutableList.Empty;
+ }
+
+ if (!list.IsEmpty)
+ {
+ foreach (var loadedAcL in list)
+ {
+ if (loadedAcL.Acl is null || loadedAcL.Acl.IsTemplateMode || loadedAcL.Acl.IsDisposed)
+ continue;
- try
- {
- ass = loadedAcL.Acl.LoadFromAssemblyName(assemblyName);
- if (ass is not null)
- return ass;
- }
- catch
- {
- // LoadFromAssemblyName throws, no need to propagate
+ try
+ {
+ ass = loadedAcL.Acl.LoadFromAssemblyName(assemblyName);
+ if (ass is not null)
+ return ass;
+ }
+ catch
+ {
+ // LoadFromAssemblyName throws, no need to propagate
+ }
}
}
@@ -315,6 +328,7 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
CompiledAssembly = null;
CompiledAssemblyImage = null;
_dependencyResolvers.Clear();
+ _assemblyManager = null;
base.Unloading -= OnUnload;
this.IsDisposed = true;
}