diff --git a/Barotrauma/BarotraumaShared/LocalMods/LuaCsForBarotrauma/ModConfig.xml b/Barotrauma/BarotraumaShared/LocalMods/LuaCsForBarotrauma/ModConfig.xml
index 363f7695b..cd06c211b 100644
--- a/Barotrauma/BarotraumaShared/LocalMods/LuaCsForBarotrauma/ModConfig.xml
+++ b/Barotrauma/BarotraumaShared/LocalMods/LuaCsForBarotrauma/ModConfig.xml
@@ -2,4 +2,7 @@
+
+
+
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/DataInterfaceImplementations.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/DataInterfaceImplementations.cs
index 0c0fad9cd..4a3ec7268 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/DataInterfaceImplementations.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/DataInterfaceImplementations.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml.Linq;
+using System.Xml.Serialization;
using Barotrauma.LuaCs;
using Barotrauma.Steam;
using OneOf;
@@ -44,6 +45,7 @@ public record AssemblyResourceInfo : BaseResourceInfo, IAssemblyResourceInfo
public string FriendlyName { get; init; }
public bool IsScript { get; init; }
public bool UseInternalAccessName { get; init; }
+ public bool IsReferenceModeOnly { get; init; }
}
///
@@ -81,9 +83,12 @@ public record ConfigInfo : IConfigInfo
public record ConfigProfileInfo : IConfigProfileInfo
{
+ ///
+ /// Profile name.
+ ///
public string InternalName { get; init; }
public ContentPackage OwnerPackage { get; init; }
- public IReadOnlyList<(string ConfigName, XElement Element)> ProfileValues { get; init; }
+ public IReadOnlyList<(string SettingName, XElement Element)> ProfileValues { get; init; }
}
#endregion
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IBaseInfoDefinitions.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IBaseInfoDefinitions.cs
index 4f5cb032b..2326ecce2 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IBaseInfoDefinitions.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IBaseInfoDefinitions.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
+using System.Xml.Serialization;
namespace Barotrauma.LuaCs.Data;
@@ -24,12 +25,14 @@ public interface IPlatformInfo
/// Platforms that these localization files should be loaded for.
///
[Required]
+ [XmlAttribute("Platform")]
Platform SupportedPlatforms { get; }
///
/// Targets that these localization files should be loaded for.
///
[Required]
+ [XmlAttribute("Target")]
Target SupportedTargets { get; }
}
@@ -44,6 +47,7 @@ public interface IResourceInfo : IPlatformInfo
/// Specifies the loading order for all assets of the same type (ie. styles, assemblies, etc.) from
/// the same . Lower number is higher priority, see
///
+ [XmlAttribute("LoadPriority")]
int LoadPriority { get; }
///
@@ -56,5 +60,6 @@ public interface IResourceInfo : IPlatformInfo
/// Marks this resource as optional (ie. Cross-CP content). Setting this to true will allow the dependency system to
/// try and order the loading but not fail if it runs into circular dependency issues.
///
+ [XmlAttribute("Optional")]
bool Optional { get; }
}
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IConfigProfileInfo.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IConfigProfileInfo.cs
index 5d5f9065d..28e9a6e1a 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IConfigProfileInfo.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IConfigProfileInfo.cs
@@ -5,5 +5,5 @@ namespace Barotrauma.LuaCs.Data;
public interface IConfigProfileInfo : IDataInfo
{
- IReadOnlyList<(string ConfigName, XElement Element)> ProfileValues { get; }
+ IReadOnlyList<(string SettingName, XElement Element)> ProfileValues { get; }
}
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IDataInfo.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IDataInfo.cs
index d49be249b..652ddd967 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IDataInfo.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IDataInfo.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Xml.Serialization;
namespace Barotrauma.LuaCs.Data;
@@ -11,6 +12,7 @@ public interface IDataInfo : IEqualityComparer, IEquatable
///
/// Internal name unique within the resources inside a package.
///
+ [XmlAttribute("Name")]
string InternalName { get; }
///
/// The package this information belongs to.
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IResourceInfoDeclarations.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IResourceInfoDeclarations.cs
index f40850cfa..32d17a16e 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IResourceInfoDeclarations.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IResourceInfoDeclarations.cs
@@ -2,6 +2,7 @@
using System.Collections.Immutable;
using System.Globalization;
using System.Runtime.CompilerServices;
+using System.Xml.Serialization;
namespace Barotrauma.LuaCs.Data;
@@ -18,6 +19,7 @@ public interface ILuaScriptResourceInfo : IBaseResourceInfo
///
/// Should this script be run automatically.
///
+ [XmlAttribute("IsAutorun")]
public bool IsAutorun { get; }
}
@@ -27,17 +29,27 @@ public interface IAssemblyResourceInfo : IBaseResourceInfo
/// The friendly name of the assembly. Script files belonging to the same assembly should all have the same name.
/// Legacy scripts will all be given the sanitized name of the Content Package they belong to.
///
+ [XmlAttribute("FriendlyName")]
public string FriendlyName { get; }
///
/// Is this entry referring to a script file collection.
///
+ [XmlAttribute("IsScript")]
public bool IsScript { get; }
///
/// [Required(IsScript: true)] Whether the internal compiled assembly name should be named to enabled use of the
/// attribute.
///
+ [XmlAttribute("UseInternalAccessName")]
public bool UseInternalAccessName { get; }
+
+ ///
+ /// Should the following resources only be used for Compilation MetadataReference.
+ /// NOTE: Affects the entire package's assembly resources, meant for internal use only.
+ ///
+ [XmlAttribute("IsReferenceModeOnly")]
+ public bool IsReferenceModeOnly { get; }
}
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/AssemblyLoader.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/AssemblyLoader.cs
index 6a323c12e..bd82efe1f 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/AssemblyLoader.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Plugins/AssemblyLoader.cs
@@ -208,6 +208,10 @@ public sealed class AssemblyLoader : AssemblyLoadContext, IAssemblyLoaderService
AreOperationRunning = true;
foreach (var data in _loadedAssemblyData.Values)
{
+ if (data.AssemblyReference is null)
+ {
+ continue;
+ }
yield return data.AssemblyReference;
}
AreOperationRunning = false;
@@ -356,10 +360,10 @@ public sealed class AssemblyLoader : AssemblyLoadContext, IAssemblyLoaderService
if (additionalDependencyPaths.Any())
{
var r = AddDependencyPaths(additionalDependencyPaths);
- if (!r.IsFailed)
+ if (r.IsFailed)
{
// we have errors, loading may not work.
- return FluentResults.Result.Fail(new Error($"Failed to load dependency paths.")
+ return FluentResults.Result.Fail(new Error($"Failed to load dependency paths for '{assemblyFilePath}' with paths: {additionalDependencyPaths.Aggregate((s, ac) => $"{ac}| P={s}")}.")
.WithMetadata(MetadataType.ExceptionObject, this)
.WithMetadata(MetadataType.RootObject, assemblyFilePath))
.WithErrors(r.Errors);
@@ -379,7 +383,7 @@ public sealed class AssemblyLoader : AssemblyLoadContext, IAssemblyLoaderService
try
{
var assembly = LoadFromAssemblyPath(sanitizedFilePath);
- _loadedAssemblyData[assembly] = new AssemblyData(assembly, sanitizedFilePath);
+ _loadedAssemblyData[assembly] = new AssemblyData(assembly, assembly.Location);
return new Result().WithSuccess($"Loaded assembly '{assembly.GetName()}'").WithValue(assembly);
}
catch (FileNotFoundException fnfe)
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigFileParserService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigFileParserService.cs
index 1a6f63933..33569f85b 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigFileParserService.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigFileParserService.cs
@@ -79,7 +79,8 @@ public sealed class ModConfigFileParserService :
// Type Specific
FriendlyName = src.Element.GetAttributeString("FriendlyName", string.Empty),
IsScript = src.Element.GetAttributeBool("IsScript", false),
- UseInternalAccessName = src.Element.GetAttributeBool("UseInternalAccessName", false)
+ UseInternalAccessName = src.Element.GetAttributeBool("UseInternalAccessName", false),
+ IsReferenceModeOnly = src.Element.GetAttributeBool("IsReferenceModeOnly", false)
};
}
@@ -211,8 +212,8 @@ public sealed class ModConfigFileParserService :
private (Platform Platform, Target Target) GetRuntimeEnvironment(XElement element)
{
return (
- Platform: element.GetAttributeEnum("Platform", Platform.Windows | Platform.Linux | Platform.OSX),
- Target: element.GetAttributeEnum("Target", Target.Client | Target.Server));
+ Platform: element.GetAttributeEnum("Platform", Platform.Any),
+ Target: element.GetAttributeEnum("Target", Target.Any));
}
private async Task>> TryParseGenericResourcesAsync(IEnumerable sources)
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigService.cs
index cd3ea8085..e4bc8897a 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigService.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/ModConfigService.cs
@@ -264,7 +264,8 @@ public sealed class ModConfigService : IModConfigService
FriendlyName = $"{src.Name}.{searchPathways.SubFolder.Replace('/','.')}",
IncompatiblePackages = ImmutableArray.Empty,
RequiredPackages = ImmutableArray.Empty,
- IsScript = false
+ IsScript = false,
+ IsReferenceModeOnly = false
});
}
}
@@ -304,7 +305,8 @@ public sealed class ModConfigService : IModConfigService
IncompatiblePackages = ImmutableArray.Empty,
RequiredPackages = ImmutableArray.Empty,
UseInternalAccessName = true,
- IsScript = true
+ IsScript = true,
+ IsReferenceModeOnly = false
});
}
}
diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs
index c020949da..ecac7daaf 100644
--- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs
+++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/PluginManagementService.cs
@@ -86,6 +86,29 @@ public class PluginManagementService : IAssemblyManagementService
.ToString(),
ScriptParseOptions);
+ private ImmutableArray _baseMetadataReferences = ImmutableArray.Empty;
+ private IEnumerable BaseMetadataReferences
+ {
+ get
+ {
+ if (_baseMetadataReferences.IsDefaultOrEmpty)
+ {
+ _baseMetadataReferences = Basic.Reference.Assemblies.Net80.References.All
+ .Union(AssemblyLoadContext.Default.Assemblies
+ .Where(ass =>
+ !ass.IsDynamic &&
+ !ass.GetName().FullName.EndsWith("Barotrauma.Core") &&
+ !ass.GetName().FullName.EndsWith("Barotrauma") &&
+ !ass.GetName().FullName.EndsWith("DedicatedServer"))
+ .Select(MetadataReference (ass) => MetadataReference.CreateFromFile(ass.Location)))
+ .Where(ar => ar is not null)
+ .ToImmutableArray();
+ }
+
+ return _baseMetadataReferences;
+ }
+ }
+
#endregion
#region Disposal
@@ -213,14 +236,35 @@ public class PluginManagementService : IAssemblyManagementService
public Result> GetImplementingTypes(bool includeInterfaces = false, bool includeAbstractTypes = false,
bool includeDefaultContext = true)
{
-#if !DEBUG
- throw new NotImplementedException();
-#endif
+ if (includeInterfaces)
+ {
+ includeAbstractTypes = true;
+ }
+
+ using var lck = _operationsLock.AcquireReaderLock().ConfigureAwait(false).GetAwaiter().GetResult();
+ IService.CheckDisposed(this);
+
var builder = ImmutableArray.CreateBuilder();
- foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())
+ if (includeDefaultContext)
{
- foreach (var type in ass.GetSafeTypes())
+ foreach (var ass in AssemblyLoadContext.Default.Assemblies)
+ {
+ AddTypesFromAssembly(ass);
+ }
+ }
+
+ foreach (var ass in _assemblyLoaders.Values.Where(al => !al.IsReferenceOnlyMode).SelectMany(al => al.Assemblies))
+ {
+ AddTypesFromAssembly(ass);
+ }
+
+ return builder.ToImmutable();
+
+
+ void AddTypesFromAssembly(Assembly assembly)
+ {
+ foreach (var type in assembly.GetSafeTypes())
{
if ((includeInterfaces || !type.IsInterface)
&& (includeAbstractTypes || !type.IsAbstract)
@@ -230,8 +274,6 @@ public class PluginManagementService : IAssemblyManagementService
}
}
}
-
- return builder.ToImmutable();
}
public Type GetType(string typeName, bool isByRefType = false, bool includeInterfaces = false,
@@ -255,9 +297,21 @@ public class PluginManagementService : IAssemblyManagementService
return type;
}
+
+ foreach (var ass in AssemblyLoadContext.Default.Assemblies)
+ {
+ if (ass.GetType(typeName, false, false) is not {} type2 || (!includeInterfaces && type2.IsInterface))
+ {
+ continue;
+ }
+
+ return isByRefType ? type2.MakeByRefType() : type2;
+ }
}
- foreach (var ass in AssemblyLoadContext.All.SelectMany(alc => alc.Assemblies))
+ foreach (var ass in AssemblyLoadContext.All
+ .Where(alc => alc != AssemblyLoadContext.Default)
+ .SelectMany(alc => alc.Assemblies))
{
if (ass.GetType(typeName, false, false) is not {} type || (!includeInterfaces && type.IsInterface))
{
@@ -426,7 +480,7 @@ public class PluginManagementService : IAssemblyManagementService
new IAssemblyLoaderService.LoaderInitData(
InstanceId: Guid.NewGuid(),
contentPackRes.Key.Name,
- IsReferenceMode: false,
+ IsReferenceMode: contentPackRes.Any(r => r.IsReferenceModeOnly),
OwnerPackage: contentPackRes.Key,
OnUnload: OnAssemblyLoaderUnloading,
OnResolvingManaged: OnAssemblyLoaderResolvingManaged,
@@ -465,7 +519,7 @@ public class PluginManagementService : IAssemblyManagementService
new IAssemblyLoaderService.LoaderInitData(
InstanceId: Guid.NewGuid(),
contentPackRes.Key.Name,
- IsReferenceMode: false,
+ IsReferenceMode: contentPackRes.Any(r => r.IsReferenceModeOnly),
OwnerPackage: contentPackRes.Key,
OnUnload: OnAssemblyLoaderUnloading,
OnResolvingManaged: OnAssemblyLoaderResolvingManaged,
@@ -550,35 +604,13 @@ public class PluginManagementService : IAssemblyManagementService
IEnumerable GetMetadataReferences()
{
-#if !DEBUG
- throw new NotImplementedException($"Needs to use publicized barotrauma assemblies and cache metadata.");
-#endif
- var publicizedDir = Path.Combine(Directory.GetCurrentDirectory(), "Publicized");
-
- string[] publicizedAssemblies =
+ var builder = ImmutableArray.CreateBuilder();
+ builder.AddRange(BaseMetadataReferences);
+ foreach (var loaderService in _assemblyLoaders)
{
-#if CLIENT
- "Barotrauma",
-#elif SERVER
- "DedicatedServer",
-#endif
- "BarotraumaCore"
- };
-
- var publicizedRefs = publicizedAssemblies
- .Select(name => Path.Combine(publicizedDir, $"{name}.dll"))
- .Where(File.Exists)
- .Select(path => MetadataReference.CreateFromFile(path));
-
- var runtimeRefs = AppDomain.CurrentDomain.GetAssemblies()
- .Where(ass =>
- !string.IsNullOrWhiteSpace(ass.Location) &&
- !publicizedAssemblies.Contains(ass.GetName().Name))
- .Select(ass => MetadataReference.CreateFromFile(ass.Location));
-
- return Basic.Reference.Assemblies.Net80.References.All
- .Union(runtimeRefs)
- .Union(publicizedRefs);
+ builder.AddRange(loaderService.Value.AssemblyReferences.Where(ar => ar is not null));
+ }
+ return builder.ToImmutable();
}
}