Minecraft-Console-Client/MinecraftClient/Scripting/DynamicRun/Builder/CompileRunner.cs
breadbyte 023cc2e2d4
Fix Linux issues with the scripting system
This fixes bugs in the scripting system in which scripts does not compile and run on Linux.

This commit also changes wording around the logging in the scripting system to avoid confusion between script errors and regular script compilation.
2022-10-14 02:31:31 +08:00

46 lines
No EOL
1.7 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 continues to run." : "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);
}
}
}