From aaa4a91e01446230efb4ef72fb91f70564018bf6 Mon Sep 17 00:00:00 2001 From: MapleWheels Date: Wed, 25 Oct 2023 05:29:01 -0400 Subject: [PATCH] Squash. (#164) - Added use internals attrib option to RunConfig - Changed compilation and resolution to ignore disposed ACLs. --- .../LuaCs/Plugins/CsPackageManager.cs | 6 ++- .../MemoryFileAssemblyContextLoader.cs | 38 ++++++++++++++++--- .../SharedSource/LuaCs/Plugins/RunConfig.cs | 8 +++- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs index 6b9397e3b..8b77c6e59 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/CsPackageManager.cs @@ -574,11 +574,13 @@ public sealed class CsPackageManager : IDisposable // try compile successState = _assemblyManager.LoadAssemblyFromMemory( - pair.Key.Name.Replace(" ",""), + pair.Value.config.UseInternalAssemblyName ? "CompiledAssembly" : pair.Key.Name.Replace(" ",""), syntaxTrees, null, CompilationOptions, - pair.Key.Name, ref id, pair.Value.config.UseNonPublicizedAssemblies ? null : publicizedAssemblies); + pair.Key.Name, + ref id, + pair.Value.config.UseNonPublicizedAssemblies ? null : publicizedAssemblies); if (successState is not AssemblyLoadingSuccessState.Success) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs index a6222bcb9..66d3bd004 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/MemoryFileAssemblyContextLoader.cs @@ -5,11 +5,14 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.Loader; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; // ReSharper disable ConditionIsAlwaysTrueOrFalse +[assembly: InternalsVisibleTo("CompiledAssembly")] + namespace Barotrauma; /// @@ -30,10 +33,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 +162,11 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext 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 +177,28 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext .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 +278,8 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext //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 +312,6 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext CompiledAssemblyImage = null; _dependencyResolvers.Clear(); base.Unloading -= OnUnload; + this.IsDisposed = true; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/RunConfig.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/RunConfig.cs index 4d8505d25..64bc66006 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/RunConfig.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Plugins/RunConfig.cs @@ -33,9 +33,15 @@ public sealed class RunConfig /// Compiles the mod using non-publicized assemblies. /// [XmlElement(ElementName = "UseNonPublicizedAssemblies")] - [DefaultValue(false)] public bool UseNonPublicizedAssemblies { get; set; } + /// + /// If the mod includes source files, the compiled assembly will be named "CompiledAssembly" and have the [InternalVisibleTo()] attribute applied to it. + /// + [XmlElement(ElementName = "UseInternalAssemblyName")] + [DefaultValue(false)] + public bool UseInternalAssemblyName { get; set; } + [XmlElement(ElementName = "AutoGenerated")] public bool AutoGenerated { get; set; }