Fixed Script Scheduler bug

This commit is contained in:
Anon 2026-06-06 12:09:36 +02:00
parent 5b13e740ef
commit a5423211ad
6 changed files with 131 additions and 55 deletions

View file

@ -26,7 +26,7 @@ namespace MinecraftClient.Scripting
/// <param name="run">Set to false to compile and cache the script without launching it</param>
/// <exception cref="CSharpException">Thrown if an error occured</exception>
/// <returns>Result of the execution, returned by the script</returns>
public static object? Run(ChatBot apiHandler, string[] lines, string[] args, Dictionary<string, object>? localVars, bool run = true, string scriptName = "Unknown Script")
public static object? Run(ChatBot apiHandler, string[] lines, string[] args, Dictionary<string, object>? localVars, bool run = true, string scriptName = "Unknown Script", string? scriptOwnerKey = null)
{
//Script compatibility check for handling future versions differently
if (lines.Length < 1 || lines[0] != "//MCCScript 1.0")
@ -143,7 +143,7 @@ namespace MinecraftClient.Scripting
{
try
{
var compiled = runner.Execute(assembly!, args, localVars, apiHandler);
var compiled = runner.Execute(assembly!, args, localVars, apiHandler, scriptOwnerKey);
return compiled;
}
catch (Exception e) { throw new CSharpException(CSErrorType.RuntimeError, e); }
@ -209,10 +209,11 @@ namespace MinecraftClient.Scripting
/// <param name="apiHandler">ChatBot API Handler</param>
/// <param name="tickHandler">ChatBot tick handler</param>
/// <param name="localVars">Local variables passed along with the script</param>
public CSharpAPI(ChatBot apiHandler, Dictionary<string, object>? localVars)
public CSharpAPI(ChatBot apiHandler, Dictionary<string, object>? localVars, string? scriptOwnerKey = null)
{
SetMaster(apiHandler);
this.localVars = localVars;
SetScriptOwnerKey(scriptOwnerKey);
}
/// <summary>

View file

@ -39,9 +39,20 @@ namespace MinecraftClient.Scripting
//Handler will be automatically set on bot loading, don't worry about this
public void SetHandler(McClient handler) { _handler = handler; }
protected void SetMaster(ChatBot master) { this.master = master; }
protected void LoadBot(ChatBot bot) { Handler.BotUnLoad(bot); Handler.BotLoad(bot); }
protected void LoadBot(ChatBot bot)
{
if (ScriptOwnerKey is not null)
bot.SetScriptOwnerKey(ScriptOwnerKey);
if (Handler.GetLoadedChatBots().Any(loadedBot => ReferenceEquals(loadedBot, bot)))
Handler.BotUnLoad(bot);
Handler.BotLoad(bot);
}
protected List<ChatBot> GetLoadedChatBots() { return Handler.GetLoadedChatBots(); }
protected void UnLoadBot(ChatBot bot) { Handler.BotUnLoad(bot); }
internal string? ScriptOwnerKey { get; private set; }
internal void SetScriptOwnerKey(string? scriptOwnerKey) { ScriptOwnerKey = scriptOwnerKey; }
private McClient? _handler = null;
private ChatBot? master = null;
private readonly List<string> registeredPluginChannels = new();

View file

@ -13,9 +13,9 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder
{
internal class CompileRunner
{
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
public object? Execute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler, string? scriptOwnerKey = null)
{
var assemblyLoadContextWeakRef = LoadAndExecute(compiledAssembly, args, localVars, apiHandler);
var assemblyLoadContextWeakRef = LoadAndExecute(compiledAssembly, args, localVars, apiHandler, scriptOwnerKey);
for (var i = 0; i < 8 && assemblyLoadContextWeakRef.Item1.IsAlive; i++)
{
@ -28,18 +28,18 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler)
private static Tuple<WeakReference, object?> LoadAndExecute(byte[] compiledAssembly, string[] args, Dictionary<string, object>? localVars, ChatBot apiHandler, string? scriptOwnerKey)
{
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 });
var execResult = compiledScript.GetType().GetMethod("__run")!.Invoke(compiledScript, new object[] { new CSharpAPI(apiHandler, localVars, scriptOwnerKey), args });
assemblyLoadContext.Unload();
return new(new WeakReference(assemblyLoadContext), execResult);
}
}
}
}