Minecraft-Console-Client/MinecraftClient/Scripting/DynamicRun/Builder/CompileRunner.cs
breadbyte d9f1a77ac2
.NET 5+ Support (#1674)
Implement changes to support .NET 5 onwards.
Co-authored-by: ReinforceZwei <39955851+ReinforceZwei@users.noreply.github.com>
Co-authored-by: ORelio <ORelio@users.noreply.github.com>
2022-07-03 22:34:07 +08:00

48 lines
No EOL
1.8 KiB
C#

/*
MIT License
Copyright (c) 2019 Laurent Kempé
https://github.com/laurentkempe/DynamicRun/blob/master/LICENSE
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using MinecraftClient;
namespace DynamicRun.Builder
{
internal class CompileRunner
{
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object> localVars, ChatBot apiHandler)
{
var assemblyLoadContextWeakRef = LoadAndExecute(compiledAssembly, args, localVars, apiHandler);
for (var i = 0; i < 8 && assemblyLoadContextWeakRef.Item1.IsAlive; i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
ConsoleIO.WriteLogLine(assemblyLoadContextWeakRef.Item1.IsAlive ? "Script failed to clean-up" : "Script finished!");
return assemblyLoadContextWeakRef.Item2;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object> localVars, ChatBot apiHandler)
{
using (var asm = new MemoryStream(compiledAssembly))
{
var assemblyLoadContext = new SimpleUnloadableAssemblyLoadContext();
var assembly = assemblyLoadContext.LoadFromStream(asm);
var compiledScript = assembly.CreateInstance("ScriptLoader.Script");
var execResult = compiledScript.GetType().GetMethod("__run").Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, localVars), args });
assemblyLoadContext.Unload();
return new (new WeakReference(assemblyLoadContext), execResult);
}
}
}
}