local breakSocketHandle,debugXpCall =require("LuaDebug")("localhost",7003)
cc.Director:getInstance():getScheduler():scheduleScriptFunc(breakSocketHandle,0.3,false)
下载LuaDebug.lua
local debugger_stackInfo =nillocal coro_debugger =nillocal debugger_require = require
local debugger_exeLuaString =nillocal loadstring_ =nilif(loadstring)then
loadstring_ = loadstring
else
loadstring_ = load
endlocal ZZBase64 ={}local LuaDebugTool_ =nilif(LuaDebugTool)then
LuaDebugTool_ = LuaDebugTool
elseif(CS and CS.LuaDebugTool)then
LuaDebugTool_ = CS.LuaDebugTool;endlocal LuaDebugTool = LuaDebugTool_
local loadstring = loadstring_
local getinfo = debug.getinfo
localfunctioncreateSocket()local base = _G
local 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()ifnot sock thenreturnnil, err endif laddress thenlocal res, err = sock:bind(laddress, lport,-1)ifnot res thenreturnnil, err endendlocal res, err = sock:connect(address, port)ifnot res thenreturnnil, err endreturn sock
endendfunction _M.bind(host, port, backlog)if host =="*"then host ="0.0.0.0"endlocal addrinfo, err = socket.dns.getaddrinfo(host);ifnot addrinfo thenreturnnil, err endlocal sock, res
err ="no info on address"for i, alt in base.ipairs(addrinfo)doif alt.family =="inet"then
sock, err = socket.tcp4()else
sock, err = socket.tcp6()endifnot sock thenreturnnil, err end
sock:setoption("reuseaddr",true)
res, err = sock:bind(alt.addr, port)ifnot res then
sock:close()else
res, err = sock:listen(backlog)ifnot res then
sock:close()elsereturn sock
endendendreturnnil, err
end
_M.try = _M.newtry()function _M.choose(table)returnfunction(name, opt1, opt2)if base.type(name)~="string"then
name, opt1, opt2 ="default", name, opt1
endlocal f = table[name or"nil"]ifnot f then base.error("unknown key (".. base.tostring(name)..")",3)elsereturnf(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 =2048
sinkt["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)ifnot chunk then
sock:close()return1elsereturn sock:send(chunk)endend})end
sinkt["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 thenreturn sock:send(chunk)elsereturn1endend})end
sinkt["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 <=0thenreturnnilendlocal size = math.min(socket.BLOCKSIZE, length)local chunk, err = sock:receive(size)if err thenreturnnil, err end
length = length - string.len(chunk)return chunk
end})end
sourcet["until-closed"]=function(sock)local done
return base.setmetatable({
getfd =function()return sock:getfd()end,
dirty =function()return sock:dirty()end},{
__call =function()if done thenreturnnilendlocal chunk, err, partial = sock:receive(socket.BLOCKSIZE)ifnot err thenreturn chunk
elseif err =="closed"then
sock:close()
done =1return partial
elsereturnnil, err endend})end
sourcet["default"]= sourcet["until-closed"]
_M.source = _M.choose(sourcet)return _M
endlocalfunctioncreateJson()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 constants
json.EMPTY_ARRAY ={}
json.EMPTY_OBJECT ={}-- Public functions-- Private functionslocal decode_scanArray
local decode_scanComment
local decode_scanConstant
local decode_scanNumber
local decode_scanObject
local decode_scanString
local decode_scanWhitespace
local encodeString
local isArray
local 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 ==nilthenreturn"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'thenreturntostring(v)end-- Handle tablesif vtype =='table'thenlocal rval ={}-- Consider arrays separatelylocal bArray, maxCount =isArray(v)if bArray thenfor i =1, maxCount do
table.insert(rval, json.encode(v[i]))endelse-- An object, not an arrayfor i, j inpairs(v)doifisEncodable(i)andisEncodable(j)then
table.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 or1
startPos =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 =='{'thenreturndecode_scanObject(s, startPos)end-- Arrayif curChar =='['thenreturndecode_scanArray(s, startPos)end-- Numberif string.find("+-0123456789.e", curChar,1,true)thenreturndecode_scanNumber(s, startPos)end-- Stringif curChar =="\""or curChar ==[[']]thenreturndecode_scanString(s, startPos)endif string.sub(s, startPos, startPos +1)=='/*'thenreturn json.decode(s,decode_scanComment(s, startPos))end-- Otherwise, it must be a constantreturndecode_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.functiondecode_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 elementsrepeat
startPos =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 ==',')then
startPos =decode_scanWhitespace(s, startPos +1)endassert(startPos <= stringLen,'JSON String ended unexpectedly scanning array.')
object, startPos = json.decode(s, startPos)
table.insert(array, object)untilfalseend--- 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 commentfunctiondecode_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.functiondecode_scanConstant(s, startPos)local consts ={["true"]=true,["false"]=false,["null"]=nil}local constNames ={"true","false","null"}for i, k inpairs(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.functiondecode_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
)do
endPos = 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)returnstringEval(), endPos
end--- 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.functiondecode_scanObject(s, startPos)local object ={}local stringLen = string.len(s)local key, value
assert(string.sub(s, startPos, startPos)=='{','decode_scanObject called but object does not start at position '.. startPos ..' in string:\n'.. s)
startPos = startPos +1repeat
startPos =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 ==',')then
startPos =decode_scanWhitespace(s, startPos +1)endassert(startPos <= stringLen,'JSON string ended unexpectedly scanning object.')-- Scan the key
key, 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]= value
untilfalse-- 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.functiondecode_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, startPos
while string.find(s, startChar, j +1)~= j +1dolocal oldj = j
i, j = string.find(s,"\\.", j +1)local x, y = string.find(s, startChar, oldj +1)ifnot i or x < i then
i, j = x, y -1end
table.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 x
if n <128then
x = string.char(n %128)elseif n <2048then-- [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))end
table.insert(t, x)else
table.insert(t, escapeSequences[string.sub(s, i, j)])endend
table.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.functiondecode_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)do
startPos = startPos +1endreturn startPos
end--- 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. functionisArray(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)thenreturntrue,0endif(t == json.EMPTY_OBJECT)thenreturnfalseendlocal maxIndex =0for k, v inpairs(t)doif(type(k)=='number'and math.floor(k)== k and1<= k)then-- k,v is an indexed pairif(notisEncodable(v))thenreturnfalseend-- All array elements must be encodable
maxIndex = math.max(maxIndex, k)elseif(k =='n')thenif v ~=(t.n or#t)thenreturnfalseend-- False if n does not hold the number of elementselse-- Else of (k=='n')ifisEncodable(v)thenreturnfalseendend-- End of (k~='n')end-- End of k,v not an indexed pairend-- End of loop across all pairsreturntrue, maxIndex
end--- 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.functionisEncodable(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 json
endlocal debugger_print = print
local 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,
printType =1,
isDebugPrint =true,
hookType ="lrc",
currentFileName ="",
currentTempFunc =nil,
splitFilePaths ={},--分割字符串缓存
DebugLuaFie ="",
version ="1.0.4",-- luajit only
stepNextFun =nil,
runLineCount =0,}
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}functionprint1(...)if((LuaDebugger.printType ==1or LuaDebugger.printType ==3)or(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==3))thendebugger_print(...)endif((LuaDebugger.printType ==1or LuaDebugger.printType ==2)or(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==2))thenif(debug_server)thenlocal arg ={...}local str =""if(#arg ==0)then
arg ={"nil"}endfor k, v inpairs(arg)do
str = str ..tostring(v).."\t"endlocal sendMsg ={
event = LuaDebugger.event.C2S_LuaPrint,
data ={ msg = ZZBase64.encode(str), type =1}}local sendStr = json.encode(sendMsg)
debug_server:send(sendStr .."__debugger_k0204__")endendend
print = print1
functionluaIdePrintWarn(...)if(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==3)thendebugger_print(...)endif(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==2)thenif(debug_server)thenlocal arg ={...}local str =""if(#arg ==0)then
arg ={"nil"}endfor k, v inpairs(arg)do
str = str ..tostring(v).."\t"endlocal sendMsg ={
event = LuaDebugger.event.C2S_LuaPrint,
data ={ msg = ZZBase64.encode(str), type =2}}local sendStr = json.encode(sendMsg)
debug_server:send(sendStr .."__debugger_k0204__")endendendfunctionluaIdePrintErr(...)if(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==3)thendebugger_print(...)endif(LuaDebugger.isProntToConsole ==1or LuaDebugger.isProntToConsole ==2)thenif(debug_server)thenlocal arg ={...}local str =""if(#arg ==0)then
arg ={"nil"}endfor k, v inpairs(arg)do
str = str ..tostring(v).."\t"endlocal sendMsg ={
event = LuaDebugger.event.C2S_LuaPrint,
data ={ msg = ZZBase64.encode(str), type =3}}local sendStr = json.encode(sendMsg)
debug_server:send(sendStr .."__debugger_k0204__")endendend----=============================工具方法=============================================local debug_hook =nillocalfunctiondebugger_strSplit(input, delimiter)
input =tostring(input)
delimiter =tostring(delimiter)if(delimiter =='')thenreturnfalseendlocal pos, arr =0,{}-- for each divider foundfor st, sp infunction()return string.find(input, delimiter, pos,true)enddo
table.insert(arr, string.sub(input, pos, st -1))
pos = sp +1end
table.insert(arr, string.sub(input, pos))return arr
endlocalfunctiondebugger_strTrim(input)
input = string.gsub(input,"^[ \t\n\r]+","")return string.gsub(input,"[ \t\n\r]+$","")endlocalfunctiondebugger_dump(value, desciption, nesting)iftype(nesting)~="number"then nesting =3endlocal lookupTable ={}local result ={}localfunction_v(v)iftype(v)=="string"then
v ="\"".. v .."\""endreturntostring(v)endlocal traceback =debugger_strSplit(debug.traceback("",2),"\n")print1("dump from: "..debugger_strTrim(traceback[3]))localfunction_dump(value, desciption, indent, nest, keylen)
desciption = desciption or"<var>"
spc =""iftype(keylen)=="number"then
spc = string.rep(" ", keylen - string.len(_v(desciption)))endiftype(value)~="table"then
result[#result +1]= string.format("%s%s%s = %s", indent,_v(desciption), spc,_v(value))elseif lookupTable[value]then
result[#result +1]= string.format("%s%s%s = *REF*", indent, desciption, spc)else
lookupTable[value]=trueif nest > nesting then
result[#result +1]= string.format("%s%s = *MAX NESTING*", indent, desciption)else
result[#result +1]= string.format("%s%s = {", indent,_v(desciption))local indent2 = indent .." "local keys ={}local keylen =0local values ={}for k, v inpairs(value)do
keys[#keys +1]= k
local vk =_v(k)local vkl = string.len(vk)if vkl > keylen then keylen = vkl end
values[k]= v
end
table.sort(keys,function(a, b)iftype(a)=="number"andtype(b)=="number"thenreturn a < b
elsereturntostring(a)<tostring(b)endend)for i, k inipairs(keys)do_dump(values[k], k, indent2, nest +1, keylen)end
result[#result +1]= string.format("%s}", indent)endendend_dump(value, desciption,"- ",1)for i, line inipairs(result)doprint1(line)endendlocalfunctiondebugger_setVarInfo(name, value)local vt =type(value)local valueStr =""if(vt ~="table")then
valueStr =tostring(value)
valueStr = ZZBase64.encode(valueStr)else-- valueStr = topointer(value)endlocal valueInfo ={
name = name,
valueType = vt,
valueStr = valueStr
}return valueInfo;endlocalfunctiondebugger_getvalue(f)local i =1local locals ={}-- get localswhiletruedolocal name, value = debug.getlocal(f, i)ifnot name thenbreakendif(name ~="(*temporary)")then
locals[name]= value
end
i = i +1endlocal func =getinfo(f,"f").func
i =1local ups ={}while func do-- check for func as it may be nil for tail callslocal name, value = debug.getupvalue(func, i)ifnot name thenbreakend
ups[name]= value
i = 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,100dolocal source =getinfo(i)local isadd =trueif(i == ignoreCount)thenlocal file = source.source
if(file:find(LuaDebugger.DebugLuaFie))thenreturnendif(file =="=[C]")then
isadd =falseendendifnot source thenbreak;endif(isadd)thenlocal file = source.source
if file:find("@")==1then
file = file:sub(2);ifnot file:find("/")then
file = file:gsub("%.","/")endendlocal info ={
src = file,
scoreName = source.name,
currentline = source.currentline,
linedefined = source.linedefined,
what = source.what,
nameWhat = source.namewhat
}
index = i
local vars =debugger_getvalue(i +1)
table.insert(stack, info)
table.insert(varInfos, vars)
table.insert(funcs, source.func)endif source.what =='main'thenbreakendendlocal stackInfo ={ stack = stack, vars = varInfos, funcs = funcs }local data =nilifnot jit then
data ={
stack = stackInfo.stack,
vars = stackInfo.vars,
funcs = stackInfo.funcs,
event = event,
funcsLength =#stackInfo.funcs
}
LuaDebugger.currentTempFunc = data.funcs[1]else
data ={
stack = stackInfo.stack,
vars = stackInfo.vars,
funcs = stackInfo.funcs,
event = event
}endreturn data
end--==============================工具方法 end======================================================--===========================断点信息==================================================local debugger_setBreak =nillocalfunctiondebugger_receiveDebugBreakInfo()if(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 thendebugger_exeLuaString(netData.data,false)endendendendlocalfunctionsplitFilePath(path)ifnot jit thenif(LuaDebugger.splitFilePaths[path])thenreturn LuaDebugger.splitFilePaths[path]endendlocal pos, arr =0,{}-- for each divider foundfor st, sp infunction()return string.find(path,'/', pos,true)enddo
table.insert(arr, string.sub(path, pos, st -1))
pos = sp +1end
table.insert(arr, string.sub(path, pos))ifnot jit then
LuaDebugger.splitFilePaths[path]= arr
endreturn arr
end
debugger_setBreak =function(datas)local breakInfos = LuaDebugger.breakInfos
for i, data inipairs(datas)dolocal breakInfo = breakInfos[data.fileName]if(not breakInfo)then
breakInfos[data.fileName]={}
breakInfo = breakInfos[data.fileName]endif(not data.lines or#data.lines ==0)then
breakInfo[data.serverPath]=nilelselocal lineInfos ={}for li, line inipairs(data.lines)do
lineInfos[line]=trueend
breakInfo[data.serverPath]={
pathNames =splitFilePath(data.serverPath),
lines = lineInfos,
hitConditions = data.hitConditions,
countConditions = data.countConditions
}endlocal count =0for i, linesInfo inpairs(breakInfo)do
count = count +1endif(count ==0)then
breakInfos[data.fileName]=nilendend-- debugger_dump(breakInfos, "breakInfos", 6)--检查是否需要断点local isHook =falsefor k, v inpairs(breakInfos)do
isHook =truebreakend--这样做的原因是为了最大限度的使手机调试更加流畅 注意这里会连续的进行n次if(isHook)thenif(not LuaDebugger.isHook)then
debug.sethook(debug_hook,"lrc")end
LuaDebugger.isHook =trueelseif(LuaDebugger.isHook)then
debug.sethook()end
LuaDebugger.isHook =falseendendlocalfunctiondebugger_checkFileIsBreak(fileName)return LuaDebugger.breakInfos[fileName]endlocalfunctiondebugger_checkIsBreak(fileName, line)local breakInfo = LuaDebugger.breakInfos[fileName]if(breakInfo)thenlocal ischeck =falsefor k, lineInfo inpairs(breakInfo)dolocal lines = lineInfo.lines
if(lines and lines[line])then
ischeck =truebreakendendif(not ischeck)thenreturnend--并且在断点中local info =getinfo(3)local source = info.source
source = source:gsub("\\","/")if source:find("@")==1then
source = source:sub(2);ifnot source:find("/")then
source = source:gsub("%.","/")endendlocal index = source:find("%.lua")ifnot index then
source = source ..".lua"endlocal hitPathNames =splitFilePath(source)local hitCounts ={}local flineInfo
local hitCondition =falselocal hasCondition =falselocal hasCountCondition =falselocal hitCountCondition =falsefor k, lineInfo inpairs(breakInfo)dolocal lines = lineInfo.lines
local pathNames = lineInfo.pathNames
if(lines and lines[line])then
flineInfo = lineInfo
-- debugger_dump(lineInfo, "lineInfo", 6)-- conditionif lineInfo.hitConditions and lineInfo.hitConditions[tostring(line)]then
hasCondition =truelocal condition = lineInfo.hitConditions[tostring(line)]-- debugger_dump(condition, "condition", 6)local stackInfo =debugger_stackInfo(4,nil)local doCondition =function()local envs ={ _G = _G }local vars = stackInfo.vars[1]local locals = vars.locals;local ups = vars.ups
for k, v inpairs(ups)do
envs[k]= v
endfor k, v inpairs(locals)do
envs[k]= v
endsetmetatable(envs,{ __index = _G })local funStr ="return ".. condition
local fun =loadstring(funStr)setfenv(fun, envs)returnfun()endlocal status, msg =xpcall(doCondition,function(error)end)
hitCondition = status and msg
endif hitCondition ornot hasCondition then--判断路径
hitCounts[k]=0local hitPathNamesCount =#hitPathNames
local pathNamesCount =#pathNames
while(true)doif(pathNames[pathNamesCount]~= hitPathNames[hitPathNamesCount])thenbreakelse
hitCounts[k]= hitCounts[k]+1end
pathNamesCount = pathNamesCount -1
hitPathNamesCount = hitPathNamesCount -1if(pathNamesCount <=0or hitPathNamesCount <=0)thenbreakendendendbreakendendlocal hitFieName =""local maxCount =0for k, v inpairs(hitCounts)doif(v > maxCount)then
maxCount = v
hitFieName = k
endendif(#hitPathNames ==1or(#hitPathNames >1and maxCount >1))thenif(hitFieName ~=""and flineInfo)then-- debugger_dump(flineInfo, "flineInfo", 6)if flineInfo.hitCount ==nilthen flineInfo.hitCount ={}endif flineInfo.hitCount[line]==nilthen flineInfo.hitCount[line]=0endlocal currentCount = flineInfo.hitCount[line]if flineInfo.countConditions and flineInfo.countConditions[tostring(line)]then
hasCountCondition =truelocal targetCount =tonumber(flineInfo.countConditions[tostring(line)])
hitCountCondition = currentCount == targetCount -1end
flineInfo.hitCount[line]= currentCount +1if hitCondition or hitCountCondition ornot hasCountCondition thenreturn hitFieName
endendendendreturnfalseend--=====================================断点信息 end ----------------------------------------------local controller_host ="192.168.1.102"local controller_port =7003localfunctiondebugger_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)localfunctionloadScript()local luastr = data.luastr
if(isBreakPoint)thenlocal currentTabble ={ _G = _G }local frameId = data.frameId
frameId = frameId +1local func = LuaDebugger.currentDebuggerData.funcs[frameId];local vars = LuaDebugger.currentDebuggerData.vars[frameId]local locals = vars.locals;local ups = vars.ups
for k, v inpairs(ups)do
currentTabble[k]= v
endfor k, v inpairs(locals)do
currentTabble[k]= v
endsetmetatable(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)endelsedebugger_sendMsg(debug_server, LuaDebugger.event.C2S_LoadLuaScript,{ msg ="加载代码失败"})endendlocalfunctiongetLuaFileName(str)local pos =0local fileName ="";-- for each divider foundfor st, sp infunction()return string.find(str,'/', pos,true)enddo
pos = sp +1end
fileName = string.sub(str, pos)return fileName;endlocalfunctiongetSource(source)if(LuaDebugger.pathCachePaths[source])thenreturn LuaDebugger.pathCachePaths[source]endlocal file = source
file = file:gsub("\\","/")if file:find("@")==1then
file = file:sub(2);ifnot file:find("/")then
file = file:gsub("%.","/")endendlocal index = file:find("%.lua")ifnot index then
file = file ..".lua"end
file =getLuaFileName(file)
LuaDebugger.pathCachePaths[source]= file
return file;endlocalfunctiondebugger_GeVarInfoBytUserData(server, var, variablesReference, debugSpeedIndex)local fileds = LuaDebugTool.getUserDataInfo(var)local varInfos ={}if(tolua)thenlocal luavars = tolua.getpeer(var)if(luavars)thenfor k, v inpairs(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 = ZZBase64.encode(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 变量的方法localfunctiondebugger_getBreakVar(body, server)local variablesReference = body.variablesReference
local debugSpeedIndex = body.debugSpeedIndex
local vinfos ={}localfunctionexe()local frameId = body.frameId;local type_ = body.type;local keys = body.keys;--找到对应的varlocal tvars =nilif(type_ ==1)then
tvars = LuaDebugger.currentDebuggerData.vars[frameId +1]
tvars = tvars.locals
elseif(type_ ==2)then
tvars = LuaDebugger.currentDebuggerData.vars[frameId +1]
tvars = tvars.ups
elseif(type_ ==3)then
tvars = _G
end-- FIX(20211115):对象新增__todebug函数以输出调试内容(protobuf字段显示问题)local vars ={}for k, v inpairs(tvars)doiftype(v)=="table"then-- FIX(20211214):loop in gettablexpcall(function()if v.__todebug then
vars[k]= v:__todebug()else
vars[k]= v
endend,function()
vars[k]= v
end)else
vars[k]= v
endend--特殊处理下for i, v inipairs(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 =="]")then
v = string.sub(v,2, len -1);end
vars = vars[v]else
vars = vars[v]endif(type(vars)=="userdata"and tolua ~=niland LuaDebugTool ==nil)then
vars = tolua.getpeer(vars)endif(vars ==nil)thenbreak;endendlocal varType =type(vars)if(varType =="userdata")thenif(LuaDebugTool)thendebugger_GeVarInfoBytUserData(server, vars, variablesReference, debugSpeedIndex)return;elseif(tolua ==nil)thendebugger_sendMsg(server, LuaDebugger.event.C2S_ReqVar,{
variablesReference = variablesReference,
debugSpeedIndex = debugSpeedIndex,
vars = vinfos,
isComplete =1})returnendendlocal count =0;if(vars)thenfor k, v inpairs(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("debugger_getBreakVar error: \n")print(error)print(debug.traceback("",2))debugger_sendMsg(server,
LuaDebugger.event.C2S_ReqVar,{
variablesReference = variablesReference,
debugSpeedIndex = debugSpeedIndex,
vars ={{
name ="error",
valueType ="string",
valueStr = ZZBase64.encode("Can not get value."),
isValue =false}},
isComplete =1})end)endlocalfunctionResetDebugInfo()
LuaDebugger.Run =false
LuaDebugger.StepIn =false
LuaDebugger.StepNext =false
LuaDebugger.StepOut =falseifnot jit then
LuaDebugger.StepNextLevel =0endendlocalfunctiondebugger_loop(server)
server = debug_server
--命令local command
local eval_env ={}local arg
whiletruedolocal line, status = server:receive()if(status =="closed")then
debug.sethook()
coroutine.yield()endif(line)thenlocal netData = json.decode(line)local event = netData.event;local body = netData.data;if(event == LuaDebugger.event.S2C_DebugClose)then
debug.sethook()
coroutine.yield()elseif event == LuaDebugger.event.S2C_SetBreakPoints then--设置断点信息localfunctionsetB()debugger_setBreak(body)endxpcall(setB,function(error)print(error)end)elseif event == LuaDebugger.event.S2C_RUN then
LuaDebugger.runTimeType = body.runTimeType
LuaDebugger.isProntToConsole = body.isProntToConsole
LuaDebugger.printType = body.printType
ResetDebugInfo()
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 =trueifnot jit then
LuaDebugger.StepNextLevel =0;end--设置当前文件名和当前行数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)endendendend
coro_debugger = coroutine.create(debugger_loop)
debug_hook =function(event, line)ifnot jit thenif(not LuaDebugger.isHook)thenreturnendif(LuaDebugger.Run)thenif(event =="line")thenlocal isCheck =falsefor k, breakInfo inpairs(LuaDebugger.breakInfos)dofor bk, linesInfo inpairs(breakInfo)doif(linesInfo.lines[line])then
isCheck =truebreakendendif(isCheck)thenbreakendendif(not isCheck)thenreturnendelse
LuaDebugger.currentFileName =nil
LuaDebugger.currentTempFunc =nilreturnendend--跳出if(LuaDebugger.StepOut)thenif(event =="line"or event =="call")thenreturnendlocal tempFun =getinfo(2,"f").func
if(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)then
LuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel +1end-- print1("stepIn",LuaDebugger.StepNextLevel)local stepInfo =getinfo(2,"S")local source = stepInfo.source
if(source:find(LuaDebugger.DebugLuaFie)or source =="=[C]")thenreturnend
file =getSource(source);
LuaDebugger.currentFileName = file
-- endelseif(event =="return"or event =="tail return")then-- if(not LuaDebugger.StepOut) thenif(not LuaDebugger.Run)then
LuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel -1end
LuaDebugger.currentFileName =nil-- endelseif(event =="line")thenif(LuaDebugger.StepIn)thenlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)--挂起等待调试器作出反应if(data)then
LuaDebugger.currentTempFunc = data.funcs[1]
coroutine.resume(coro_debugger, data)return;endendif(LuaDebugger.StepNext)thenif(LuaDebugger.StepNextLevel <=0)thenlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)--挂起等待调试器作出反应if(data)then
LuaDebugger.currentTempFunc = data.funcs[1]
coroutine.resume(coro_debugger, data)returnendendendlocal stepInfo =nilif(not LuaDebugger.currentFileName)then
stepInfo =getinfo(2,"S")local source = stepInfo.source
if(source =="=[C]"or source:find(LuaDebugger.DebugLuaFie))thenreturnend
file =getSource(source);
LuaDebugger.currentFileName = file
end
file = LuaDebugger.currentFileName
--判断断点local breakInfo = LuaDebugger.breakInfos[file]if(breakInfo)thenlocal ischeck =falsefor k, lineInfo inpairs(breakInfo)dolocal lines = lineInfo.lines
if(lines and lines[line])then
ischeck =truebreakendendif(not ischeck)thenreturnend--并且在断点中local info = stepInfo
if(not info)then
info =getinfo(2)endlocal hitPathNames =splitFilePath(file)local hitCounts ={}local flineInfo
local hitCondition =falselocal hasCondition =falselocal hasCountCondition =falselocal hitCountCondition =falsefor k, lineInfo inpairs(breakInfo)dolocal lines = lineInfo.lines
local pathNames = lineInfo.pathNames
if(lines and lines[line])then
flineInfo = lineInfo
-- debugger_dump(lineInfo, "lineInfo", 6)-- conditionif lineInfo.hitConditions and lineInfo.hitConditions[tostring(line)]then
hasCondition =truelocal condition = lineInfo.hitConditions[tostring(line)]-- debugger_dump(condition, "condition", 6)local stackInfo =debugger_stackInfo(3,nil)local doCondition =function()local envs ={ _G = _G }local vars = stackInfo.vars[1]local locals = vars.locals;local ups = vars.ups
for k, v inpairs(ups)do
envs[k]= v
endfor k, v inpairs(locals)do
envs[k]= v
endsetmetatable(envs,{ __index = _G })local funStr ="return ".. condition
local fun =loadstring(funStr)setfenv(fun, envs)returnfun()endlocal status, msg =xpcall(doCondition,function(error)end)
hitCondition = status and msg
endif hitCondition ornot hasCondition then--判断路径
hitCounts[k]=0local hitPathNamesCount =#hitPathNames
local pathNamesCount =#pathNames
while(true)doif(pathNames[pathNamesCount]~= hitPathNames[hitPathNamesCount])thenbreakelse
hitCounts[k]= hitCounts[k]+1end
pathNamesCount = pathNamesCount -1
hitPathNamesCount = hitPathNamesCount -1if(pathNamesCount <=0or hitPathNamesCount <=0)thenbreakendendendbreakendendlocal hitFieName =""local maxCount =0for k, v inpairs(hitCounts)doif(v > maxCount)then
maxCount = v
hitFieName = k
endendlocal hitPathNamesLength =#hitPathNames
if(hitPathNamesLength ==1or(hitPathNamesLength >1and maxCount >1))thenif(hitFieName ~=""and flineInfo)then-- debugger_dump(flineInfo, "flineInfo", 6)if flineInfo.hitCount ==nilthen flineInfo.hitCount ={}endif flineInfo.hitCount[line]==nilthen flineInfo.hitCount[line]=0endlocal currentCount = flineInfo.hitCount[line]if flineInfo.countConditions and flineInfo.countConditions[tostring(line)]then
hasCountCondition =truelocal targetCount =tonumber(flineInfo.countConditions[tostring(line)])
hitCountCondition = currentCount == targetCount -1end
flineInfo.hitCount[line]= currentCount +1if hitCondition or hitCountCondition ornot hasCountCondition thenlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_HITBreakPoint)
coroutine.resume(coro_debugger, data)endendendendendelselocal file =nilif(event =="line")thenlocal funs =nillocal funlength =0if(LuaDebugger.currentDebuggerData)then
funs = LuaDebugger.currentDebuggerData.funcs
funlength =#funs
endlocal stepInfo =getinfo(2)local tempFunc = stepInfo.func
local source = stepInfo.source
file =getSource(source);if(source =="=[C]"or source:find(LuaDebugger.DebugLuaFie))thenreturnendif(funlength >0and funs[1]== tempFunc and LuaDebugger.currentLine ~= line)then
LuaDebugger.runLineCount = LuaDebugger.runLineCount +1endif(LuaDebugger.StepOut)thenif(funlength ==1)thenResetDebugInfo()
LuaDebugger.Run =truereturnelseif(funs[2]== tempFunc)thenlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_StepInResponse)-- print("StepIn 挂起")--挂起等待调试器作出反应
coroutine.resume(coro_debugger, data)returnendendendif(LuaDebugger.StepIn)thenif(funs[1]== tempFunc and LuaDebugger.runLineCount ==0)thenreturnendlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_StepInResponse)-- print("StepIn 挂起")--挂起等待调试器作出反应
coroutine.resume(coro_debugger, data)returnendif(LuaDebugger.StepNext)thenif(LuaDebugger.currentLine == line)thenreturnendif(funs)thenif(funs[1]~= tempFunc)then--判断是否是和下一个fun 相同如果相同if(funlength >1)thenif(funs[2]== tempFunc)thenelsereturnendelsereturnendendendlocal data =debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)
LuaDebugger.runLineCount =0
LuaDebugger.currentLine = line
--挂起等待调试器作出反应
coroutine.resume(coro_debugger, data)returnendlocal isHit =falselocal sevent =nil--断点判断if(isHit ==falseanddebugger_checkIsBreak(file, line))thenif(funs and funs[1]== tempFunc and LuaDebugger.runLineCount ==0)then
LuaDebugger.runLineCount =0returnend
LuaDebugger.runLineCount =0
LuaDebugger.currentLine = line
isHit =true
sevent = LuaDebugger.event.C2S_HITBreakPoint
--调用 coro_debugger 并传入 参数local data =debugger_stackInfo(3, sevent)--挂起等待调试器作出反应
coroutine.resume(coro_debugger, data)endendendendlocalfunctiondebugger_xpcall()--调用 coro_debugger 并传入 参数local data =debugger_stackInfo(4, LuaDebugger.event.C2S_HITBreakPoint)--挂起等待调试器作出反应
coroutine.resume(coro_debugger, data)end--调试开始localfunctionstart()ifnot jit then
LuaDebugger.DebugLuaFie =getLuaFileName(getinfo(1).source)endlocal socket =createSocket()print(controller_host)print(controller_port)local server = socket.connect(controller_host, controller_port)
debug_server = server
if server then--创建breakInfo socket
socket =createSocket()
breakInfoSocket = socket.connect(controller_host, controller_port)if(breakInfoSocket)then
breakInfoSocket: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)end
coroutine.resume(coro_debugger, server)endendfunctionStartDebug(host, port)
LuaDebugger.DebugLuaFie =getLuaFileName(getinfo(1).source)if jit thenlocal index = LuaDebugger.DebugLuaFie:find("%.lua")if index thenlocal fileNameLength = string.len(LuaDebugger.DebugLuaFie)
LuaDebugger.DebugLuaFie = LuaDebugger.DebugLuaFie:sub(1, fileNameLength -4)endendifnot port thenlocal token =getinfo(1).source
if token then
token = token:gsub("@","")
token = token:gsub("\\","")
token = token:gsub("/","")
token = token:gsub(":","")
token = token:gsub("LuaDebug.lua","")
token = token:lower()
port =0print(token)for i =1,#token do
port = port + string.byte(token:sub(i, i))end
port = port %10000+50000endendifnot host thenprint("debug host can not be nil")endifnot port thenprint("debug port can not be nil")endiftype(host)~="string"thenprint("debug host arg must be string")endiftype(port)~="number"thenprint("debug port arg must be number")end
controller_host = host
controller_port = port
xpcall(start,function(error)print(error)end)return debugger_receiveDebugBreakInfo, debugger_xpcall
end--base64local string = string
ZZBase64.__code ={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',};
ZZBase64.__decode ={}for k, v inpairs(ZZBase64.__code)do
ZZBase64.__decode[string.byte(v,1)]= k -1endfunction ZZBase64.encode(text)local len = string.len(text)local left = len %3
len = len - left
local res ={}local index =1for i =1, len,3dolocal a = string.byte(text, i)local b = string.byte(text, i +1)local c = string.byte(text, i +2)-- num = a<<16 + b<<8 + clocal num = a *65536+ b *256+ c
for j =1,4do--tmp = num >> ((4 -j) * 6)local tmp = math.floor(num /(2^((4- j)*6)))--curPos = tmp&0x3flocal curPos = tmp %64+1
res[index]= ZZBase64.__code[curPos]
index = index +1endendif left ==1then
ZZBase64.__left1(res, index, text, len)elseif left ==2then
ZZBase64.__left2(res, index, text, len)endreturn table.concat(res)endfunction ZZBase64.__left2(res, index, text, len)local num1 = string.byte(text, len +1)
num1 = num1 *1024--lshift 10 local num2 = string.byte(text, len +2)
num2 = num2 *4--lshift 2 local num = num1 + num2
local tmp1 = math.floor(num /4096)--rShift 12local curPos = tmp1 %64+1
res[index]= ZZBase64.__code[curPos]local tmp2 = math.floor(num /64)
curPos = tmp2 %64+1
res[index +1]= ZZBase64.__code[curPos]
curPos = num %64+1
res[index +2]= ZZBase64.__code[curPos]
res[index +3]="=";endfunction ZZBase64.__left1(res, index, text, len)local num = string.byte(text, len +1)
num = num *16local tmp = math.floor(num /64)local curPos = tmp %64+1
res[index]= ZZBase64.__code[curPos]
curPos = num %64+1
res[index +1]= ZZBase64.__code[curPos]
res[index +2]="=";
res[index +3]="=";endfunction ZZBase64.decode(text)local len = string.len(text)local left =0if string.sub(text, len -1)=="=="then
left =2
len = len -4elseif string.sub(text, len)=="="then
left =1
len = len -4endlocal res ={}local index =1local decode = ZZBase64.__decode
for i =1, len,4dolocal a = decode[string.byte(text, i )]local b = decode[string.byte(text, i +1)]local c = decode[string.byte(text, i +2)]local d = decode[string.byte(text, i +3)]--num = a<<18 + b<<12 + c<<6 + dlocal num = a *262144+ b *4096+ c *64+ d
local e = string.char(num %256)
num = math.floor(num /256)local f = string.char(num %256)
num = math.floor(num /256)
res[index]= string.char(num %256)
res[index +1]= f
res[index +2]= e
index = index +3endif left ==1then
ZZBase64.__decodeLeft1(res, index, text, len)elseif left ==2then
ZZBase64.__decodeLeft2(res, index, text, len)endreturn table.concat(res)endfunction ZZBase64.__decodeLeft1(res, index, text, len)local decode = ZZBase64.__decode
local a = decode[string.byte(text, len +1)]local b = decode[string.byte(text, len +2)]local c = decode[string.byte(text, len +3)]local num = a *4096+ b *64+ c
local num1 = math.floor(num /1024)%256local num2 = math.floor(num /4)%256
res[index]= string.char(num1)
res[index +1]= string.char(num2)endfunction ZZBase64.__decodeLeft2(res, index, text, len)local decode = ZZBase64.__decode
local a = decode[string.byte(text, len +1)]local b = decode[string.byte(text, len +2)]local num = a *64+ b
num = math.floor(num /16)
res[index]= string.char(num)endreturn StartDebug