2022-07-03 22:34:07 +08:00
|
|
|
|
/*
|
|
|
|
|
|
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
|
|
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
|
2022-07-03 22:34:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
var assemblyLoadContextWeakRef = LoadAndExecute(compiledAssembly, args, localVars, apiHandler);
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < 8 && assemblyLoadContextWeakRef.Item1.IsAlive; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
GC.Collect();
|
|
|
|
|
|
GC.WaitForPendingFinalizers();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-20 20:05:36 +08:00
|
|
|
|
ConsoleIO.WriteLogLine(assemblyLoadContextWeakRef.Item1.IsAlive ? "[Script] Script continues to run." : "[Script] Script finished!");
|
2022-07-03 22:34:07 +08:00
|
|
|
|
return assemblyLoadContextWeakRef.Item2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
2022-10-02 18:31:08 +08:00
|
|
|
|
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
|
2022-07-03 22:34:07 +08:00
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
using var asm = new MemoryStream(compiledAssembly);
|
|
|
|
|
|
var assemblyLoadContext = new SimpleUnloadableAssemblyLoadContext();
|
2022-07-03 22:34:07 +08:00
|
|
|
|
|
2022-10-02 18:31:08 +08:00
|
|
|
|
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 });
|
2022-07-03 22:34:07 +08:00
|
|
|
|
|
2022-10-02 18:31:08 +08:00
|
|
|
|
assemblyLoadContext.Unload();
|
|
|
|
|
|
|
|
|
|
|
|
return new(new WeakReference(assemblyLoadContext), execResult);
|
2022-07-03 22:34:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|