Merge branch 'unstable-tests'
This commit is contained in:
@@ -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) =>
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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() { }
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user