public void LoadScript(string scriptString) { CurrentTempScript?.ResetHooks(); if (string.IsNullOrWhiteSpace(scriptString)) { //No script CurrentTempScript = null; return; } var scr = new HookedScriptContainer(scriptString); CurrentTempScript = scr; runningScript = scr; try { Lua.DoString(scr.ScriptString); } catch (Exception ex) { if (ex is InterpreterException e) { throw new Exception(e.DecoratedMessage); } throw ex; } finally { runningScript = null; } }
/// <summary> /// Call a hooked lua function. /// <para/> /// If you want to pass in a single array and want to access it in a single parameter in lua, convert it to a List first: /// <para/> /// C#: runner.Execute("func", List<string>); /// <para/> /// Lua: function func(list) /// </summary> /// <param name="hookName"></param> /// <param name="args"></param> public void Execute(string hookName, params object[] args) { try { foreach (var script in GlobalScripts.Values) { runningScript = script; RunLua(script, hookName, args); runningScript = null; } if (CurrentTempScript != null) { runningScript = CurrentTempScript; RunLua(CurrentTempScript, hookName, args); runningScript = null; } } catch (Exception ex) { if (ex is InterpreterException e) { throw new Exception(e.DecoratedMessage); } throw ex; } finally { runningScript = null; } }
void MakeGlobal(string name) { if (runningScript == null) { return; } if (!GlobalScripts.ContainsKey(name)) { //Unique global scripts GlobalScripts[name] = runningScript; } CurrentTempScript = null; //Remove temp so as to not dupe either way }
private void RunLua(HookedScriptContainer script, string hookName, params object[] args) { var hook = script.GetHook(hookName); if (hook != null) { if (hook.IsCoroutine) { if (hook.Coroutine.Coroutine.State == CoroutineState.Dead || !hook.CheckYieldStatus()) //Doesn't run check yield if coroutine is dead { return; } DynValue ret = hook.Coroutine.Coroutine.Resume(args); switch (hook.Coroutine.Coroutine.State) { case CoroutineState.Suspended: if (ret.IsNotNil()) { Yielder yielder = ret.ToObject <Yielder>(); hook.CurYielder = yielder; } else { hook.CurYielder = null; } break; case CoroutineState.Dead: hook.CurYielder = null; if (hook.AutoResetCoroutine) { hook.Coroutine.Assign(Lua.CreateCoroutine(hook.LuaFunc)); } break; default: break; } } else { Lua.Call(hook.LuaFunc, args); } } }
public bool ApplyStandard(Script script, HookedScriptContainer container, List <string> errors = null) { var g = script.Globals; bool ok = true; for (int i = 0; i < Standards.Count; i++) { try { //Try to see a manually added one exists var hook = container.GetHook(Standards[i].Path); if (hook == null) { //It was not already added var globalItem = g.Get(Standards[i].Path); if (globalItem.Type == DataType.Nil) { if (Standards[i].Required) { //It is required, add error ok = false; errors?.Add($"Script does not contain [{Standards[i].Path}]"); } else { continue; } } else if (globalItem.Type != DataType.Function) { //It is required, and is not a lua function if (Standards[i].Required) { ok = false; errors?.Add($"Script contains [{Standards[i].Path}], but it is not a lua function"); } } else { var funcType = Standards[i].FuncType; if (funcType.HasFlag(FuncType.Function)) { container.AddHook(Standards[i].Path, new ScriptHook(globalItem)); } else if (funcType.HasFlag(FuncType.SingleUseCoroutine)) { container.AddHook(Standards[i].Path, new ScriptHook(globalItem, script.CreateCoroutine(globalItem), false)); } else if (funcType.HasFlag(FuncType.AutoCoroutine)) { container.AddHook(Standards[i].Path, new ScriptHook(globalItem, script.CreateCoroutine(globalItem), true)); } } } else { //Is it already set up? var funcType = Standards[i].FuncType; if (funcType.HasFlag(FuncType.AllowAny)) { continue; } else if (funcType.HasFlag(FuncType.AllowAnyCoroutine)) { if (hook.IsCoroutine) { continue; } else { ok = false; errors?.Add($"User defined hook contains [{Standards[i].Path}], but it is not a coroutine"); } } else if (funcType == FuncType.Function) { if (!hook.IsCoroutine) { continue; } else { ok = false; errors?.Add($"User defined hook contains [{Standards[i].Path}], but it is not a normal function"); } } else if (funcType == FuncType.SingleUseCoroutine) { if (!hook.IsCoroutine || hook.AutoResetCoroutine) { ok = false; errors?.Add($"User defined hook contains [{Standards[i].Path}], but it is not a single-use coroutine"); } else { continue; } } else if (funcType == FuncType.AutoCoroutine) { if (!hook.IsCoroutine || !hook.AutoResetCoroutine) { ok = false; errors?.Add($"User defined hook contains [{Standards[i].Path}], but it is not an automatic coroutine"); } } } } catch { ok = false; errors?.Add($"Script does not contain [{Standards[i].Path}]"); } //Todo: Eventually do Tables too //int len = Standards[i].SplitPath.Length; //if(len == 1) //{ // //Check standard //} //else //{ // try // { // DynValue cur = script.Globals.Get(Standards[i].SplitPath[0]); // for (int j = 1; j < len; j++) // { // if(cur.) // } // } // catch // { // } //} } return(ok); }