static LuaResult FakePcall(UIntPtr L, int nargs, int nresults, int errfunc) { if (!GlobalState.CatchErrors) { return(BBLua.lua_pcall(L, nargs, nresults, errfunc)); } BBLua.lua_pushcclosure(L, ErrorHook.errorHandlerPtr, 0); BBLua.lua_insert(L, -nargs - 2); LuaResult res; if (nresults >= 0) { res = BBLua.lua_pcall(L, nargs, nresults, -nargs - 2); } else //LUA_MULTRET { int stackBefore = BBLua.lua_gettop(L); res = BBLua.lua_pcall(L, nargs, nresults, -nargs - 2); int stackNow = BBLua.lua_gettop(L); if (res == LuaResult.OK) { nresults = stackNow - stackBefore + nargs + 1; } else { nresults = 0; } } if (res != LuaResult.OK) { BBLua.lua_settop(L, -2); //remove errormsg for (int i = 0; i < nresults; i++) //push dummy returns, hopefully settlers accepts this { BBLua.lua_pushnil(L); } } BBLua.lua_remove(L, -nresults - 1); //remove error handler return(LuaResult.OK); }
public string EvaluateLua(string expression) { bool unfreeze = false; if (this.CurrentState == DebugState.Running) { unfreeze = true; if (!GameLoopHook.PauseGame()) { return("Error: Game is busy!"); } } this.DebugEngine.RemoveHook(); string asStatement = expression; expression = "return " + expression; string result = ""; LuaResult err = BBLua.luaL_loadbuffer(this.L, expression, expression.Length, "from console"); if (err == LuaResult.OK) { int stackTop = BBLua.lua_gettop(this.L); err = BBLua.lua_pcall(this.L, 0, -1, 0); int nResults = 1 + BBLua.lua_gettop(this.L) - stackTop; if (nResults == 1) { result = TosToString(); } else if (nResults > 1) { string[] results = new string[nResults]; do { nResults--; results[nResults] = TosToString(true); } while (nResults != 0); result = "(" + string.Join(", ", results) + ")"; } } else { string parseErrExpr = TosToString(); err = BBLua.luaL_loadbuffer(this.L, asStatement, asStatement.Length, "from console"); if (err == LuaResult.OK) { err = BBLua.lua_pcall(this.L, 0, 0, 0); //statement -> no return values } if (err != LuaResult.OK) { result = TosToString(); } } this.DebugEngine.SetHook(); if (unfreeze) { GameLoopHook.ResumeGame(); } return(result); }