Merge branch 'unstable-tests'

This commit is contained in:
Evil Factory
2022-04-21 11:21:30 -03:00
8 changed files with 83 additions and 19 deletions

View File

@@ -3236,6 +3236,7 @@ namespace Barotrauma
}
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
GameMain.LuaCs.RecreateCsScript();
}));
commands.Add(new Command("cl_reloadlua", "reloads lua on the client", (string[] args) =>

View File

@@ -1250,6 +1250,7 @@ namespace Barotrauma
if(LuaCsSetup.GetPackage("CsForBarotrauma", false) == null) { return; }
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
GameMain.LuaCs.RecreateCsScript();
}));
commands.Add(new Command("reloadlua", "reloads lua", (string[] args) =>

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.CodeAnalysis.Scripting;
using System.Reflection;
using Microsoft.CodeAnalysis.CSharp;
using System.Linq;
using Microsoft.CodeAnalysis;
using System.Runtime.Loader;
using System.Reflection.PortableExecutable;
using System.Reflection.Metadata;
using System.Text;
using System.Runtime.CompilerServices;
namespace Barotrauma
{
class CsScriptBase : AssemblyLoadContext
{
public const string NET_ONE_TIME_SCRIPT_ASSEMBLY = "NetOneTimeScriptAssembly";
public const string NET_SCRIPT_ASSEMBLY = "NetScriptAssembly";
public static Dictionary<string, object> Revision = new Dictionary<string, object>()
{
{ NET_SCRIPT_ASSEMBLY, 0},
{ NET_ONE_TIME_SCRIPT_ASSEMBLY, 0}
};
public CsScriptBase() : base(isCollectible: true) { }
public static SyntaxTree AssemblyInfoSyntaxTree(string asmName = null)
{
Revision[asmName] = (int)Revision[asmName] + 1;
var asmInfo = new StringBuilder();
asmInfo.AppendLine("using System.Reflection;");
asmInfo.AppendLine($"[assembly: AssemblyMetadata(\"Revision\", \"{Revision[asmName]}\")]");
asmInfo.AppendLine($"[assembly: AssemblyVersion(\"0.0.0.{Revision[asmName]}\")]");
return CSharpSyntaxTree.ParseText(asmInfo.ToString(), CSharpParseOptions.Default);
}
~CsScriptBase() { }
}
}

View File

@@ -9,6 +9,11 @@ using System.Reflection.Metadata;
namespace Barotrauma {
class CsScriptFilter
{
public static readonly string[] LoadedAssemblyName = {
CsScriptBase.NET_SCRIPT_ASSEMBLY,
CsScriptBase.NET_ONE_TIME_SCRIPT_ASSEMBLY
};
private static readonly string[] typesPermitted = {
// Basics
"System",

View File

@@ -12,7 +12,7 @@ using System.Reflection.Metadata;
namespace Barotrauma
{
class CsScriptLoader : AssemblyLoadContext
class CsScriptLoader : CsScriptBase
{
public LuaCsSetup setup;
private List<MetadataReference> defaultReferences;
@@ -20,7 +20,7 @@ namespace Barotrauma
private Dictionary<string, List<string>> sources;
public Assembly Assembly { get; private set; }
public CsScriptLoader(LuaCsSetup setup) : base(isCollectible: true)
public CsScriptLoader(LuaCsSetup setup)
{
this.setup = setup;
@@ -62,6 +62,7 @@ namespace Barotrauma
var syntaxTrees = new List<SyntaxTree>();
if (sources.Count <= 0) throw new Exception("No Cs sources detected");
syntaxTrees.Add(AssemblyInfoSyntaxTree(NET_SCRIPT_ASSEMBLY));
foreach ((var folder, var src) in sources)
{
try
@@ -92,7 +93,7 @@ namespace Barotrauma
.WithMetadataImportOptions(MetadataImportOptions.All)
.WithOptimizationLevel(OptimizationLevel.Release)
.WithAllowUnsafe(false);
var compilation = CSharpCompilation.Create("NetScriptAssembly",syntaxTrees, defaultReferences, options);
var compilation = CSharpCompilation.Create(NET_SCRIPT_ASSEMBLY,syntaxTrees, defaultReferences, options);
using (var mem = new MemoryStream())
{
@@ -153,10 +154,5 @@ namespace Barotrauma
{
Assembly = null;
}
~CsScriptLoader()
{
}
}
}

View File

@@ -13,7 +13,7 @@ using MoonSharp.Interpreter;
namespace Barotrauma
{
class CsScriptRunner : AssemblyLoadContext
class CsScriptRunner : CsScriptBase
{
public LuaCsSetup setup;
private List<MetadataReference> defaultReferences;
@@ -25,7 +25,7 @@ namespace Barotrauma
"System.Linq"
};
public CsScriptRunner(LuaCsSetup setup) : base(isCollectible: true)
public CsScriptRunner(LuaCsSetup setup)
{
this.setup = setup;
@@ -56,7 +56,7 @@ namespace Barotrauma
{
code = ToOneTimeScript(code);
var syntaxTree = SyntaxFactory.ParseSyntaxTree(code, CSharpParseOptions.Default);
var compilation = CSharpCompilation.Create("NetOneTimeScriptAssembly", new[] { syntaxTree }, defaultReferences, compileOptions);
var compilation = CSharpCompilation.Create(NET_ONE_TIME_SCRIPT_ASSEMBLY, new[] { AssemblyInfoSyntaxTree(NET_ONE_TIME_SCRIPT_ASSEMBLY), syntaxTree }, defaultReferences, compileOptions);
Assembly assembly = null;
using (var mem = new MemoryStream())
@@ -103,8 +103,7 @@ namespace Barotrauma
scriptResilt = method.Invoke(runner, null);
foreach (var type in assembly.GetTypes())
{
//UserData.UnregisterType(type, true);
UserData.UnregisterType(type);
UserData.UnregisterType(type, true);
}
}
else LuaCsSetup.PrintCsError("Script Error - no run method detected");
@@ -115,6 +114,8 @@ namespace Barotrauma
}
}
Unload();
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (Exception ex)
{

View File

@@ -13,8 +13,14 @@ namespace Barotrauma
{
var type = Type.GetType(typeName);
if (type != null) return type;
foreach (var a in AppDomain.CurrentDomain.GetAssemblies().Reverse())
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
if (CsScriptFilter.LoadedAssemblyName.Contains(a.GetName().Name))
{
var attrs = a.GetCustomAttributes<AssemblyMetadataAttribute>();
var revision = attrs.FirstOrDefault(attr => attr.Key == "Revision")?.Value;
if (revision != null && int.Parse(revision) != (int)CsScriptBase.Revision[a.GetName().Name]) { continue; }
}
type = a.GetType(typeName);
if (type != null)
return type;

View File

@@ -12,8 +12,8 @@ using System.Runtime.CompilerServices;
using System.Linq;
using System.Reflection;
[assembly: InternalsVisibleTo("NetScriptAssembly", AllInternalsVisible = true)]
[assembly: InternalsVisibleTo("NetOneTimeScriptAssembly", AllInternalsVisible = true)]
[assembly: InternalsVisibleTo(Barotrauma.CsScriptBase.NET_SCRIPT_ASSEMBLY, AllInternalsVisible = true)]
[assembly: InternalsVisibleTo(Barotrauma.CsScriptBase.NET_ONE_TIME_SCRIPT_ASSEMBLY, AllInternalsVisible = true)]
namespace Barotrauma
{
class LuaCsSetupConfig
@@ -40,6 +40,17 @@ namespace Barotrauma
private Script lua;
public CsScriptRunner CsScript { get; private set; }
/// <summary>
/// due to there's a race on the process and the unloaded AssemblyLoadContexts,
/// should recreate runner after the script runs
/// </summary>
public void RecreateCsScript()
{
GameMain.LuaCs.CsScript = new CsScriptRunner(GameMain.LuaCs.CsScript.setup);
lua.Globals["CsScript"] = CsScript;
}
public LuaGame Game { get; private set; }
public LuaScriptLoader LuaScriptLoader { get; private set; }
@@ -314,9 +325,9 @@ namespace Barotrauma
public void Stop()
{
foreach (var type in AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name == "NetScriptAssembly").SelectMany(assembly => assembly.GetTypes()))
foreach (var type in AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name == CsScriptBase.NET_SCRIPT_ASSEMBLY).SelectMany(assembly => assembly.GetTypes()))
{
UserData.UnregisterType(type);
UserData.UnregisterType(type, true);
}
foreach (var mod in ACsMod.LoadedMods.ToArray()) mod.Dispose();
ACsMod.LoadedMods.Clear();
@@ -450,7 +461,8 @@ modding needs.
var modTypes = CsScriptLoader.Compile();
modTypes.ForEach(t =>
{
UserData.RegisterType(t);
//Please register `t` in lua-side
//UserData.RegisterType(t);
t.GetConstructor(new Type[] { })?.Invoke(null);
});
}