This action will force synchronization from jzt/UnityFun, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
local debugger_stackInfo = nillocal coro_debugger = nillocal debugger_require = requirelocal debugger_exeLuaString = nillocal loadstring_ = nilif(loadstring) thenloadstring_ = loadstringelseloadstring_ = loadendlocal LuaDebugTool_ = nilif(LuaDebugTool) thenLuaDebugTool_ = LuaDebugToolelseif(CS and CS.LuaDebugTool) thenLuaDebugTool_ = CS.LuaDebugTool;endlocal LuaDebugTool = LuaDebugTool_local loadstring = loadstring_local getinfo = debug.getinfolocal function createSocket()local base = _Glocal string = require("string")local math = require("math")local socket = require("socket.core")local _M = socket------------------------------------------------------------------------------- Exported auxiliar functions-----------------------------------------------------------------------------function _M.connect4(address, port, laddress, lport)return socket.connect(address, port, laddress, lport, "inet")endfunction _M.connect6(address, port, laddress, lport)return socket.connect(address, port, laddress, lport, "inet6")endif(not _M.connect) thenfunction _M.connect(address, port, laddress, lport)local sock, err = socket.tcp()if not sock then return nil, err endif laddress thenlocal res, err = sock:bind(laddress, lport, -1)if not res then return nil, err endendlocal res, err = sock:connect(address, port)if not res then return nil, err endreturn sockendendfunction _M.bind(host, port, backlog)if host == "*" then host = "0.0.0.0" endlocal addrinfo, err = socket.dns.getaddrinfo(host);if not addrinfo then return nil, err endlocal sock, reserr = "no info on address"for i, alt in base.ipairs(addrinfo) doif alt.family == "inet" thensock, err = socket.tcp4()elsesock, err = socket.tcp6()endif not sock then return nil, err endsock:setoption("reuseaddr", true)res, err = sock:bind(alt.addr, port)if not res thensock:close()elseres, err = sock:listen(backlog)if not res thensock:close()elsereturn sockendendendreturn nil, errend_M.try = _M.newtry()function _M.choose(table)return function(name, opt1, opt2)if base.type(name) ~= "string" thenname, opt1, opt2 = "default", name, opt1endlocal f = table[name or "nil"]if not f then base.error("unknown key (" .. base.tostring(name) .. ")", 3)else return f(opt1, opt2) endendend------------------------------------------------------------------------------- Socket sources and sinks, conforming to LTN12------------------------------------------------------------------------------- create namespaces inside LuaSocket namespacelocal sourcet, sinkt = {}, {}_M.sourcet = sourcet_M.sinkt = sinkt_M.BLOCKSIZE = 2048sinkt["close-when-done"] = function(sock)return base.setmetatable({getfd = function() return sock:getfd() end,dirty = function() return sock:dirty() end}, {__call = function(self, chunk, err)if not chunk thensock:close()return 1else return sock:send(chunk) endend})endsinkt["keep-open"] = function(sock)return base.setmetatable({getfd = function() return sock:getfd() end,dirty = function() return sock:dirty() end}, {__call = function(self, chunk, err)if chunk then return sock:send(chunk)else return 1 endend})endsinkt["default"] = sinkt["keep-open"]_M.sink = _M.choose(sinkt)sourcet["by-length"] = function(sock, length)return base.setmetatable({getfd = function() return sock:getfd() end,dirty = function() return sock:dirty() end}, {__call = function()if length <= 0 then return nil endlocal size = math.min(socket.BLOCKSIZE, length)local chunk, err = sock:receive(size)if err then return nil, err endlength = length - string.len(chunk)return chunkend})endsourcet["until-closed"] = function(sock)local donereturn base.setmetatable({getfd = function() return sock:getfd() end,dirty = function() return sock:dirty() end}, {__call = function()if done then return nil endlocal chunk, err, partial = sock:receive(socket.BLOCKSIZE)if not err then return chunkelseif err == "closed" thensock:close()done = 1return partialelse return nil, err endend})endsourcet["default"] = sourcet["until-closed"]_M.source = _M.choose(sourcet)return _Mendlocal function createJson()local math = require('math')local string = require("string")local table = require("table")local object = nil------------------------------------------------------------------------------- Module declaration-----------------------------------------------------------------------------local json = {} -- Public namespacelocal json_private = {} -- Private namespace-- Public constantsjson.EMPTY_ARRAY = {}json.EMPTY_OBJECT = {}-- Public functions-- Private functionslocal decode_scanArraylocal decode_scanCommentlocal decode_scanConstantlocal decode_scanNumberlocal decode_scanObjectlocal decode_scanStringlocal decode_scanWhitespacelocal encodeStringlocal isArraylocal isEncodable------------------------------------------------------------------------------- PUBLIC FUNCTIONS-------------------------------------------------------------------------------- Encodes an arbitrary Lua object / variable.-- @param v The Lua object / variable to be JSON encoded.-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)function json.encode(v)-- Handle nil valuesif v == nil thenreturn "null"endlocal vtype = type(v)-- Handle stringsif vtype == 'string' thenreturn "\"" .. json_private.encodeString(v) .. "\"" -- Need to handle encoding in stringend-- Handle booleansif vtype == 'number' or vtype == 'boolean' thenreturn tostring(v)end-- Handle tablesif vtype == 'table' thenlocal rval = {}-- Consider arrays separatelylocal bArray, maxCount = isArray(v)if bArray thenfor i = 1, maxCount dotable.insert(rval, json.encode(v[i]))endelse -- An object, not an arrayfor i, j in pairs(v) doif isEncodable(i) and isEncodable(j) thentable.insert(rval, "\"" .. json_private.encodeString(i) .. '\":' .. json.encode(j))endendendif bArray thenreturn '[' .. table.concat(rval, ',') .. ']'elsereturn '{' .. table.concat(rval, ',') .. '}'endend-- Handle null valuesif vtype == 'function' and v == json.null thenreturn 'null'endassert(false, 'encode attempt to encode unsupported type ' .. vtype .. ':' .. tostring(v))end--- Decodes a JSON string and returns the decoded value as a Lua data structure / value.-- @param s The string to scan.-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,-- and the position of the first character after-- the scanned JSON object.function json.decode(s, startPos)startPos = startPos and startPos or 1startPos = decode_scanWhitespace(s, startPos)assert(startPos <= string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')local curChar = string.sub(s, startPos, startPos)-- Objectif curChar == '{' thenreturn decode_scanObject(s, startPos)end-- Arrayif curChar == '[' thenreturn decode_scanArray(s, startPos)end-- Numberif string.find("+-0123456789.e", curChar, 1, true) thenreturn decode_scanNumber(s, startPos)end-- Stringif curChar == "\"" or curChar == [[']] thenreturn decode_scanString(s, startPos)endif string.sub(s, startPos, startPos + 1) == '/*' thenreturn json.decode(s, decode_scanComment(s, startPos))end-- Otherwise, it must be a constantreturn decode_scanConstant(s, startPos)end--- The null function allows one to specify a null value in an associative array (which is otherwise-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }function json.null()return json.null -- so json.null() will also return null ;-)end------------------------------------------------------------------------------- Internal, PRIVATE functions.-- Following a Python-like convention, I have prefixed all these 'PRIVATE'-- functions with an underscore.-------------------------------------------------------------------------------- Scans an array from JSON into a Lua object-- startPos begins at the start of the array.-- Returns the array and the next starting position-- @param s The string being scanned.-- @param startPos The starting position for the scan.-- @return table, int The scanned array as a table, and the position of the next character to scan.function decode_scanArray(s, startPos)local array = {} -- The return valuelocal stringLen = string.len(s)assert(string.sub(s, startPos, startPos) == '[', 'decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n' .. s)startPos = startPos + 1-- Infinite loop for array elementsrepeatstartPos = decode_scanWhitespace(s, startPos)assert(startPos <= stringLen, 'JSON String ended unexpectedly scanning array.')local curChar = string.sub(s, startPos, startPos)if(curChar == ']') thenreturn array, startPos + 1endif(curChar == ',') thenstartPos = decode_scanWhitespace(s, startPos + 1)endassert(startPos <= stringLen, 'JSON String ended unexpectedly scanning array.')object, startPos = json.decode(s, startPos)table.insert(array, object)until falseend--- Scans a comment and discards the comment.-- Returns the position of the next character following the comment.-- @param string s The JSON string to scan.-- @param int startPos The starting position of the commentfunction decode_scanComment(s, startPos)assert(string.sub(s, startPos, startPos + 1) == '/*', "decode_scanComment called but comment does not start at position " .. startPos)local endPos = string.find(s, '*/', startPos + 2)assert(endPos ~= nil, "Unterminated comment in string at " .. startPos)return endPos + 2end--- Scans for given constants: true, false or null-- Returns the appropriate Lua type, and the position of the next character to read.-- @param s The string being scanned.-- @param startPos The position in the string at which to start scanning.-- @return object, int The object (true, false or nil) and the position at which the next character should be-- scanned.function decode_scanConstant(s, startPos)local consts = {["true"] = true, ["false"] = false, ["null"] = nil}local constNames = {"true", "false", "null"}for i, k in pairs(constNames) doif string.sub(s, startPos, startPos + string.len(k) - 1) == k thenreturn consts[k], startPos + string.len(k)endendassert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)end--- Scans a number from the JSON encoded string.-- (in fact, also is able to scan numeric +- eqns, which is not-- in the JSON spec.)-- Returns the number, and the position of the next character-- after the number.-- @param s The string being scanned.-- @param startPos The position at which to start scanning.-- @return number, int The extracted number and the position of the next character to scan.function decode_scanNumber(s, startPos)local endPos = startPos + 1local stringLen = string.len(s)local acceptableChars = "+-0123456789.e"while(string.find(acceptableChars, string.sub(s, endPos, endPos), 1, true)and endPos <= stringLen) doendPos = endPos + 1endlocal stringValue = 'return ' .. string.sub(s, startPos, endPos - 1)local stringEval = loadstring(stringValue)assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)return stringEval(), endPosend--- Scans a JSON object into a Lua object.-- startPos begins at the start of the object.-- Returns the object and the next starting position.-- @param s The string being scanned.-- @param startPos The starting position of the scan.-- @return table, int The scanned object as a table and the position of the next character to scan.function decode_scanObject(s, startPos)local object = {}local stringLen = string.len(s)local key, valueassert(string.sub(s, startPos, startPos) == '{', 'decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)startPos = startPos + 1repeatstartPos = decode_scanWhitespace(s, startPos)assert(startPos <= stringLen, 'JSON string ended unexpectedly while scanning object.')local curChar = string.sub(s, startPos, startPos)if(curChar == '}') thenreturn object, startPos + 1endif(curChar == ',') thenstartPos = decode_scanWhitespace(s, startPos + 1)endassert(startPos <= stringLen, 'JSON string ended unexpectedly scanning object.')-- Scan the keykey, startPos = json.decode(s, startPos)assert(startPos <= stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)startPos = decode_scanWhitespace(s, startPos)assert(startPos <= stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)assert(string.sub(s, startPos, startPos) == ':', 'JSON object key-value assignment mal-formed at ' .. startPos)startPos = decode_scanWhitespace(s, startPos + 1)assert(startPos <= stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)value, startPos = json.decode(s, startPos)object[key] = valueuntil false -- infinite loop while key-value pairs are foundend-- START SoniEx2-- Initialize some things used by decode_scanString-- You know, for efficiencylocal escapeSequences = {["\\t"] = "\t",["\\f"] = "\f",["\\r"] = "\r",["\\n"] = "\n",["\\b"] = ""}setmetatable(escapeSequences, {__index = function(t, k)-- skip "\" aka strip escapereturn string.sub(k, 2)end})-- END SoniEx2--- Scans a JSON string from the opening inverted comma or single quote to the-- end of the string.-- Returns the string extracted as a Lua string,-- and the position of the next non-string character-- (after the closing inverted comma or single quote).-- @param s The string being scanned.-- @param startPos The starting position of the scan.-- @return string, int The extracted string as a Lua string, and the next character to parse.function decode_scanString(s, startPos)assert(startPos, 'decode_scanString(..) called without start position')local startChar = string.sub(s, startPos, startPos)-- START SoniEx2-- PS: I don't think single quotes are valid JSONassert(startChar == "\"" or startChar == [[']], 'decode_scanString called for a non-string')--assert(startPos, "String decoding failed: missing closing " .. startChar .. " for string at position " .. oldStart)local t = {}local i, j = startPos, startPoswhile string.find(s, startChar, j + 1) ~= j + 1 dolocal oldj = ji, j = string.find(s, "\\.", j + 1)local x, y = string.find(s, startChar, oldj + 1)if not i or x < i theni, j = x, y - 1endtable.insert(t, string.sub(s, oldj + 1, i - 1))if string.sub(s, i, j) == "\\u" thenlocal a = string.sub(s, j + 1, j + 4)j = j + 4local n = tonumber(a, 16)assert(n, "String decoding failed: bad Unicode escape " .. a .. " at position " .. i .. " : " .. j)-- math.floor(x/2^y) == lazy right shift-- a % 2^b == bitwise_and(a, (2^b)-1)-- 64 = 2^6-- 4096 = 2^12 (or 2^6 * 2^6)local xif n < 128 thenx = string.char(n % 128)elseif n < 2048 then-- [110x xxxx] [10xx xxxx]x = string.char(192 +(math.floor(n / 64) % 32), 128 +(n % 64))else-- [1110 xxxx] [10xx xxxx] [10xx xxxx]x = string.char(224 +(math.floor(n / 4096) % 16), 128 +(math.floor(n / 64) % 64), 128 +(n % 64))endtable.insert(t, x)elsetable.insert(t, escapeSequences[string.sub(s, i, j)])endendtable.insert(t, string.sub(j, j + 1))assert(string.find(s, startChar, j + 1), "String decoding failed: missing closing " .. startChar .. " at position " .. j .. "(for string at position " .. startPos .. ")")return table.concat(t, ""), j + 2-- END SoniEx2end--- Scans a JSON string skipping all whitespace from the current start position.-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.-- @param s The string being scanned-- @param startPos The starting position where we should begin removing whitespace.-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string-- was reached.function decode_scanWhitespace(s, startPos)local whitespace = " \n\r\t"local stringLen = string.len(s)while(string.find(whitespace, string.sub(s, startPos, startPos), 1, true) and startPos <= stringLen) dostartPos = startPos + 1endreturn startPosend--- Encodes a string to be JSON-compatible.-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)-- @param s The string to return as a JSON encoded (i.e. backquoted string)-- @return The string appropriately escaped.local escapeList = {["\""] = '\\\"',['\\'] = '\\\\',['/'] = '\\/',[''] = '\\b',['\f'] = '\\f',['\n'] = '\\n',['\r'] = '\\r',['\t'] = '\\t'}function json_private.encodeString(s)local s = tostring(s)return s:gsub(".", function(c) return escapeList[c] end) -- SoniEx2: 5.0 compatend-- Determines whether the given Lua type is an array or a table / dictionary.-- We consider any table an array if it has indexes 1..n for its n items, and no-- other data in the table.-- I think this method is currently a little 'flaky', but can't think of a good way around it yet...-- @param t The table to evaluate as an array-- @return boolean, number True if the table can be represented as an array, false otherwise. If true,-- the second returned value is the maximum-- number of indexed elements in the array.function isArray(t)-- Next we count all the elements, ensuring that any non-indexed elements are not-encodable-- (with the possible exception of 'n')if(t == json.EMPTY_ARRAY) then return true, 0 endif(t == json.EMPTY_OBJECT) then return false endlocal maxIndex = 0for k, v in pairs(t) doif(type(k) == 'number' and math.floor(k) == k and 1 <= k) then -- k,v is an indexed pairif(not isEncodable(v)) then return false end -- All array elements must be encodablemaxIndex = math.max(maxIndex, k)elseif(k == 'n') thenif v ~=(t.n or # t) then return false end -- False if n does not hold the number of elementselse -- Else of (k=='n')if isEncodable(v) then return false endend -- End of (k~='n')end -- End of k,v not an indexed pairend -- End of loop across all pairsreturn true, maxIndexend--- Determines whether the given Lua object / table / variable can be JSON encoded. The only-- types that are JSON encodable are: string, boolean, number, nil, table and json.null.-- In this implementation, all other types are ignored.-- @param o The object to examine.-- @return boolean True if the object should be JSON encoded, false if it should be ignored.function isEncodable(o)local t = type(o)return(t == 'string' or t == 'boolean' or t == 'number' or t == 'nil' or t == 'table') or(t == 'function' and o == json.null)endreturn jsonendlocal debugger_print = printlocal debug_server = nillocal breakInfoSocket = nillocal json = createJson()local LuaDebugger = {fileMaps = {},Run = true, --表示正常运行只检测断点StepIn = false,StepInLevel = 0,StepNext = false,StepNextLevel = 0,StepOut = false,breakInfos = {},runTimeType = nil,isHook = true,pathCachePaths = {},isProntToConsole = 1,isDebugPrint = true,hookType = "lrc",currentFileName = "",currentTempFunc = nil,--分割字符串缓存splitFilePaths = {},DebugLuaFie="",version="1.0.1"}LuaDebugger.event = {S2C_SetBreakPoints = 1,C2S_SetBreakPoints = 2,S2C_RUN = 3,C2S_HITBreakPoint = 4,S2C_ReqVar = 5,C2S_ReqVar = 6,--单步跳过请求S2C_NextRequest = 7,--单步跳过反馈C2S_NextResponse = 8,-- 单步跳过 结束 没有下一步C2S_NextResponseOver = 9,--单步跳入S2C_StepInRequest = 10,C2S_StepInResponse = 11,--单步跳出S2C_StepOutRequest = 12,--单步跳出返回C2S_StepOutResponse = 13,--打印C2S_LuaPrint = 14,S2C_LoadLuaScript = 16,C2S_SetSocketName = 17,C2S_LoadLuaScript = 18,C2S_DebugXpCall = 20,S2C_DebugClose = 21}function print1(...)if(LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 3) thendebugger_print(...)endif(LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 2) thenif(debug_server) thenlocal arg = {...} --这里的...和{}符号中间需要有空格号,否则会出错local str = ""for k, v in pairs(arg) dostr = str .. tostring(v) .. "\t"endlocal sendMsg = {event = LuaDebugger.event.C2S_LuaPrint,data = {msg = str}}local sendStr = json.encode(sendMsg)debug_server:send(sendStr .. "__debugger_k0204__")endendendprint = print1----=============================工具方法=============================================local debug_hook = nillocal function debugger_strSplit(input, delimiter)input = tostring(input)delimiter = tostring(delimiter)if(delimiter == '') then return false endlocal pos, arr = 0, {}-- for each divider foundfor st, sp in function() return string.find(input, delimiter, pos, true) end dotable.insert(arr, string.sub(input, pos, st - 1))pos = sp + 1endtable.insert(arr, string.sub(input, pos))return arrendlocal function debugger_strTrim(input)input = string.gsub(input, "^[ \t\n\r]+", "")return string.gsub(input, "[ \t\n\r]+$", "")endlocal function debugger_dump(value, desciption, nesting)if type(nesting) ~= "number" then nesting = 3 endlocal lookupTable = {}local result = {}local function _v(v)if type(v) == "string" thenv = "\"" .. v .. "\""endreturn tostring(v)endlocal traceback = debugger_strSplit(debug.traceback("", 2), "\n")print1("dump from: " .. debugger_strTrim(traceback[3]))local function _dump(value, desciption, indent, nest, keylen)desciption = desciption or "<var>"spc = ""if type(keylen) == "number" thenspc = string.rep(" ", keylen - string.len(_v(desciption)))endif type(value) ~= "table" thenresult[# result + 1] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))elseif lookupTable[value] thenresult[# result + 1] = string.format("%s%s%s = *REF*", indent, desciption, spc)elselookupTable[value] = trueif nest > nesting thenresult[# result + 1] = string.format("%s%s = *MAX NESTING*", indent, desciption)elseresult[# result + 1] = string.format("%s%s = {", indent, _v(desciption))local indent2 = indent .. " "local keys = {}local keylen = 0local values = {}for k, v in pairs(value) dokeys[# keys + 1] = klocal vk = _v(k)local vkl = string.len(vk)if vkl > keylen then keylen = vkl endvalues[k] = vendtable.sort(keys, function(a, b)if type(a) == "number" and type(b) == "number" thenreturn a < belsereturn tostring(a) < tostring(b)endend)for i, k in ipairs(keys) do_dump(values[k], k, indent2, nest + 1, keylen)endresult[# result + 1] = string.format("%s}", indent)endendend_dump(value, desciption, "- ", 1)for i, line in ipairs(result) doprint1(line)endendlocal function ToBase64(source_str)local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'local s64 = ''local str = source_strwhile # str > 0 dolocal bytes_num = 0local buf = 0for byte_cnt = 1, 3 dobuf =(buf * 256)if # str > 0 thenbuf = buf + string.byte(str, 1, 1)str = string.sub(str, 2)bytes_num = bytes_num + 1endendfor group_cnt = 1,(bytes_num + 1) dolocal b64char = math.fmod(math.floor(buf / 262144), 64) + 1s64 = s64 .. string.sub(b64chars, b64char, b64char)buf = buf * 64endfor fill_cnt = 1,(3 - bytes_num) dos64 = s64 .. '='endendreturn s64endlocal function debugger_setVarInfo(name, value)local vt = type(value)local valueStr = ""if(vt ~= "table") thenvalueStr = tostring(value)valueStr = ToBase64(valueStr)else-- valueStr = topointer(value)endlocal valueInfo = {name = name,valueType = vt,valueStr = valueStr}return valueInfo;endlocal function debugger_getvalue(f)local i = 1local locals = {}-- get localswhile true dolocal name, value = debug.getlocal(f, i)if not name then break endif(name ~= "(*temporary)") thenlocals[name] = valueendi = i + 1endlocal func = getinfo(f, "f").funci = 1local ups = {}while func do -- check for func as it may be nil for tail callslocal name, value = debug.getupvalue(func, i)if not name then break endups[name] = valuei = i + 1endreturn {locals = locals, ups = ups}end--获取堆栈debugger_stackInfo = function(ignoreCount, event)local datas = {}local stack = {}local varInfos = {}local funcs = {}local index = 0;for i = ignoreCount, 100 dolocal source = getinfo(i)local isadd = trueif(i == ignoreCount) thenlocal file = source.sourceif(file:find(LuaDebugger.DebugLuaFie)) thenreturnendif(file == "=[C]") thenisadd = falseendendif not source thenbreak;endif(isadd) thenlocal file = source.sourcelocal info ={src = file,scoreName = source.name,currentline = source.currentline,linedefined = source.linedefined,what = source.what,nameWhat = source.namewhat}index = ilocal vars = debugger_getvalue(i + 1)table.insert(stack, info)table.insert(varInfos, vars)table.insert(funcs, source.func)endif source.what == 'main' then break endendlocal stackInfo = {stack = stack, vars = varInfos, funcs = funcs}local data = {stack = stackInfo.stack,vars = stackInfo.vars,funcs = stackInfo.funcs,event = event,funcsLength = #stackInfo.funcs}LuaDebugger.currentTempFunc = data.funcs[1]return dataend--==============================工具方法 end======================================================--===========================点断信息==================================================--根据不同的游戏引擎进行定时获取断点信息--CCDirector:sharedDirector():getScheduler()local debugger_setBreak = nillocal function debugger_receiveDebugBreakInfo()if(jit) thenif(LuaDebugger.debugLuaType ~= "jit") thenlocal msg = "当前luajit版本为: "..jit.version.." 请使用LuaDebugjit 进行调试!"print(msg)endendif(breakInfoSocket) thenlocal msg, status = breakInfoSocket:receive()if(msg) thenlocal netData = json.decode(msg)if netData.event == LuaDebugger.event.S2C_SetBreakPoints thendebugger_setBreak(netData.data)elseif netData.event == LuaDebugger.event.S2C_LoadLuaScript thenprint("获取数据")debugger_exeLuaString(netData.data, false)endendendendlocal function splitFilePath(path)if(LuaDebugger.splitFilePaths[path]) thenreturn LuaDebugger.splitFilePaths[path]endlocal pos, arr = 0, {}-- for each divider foundfor st, sp in function() return string.find(path, '/', pos, true) end dotable.insert(arr, string.sub(path, pos, st - 1))pos = sp + 1endtable.insert(arr, string.sub(path, pos))LuaDebugger.splitFilePaths[path] = arrreturn arrenddebugger_setBreak = function(datas)local breakInfos = LuaDebugger.breakInfosfor i, data in ipairs(datas) dolocal breakInfo = breakInfos[data.fileName]if(not breakInfo) thenbreakInfos[data.fileName] = {}breakInfo = breakInfos[data.fileName]endif(not data.lines or # data.lines == 0) thenbreakInfo[data.serverPath] = nilelselocal lineInfos = {}for li, line in ipairs(data.lines) dolineInfos[line] = trueendbreakInfo[data.serverPath] = {pathNames = splitFilePath(data.serverPath),lines = lineInfos}endlocal count = 0for i, linesInfo in pairs(breakInfo) docount = count + 1endif(count == 0) thenbreakInfos[data.fileName] = nilendend--debugger_dump(breakInfos, "breakInfos", 6)--检查是否需要断点local isHook = falsefor k, v in pairs(breakInfos) doisHook = truebreakend--这样做的原因是为了最大限度的使手机调试更加流畅 注意这里会连续的进行n次if(isHook) thenif(not LuaDebugger.isHook) thendebug.sethook(debug_hook, "lrc")endLuaDebugger.isHook = trueelseif(LuaDebugger.isHook) thendebug.sethook()endLuaDebugger.isHook = falseendendlocal function debugger_checkFileIsBreak(fileName)return LuaDebugger.breakInfos[fileName]endlocal function debugger_checkIsBreak(fileName, line)local breakInfo = LuaDebugger.breakInfos[fileName]if(breakInfo) thenlocal ischeck = falsefor k, lineInfo in pairs(breakInfo) dolocal lines = lineInfo.linesif(lines and lines[line]) thenischeck = truebreakendendif(not ischeck) then return end--并且在断点中local info = getinfo(3)local source = info.sourcesource = source:gsub("\\", "/")if source:find("@") == 1 thensource = source:sub(2);endlocal index = source:find("%.lua")if not index thensource = source .. ".lua"endlocal hitPathNames = splitFilePath(source)local isHit = truelocal hitCounts = {}for k, lineInfo in pairs(breakInfo) dolocal lines = lineInfo.lineslocal pathNames = lineInfo.pathNamesif(lines and lines[line]) then--判断路径hitCounts[k] = 0local hitPathNamesCount = # hitPathNameslocal pathNamesCount = # pathNameswhile(true) doif(pathNames[pathNamesCount] ~= hitPathNames[hitPathNamesCount]) thenisHit = falsebreakelsehitCounts[k] = hitCounts[k] + 1endpathNamesCount = pathNamesCount - 1hitPathNamesCount = hitPathNamesCount - 1if(pathNamesCount <= 0 or hitPathNamesCount <= 0) thenbreak;endendendendlocal hitFieName = ""local maxCount = 0for k, v in pairs(hitCounts) doif(v > maxCount) thenmaxCount = vhitFieName = k;endendif(# hitPathNames == 1 or(# hitPathNames > 1 and maxCount > 1)) thenif(hitFieName ~= "") thenreturn hitFieNameendendendreturn falseend--=====================================断点信息 end ----------------------------------------------local controller_host = "192.168.1.102"local controller_port = 7003local function debugger_sendMsg(serverSocket, eventName, data)local sendMsg = {event = eventName,data = data}local sendStr = json.encode(sendMsg)serverSocket:send(sendStr .. "__debugger_k0204__")end--执行lua字符串debugger_exeLuaString = function(data, isBreakPoint)local function loadScript()local luastr = data.luastrif(isBreakPoint) thenlocal currentTabble = {_G = _G}local frameId = data.frameIdframeId = frameId + 1local func = LuaDebugger.currentDebuggerData.funcs[frameId];local vars = LuaDebugger.currentDebuggerData.vars[frameId]local locals = vars.locals;local ups = vars.upsfor k, v in pairs(ups) docurrentTabble[k] = vendfor k, v in pairs(locals) docurrentTabble[k] = vendsetmetatable(currentTabble, {__index = _G})local fun = loadstring(luastr)setfenv(fun, currentTabble)fun()elselocal fun = loadstring(luastr)fun()endendlocal status, msg = xpcall(loadScript, function(error)print(error)end)if(status) thendebugger_sendMsg(debug_server, LuaDebugger.event.C2S_LoadLuaScript, {msg = "执行代码成功"})if(isBreakPoint) thendebugger_sendMsg(debug_server, LuaDebugger.event.C2S_HITBreakPoint, LuaDebugger.currentDebuggerData.stack)endelsedebugger_sendMsg(debug_server, LuaDebugger.event.C2S_LoadLuaScript, {msg = "加载代码失败"})endendlocal function getLuaFileName(str)local pos = 0local fileName = "";-- for each divider foundfor st, sp in function() return string.find(str, '/', pos, true) end dopos = sp + 1endfileName = string.sub(str, pos)return fileName;endlocal function getSource(source)if(LuaDebugger.pathCachePaths[source]) thenreturn LuaDebugger.pathCachePaths[source]endlocal file = sourcefile = file:gsub("\\", "/")if file:find("@") == 1 thenfile = file:sub(2);endlocal index = file:find("%.lua")if not index thenfile = file .. ".lua"endfile = getLuaFileName(file)LuaDebugger.pathCachePaths[source] = filereturn file;endlocal function debugger_GeVarInfoBytUserData(server,var,variablesReference,debugSpeedIndex)local fileds = LuaDebugTool.getUserDataInfo(var)local varInfos = {}if(tolua) thenlocal luavars = tolua.getpeer(vars)if(luavars) thenfor k, v in pairs(luavars) dolocal vinfo = debugger_setVarInfo(k, v)table.insert(varInfos, vinfo)endendend--c# varsfor i=1,fileds.Count dolocal filed = fileds[i-1]local valueInfo = {name = filed.name,valueType = filed.valueType,valueStr = ToBase64(filed.valueStr),isValue = filed.isValue}table.insert( varInfos,valueInfo)enddebugger_sendMsg(server, LuaDebugger.event.C2S_ReqVar, {variablesReference = variablesReference,debugSpeedIndex = debugSpeedIndex,vars = varInfos,isComplete = 1})end--获取lua 变量的方法local function debugger_getBreakVar(body, server)local variablesReference = body.variablesReferencelocal debugSpeedIndex = body.debugSpeedIndexlocal vinfos = {}local function exe()local frameId = body.frameId;local type_ = body.type;local keys = body.keys;--找到对应的varlocal vars = nilif(type_ == 1) thenvars = LuaDebugger.currentDebuggerData.vars[frameId + 1]vars = vars.localselseif(type_ == 2) thenvars = LuaDebugger.currentDebuggerData.vars[frameId + 1]vars = vars.upselseif(type_ == 3) thenvars = _Gend--特殊处理下for i, v in ipairs(keys) dolocal start_m = string.sub(v,1,1)if(start_m == "[") thenlocal len = string.len( v )local end_m = string.sub(v,len,len)if(end_m == "]") thenv = string.sub(v,2,len-1);endvars = vars[v]elsevars = vars[v]endif(type(vars) == "userdata" and LuaDebugTool == nil) thenvars = tolua.getpeer(vars)endif(vars == nil) thenbreak;endendif(type(vars) == "userdata" and LuaDebugTool) thendebugger_GeVarInfoBytUserData(server,vars,variablesReference,debugSpeedIndex)return;endlocal count = 0;if(vars ~= nil) thenfor k, v in pairs(vars) dolocal vinfo = debugger_setVarInfo(k, v)table.insert(vinfos, vinfo)if(# vinfos > 10) thendebugger_sendMsg(server,LuaDebugger.event.C2S_ReqVar,{variablesReference = variablesReference,debugSpeedIndex = debugSpeedIndex,vars = vinfos,isComplete = 0})vinfos = {}endendenddebugger_sendMsg(server, LuaDebugger.event.C2S_ReqVar, {variablesReference = variablesReference,debugSpeedIndex = debugSpeedIndex,vars = vinfos,isComplete = 1})endxpcall(exe, function(error)print("获取变量错误 错误消息-----------------")print(error)print(debug.traceback("", 2))debugger_sendMsg(server,LuaDebugger.event.C2S_ReqVar,{variablesReference = variablesReference,debugSpeedIndex = debugSpeedIndex,vars = {{name ="error",valueType = "string",valueStr = ToBase64("无法获取属性值"),isValue = false}},isComplete = 1})end)endlocal function ResetDebugInfo()LuaDebugger.Run = falseLuaDebugger.StepIn = falseLuaDebugger.StepNext = falseLuaDebugger.StepOut = falseLuaDebugger.StepNextLevel = 0endlocal function debugger_loop(server)server = debug_server--命令local commandlocal eval_env = {}local argwhile true dolocal line, status = server:receive()if(status == "closed") thendebug.sethook()coroutine.yield()endif(line) thenlocal netData = json.decode(line)local event = netData.event;local body = netData.data;if(event == LuaDebugger.event.S2C_DebugClose) thendebug.sethook()coroutine.yield()elseif event == LuaDebugger.event.S2C_SetBreakPoints then--设置断点信息local function setB()debugger_setBreak(body)endxpcall(setB, function(error)print(error)end)elseif event == LuaDebugger.event.S2C_RUN thenLuaDebugger.runTimeType = body.runTimeTypeLuaDebugger.isProntToConsole = body.isProntToConsoleResetDebugInfo()LuaDebugger.Run = truelocal data = coroutine.yield()LuaDebugger.currentDebuggerData = data;debugger_sendMsg(server, data.event, {stack = data.stack})elseif event == LuaDebugger.event.S2C_ReqVar then--请求数据信息debugger_getBreakVar(body, server)elseif event == LuaDebugger.event.S2C_NextRequest thenResetDebugInfo()LuaDebugger.StepNext = trueLuaDebugger.StepNextLevel = 0;--设置当前文件名和当前行数local data = coroutine.yield()--重置调试信息LuaDebugger.currentDebuggerData = data;debugger_sendMsg(server, data.event, {stack = data.stack})elseif(event == LuaDebugger.event.S2C_StepInRequest) then--单步跳入ResetDebugInfo()LuaDebugger.StepIn = truelocal data = coroutine.yield()--重置调试信息LuaDebugger.currentDebuggerData = data;debugger_sendMsg(server, data.event, {stack = data.stack,eventType = data.eventType})elseif(event == LuaDebugger.event.S2C_StepOutRequest) then--单步跳出ResetDebugInfo()LuaDebugger.StepOut = truelocal data = coroutine.yield()--重置调试信息LuaDebugger.currentDebuggerData = data;debugger_sendMsg(server, data.event, {stack = data.stack,eventType = data.eventType})elseif event == LuaDebugger.event.S2C_LoadLuaScript thendebugger_exeLuaString(body, true)endendendendcoro_debugger = coroutine.create(debugger_loop)debug_hook = function(event, line)if(not LuaDebugger.isHook) thenreturnendif(LuaDebugger.Run) thenif(event == "line") thenlocal isCheck = falsefor k, breakInfo in pairs(LuaDebugger.breakInfos) dofor bk, linesInfo in pairs(breakInfo) doif(linesInfo.lines[line]) thenisCheck = truebreakendendif(isCheck) thenbreakendendif(not isCheck) thenreturnendelseLuaDebugger.currentFileName = nilLuaDebugger.currentTempFunc = nilreturnendend--跳出if(LuaDebugger.StepOut) thenif(event == "line" or event == "call") thenreturnendlocal tempFun = getinfo(2,"f").funcif(LuaDebugger.currentDebuggerData.funcsLength == 1) thenResetDebugInfo();LuaDebugger.Run = trueelseif(LuaDebugger.currentDebuggerData.funcs[2] == tempFun) thenlocal data = debugger_stackInfo(3, LuaDebugger.event.C2S_StepInResponse)--挂起等待调试器作出反应coroutine.resume(coro_debugger, data)endendreturnend-- debugger_dump(LuaDebugger,"LuaDebugger")-- print1(LuaDebugger.StepNextLevel,"LuaDebugger.StepNextLevel")local file = nilif(event == "call") then-- if(not LuaDebugger.StepOut) thenif(not LuaDebugger.Run) thenLuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel+1end-- print1("stepIn",LuaDebugger.StepNextLevel)local stepInfo = getinfo(2,"S")local source = stepInfo.sourceif(source:find(LuaDebugger.DebugLuaFie) or source == "=[C]") thenreturnendfile = getSource(source);LuaDebugger.currentFileName = file-- endelseif(event == "return" or event == "tail return") then-- if(not LuaDebugger.StepOut) thenif(not LuaDebugger.Run) thenLuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel-1endLuaDebugger.currentFileName = nil-- endelseif(event == "line") thenif(LuaDebugger.StepIn) thenlocal data = debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)--挂起等待调试器作出反应LuaDebugger.currentTempFunc = data.funcs[1]coroutine.resume(coro_debugger, data)endif(LuaDebugger.StepNext ) thenif( LuaDebugger.StepNextLevel <= 0) thenlocal data = debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)--挂起等待调试器作出反应LuaDebugger.currentTempFunc = data.funcs[1]coroutine.resume(coro_debugger, data)returnendendlocal stepInfo = nilif(not LuaDebugger.currentFileName) thenstepInfo = getinfo(2,"S")local source = stepInfo.sourceif(source == "=[C]" or source:find(LuaDebugger.DebugLuaFie)) then return endfile = getSource(source);LuaDebugger.currentFileName = fileendfile = LuaDebugger.currentFileName--判断断点local breakInfo = LuaDebugger.breakInfos[file]if(breakInfo) thenlocal ischeck = falsefor k, lineInfo in pairs(breakInfo) dolocal lines = lineInfo.linesif(lines and lines[line]) thenischeck = truebreakendendif(not ischeck) then return end--并且在断点中local info = stepInfoif(not info) theninfo = getinfo(2)endlocal hitPathNames = splitFilePath(file)local hitCounts = {}for k, lineInfo in pairs(breakInfo) dolocal lines = lineInfo.lineslocal pathNames = lineInfo.pathNamesif(lines and lines[line]) then--判断路径hitCounts[k] = 0local hitPathNamesCount = # hitPathNameslocal pathNamesCount = # pathNameswhile(true) doif(pathNames[pathNamesCount] ~= hitPathNames[hitPathNamesCount]) thenbreakelsehitCounts[k] = hitCounts[k] + 1endpathNamesCount = pathNamesCount - 1hitPathNamesCount = hitPathNamesCount - 1if(pathNamesCount <= 0 or hitPathNamesCount <= 0) thenbreak;endendendendlocal hitFieName = ""local maxCount = 0for k, v in pairs(hitCounts) doif(v > maxCount) thenmaxCount = vhitFieName = k;endendlocal hitPathNamesLength = #hitPathNamesif(hitPathNamesLength == 1 or(hitPathNamesLength > 1 and maxCount > 1)) thenif(hitFieName ~= "") thenlocal data = debugger_stackInfo(3, LuaDebugger.event.C2S_HITBreakPoint)--挂起等待调试器作出反应coroutine.resume(coro_debugger, data)endendendendendlocal function debugger_xpcall()--调用 coro_debugger 并传入 参数local data = debugger_stackInfo(4, LuaDebugger.event.C2S_HITBreakPoint)--挂起等待调试器作出反应coroutine.resume(coro_debugger, data)end--调试开始local function start()LuaDebugger.DebugLuaFie = getLuaFileName(getinfo(1).source)local socket = createSocket()print(controller_host)print(controller_port)local server = socket.connect(controller_host, controller_port)debug_server = server;if server then--创建breakInfo socketsocket = createSocket()breakInfoSocket = socket.connect(controller_host, controller_port)if(breakInfoSocket) thenbreakInfoSocket:settimeout(0)debugger_sendMsg(breakInfoSocket, LuaDebugger.event.C2S_SetSocketName, {name = "breakPointSocket"})debugger_sendMsg(server, LuaDebugger.event.C2S_SetSocketName, {name = "mainSocket",version = LuaDebugger.version})xpcall(function()debug.sethook(debug_hook, "lrc")end, function(error)print("error:", error)end)if(jit) thenif(LuaDebugger.debugLuaType ~= "jit") thenprint("error======================================================")local msg = "当前luajit版本为: "..jit.version.." 请使用LuaDebugjit 进行调试!"print(msg)endendcoroutine.resume(coro_debugger, server)endendendfunction StartDebug(host, port)if(not host) thenprint("error host nil")endif(not port) thenprint("error prot nil")endif(type(host) ~= "string") thenprint("error host not string")endif(type(port) ~= "number") thenprint("error host not number")endcontroller_host = hostcontroller_port = portxpcall(start, function(error)-- bodyprint(error)end)return debugger_receiveDebugBreakInfo, debugger_xpcallendreturn StartDebug
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。