コード例 #1
0
        //returns false if game was busy
        public bool SaveLoadedFiles()
        {
            bool wasRunning = this.DebugEngine.CurrentState == DebugState.Running;

            if (wasRunning)
            {
                if (!GameLoopHook.PauseGame())
                {
                    return(false);
                }
            }

            string data = CreateFileString();

            BBLua.lua_newtable(this.L);
            int i = 1;

            foreach (string substr in data.SplitBy(15000)) //the limit in shok seems to be at ~ 2^14, otherwise crashes savegame loading
            {
                BBLua.lua_pushstring(this.L, substr);
                BBLua.lua_rawseti(this.L, -2, i);
                i++;
            }
            BBLua.lua_setglobal(this.L, "_LuaDebugger_FileData");

            if (wasRunning)
            {
                GameLoopHook.ResumeGame();
            }

            return(true);
        }
コード例 #2
0
        protected void GetVarAndCleanG(string varName)
        {
            BBLua.lua_getglobal(ls.L, varName); //fetch value

            BBLua.lua_pushnil(ls.L);
            BBLua.lua_setglobal(ls.L, varName); //remove from _G
        }
コード例 #3
0
 protected void RegisterLogFunction()
 {
     BBLua.lua_pushstring(this.ls.L, "LuaDebugger");
     BBLua.lua_newtable(this.ls.L);
     BBLua.lua_pushstring(this.ls.L, "Log");
     BBLua.lua_pushcclosure(this.ls.L, Marshal.GetFunctionPointerForDelegate(this.logCallback), 0);
     BBLua.lua_rawset(this.ls.L, -3);
     BBLua.lua_rawset(this.ls.L, (int)LuaPseudoIndices.GLOBALSINDEX);
 }
コード例 #4
0
        protected unsafe void DebugHook(UIntPtr L, IntPtr ptr) //unsafe for speed
        {
            LuaStackRecord *sr = (LuaStackRecord *)ptr;

            BBLua.lua_getstack(L, 0, ptr);
            if (sr->debugEvent == LuaEvent.Call)
            {
                this.callStack++;
            }
            else if (sr->debugEvent == LuaEvent.Return || sr->debugEvent == LuaEvent.TailReturn)
            {
                this.callStack--;

                if ((this.callStack == 0) && //stepping into engine code is not possible -> resume
                    (this.CurrentRequest == DebugRequest.StepIn || this.CurrentRequest == DebugRequest.StepToLevel))
                {
                    this.CurrentRequest = DebugRequest.Resume;
                    this.CurrentState   = DebugState.Running;
                    FireStateChangedEvent();
                }
            }
            // event == line
            else if (this.CurrentRequest == DebugRequest.Pause || this.CurrentRequest == DebugRequest.StepIn)
            {
                NormalBreak();
            }
            else if (this.CurrentRequest == DebugRequest.StepToLevel && (this.callStack <= this.targetCallStackLevel))
            {
                NormalBreak();
            }
            // request == resume
            else
            {
                List <Breakpoint> bpsAtLine;
                if (!this.lineToBP.TryGetValue(sr->currentline, out bpsAtLine))
                {
                    return; //no breakpoints on this line
                }
                BBLua.lua_getinfo(L, "S", ptr);
                LuaDebugSourceRecord dr = (LuaDebugSourceRecord)Marshal.PtrToStructure(ptr, typeof(LuaDebugSourceRecord));

                foreach (Breakpoint bp in bpsAtLine)
                {
                    if (bp.File.Filename == dr.source)
                    {
                        NormalBreak();
                        break;
                    }
                }
            }
        }
コード例 #5
0
        public static LuaFunctionInfo ReadFunctionInfo(LuaState ls, int level)
        {
            IntPtr memBlock = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LuaDebugRecord)));

            if (BBLua.lua_getstack(ls.L, level, memBlock) == 0)
            {
                return(null);
            }
            BBLua.lua_getinfo(ls.L, "nSlu", memBlock);
            LuaDebugRecord ldr = (LuaDebugRecord)Marshal.PtrToStructure(memBlock, typeof(LuaDebugRecord));

            LuaFunctionInfo lfi = new LuaFunctionInfo(memBlock, ls, ldr.nups);

            if (ldr.source.Length > 1 && ldr.source[0] != '=')
            {
                lfi.Source = ldr.source;
                lfi.Line   = ldr.currentline;
            }
            else
            {
                lfi.Source = "unavailable";
                lfi.Line   = 0;
            }

            if (ldr.what == "C")
            {
                lfi.FunctionName = "Game Engine (direct call)";
            }
            else if (ldr.what == "main")
            {
                lfi.FunctionName = "Game Engine (code outside function)";
            }
            else if (ldr.name != "" && ldr.namewhat != "")
            {
                lfi.FunctionName = ldr.namewhat + " " + ldr.name + "()";
            }
            else if (ldr.what == "Lua" || ldr.what == "tail")
            {
                lfi.FunctionName = "Lua Code";
            }


            if (ls.LoadedFiles.ContainsKey(lfi.Source))
            {
                lfi.CanFakeEnvironment = true;
            }

            return(lfi);
        }
コード例 #6
0
        static int ErrorCatcher(UIntPtr L) //could be moved into DebugEngine, but this would cost perfomance to fetch the correct delegate for each pcall
        {
            string errMsg = BBLua.lua_tostring(L, -1);

            BBLua.lua_settop(L, -2);

            LuaErrorCaught callback;

            if (stateErrHandler.TryGetValue(L, out callback))
            {
                callback(errMsg);
            }

            return(0);
        }
コード例 #7
0
        protected void TryFakeVar(string varName, int n, List <FakeVar> memory)
        {
            BBLua.lua_getglobal(ls.L, varName);
            bool fakePossible = BBLua.lua_type(ls.L, -1) == LuaType.Nil;

            BBLua.lua_settop(ls.L, -2); //remove nil
            if (fakePossible)
            {
                memory.Add(new FakeVar(n, varName));
                BBLua.lua_setglobal(ls.L, varName);
            }
            else
            {
                BBLua.lua_settop(ls.L, -2); //remove value
            }
        }
コード例 #8
0
        //returns false if game was busy
        public bool RestoreLoadedFiles()
        {
            bool wasRunning = this.DebugEngine.CurrentState == DebugState.Running;

            if (wasRunning)
            {
                if (!GameLoopHook.PauseGame())
                {
                    return(false);
                }
            }

            BBLua.lua_getglobal(this.L, "_LuaDebugger_FileData");
            if (BBLua.lua_type(this.L, -1) != LuaType.Table)
            {
                if (wasRunning)
                {
                    GameLoopHook.ResumeGame();
                }
                return(true);
            }

            StringBuilder sb = new StringBuilder();

            for (int i = 1; ; i++)
            {
                BBLua.lua_rawgeti(this.L, -1, i);
                if (BBLua.lua_type(this.L, -1) != LuaType.String)
                {
                    BBLua.lua_settop(this.L, -2);
                    break;
                }
                sb.Append(BBLua.lua_tostring(this.L, -1));
                BBLua.lua_settop(this.L, -2);
            }

            if (wasRunning)
            {
                GameLoopHook.ResumeGame();
            }

            this.LoadedFiles.Clear();

            RestoreFromFileString(sb.ToString());

            return(true);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        public void FakeG()
        {
            this.fakedLocals   = new List <FakeVar>();
            this.fakedUpvalues = new List <FakeVar>();
            if (!this.CanFakeEnvironment)
            {
                return;
            }

            string varName;

            BBLua.lua_getinfo(ls.L, "f", this.funcInfo); // 'f': pushes func onto stack

            for (int i = 1; ; i++)
            {
                varName = BBLua.lua_getupvalue(ls.L, -1, i);
                if (varName == null)
                {
                    break;
                }
                TryFakeVar(varName, i, this.fakedUpvalues);
            }

            BBLua.lua_settop(ls.L, -2); //remove func from stack

            for (int i = 1; ; i++)
            {
                varName = BBLua.lua_getlocal(ls.L, this.funcInfo, i);
                if (varName == null)
                {
                    break;
                }
                if (varName.Length > 0 && varName[0] != '(')
                {
                    TryFakeVar(varName, i, this.fakedLocals);
                }
                else
                {
                    BBLua.lua_settop(ls.L, -2); //remove value
                }
            }
        }
コード例 #11
0
        protected string GetTosFunctionInfo()
        {
            IntPtr memBlock = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LuaDebugRecord)));

            BBLua.lua_getinfo(this.L, ">nSf", memBlock); //fill structure and pop func back onto stack after removing it
            LuaDebugRecord ldr = (LuaDebugRecord)Marshal.PtrToStructure(memBlock, typeof(LuaDebugRecord));

            Marshal.FreeHGlobal(memBlock);

            string source;

            if (ldr.what == "C")
            {
                source = "Game Engine at 0x" + BBLua.lua_tocfunction(this.L, -1).ToInt32().ToString("X");
            }
            else
            {
                source = '\b' + ldr.source + ':' + ldr.linedefined + '\b';//" (line " + ldr.linedefined + ")";
            }
            return("<Function, defined in " + source + ">");
        }
コード例 #12
0
        public void UnFakeG()
        {
            if (!this.CanFakeEnvironment)
            {
                return;
            }

            BBLua.lua_getinfo(ls.L, "f", this.funcInfo); // 'f': pushes func onto stack

            foreach (FakeVar fv in this.fakedUpvalues)
            {
                GetVarAndCleanG(fv.VarName);
                string vn = BBLua.lua_setupvalue(ls.L, -2, fv.Number);
            }

            BBLua.lua_settop(ls.L, -2); //remove func

            foreach (FakeVar fv in this.fakedLocals)
            {
                GetVarAndCleanG(fv.VarName);
                string vn = BBLua.lua_setlocal(ls.L, this.funcInfo, fv.Number);
            }
        }
コード例 #13
0
 public static void lua_newtable(UIntPtr L)
 {
     BBLua.lua_createtable(L, 0, 0);
 }
コード例 #14
0
 public void SetHook()
 {
     BBLua.lua_sethook(this.ls.L, this.debugHook, LuaHookType.Line | LuaHookType.Call | LuaHookType.Return, 0);
 }
コード例 #15
0
 public void RemoveHook()
 {
     BBLua.lua_sethook(this.ls.L, this.debugHook, LuaHookType.Nothing, 0);
 }
コード例 #16
0
        public string TosToString(bool popStack, bool noExpand, Dictionary <IntPtr, bool> printedTables)
        {
            LuaType type = BBLua.lua_type(this.L, -1);
            string  result;

            switch (type)
            {
            case LuaType.Nil:
                result = "nil";
                break;

            case LuaType.Boolean:
                result = BBLua.lua_toboolean(this.L, -1).ToString();
                break;

            case LuaType.Number:
                result = BBLua.lua_tonumber(this.L, -1).ToString();
                break;

            case LuaType.String:
                result = "\"" + BBLua.lua_tostring(this.L, -1) + "\"";
                break;

            case LuaType.Function:
                result = GetTosFunctionInfo();
                break;

            case LuaType.Table:
                if (noExpand)
                {
                    goto default;
                }

                IntPtr tblPtr = BBLua.lua_topointer(this.L, -1);
                if (printedTables.ContainsKey(tblPtr))
                {
                    result = "<Table, recursion>";
                    break;
                }

                result = "{";
                BBLua.lua_pushnil(this.L);
                while (BBLua.lua_next(this.L, -2) != 0)
                {
                    printedTables.Add(tblPtr, true);
                    string val = IndentMultiLine(TosToString(true, false, printedTables));
                    string key = TosToString(false, true, printedTables);
                    printedTables.Remove(tblPtr);

                    if (key[0] == '\"')
                    {
                        string rawString = key.Substring(1, key.Length - 2);
                        if (alphaNumeric.IsMatch(rawString))
                        {
                            result += "\n    " + rawString + " = " + val + ",";
                        }
                        else
                        {
                            result += "\n    [" + key + "] = " + val + ",";
                        }
                    }
                    else
                    {
                        result += "\n    [" + key + "] = " + val + ",";
                    }
                }
                result += "\n}";
                break;

            case LuaType.UserData:
            case LuaType.LightUserData:
                IntPtr ptr = BBLua.lua_touserdata(this.L, -1);
                result = "<" + type.ToString() + ", at 0x" + ptr.ToInt32().ToString("X") + ">";
                break;

            default:
                result = "<" + type.ToString() + ">";
                break;
            }

            if (popStack)
            {
                BBLua.lua_settop(this.L, -2);
            }
            return(result);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
 public static void lua_setglobal(UIntPtr L, string name)
 {
     BBLua.lua_pushstring(L, name);
     BBLua.lua_insert(L, -2);
     BBLua.lua_rawset(L, (int)LuaPseudoIndices.GLOBALSINDEX);
 }