Merge branch 'unstable-tests'
This commit is contained in:
@@ -3236,6 +3236,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
|
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
|
||||||
|
GameMain.LuaCs.RecreateCsScript();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("cl_reloadlua", "reloads lua on the client", (string[] args) =>
|
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; }
|
if(LuaCsSetup.GetPackage("CsForBarotrauma", false) == null) { return; }
|
||||||
|
|
||||||
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
|
GameMain.LuaCs.CsScript.Run(string.Join(" ", args));
|
||||||
|
GameMain.LuaCs.RecreateCsScript();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("reloadlua", "reloads lua", (string[] args) =>
|
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 {
|
namespace Barotrauma {
|
||||||
class CsScriptFilter
|
class CsScriptFilter
|
||||||
{
|
{
|
||||||
|
public static readonly string[] LoadedAssemblyName = {
|
||||||
|
CsScriptBase.NET_SCRIPT_ASSEMBLY,
|
||||||
|
CsScriptBase.NET_ONE_TIME_SCRIPT_ASSEMBLY
|
||||||
|
};
|
||||||
|
|
||||||
private static readonly string[] typesPermitted = {
|
private static readonly string[] typesPermitted = {
|
||||||
// Basics
|
// Basics
|
||||||
"System",
|
"System",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using System.Reflection.Metadata;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class CsScriptLoader : AssemblyLoadContext
|
class CsScriptLoader : CsScriptBase
|
||||||
{
|
{
|
||||||
public LuaCsSetup setup;
|
public LuaCsSetup setup;
|
||||||
private List<MetadataReference> defaultReferences;
|
private List<MetadataReference> defaultReferences;
|
||||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
|||||||
private Dictionary<string, List<string>> sources;
|
private Dictionary<string, List<string>> sources;
|
||||||
public Assembly Assembly { get; private set; }
|
public Assembly Assembly { get; private set; }
|
||||||
|
|
||||||
public CsScriptLoader(LuaCsSetup setup) : base(isCollectible: true)
|
public CsScriptLoader(LuaCsSetup setup)
|
||||||
{
|
{
|
||||||
this.setup = setup;
|
this.setup = setup;
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ namespace Barotrauma
|
|||||||
var syntaxTrees = new List<SyntaxTree>();
|
var syntaxTrees = new List<SyntaxTree>();
|
||||||
|
|
||||||
if (sources.Count <= 0) throw new Exception("No Cs sources detected");
|
if (sources.Count <= 0) throw new Exception("No Cs sources detected");
|
||||||
|
syntaxTrees.Add(AssemblyInfoSyntaxTree(NET_SCRIPT_ASSEMBLY));
|
||||||
foreach ((var folder, var src) in sources)
|
foreach ((var folder, var src) in sources)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -92,7 +93,7 @@ namespace Barotrauma
|
|||||||
.WithMetadataImportOptions(MetadataImportOptions.All)
|
.WithMetadataImportOptions(MetadataImportOptions.All)
|
||||||
.WithOptimizationLevel(OptimizationLevel.Release)
|
.WithOptimizationLevel(OptimizationLevel.Release)
|
||||||
.WithAllowUnsafe(false);
|
.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())
|
using (var mem = new MemoryStream())
|
||||||
{
|
{
|
||||||
@@ -153,10 +154,5 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Assembly = null;
|
Assembly = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
~CsScriptLoader()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ using MoonSharp.Interpreter;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class CsScriptRunner : AssemblyLoadContext
|
class CsScriptRunner : CsScriptBase
|
||||||
{
|
{
|
||||||
public LuaCsSetup setup;
|
public LuaCsSetup setup;
|
||||||
private List<MetadataReference> defaultReferences;
|
private List<MetadataReference> defaultReferences;
|
||||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
|||||||
"System.Linq"
|
"System.Linq"
|
||||||
};
|
};
|
||||||
|
|
||||||
public CsScriptRunner(LuaCsSetup setup) : base(isCollectible: true)
|
public CsScriptRunner(LuaCsSetup setup)
|
||||||
{
|
{
|
||||||
this.setup = setup;
|
this.setup = setup;
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
code = ToOneTimeScript(code);
|
code = ToOneTimeScript(code);
|
||||||
var syntaxTree = SyntaxFactory.ParseSyntaxTree(code, CSharpParseOptions.Default);
|
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;
|
Assembly assembly = null;
|
||||||
using (var mem = new MemoryStream())
|
using (var mem = new MemoryStream())
|
||||||
@@ -103,8 +103,7 @@ namespace Barotrauma
|
|||||||
scriptResilt = method.Invoke(runner, null);
|
scriptResilt = method.Invoke(runner, null);
|
||||||
foreach (var type in assembly.GetTypes())
|
foreach (var type in assembly.GetTypes())
|
||||||
{
|
{
|
||||||
//UserData.UnregisterType(type, true);
|
UserData.UnregisterType(type, true);
|
||||||
UserData.UnregisterType(type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else LuaCsSetup.PrintCsError("Script Error - no run method detected");
|
else LuaCsSetup.PrintCsError("Script Error - no run method detected");
|
||||||
@@ -115,6 +114,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Unload();
|
Unload();
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,8 +13,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var type = Type.GetType(typeName);
|
var type = Type.GetType(typeName);
|
||||||
if (type != null) return type;
|
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);
|
type = a.GetType(typeName);
|
||||||
if (type != null)
|
if (type != null)
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("NetScriptAssembly", AllInternalsVisible = true)]
|
[assembly: InternalsVisibleTo(Barotrauma.CsScriptBase.NET_SCRIPT_ASSEMBLY, AllInternalsVisible = true)]
|
||||||
[assembly: InternalsVisibleTo("NetOneTimeScriptAssembly", AllInternalsVisible = true)]
|
[assembly: InternalsVisibleTo(Barotrauma.CsScriptBase.NET_ONE_TIME_SCRIPT_ASSEMBLY, AllInternalsVisible = true)]
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
class LuaCsSetupConfig
|
class LuaCsSetupConfig
|
||||||
@@ -40,6 +40,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Script lua;
|
private Script lua;
|
||||||
public CsScriptRunner CsScript { get; private set; }
|
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 LuaGame Game { get; private set; }
|
||||||
public LuaScriptLoader LuaScriptLoader { get; private set; }
|
public LuaScriptLoader LuaScriptLoader { get; private set; }
|
||||||
|
|
||||||
@@ -314,9 +325,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Stop()
|
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();
|
foreach (var mod in ACsMod.LoadedMods.ToArray()) mod.Dispose();
|
||||||
ACsMod.LoadedMods.Clear();
|
ACsMod.LoadedMods.Clear();
|
||||||
@@ -450,7 +461,8 @@ modding needs.
|
|||||||
var modTypes = CsScriptLoader.Compile();
|
var modTypes = CsScriptLoader.Compile();
|
||||||
modTypes.ForEach(t =>
|
modTypes.ForEach(t =>
|
||||||
{
|
{
|
||||||
UserData.RegisterType(t);
|
//Please register `t` in lua-side
|
||||||
|
//UserData.RegisterType(t);
|
||||||
t.GetConstructor(new Type[] { })?.Invoke(null);
|
t.GetConstructor(new Type[] { })?.Invoke(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user