LuaDebug.lua 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617
  1. local debugger_reLoadFile =nil
  2. xpcall(function()
  3. debugger_reLoadFile = require("luaideReLoadFile")
  4. end,function()
  5. debugger_reLoadFile = function() print("未实现代码重载") end
  6. end)
  7. local debugger_stackInfo = nil
  8. local coro_debugger = nil
  9. local debugger_require = require
  10. local debugger_exeLuaString = nil
  11. local checkSetVar = nil
  12. local loadstring_ = nil
  13. local debugger_sendMsg = nil
  14. if (loadstring) then
  15. loadstring_ = loadstring
  16. else
  17. loadstring_ = load
  18. end
  19. --只针对 luadebug 调试 jit版本不存在这个问题
  20. local setfenv = setfenv
  21. if (not setfenv) then
  22. setfenv =
  23. function(fn, env)
  24. local i = 1
  25. while true do
  26. local name = debug.getupvalue(fn, i)
  27. if name == "_ENV" then
  28. debug.upvaluejoin(
  29. fn,
  30. i,
  31. (function()
  32. return env
  33. end),
  34. 1
  35. )
  36. break
  37. elseif not name then
  38. break
  39. end
  40. i = i + 1
  41. end
  42. return fn
  43. end
  44. end
  45. local ZZBase64 = {}
  46. local LuaDebugTool_ = nil
  47. if (LuaDebugTool) then
  48. LuaDebugTool_ = LuaDebugTool
  49. elseif (CS and CS.LuaDebugTool) then
  50. LuaDebugTool_ = CS.LuaDebugTool
  51. end
  52. local LuaDebugTool = LuaDebugTool_
  53. local loadstring = loadstring_
  54. local getinfo = debug.getinfo
  55. local function createSocket()
  56. local base = _G
  57. local string = require("string")
  58. local math = require("math")
  59. local socket = require("socket.core")
  60. local _M = socket
  61. -----------------------------------------------------------------------------
  62. -- Exported auxiliar functions
  63. -----------------------------------------------------------------------------
  64. function _M.connect4(address, port, laddress, lport)
  65. return socket.connect(address, port, laddress, lport, "inet")
  66. end
  67. function _M.connect6(address, port, laddress, lport)
  68. return socket.connect(address, port, laddress, lport, "inet6")
  69. end
  70. if (not _M.connect) then
  71. function _M.connect(address, port, laddress, lport)
  72. local sock, err = socket.tcp()
  73. if not sock then
  74. return nil, err
  75. end
  76. if laddress then
  77. local res, err = sock:bind(laddress, lport, -1)
  78. if not res then
  79. return nil, err
  80. end
  81. end
  82. local res, err = sock:connect(address, port)
  83. if not res then
  84. return nil, err
  85. end
  86. return sock
  87. end
  88. end
  89. function _M.bind(host, port, backlog)
  90. if host == "*" then
  91. host = "0.0.0.0"
  92. end
  93. local addrinfo, err = socket.dns.getaddrinfo(host)
  94. if not addrinfo then
  95. return nil, err
  96. end
  97. local sock, res
  98. err = "no info on address"
  99. for i, alt in base.ipairs(addrinfo) do
  100. if alt.family == "inet" then
  101. sock, err = socket.tcp4()
  102. else
  103. sock, err = socket.tcp6()
  104. end
  105. if not sock then
  106. return nil, err
  107. end
  108. sock:setoption("reuseaddr", true)
  109. res, err = sock:bind(alt.addr, port)
  110. if not res then
  111. sock:close()
  112. else
  113. res, err = sock:listen(backlog)
  114. if not res then
  115. sock:close()
  116. else
  117. return sock
  118. end
  119. end
  120. end
  121. return nil, err
  122. end
  123. _M.try = _M.newtry()
  124. function _M.choose(table)
  125. return function(name, opt1, opt2)
  126. if base.type(name) ~= "string" then
  127. name, opt1, opt2 = "default", name, opt1
  128. end
  129. local f = table[name or "nil"]
  130. if not f then
  131. base.error("unknown key (" .. base.tostring(name) .. ")", 3)
  132. else
  133. return f(opt1, opt2)
  134. end
  135. end
  136. end
  137. -----------------------------------------------------------------------------
  138. -- Socket sources and sinks, conforming to LTN12
  139. -----------------------------------------------------------------------------
  140. -- create namespaces inside LuaSocket namespace
  141. local sourcet, sinkt = {}, {}
  142. _M.sourcet = sourcet
  143. _M.sinkt = sinkt
  144. _M.BLOCKSIZE = 2048
  145. sinkt["close-when-done"] =
  146. function(sock)
  147. return base.setmetatable(
  148. {
  149. getfd = function()
  150. return sock:getfd()
  151. end,
  152. dirty = function()
  153. return sock:dirty()
  154. end
  155. },
  156. {
  157. __call = function(self, chunk, err)
  158. if not chunk then
  159. sock:close()
  160. return 1
  161. else
  162. return sock:send(chunk)
  163. end
  164. end
  165. }
  166. )
  167. end
  168. sinkt["keep-open"] =
  169. function(sock)
  170. return base.setmetatable(
  171. {
  172. getfd = function()
  173. return sock:getfd()
  174. end,
  175. dirty = function()
  176. return sock:dirty()
  177. end
  178. },
  179. {
  180. __call = function(self, chunk, err)
  181. if chunk then
  182. return sock:send(chunk)
  183. else
  184. return 1
  185. end
  186. end
  187. }
  188. )
  189. end
  190. sinkt["default"] = sinkt["keep-open"]
  191. _M.sink = _M.choose(sinkt)
  192. sourcet["by-length"] =
  193. function(sock, length)
  194. return base.setmetatable(
  195. {
  196. getfd = function()
  197. return sock:getfd()
  198. end,
  199. dirty = function()
  200. return sock:dirty()
  201. end
  202. },
  203. {
  204. __call = function()
  205. if length <= 0 then
  206. return nil
  207. end
  208. local size = math.min(socket.BLOCKSIZE, length)
  209. local chunk, err = sock:receive(size)
  210. if err then
  211. return nil, err
  212. end
  213. length = length - string.len(chunk)
  214. return chunk
  215. end
  216. }
  217. )
  218. end
  219. sourcet["until-closed"] =
  220. function(sock)
  221. local done
  222. return base.setmetatable(
  223. {
  224. getfd = function()
  225. return sock:getfd()
  226. end,
  227. dirty = function()
  228. return sock:dirty()
  229. end
  230. },
  231. {
  232. __call = function()
  233. if done then
  234. return nil
  235. end
  236. local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
  237. if not err then
  238. return chunk
  239. elseif err == "closed" then
  240. sock:close()
  241. done = 1
  242. return partial
  243. else
  244. return nil, err
  245. end
  246. end
  247. }
  248. )
  249. end
  250. sourcet["default"] = sourcet["until-closed"]
  251. _M.source = _M.choose(sourcet)
  252. return _M
  253. end
  254. local function createJson()
  255. local math = require("math")
  256. local string = require("string")
  257. local table = require("table")
  258. local object = nil
  259. -----------------------------------------------------------------------------
  260. -- Module declaration
  261. -----------------------------------------------------------------------------
  262. local json = {} -- Public namespace
  263. local json_private = {} -- Private namespace
  264. -- Public constants
  265. json.EMPTY_ARRAY = {}
  266. json.EMPTY_OBJECT = {}
  267. -- Public functions
  268. -- Private functions
  269. local decode_scanArray
  270. local decode_scanComment
  271. local decode_scanConstant
  272. local decode_scanNumber
  273. local decode_scanObject
  274. local decode_scanString
  275. local decode_scanWhitespace
  276. local encodeString
  277. local isArray
  278. local isEncodable
  279. -----------------------------------------------------------------------------
  280. -- PUBLIC FUNCTIONS
  281. -----------------------------------------------------------------------------
  282. --- Encodes an arbitrary Lua object / variable.
  283. -- @param v The Lua object / variable to be JSON encoded.
  284. -- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)
  285. function json.encode(v)
  286. -- Handle nil values
  287. if v == nil then
  288. return "null"
  289. end
  290. local vtype = type(v)
  291. -- Handle strings
  292. if vtype == "string" then
  293. return '"' .. json_private.encodeString(v) .. '"' -- Need to handle encoding in string
  294. end
  295. -- Handle booleans
  296. if vtype == "number" or vtype == "boolean" then
  297. return tostring(v)
  298. end
  299. -- Handle tables
  300. if vtype == "table" then
  301. local rval = {}
  302. -- Consider arrays separately
  303. local bArray, maxCount = isArray(v)
  304. if bArray then
  305. for i = 1, maxCount do
  306. table.insert(rval, json.encode(v[i]))
  307. end
  308. else -- An object, not an array
  309. for i, j in pairs(v) do
  310. if isEncodable(i) and isEncodable(j) then
  311. table.insert(rval, '"' .. json_private.encodeString(i) .. '":' .. json.encode(j))
  312. end
  313. end
  314. end
  315. if bArray then
  316. return "[" .. table.concat(rval, ",") .. "]"
  317. else
  318. return "{" .. table.concat(rval, ",") .. "}"
  319. end
  320. end
  321. -- Handle null values
  322. if vtype == "function" and v == json.null then
  323. return "null"
  324. end
  325. assert(false, "encode attempt to encode unsupported type " .. vtype .. ":" .. tostring(v))
  326. end
  327. --- Decodes a JSON string and returns the decoded value as a Lua data structure / value.
  328. -- @param s The string to scan.
  329. -- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.
  330. -- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,
  331. -- and the position of the first character after
  332. -- the scanned JSON object.
  333. function json.decode(s, startPos)
  334. startPos = startPos and startPos or 1
  335. startPos = decode_scanWhitespace(s, startPos)
  336. assert(startPos <= string.len(s), "Unterminated JSON encoded object found at position in [" .. s .. "]")
  337. local curChar = string.sub(s, startPos, startPos)
  338. -- Object
  339. if curChar == "{" then
  340. return decode_scanObject(s, startPos)
  341. end
  342. -- Array
  343. if curChar == "[" then
  344. return decode_scanArray(s, startPos)
  345. end
  346. -- Number
  347. if string.find("+-0123456789.e", curChar, 1, true) then
  348. return decode_scanNumber(s, startPos)
  349. end
  350. -- String
  351. if curChar == '"' or curChar == [[']] then
  352. return decode_scanString(s, startPos)
  353. end
  354. if string.sub(s, startPos, startPos + 1) == "/*" then
  355. return json.decode(s, decode_scanComment(s, startPos))
  356. end
  357. -- Otherwise, it must be a constant
  358. return decode_scanConstant(s, startPos)
  359. end
  360. --- The null function allows one to specify a null value in an associative array (which is otherwise
  361. -- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }
  362. function json.null()
  363. return json.null -- so json.null() will also return null ;-)
  364. end
  365. -----------------------------------------------------------------------------
  366. -- Internal, PRIVATE functions.
  367. -- Following a Python-like convention, I have prefixed all these 'PRIVATE'
  368. -- functions with an underscore.
  369. -----------------------------------------------------------------------------
  370. --- Scans an array from JSON into a Lua object
  371. -- startPos begins at the start of the array.
  372. -- Returns the array and the next starting position
  373. -- @param s The string being scanned.
  374. -- @param startPos The starting position for the scan.
  375. -- @return table, int The scanned array as a table, and the position of the next character to scan.
  376. function decode_scanArray(s, startPos)
  377. local array = {} -- The return value
  378. local stringLen = string.len(s)
  379. assert(
  380. string.sub(s, startPos, startPos) == "[",
  381. "decode_scanArray called but array does not start at position " .. startPos .. " in string:\n" .. s
  382. )
  383. startPos = startPos + 1
  384. -- Infinite loop for array elements
  385. repeat
  386. startPos = decode_scanWhitespace(s, startPos)
  387. assert(startPos <= stringLen, "JSON String ended unexpectedly scanning array.")
  388. local curChar = string.sub(s, startPos, startPos)
  389. if (curChar == "]") then
  390. return array, startPos + 1
  391. end
  392. if (curChar == ",") then
  393. startPos = decode_scanWhitespace(s, startPos + 1)
  394. end
  395. assert(startPos <= stringLen, "JSON String ended unexpectedly scanning array.")
  396. object, startPos = json.decode(s, startPos)
  397. table.insert(array, object)
  398. until false
  399. end
  400. --- Scans a comment and discards the comment.
  401. -- Returns the position of the next character following the comment.
  402. -- @param string s The JSON string to scan.
  403. -- @param int startPos The starting position of the comment
  404. function decode_scanComment(s, startPos)
  405. assert(
  406. string.sub(s, startPos, startPos + 1) == "/*",
  407. "decode_scanComment called but comment does not start at position " .. startPos
  408. )
  409. local endPos = string.find(s, "*/", startPos + 2)
  410. assert(endPos ~= nil, "Unterminated comment in string at " .. startPos)
  411. return endPos + 2
  412. end
  413. --- Scans for given constants: true, false or null
  414. -- Returns the appropriate Lua type, and the position of the next character to read.
  415. -- @param s The string being scanned.
  416. -- @param startPos The position in the string at which to start scanning.
  417. -- @return object, int The object (true, false or nil) and the position at which the next character should be
  418. -- scanned.
  419. function decode_scanConstant(s, startPos)
  420. local consts = {["true"] = true, ["false"] = false, ["null"] = nil}
  421. local constNames = {"true", "false", "null"}
  422. for i, k in pairs(constNames) do
  423. if string.sub(s, startPos, startPos + string.len(k) - 1) == k then
  424. return consts[k], startPos + string.len(k)
  425. end
  426. end
  427. assert(nil, "Failed to scan constant from string " .. s .. " at starting position " .. startPos)
  428. end
  429. --- Scans a number from the JSON encoded string.
  430. -- (in fact, also is able to scan numeric +- eqns, which is not
  431. -- in the JSON spec.)
  432. -- Returns the number, and the position of the next character
  433. -- after the number.
  434. -- @param s The string being scanned.
  435. -- @param startPos The position at which to start scanning.
  436. -- @return number, int The extracted number and the position of the next character to scan.
  437. function decode_scanNumber(s, startPos)
  438. local endPos = startPos + 1
  439. local stringLen = string.len(s)
  440. local acceptableChars = "+-0123456789.e"
  441. while (string.find(acceptableChars, string.sub(s, endPos, endPos), 1, true) and endPos <= stringLen) do
  442. endPos = endPos + 1
  443. end
  444. local stringValue = "return " .. string.sub(s, startPos, endPos - 1)
  445. local stringEval = loadstring(stringValue)
  446. assert(
  447. stringEval,
  448. "Failed to scan number [ " .. stringValue .. "] in JSON string at position " .. startPos .. " : " .. endPos
  449. )
  450. return stringEval(), endPos
  451. end
  452. --- Scans a JSON object into a Lua object.
  453. -- startPos begins at the start of the object.
  454. -- Returns the object and the next starting position.
  455. -- @param s The string being scanned.
  456. -- @param startPos The starting position of the scan.
  457. -- @return table, int The scanned object as a table and the position of the next character to scan.
  458. function decode_scanObject(s, startPos)
  459. local object = {}
  460. local stringLen = string.len(s)
  461. local key, value
  462. assert(
  463. string.sub(s, startPos, startPos) == "{",
  464. "decode_scanObject called but object does not start at position " .. startPos .. " in string:\n" .. s
  465. )
  466. startPos = startPos + 1
  467. repeat
  468. startPos = decode_scanWhitespace(s, startPos)
  469. assert(startPos <= stringLen, "JSON string ended unexpectedly while scanning object.")
  470. local curChar = string.sub(s, startPos, startPos)
  471. if (curChar == "}") then
  472. return object, startPos + 1
  473. end
  474. if (curChar == ",") then
  475. startPos = decode_scanWhitespace(s, startPos + 1)
  476. end
  477. assert(startPos <= stringLen, "JSON string ended unexpectedly scanning object.")
  478. -- Scan the key
  479. key, startPos = json.decode(s, startPos)
  480. assert(startPos <= stringLen, "JSON string ended unexpectedly searching for value of key " .. key)
  481. startPos = decode_scanWhitespace(s, startPos)
  482. assert(startPos <= stringLen, "JSON string ended unexpectedly searching for value of key " .. key)
  483. assert(
  484. string.sub(s, startPos, startPos) == ":",
  485. "JSON object key-value assignment mal-formed at " .. startPos
  486. )
  487. startPos = decode_scanWhitespace(s, startPos + 1)
  488. assert(startPos <= stringLen, "JSON string ended unexpectedly searching for value of key " .. key)
  489. value, startPos = json.decode(s, startPos)
  490. object[key] = value
  491. until false -- infinite loop while key-value pairs are found
  492. end
  493. -- START SoniEx2
  494. -- Initialize some things used by decode_scanString
  495. -- You know, for efficiency
  496. local escapeSequences = {
  497. ["\\t"] = "\t",
  498. ["\\f"] = "\f",
  499. ["\\r"] = "\r",
  500. ["\\n"] = "\n",
  501. ["\\b"] = ""
  502. }
  503. setmetatable(
  504. escapeSequences,
  505. {
  506. __index = function(t, k)
  507. -- skip "\" aka strip escape
  508. return string.sub(k, 2)
  509. end
  510. }
  511. )
  512. -- END SoniEx2
  513. --- Scans a JSON string from the opening inverted comma or single quote to the
  514. -- end of the string.
  515. -- Returns the string extracted as a Lua string,
  516. -- and the position of the next non-string character
  517. -- (after the closing inverted comma or single quote).
  518. -- @param s The string being scanned.
  519. -- @param startPos The starting position of the scan.
  520. -- @return string, int The extracted string as a Lua string, and the next character to parse.
  521. function decode_scanString(s, startPos)
  522. assert(startPos, "decode_scanString(..) called without start position")
  523. local startChar = string.sub(s, startPos, startPos)
  524. -- START SoniEx2
  525. -- PS: I don't think single quotes are valid JSON
  526. assert(startChar == '"' or startChar == [[']], "decode_scanString called for a non-string")
  527. --assert(startPos, "String decoding failed: missing closing " .. startChar .. " for string at position " .. oldStart)
  528. local t = {}
  529. local i, j = startPos, startPos
  530. while string.find(s, startChar, j + 1) ~= j + 1 do
  531. local oldj = j
  532. i, j = string.find(s, "\\.", j + 1)
  533. local x, y = string.find(s, startChar, oldj + 1)
  534. if not i or x < i then
  535. i, j = x, y - 1
  536. end
  537. table.insert(t, string.sub(s, oldj + 1, i - 1))
  538. if string.sub(s, i, j) == "\\u" then
  539. local a = string.sub(s, j + 1, j + 4)
  540. j = j + 4
  541. local n = tonumber(a, 16)
  542. assert(n, "String decoding failed: bad Unicode escape " .. a .. " at position " .. i .. " : " .. j)
  543. -- math.floor(x/2^y) == lazy right shift
  544. -- a % 2^b == bitwise_and(a, (2^b)-1)
  545. -- 64 = 2^6
  546. -- 4096 = 2^12 (or 2^6 * 2^6)
  547. local x
  548. if n < 128 then
  549. x = string.char(n % 128)
  550. elseif n < 2048 then
  551. -- [110x xxxx] [10xx xxxx]
  552. x = string.char(192 + (math.floor(n / 64) % 32), 128 + (n % 64))
  553. else
  554. -- [1110 xxxx] [10xx xxxx] [10xx xxxx]
  555. x = string.char(224 + (math.floor(n / 4096) % 16), 128 + (math.floor(n / 64) % 64), 128 + (n % 64))
  556. end
  557. table.insert(t, x)
  558. else
  559. table.insert(t, escapeSequences[string.sub(s, i, j)])
  560. end
  561. end
  562. table.insert(t, string.sub(j, j + 1))
  563. assert(
  564. string.find(s, startChar, j + 1),
  565. "String decoding failed: missing closing " ..
  566. startChar .. " at position " .. j .. "(for string at position " .. startPos .. ")"
  567. )
  568. return table.concat(t, ""), j + 2
  569. -- END SoniEx2
  570. end
  571. --- Scans a JSON string skipping all whitespace from the current start position.
  572. -- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.
  573. -- @param s The string being scanned
  574. -- @param startPos The starting position where we should begin removing whitespace.
  575. -- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string
  576. -- was reached.
  577. function decode_scanWhitespace(s, startPos)
  578. local whitespace = " \n\r\t"
  579. local stringLen = string.len(s)
  580. while (string.find(whitespace, string.sub(s, startPos, startPos), 1, true) and startPos <= stringLen) do
  581. startPos = startPos + 1
  582. end
  583. return startPos
  584. end
  585. --- Encodes a string to be JSON-compatible.
  586. -- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)
  587. -- @param s The string to return as a JSON encoded (i.e. backquoted string)
  588. -- @return The string appropriately escaped.
  589. local escapeList = {
  590. ['"'] = '\\"',
  591. ["\\"] = "\\\\",
  592. ["/"] = "\\/",
  593. [""] = "\\b",
  594. ["\f"] = "\\f",
  595. ["\n"] = "\\n",
  596. ["\r"] = "\\r",
  597. ["\t"] = "\\t"
  598. }
  599. function json_private.encodeString(s)
  600. local s = tostring(s)
  601. return s:gsub(
  602. ".",
  603. function(c)
  604. return escapeList[c]
  605. end
  606. ) -- SoniEx2: 5.0 compat
  607. end
  608. -- Determines whether the given Lua type is an array or a table / dictionary.
  609. -- We consider any table an array if it has indexes 1..n for its n items, and no
  610. -- other data in the table.
  611. -- I think this method is currently a little 'flaky', but can't think of a good way around it yet...
  612. -- @param t The table to evaluate as an array
  613. -- @return boolean, number True if the table can be represented as an array, false otherwise. If true,
  614. -- the second returned value is the maximum
  615. -- number of indexed elements in the array.
  616. function isArray(t)
  617. -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
  618. -- (with the possible exception of 'n')
  619. if (t == json.EMPTY_ARRAY) then
  620. return true, 0
  621. end
  622. if (t == json.EMPTY_OBJECT) then
  623. return false
  624. end
  625. local maxIndex = 0
  626. for k, v in pairs(t) do
  627. if (type(k) == "number" and math.floor(k) == k and 1 <= k) then -- k,v is an indexed pair
  628. if (not isEncodable(v)) then
  629. return false
  630. end -- All array elements must be encodable
  631. maxIndex = math.max(maxIndex, k)
  632. else
  633. if (k == "n") then
  634. if v ~= (t.n or #t) then
  635. return false
  636. end -- False if n does not hold the number of elements
  637. else -- Else of (k=='n')
  638. if isEncodable(v) then
  639. return false
  640. end
  641. end -- End of (k~='n')
  642. end -- End of k,v not an indexed pair
  643. end -- End of loop across all pairs
  644. return true, maxIndex
  645. end
  646. --- Determines whether the given Lua object / table / variable can be JSON encoded. The only
  647. -- types that are JSON encodable are: string, boolean, number, nil, table and json.null.
  648. -- In this implementation, all other types are ignored.
  649. -- @param o The object to examine.
  650. -- @return boolean True if the object should be JSON encoded, false if it should be ignored.
  651. function isEncodable(o)
  652. local t = type(o)
  653. return (t == "string" or t == "boolean" or t == "number" or t == "nil" or t == "table") or
  654. (t == "function" and o == json.null)
  655. end
  656. return json
  657. end
  658. local debugger_print = print
  659. local debug_server = nil
  660. local breakInfoSocket = nil
  661. local json = createJson()
  662. local LuaDebugger = {
  663. fileMaps = {},
  664. Run = true, --表示正常运行只检测断点
  665. StepIn = false,
  666. StepInLevel = 0,
  667. StepNext = false,
  668. StepNextLevel = 0,
  669. StepOut = false,
  670. breakInfos = {},
  671. runTimeType = nil,
  672. isHook = true,
  673. pathCachePaths = {},
  674. isProntToConsole = 1,
  675. isFoxGloryProject = false,
  676. isDebugPrint = true,
  677. hookType = "lrc",
  678. currentFileName = "",
  679. currentTempFunc = nil,
  680. --分割字符串缓存
  681. splitFilePaths = {},
  682. DebugLuaFie = "",
  683. version = "0.9.3",
  684. serVarLevel = 4
  685. }
  686. local debug_hook = nil
  687. local _resume = coroutine.resume
  688. coroutine.resume = function(co, ...)
  689. if (LuaDebugger.isHook) then
  690. if coroutine.status(co) ~= "dead" then
  691. debug.sethook(co, debug_hook, "lrc")
  692. end
  693. end
  694. return _resume(co, ...)
  695. end
  696. LuaDebugger.event = {
  697. S2C_SetBreakPoints = 1,
  698. C2S_SetBreakPoints = 2,
  699. S2C_RUN = 3,
  700. C2S_HITBreakPoint = 4,
  701. S2C_ReqVar = 5,
  702. C2S_ReqVar = 6,
  703. --单步跳过请求
  704. S2C_NextRequest = 7,
  705. --单步跳过反馈
  706. C2S_NextResponse = 8,
  707. -- 单步跳过 结束 没有下一步
  708. C2S_NextResponseOver = 9,
  709. --单步跳入
  710. S2C_StepInRequest = 10,
  711. C2S_StepInResponse = 11,
  712. --单步跳出
  713. S2C_StepOutRequest = 12,
  714. --单步跳出返回
  715. C2S_StepOutResponse = 13,
  716. --打印
  717. C2S_LuaPrint = 14,
  718. S2C_LoadLuaScript = 16,
  719. C2S_SetSocketName = 17,
  720. C2S_LoadLuaScript = 18,
  721. C2S_DebugXpCall = 20,
  722. S2C_DebugClose = 21,
  723. S2C_SerVar = 24,
  724. C2S_SerVar = 25,
  725. S2C_ReLoadFile = 26,
  726. C2S_ReLoadFile = 27,
  727. }
  728. --@region print
  729. function print(...)
  730. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 3) then
  731. debugger_print(...)
  732. end
  733. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 2) then
  734. if (debug_server) then
  735. local arg = {...} --这里的...和{}符号中间需要有空格号,否则会出错
  736. local str = ""
  737. if (#arg == 0) then
  738. arg = {"nil"}
  739. end
  740. for k, v in pairs(arg) do
  741. str = str .. tostring(v) .. "\t"
  742. end
  743. local sendMsg = {
  744. event = LuaDebugger.event.C2S_LuaPrint,
  745. data = {msg = ZZBase64.encode(str), type = 1}
  746. }
  747. local sendStr = json.encode(sendMsg)
  748. debug_server:send(sendStr .. "__debugger_k0204__")
  749. end
  750. end
  751. end
  752. function luaIdePrintWarn(...)
  753. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 3) then
  754. debugger_print(...)
  755. end
  756. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 2) then
  757. if (debug_server) then
  758. local arg = {...} --这里的...和{}符号中间需要有空格号,否则会出错
  759. local str = ""
  760. if (#arg == 0) then
  761. arg = {"nil"}
  762. end
  763. for k, v in pairs(arg) do
  764. str = str .. tostring(v) .. "\t"
  765. end
  766. local sendMsg = {
  767. event = LuaDebugger.event.C2S_LuaPrint,
  768. data = {msg = ZZBase64.encode(str), type = 2}
  769. }
  770. local sendStr = json.encode(sendMsg)
  771. debug_server:send(sendStr .. "__debugger_k0204__")
  772. end
  773. end
  774. end
  775. function luaIdePrintErr(...)
  776. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 3) then
  777. debugger_print(...)
  778. end
  779. if (LuaDebugger.isProntToConsole == 1 or LuaDebugger.isProntToConsole == 2) then
  780. if (debug_server) then
  781. local arg = {...} --这里的...和{}符号中间需要有空格号,否则会出错
  782. local str = ""
  783. if (#arg == 0) then
  784. arg = {"nil"}
  785. end
  786. for k, v in pairs(arg) do
  787. str = str .. tostring(v) .. "\t"
  788. end
  789. local sendMsg = {
  790. event = LuaDebugger.event.C2S_LuaPrint,
  791. data = {msg = ZZBase64.encode(str), type = 3}
  792. }
  793. local sendStr = json.encode(sendMsg)
  794. debug_server:send(sendStr .. "__debugger_k0204__")
  795. end
  796. end
  797. end
  798. --@endregion
  799. --@region 辅助方法
  800. local function debugger_lastIndex(str, p)
  801. local startIndex = string.find(str, p, 1)
  802. while startIndex do
  803. local findstartIndex = string.find(str, p, startIndex + 1)
  804. if (not findstartIndex) then
  805. break
  806. else
  807. startIndex = findstartIndex
  808. end
  809. end
  810. return startIndex
  811. end
  812. local function debugger_convertParentDir(dir)
  813. local index, endindex = string.find(dir, "/%.%./")
  814. if (index) then
  815. local file1 = string.sub(dir, 1, index - 1)
  816. local startIndex = debugger_lastIndex(file1, "/")
  817. file1 = string.sub(file1, 1, startIndex - 1)
  818. local file2 = string.sub(dir, endindex)
  819. dir = file1 .. file2
  820. dir = debugger_convertParentDir(dir)
  821. return dir
  822. else
  823. return dir
  824. end
  825. end
  826. local function debugger_getFilePathInfo(file)
  827. local fileName = nil
  828. local dir = nil
  829. file = file:gsub("/.\\", "/")
  830. file = file:gsub("\\", "/")
  831. file = file:gsub("//", "/")
  832. if file:find("@") == 1 then
  833. file = file:sub(2)
  834. end
  835. local findex = file:find("%./")
  836. if (findex == 1) then
  837. file = file:sub(3)
  838. end
  839. file = debugger_convertParentDir(file)
  840. local fileLength = string.len(file)
  841. local suffixNames = {
  842. ".lua",
  843. ".txt.lua",
  844. ".txt",
  845. ".bytes"
  846. }
  847. table.sort(
  848. suffixNames,
  849. function(name1, name2)
  850. return string.len(name1) > string.len(name2)
  851. end
  852. )
  853. local suffixLengs = {}
  854. for i, suffixName in ipairs(suffixNames) do
  855. table.insert(suffixLengs, string.len(suffixName))
  856. end
  857. local fileLength = string.len(file)
  858. for i, suffix in ipairs(suffixNames) do
  859. local suffixName = string.sub(file, fileLength - suffixLengs[i] + 1)
  860. if (suffixName == suffix) then
  861. file = string.sub(file, 1, fileLength - suffixLengs[i])
  862. break
  863. end
  864. end
  865. local fileNameStartIndex = debugger_lastIndex(file, "/")
  866. if (fileNameStartIndex) then
  867. fileName = string.sub(file, fileNameStartIndex + 1)
  868. dir = string.sub(file, 1, fileNameStartIndex)
  869. file = dir .. fileName
  870. else
  871. fileNameStartIndex = debugger_lastIndex(file, "%.")
  872. if (not fileNameStartIndex) then
  873. fileName = file
  874. dir = ""
  875. else
  876. dir = string.sub(file, 1, fileNameStartIndex)
  877. dir = dir:gsub("%.", "/")
  878. fileName = string.sub(file, fileNameStartIndex + 1)
  879. file = dir .. fileName
  880. end
  881. end
  882. return file, dir, fileName
  883. end
  884. --@endregion
  885. ----=============================工具方法=============================================
  886. --@region 工具方法
  887. local function debugger_strSplit(input, delimiter)
  888. input = tostring(input)
  889. delimiter = tostring(delimiter)
  890. if (delimiter == "") then
  891. return false
  892. end
  893. local pos, arr = 0, {}
  894. -- for each divider found
  895. for st, sp in function()
  896. return string.find(input, delimiter, pos, true)
  897. end do
  898. table.insert(arr, string.sub(input, pos, st - 1))
  899. pos = sp + 1
  900. end
  901. table.insert(arr, string.sub(input, pos))
  902. return arr
  903. end
  904. local function debugger_strTrim(input)
  905. input = string.gsub(input, "^[ \t\n\r]+", "")
  906. return string.gsub(input, "[ \t\n\r]+$", "")
  907. end
  908. local function debugger_dump(value, desciption, nesting)
  909. if type(nesting) ~= "number" then
  910. nesting = 3
  911. end
  912. local lookupTable = {}
  913. local result = {}
  914. local function _v(v)
  915. if type(v) == "string" then
  916. v = '"' .. v .. '"'
  917. end
  918. return tostring(v)
  919. end
  920. local traceback = debugger_strSplit(debug.traceback("", 2), "\n")
  921. print("dump from: " .. debugger_strTrim(traceback[3]))
  922. local function _dump(value, desciption, indent, nest, keylen)
  923. desciption = desciption or "<var>"
  924. local spc = ""
  925. if type(keylen) == "number" then
  926. spc = string.rep(" ", keylen - string.len(_v(desciption)))
  927. end
  928. if type(value) ~= "table" then
  929. result[#result + 1] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))
  930. elseif lookupTable[value] then
  931. result[#result + 1] = string.format("%s%s%s = *REF*", indent, desciption, spc)
  932. else
  933. lookupTable[value] = true
  934. if nest > nesting then
  935. result[#result + 1] = string.format("%s%s = *MAX NESTING*", indent, desciption)
  936. else
  937. result[#result + 1] = string.format("%s%s = {", indent, _v(desciption))
  938. local indent2 = indent .. " "
  939. local keys = {}
  940. local keylen = 0
  941. local values = {}
  942. for k, v in pairs(value) do
  943. keys[#keys + 1] = k
  944. local vk = _v(k)
  945. local vkl = string.len(vk)
  946. if vkl > keylen then
  947. keylen = vkl
  948. end
  949. values[k] = v
  950. end
  951. table.sort(
  952. keys,
  953. function(a, b)
  954. if type(a) == "number" and type(b) == "number" then
  955. return a < b
  956. else
  957. return tostring(a) < tostring(b)
  958. end
  959. end
  960. )
  961. for i, k in ipairs(keys) do
  962. _dump(values[k], k, indent2, nest + 1, keylen)
  963. end
  964. result[#result + 1] = string.format("%s}", indent)
  965. end
  966. end
  967. end
  968. _dump(value, desciption, "- ", 1)
  969. for i, line in ipairs(result) do
  970. print(line)
  971. end
  972. end
  973. --@endregion
  974. local function debugger_valueToString(v)
  975. local vtype = type(v)
  976. local vstr = nil
  977. if (vtype == "userdata") then
  978. if (LuaDebugger.isFoxGloryProject) then
  979. return "userdata",vtype
  980. else
  981. return tostring(v), vtype
  982. end
  983. elseif (vtype == "table" or vtype == "function" or vtype == "boolean") then
  984. local value = vtype
  985. xpcall(function()
  986. value = tostring(v)
  987. end,function()
  988. value = vtype
  989. end)
  990. return value, vtype
  991. elseif (vtype == "number" or vtype == "string" ) then
  992. return v, vtype
  993. else
  994. return tostring(v), vtype
  995. end
  996. end
  997. local function debugger_setVarInfo(name, value)
  998. local valueStr, valueType = debugger_valueToString(value)
  999. local nameStr,nameType = debugger_valueToString(name)
  1000. if(valueStr == nil) then
  1001. valueStr = valueType
  1002. end
  1003. local valueInfo = {
  1004. name =nameStr,
  1005. valueType = valueType,
  1006. valueStr = ZZBase64.encode(valueStr)
  1007. }
  1008. return valueInfo
  1009. end
  1010. local function debugger_getvalue(f)
  1011. local i = 1
  1012. local locals = {}
  1013. -- get locals
  1014. while true do
  1015. local name, value = debug.getlocal(f, i)
  1016. if not name then
  1017. break
  1018. end
  1019. if (name ~= "(*temporary)") then
  1020. locals[name] = value
  1021. end
  1022. i = i + 1
  1023. end
  1024. local func = getinfo(f, "f").func
  1025. i = 1
  1026. local ups = {}
  1027. while func do -- check for func as it may be nil for tail calls
  1028. local name, value = debug.getupvalue(func, i)
  1029. if not name then
  1030. break
  1031. end
  1032. if (name == "_ENV") then
  1033. ups["_ENV_"] = value
  1034. else
  1035. ups[name] = value
  1036. end
  1037. i = i + 1
  1038. end
  1039. return {locals = locals, ups = ups}
  1040. end
  1041. --获取堆栈
  1042. debugger_stackInfo =
  1043. function(ignoreCount, event)
  1044. local datas = {}
  1045. local stack = {}
  1046. local varInfos = {}
  1047. local funcs = {}
  1048. local index = 0
  1049. for i = ignoreCount, 100 do
  1050. local source = getinfo(i)
  1051. local isadd = true
  1052. if (i == ignoreCount) then
  1053. local file = source.source
  1054. if (file:find(LuaDebugger.DebugLuaFie)) then
  1055. return
  1056. end
  1057. if (file == "=[C]") then
  1058. isadd = false
  1059. end
  1060. end
  1061. if not source then
  1062. break
  1063. end
  1064. if (isadd) then
  1065. local fullName, dir, fileName = debugger_getFilePathInfo(source.source)
  1066. local info = {
  1067. src = fullName,
  1068. scoreName = source.name,
  1069. currentline = source.currentline,
  1070. linedefined = source.linedefined,
  1071. what = source.what,
  1072. nameWhat = source.namewhat
  1073. }
  1074. index = i
  1075. local vars = debugger_getvalue(i + 1)
  1076. table.insert(stack, info)
  1077. table.insert(varInfos, vars)
  1078. table.insert(funcs, source.func)
  1079. end
  1080. if source.what == "main" then
  1081. break
  1082. end
  1083. end
  1084. local stackInfo = {stack = stack, vars = varInfos, funcs = funcs}
  1085. local data = {
  1086. stack = stackInfo.stack,
  1087. vars = stackInfo.vars,
  1088. funcs = stackInfo.funcs,
  1089. event = event,
  1090. funcsLength = #stackInfo.funcs,
  1091. upFunc = getinfo(ignoreCount - 3, "f").func
  1092. }
  1093. LuaDebugger.currentTempFunc = data.funcs[1]
  1094. return data
  1095. end
  1096. --===========================点断信息==================================================
  1097. --根据不同的游戏引擎进行定时获取断点信息
  1098. --CCDirector:sharedDirector():getScheduler()
  1099. local debugger_setBreak = nil
  1100. local function debugger_receiveDebugBreakInfo()
  1101. if (jit) then
  1102. if (LuaDebugger.debugLuaType ~= "jit") then
  1103. local msg = "当前luajit版本为: " .. jit.version .. " 请使用LuaDebugjit 进行调试!"
  1104. print(msg)
  1105. end
  1106. end
  1107. if (breakInfoSocket) then
  1108. local msg, status = breakInfoSocket:receive()
  1109. if(LuaDebugger.isLaunch and status == "closed") then
  1110. os.exit()
  1111. end
  1112. if (msg) then
  1113. local netData = json.decode(msg)
  1114. if netData.event == LuaDebugger.event.S2C_SetBreakPoints then
  1115. debugger_setBreak(netData.data)
  1116. elseif netData.event == LuaDebugger.event.S2C_LoadLuaScript then
  1117. LuaDebugger.loadScriptBody = netData.data
  1118. debugger_exeLuaString()
  1119. debugger_sendMsg(breakInfoSocket,LuaDebugger.event.C2S_LoadLuaScript,LuaDebugger.loadScriptBody)
  1120. elseif netData.event == LuaDebugger.event.S2C_ReLoadFile then
  1121. LuaDebugger.reLoadFileBody = netData.data
  1122. LuaDebugger.isReLoadFile = false
  1123. LuaDebugger.reLoadFileBody.isReLoad = debugger_reLoadFile(LuaDebugger.reLoadFileBody)
  1124. print("重载结果:",LuaDebugger.reLoadFileBody.isReLoad)
  1125. LuaDebugger.reLoadFileBody.script = nil
  1126. debugger_sendMsg(
  1127. breakInfoSocket,
  1128. LuaDebugger.event.C2S_ReLoadFile,
  1129. {
  1130. stack = LuaDebugger.reLoadFileBody
  1131. }
  1132. )
  1133. end
  1134. end
  1135. end
  1136. end
  1137. local function splitFilePath(path)
  1138. if (LuaDebugger.splitFilePaths[path]) then
  1139. return LuaDebugger.splitFilePaths[path]
  1140. end
  1141. local pos, arr = 0, {}
  1142. -- for each divider found
  1143. for st, sp in function()
  1144. return string.find(path, "/", pos, true)
  1145. end do
  1146. local pathStr = string.sub(path, pos, st - 1)
  1147. table.insert(arr, pathStr)
  1148. pos = sp + 1
  1149. end
  1150. local pathStr = string.sub(path, pos)
  1151. table.insert(arr, pathStr)
  1152. LuaDebugger.splitFilePaths[path] = arr
  1153. return arr
  1154. end
  1155. debugger_setBreak =
  1156. function(datas)
  1157. local breakInfos = LuaDebugger.breakInfos
  1158. for i, data in ipairs(datas) do
  1159. data.fileName = string.lower(data.fileName)
  1160. data.serverPath = string.lower(data.serverPath)
  1161. local breakInfo = breakInfos[data.fileName]
  1162. if (not breakInfo) then
  1163. breakInfos[data.fileName] = {}
  1164. breakInfo = breakInfos[data.fileName]
  1165. end
  1166. if (not data.breakDatas or #data.breakDatas == 0) then
  1167. breakInfo[data.serverPath] = nil
  1168. else
  1169. local fileBreakInfo = breakInfo[data.serverPath]
  1170. if (not fileBreakInfo) then
  1171. fileBreakInfo = {
  1172. pathNames = splitFilePath(data.serverPath),
  1173. --命中次數判斷計數器
  1174. hitCounts = {}
  1175. }
  1176. breakInfo[data.serverPath] = fileBreakInfo
  1177. end
  1178. local lineInfos = {}
  1179. for li, breakData in ipairs(data.breakDatas) do
  1180. lineInfos[breakData.line] = breakData
  1181. if (breakData.hitCondition and breakData.hitCondition ~= "") then
  1182. breakData.hitCondition = tonumber(breakData.hitCondition)
  1183. else
  1184. breakData.hitCondition = 0
  1185. end
  1186. if (not fileBreakInfo.hitCounts[breakData.line]) then
  1187. fileBreakInfo.hitCounts[breakData.line] = 0
  1188. end
  1189. end
  1190. fileBreakInfo.lines = lineInfos
  1191. --這裡添加命中次數判斷
  1192. for line, count in pairs(fileBreakInfo.hitCounts) do
  1193. if (not lineInfos[line]) then
  1194. fileBreakInfo.hitCounts[line] = nil
  1195. end
  1196. end
  1197. end
  1198. local count = 0
  1199. for i, linesInfo in pairs(breakInfo) do
  1200. count = count + 1
  1201. end
  1202. if (count == 0) then
  1203. breakInfos[data.fileName] = nil
  1204. end
  1205. end
  1206. --debugger_dump(breakInfos, "breakInfos", 6)
  1207. --检查是否需要断点
  1208. local isHook = false
  1209. for k, v in pairs(breakInfos) do
  1210. isHook = true
  1211. break
  1212. end
  1213. --这样做的原因是为了最大限度的使手机调试更加流畅 注意这里会连续的进行n次
  1214. if (isHook) then
  1215. if (not LuaDebugger.isHook) then
  1216. debug.sethook(debug_hook, "lrc")
  1217. end
  1218. LuaDebugger.isHook = true
  1219. else
  1220. if (LuaDebugger.isHook) then
  1221. debug.sethook()
  1222. end
  1223. LuaDebugger.isHook = false
  1224. end
  1225. end
  1226. local function debugger_checkFileIsBreak(fileName)
  1227. return LuaDebugger.breakInfos[fileName]
  1228. end
  1229. --=====================================断点信息 end ----------------------------------------------
  1230. local controller_host = "192.168.1.102"
  1231. local controller_port = 7003
  1232. debugger_sendMsg = function(serverSocket, eventName, data)
  1233. local sendMsg = {
  1234. event = eventName,
  1235. data = data
  1236. }
  1237. local sendStr = json.encode(sendMsg)
  1238. serverSocket:send(sendStr .. "__debugger_k0204__")
  1239. end
  1240. function debugger_conditionStr(condition, vars, callBack)
  1241. local function loadScript()
  1242. local currentTabble = {}
  1243. local locals = vars[1].locals
  1244. local ups = vars[1].ups
  1245. if (ups) then
  1246. for k, v in pairs(ups) do
  1247. currentTabble[k] = v
  1248. end
  1249. end
  1250. if (locals) then
  1251. for k, v in pairs(locals) do
  1252. currentTabble[k] = v
  1253. end
  1254. end
  1255. setmetatable(currentTabble, {__index = _G})
  1256. local fun = loadstring("return " .. condition)
  1257. setfenv(fun, currentTabble)
  1258. return fun()
  1259. end
  1260. local status,
  1261. msg =
  1262. xpcall(
  1263. loadScript,
  1264. function(error)
  1265. print(error)
  1266. end
  1267. )
  1268. if (status and msg) then
  1269. callBack()
  1270. end
  1271. end
  1272. --执行lua字符串
  1273. debugger_exeLuaString = function()
  1274. local function loadScript()
  1275. local script = LuaDebugger.loadScriptBody.script
  1276. if (LuaDebugger.loadScriptBody.isBreak) then
  1277. local currentTabble = {_G = _G}
  1278. local frameId = LuaDebugger.loadScriptBody.frameId
  1279. frameId = frameId
  1280. local func = LuaDebugger.currentDebuggerData.funcs[frameId]
  1281. local vars = LuaDebugger.currentDebuggerData.vars[frameId]
  1282. local locals = vars.locals
  1283. local ups = vars.ups
  1284. for k, v in pairs(ups) do
  1285. currentTabble[k] = v
  1286. end
  1287. for k, v in pairs(locals) do
  1288. currentTabble[k] = v
  1289. end
  1290. setmetatable(currentTabble, {__index = _G})
  1291. local fun = loadstring(script)
  1292. setfenv(fun, currentTabble)
  1293. fun()
  1294. else
  1295. local fun = loadstring(script)
  1296. fun()
  1297. end
  1298. end
  1299. local status,
  1300. msg =
  1301. xpcall(
  1302. loadScript,
  1303. function(error)
  1304. -- debugger_sendMsg(debug_server, LuaDebugger.event.C2S_LoadLuaScript, LuaDebugger.loadScriptBody)
  1305. end
  1306. )
  1307. LuaDebugger.loadScriptBody.script = nil
  1308. if (LuaDebugger.loadScriptBody.isBreak) then
  1309. LuaDebugger.serVarLevel = LuaDebugger.serVarLevel+1
  1310. LuaDebugger.currentDebuggerData = debugger_stackInfo(LuaDebugger.serVarLevel, LuaDebugger.event.C2S_HITBreakPoint)
  1311. LuaDebugger.loadScriptBody.stack = LuaDebugger.currentDebuggerData.stack
  1312. end
  1313. LuaDebugger.loadScriptBody.complete = true
  1314. end
  1315. --@region 调试中修改变量值
  1316. --根据key 值在 value 查找
  1317. local function debugger_getTablekey(key,keyType,value)
  1318. if(keyType == -1) then
  1319. return key
  1320. elseif(keyType == 1) then
  1321. return tonumber(key)
  1322. elseif(keyType == 2) then
  1323. local valueKey = nil
  1324. for k,v in pairs(value) do
  1325. local nameType = type(k)
  1326. if(nameType == "userdata" or nameType == "table") then
  1327. if (not LuaDebugger.isFoxGloryProject) then
  1328. valueKey = tostring(k)
  1329. if(key == valueKey) then
  1330. return k
  1331. end
  1332. break
  1333. end
  1334. end
  1335. end
  1336. end
  1337. end
  1338. local function debugger_setVarValue(server, data)
  1339. local newValue = nil
  1340. local level = LuaDebugger.serVarLevel+LuaDebugger.setVarBody.frameId
  1341. local firstKeyName = data.keys[1]
  1342. --@region vars check
  1343. local localValueChangeIndex = -1
  1344. local upValueChangeIndex = -1
  1345. local upValueFun = nil
  1346. local oldValue = nil
  1347. local i = 1
  1348. local locals = {}
  1349. -- get locals
  1350. while true do
  1351. local name, value = debug.getlocal(level, i)
  1352. if not name then
  1353. break
  1354. end
  1355. if(firstKeyName == name) then
  1356. localValueChangeIndex = i
  1357. oldValue = value
  1358. end
  1359. if (name ~= "(*temporary)") then
  1360. locals[name] = value
  1361. end
  1362. i = i + 1
  1363. end
  1364. local func = getinfo(level, "f").func
  1365. i = 1
  1366. local ups = {}
  1367. while func do -- check for func as it may be nil for tail calls
  1368. local name, value = debug.getupvalue(func, i)
  1369. if not name then
  1370. break
  1371. end
  1372. if(localValueChangeIndex == -1 and firstKeyName == name) then
  1373. upValueFun = func
  1374. oldValue = value
  1375. upValueChangeIndex = i
  1376. end
  1377. if (name == "_ENV") then
  1378. ups["_ENV_"] = value
  1379. else
  1380. ups[name] = value
  1381. end
  1382. i = i + 1
  1383. end
  1384. --@endregion
  1385. local vars = {locals = locals, ups = ups}
  1386. local function loadScript()
  1387. local currentTabble = {}
  1388. local locals = vars.locals
  1389. local ups = vars.ups
  1390. if (ups) then
  1391. for k, v in pairs(ups) do
  1392. currentTabble[k] = v
  1393. end
  1394. end
  1395. if (locals) then
  1396. for k, v in pairs(locals) do
  1397. currentTabble[k] = v
  1398. end
  1399. end
  1400. setmetatable(currentTabble, {__index = _G})
  1401. local fun = loadstring("return " .. data.value)
  1402. setfenv(fun, currentTabble)
  1403. newValue = fun()
  1404. end
  1405. local status,
  1406. msg =
  1407. xpcall(
  1408. loadScript,
  1409. function(error)
  1410. print(error, "============================")
  1411. end
  1412. )
  1413. local i = 1
  1414. -- local 查找并替换
  1415. local keyLength = #data.keys
  1416. if(keyLength == 1) then
  1417. if(localValueChangeIndex ~= -1) then
  1418. debug.setlocal(level, localValueChangeIndex, newValue)
  1419. elseif(upValueFun ~= nil) then
  1420. debug.setupvalue( upValueFun, upValueChangeIndex, newValue )
  1421. else
  1422. --全局变量查找
  1423. if(_G[firstKeyName]) then
  1424. _G[firstKeyName] = newValue
  1425. end
  1426. end
  1427. else
  1428. if(not oldValue) then
  1429. if(_G[firstKeyName]) then
  1430. oldValue = _G[firstKeyName]
  1431. end
  1432. end
  1433. local tempValue = oldValue
  1434. for i=2,keyLength-1 do
  1435. if(tempValue) then
  1436. oldValue = oldValue[debugger_getTablekey(data.keys[i],data.numberTypes[i],oldValue)]
  1437. end
  1438. end
  1439. if(tempValue) then
  1440. oldValue[debugger_getTablekey(data.keys[keyLength],data.numberTypes[keyLength],oldValue)] = newValue
  1441. end
  1442. end
  1443. local varInfo = debugger_setVarInfo(data.varName, newValue)
  1444. data.varInfo = varInfo
  1445. LuaDebugger.serVarLevel = LuaDebugger.serVarLevel+1
  1446. LuaDebugger.currentDebuggerData = debugger_stackInfo(LuaDebugger.serVarLevel, LuaDebugger.event.C2S_HITBreakPoint)
  1447. end
  1448. --@endregion
  1449. --调试修改变量值统一的 _resume
  1450. checkSetVar =
  1451. function()
  1452. if (LuaDebugger.isSetVar) then
  1453. LuaDebugger.isSetVar = false
  1454. debugger_setVarValue(debug_server,LuaDebugger.setVarBody)
  1455. LuaDebugger.serVarLevel = LuaDebugger.serVarLevel+1
  1456. _resume(coro_debugger, LuaDebugger.setVarBody)
  1457. xpcall(
  1458. checkSetVar,
  1459. function(error)
  1460. print("设置变量", error)
  1461. end
  1462. )
  1463. elseif(LuaDebugger.isLoadLuaScript) then
  1464. LuaDebugger.isLoadLuaScript = false
  1465. debugger_exeLuaString()
  1466. LuaDebugger.serVarLevel = LuaDebugger.serVarLevel+1
  1467. _resume(coro_debugger, LuaDebugger.reLoadFileBody)
  1468. xpcall(
  1469. checkSetVar,
  1470. function(error)
  1471. print("执行代码", error)
  1472. end
  1473. )
  1474. elseif(LuaDebugger.isReLoadFile) then
  1475. LuaDebugger.isReLoadFile = false
  1476. LuaDebugger.reLoadFileBody.isReLoad = debugger_reLoadFile(LuaDebugger.reLoadFileBody)
  1477. print("重载结果:",LuaDebugger.reLoadFileBody.isReLoad)
  1478. LuaDebugger.reLoadFileBody.script = nil
  1479. LuaDebugger.serVarLevel = LuaDebugger.serVarLevel+1
  1480. _resume(coro_debugger, LuaDebugger.reLoadFileBody)
  1481. xpcall(
  1482. checkSetVar,
  1483. function(error)
  1484. print("重新加载文件", error)
  1485. end
  1486. )
  1487. end
  1488. end
  1489. local function getSource(source)
  1490. source = string.lower(source)
  1491. if (LuaDebugger.pathCachePaths[source]) then
  1492. LuaDebugger.currentLineFile = LuaDebugger.pathCachePaths[source]
  1493. return LuaDebugger.pathCachePaths[source]
  1494. end
  1495. local fullName, dir, fileName = debugger_getFilePathInfo(source)
  1496. LuaDebugger.currentLineFile = fullName
  1497. LuaDebugger.pathCachePaths[source] = fileName
  1498. return fileName
  1499. end
  1500. local function debugger_GeVarInfoBytUserData(server, var)
  1501. local fileds = LuaDebugTool.getUserDataInfo(var)
  1502. local varInfos = {}
  1503. --c# vars
  1504. for i = 1, fileds.Count do
  1505. local filed = fileds[i - 1]
  1506. local valueInfo = {
  1507. name = filed.name,
  1508. valueType = filed.valueType,
  1509. valueStr = ZZBase64.encode(filed.valueStr),
  1510. isValue = filed.isValue,
  1511. csharp = true
  1512. }
  1513. table.insert(varInfos, valueInfo)
  1514. end
  1515. return varInfos
  1516. end
  1517. local function debugger_getValueByScript(value, script)
  1518. local val = nil
  1519. local status,
  1520. msg =
  1521. xpcall(
  1522. function()
  1523. local fun = loadstring("return " .. script)
  1524. setfenv(fun, value)
  1525. val = fun()
  1526. end,
  1527. function(error)
  1528. print(error, "====>")
  1529. val = nil
  1530. end
  1531. )
  1532. return val
  1533. end
  1534. local function debugger_getVarByKeys(value, keys, index)
  1535. local str = ""
  1536. local keyLength = #keys
  1537. for i = index, keyLength do
  1538. local key = keys[i]
  1539. if (key == "[metatable]") then
  1540. else
  1541. if (i == index) then
  1542. if (string.find(key, "%.")) then
  1543. if (str == "") then
  1544. i = index + 1
  1545. value = value[key]
  1546. end
  1547. if (i >= #keys) then
  1548. return index, value
  1549. end
  1550. return debugger_getVarByKeys(value, keys, i)
  1551. else
  1552. str = key
  1553. end
  1554. else
  1555. if (string.find(key, "%[")) then
  1556. str = str .. key
  1557. elseif (type(key) == "string") then
  1558. if (string.find(key, "table:") or string.find(key, "userdata:") or string.find(key, "function:")) then
  1559. if (str ~= "") then
  1560. local vl = debugger_getValueByScript(value, str)
  1561. value = vl
  1562. if (value) then
  1563. for k, v in pairs(value) do
  1564. local ktype = type(k)
  1565. if (ktype == "userdata" or ktype == "table" or ktype == "function") then
  1566. local keyName = debugger_valueToString(k)
  1567. if (keyName == key) then
  1568. value = v
  1569. break
  1570. end
  1571. end
  1572. end
  1573. end
  1574. str = ""
  1575. if (i == keyLength) then
  1576. return #keys, value
  1577. else
  1578. return debugger_getVarByKeys(value, keys, i + 1)
  1579. end
  1580. else
  1581. str = str .. '["' .. key .. '"]'
  1582. end
  1583. else
  1584. str = str .. '["' .. key .. '"]'
  1585. end
  1586. else
  1587. str = str .. "[" .. key .. "]"
  1588. end
  1589. end
  1590. end
  1591. end
  1592. local v = debugger_getValueByScript(value, str)
  1593. return #keys, v
  1594. end
  1595. --[[
  1596. @desc: 查找c# 值
  1597. author:k0204
  1598. time:2018-04-07 21:32:31
  1599. return
  1600. ]]
  1601. local function debugger_getCSharpValue(value, searchIndex, keys)
  1602. local key = keys[searchIndex]
  1603. local val = LuaDebugTool.getCSharpValue(value, key)
  1604. if (val) then
  1605. --1最后一个 直接返回
  1606. if (searchIndex == #keys) then
  1607. return #keys, val
  1608. else
  1609. --2再次获得 如果没有找到那么 进行lua 层面查找
  1610. local vindex, val1 = debugger_getCSharpValue(val, searchIndex + 1, keys)
  1611. if (not val1) then
  1612. --组建新的keys
  1613. local tempKeys = {}
  1614. for i = vindex, #keys do
  1615. table.insert(tempKeys, keys[i])
  1616. end
  1617. local vindx, val1 = debugger_searchVarByKeys(value, searckKeys, 1)
  1618. return vindx, val1
  1619. else
  1620. return vindex, val1
  1621. end
  1622. end
  1623. else
  1624. --3最终这里返回 所以2 中 没有当val1 不为空的处理
  1625. return searchIndex, val
  1626. end
  1627. end
  1628. local function debugger_searchVarByKeys(value, keys, searckKeys)
  1629. local index, val = debugger_getVarByKeys(value, searckKeys, 1)
  1630. if (not LuaDebugTool or not LuaDebugTool.getCSharpValue or type(LuaDebugTool.getCSharpValue) ~= "function") then
  1631. return index, val
  1632. end
  1633. if (val) then
  1634. if (index == #keys) then
  1635. return index, val
  1636. else
  1637. local searchStr = ""
  1638. --进行c# 值查找
  1639. local keysLength = #keys
  1640. local searchIndex = index + 1
  1641. local sindex, val = debugger_getCSharpValue(val, searchIndex, keys)
  1642. return sindex, val
  1643. end
  1644. else
  1645. --进行递减
  1646. local tempKeys = {}
  1647. for i = 1, #searckKeys - 1 do
  1648. table.insert(tempKeys, keys[i])
  1649. end
  1650. if (#tempKeys == 0) then
  1651. return #keys, nil
  1652. end
  1653. return debugger_searchVarByKeys(value, keys, tempKeys)
  1654. end
  1655. end
  1656. --[[
  1657. @desc: 获取metatable 信息
  1658. author:k0204
  1659. time:2018-04-06 20:27:12
  1660. return
  1661. ]]
  1662. local function debugger_getmetatable(value, metatable, vinfos, server, variablesReference, debugSpeedIndex, metatables)
  1663. for i, mtable in ipairs(metatables) do
  1664. if (metatable == mtable) then
  1665. return vinfos
  1666. end
  1667. end
  1668. table.insert(metatables, metatable)
  1669. for k, v in pairs(metatable) do
  1670. local val = nil
  1671. if (type(k) == "string") then
  1672. xpcall(
  1673. function()
  1674. val = value[k]
  1675. end,
  1676. function(error)
  1677. val = nil
  1678. end
  1679. )
  1680. if (val == nil) then
  1681. xpcall(
  1682. function()
  1683. if (string.find(k, "__")) then
  1684. val = v
  1685. end
  1686. end,
  1687. function(error)
  1688. val = nil
  1689. end
  1690. )
  1691. end
  1692. end
  1693. if (val) then
  1694. local vinfo = debugger_setVarInfo(k, val)
  1695. table.insert(vinfos, vinfo)
  1696. if (#vinfos > 10) then
  1697. debugger_sendMsg(
  1698. server,
  1699. LuaDebugger.event.C2S_ReqVar,
  1700. {
  1701. variablesReference = variablesReference,
  1702. debugSpeedIndex = debugSpeedIndex,
  1703. vars = vinfos,
  1704. isComplete = 0
  1705. }
  1706. )
  1707. vinfos = {}
  1708. end
  1709. end
  1710. end
  1711. local m = getmetatable(metatable)
  1712. if (m) then
  1713. return debugger_getmetatable(value, m, vinfos, server, variablesReference, debugSpeedIndex, metatables)
  1714. else
  1715. return vinfos
  1716. end
  1717. end
  1718. local function debugger_sendTableField(luatable, vinfos, server, variablesReference, debugSpeedIndex, valueType)
  1719. if (valueType == "userdata") then
  1720. if (tolua and tolua.getpeer) then
  1721. luatable = tolua.getpeer(luatable)
  1722. else
  1723. return vinfos
  1724. end
  1725. end
  1726. if (luatable == nil) then
  1727. return vinfos
  1728. end
  1729. for k, v in pairs(luatable) do
  1730. local vinfo = debugger_setVarInfo(k, v)
  1731. table.insert(vinfos, vinfo)
  1732. if (#vinfos > 10) then
  1733. debugger_sendMsg(
  1734. server,
  1735. LuaDebugger.event.C2S_ReqVar,
  1736. {
  1737. variablesReference = variablesReference,
  1738. debugSpeedIndex = debugSpeedIndex,
  1739. vars = vinfos,
  1740. isComplete = 0
  1741. }
  1742. )
  1743. vinfos = {}
  1744. end
  1745. end
  1746. return vinfos
  1747. end
  1748. local function debugger_sendTableValues(value, server, variablesReference, debugSpeedIndex)
  1749. local vinfos = {}
  1750. local luatable = {}
  1751. local valueType = type(value)
  1752. local userDataInfos = {}
  1753. local m = nil
  1754. if (valueType == "userdata") then
  1755. m = getmetatable(value)
  1756. vinfos = debugger_sendTableField(value, vinfos, server, variablesReference, debugSpeedIndex, valueType)
  1757. if (LuaDebugTool) then
  1758. local varInfos = debugger_GeVarInfoBytUserData(server, value, variablesReference, debugSpeedIndex)
  1759. for i, v in ipairs(varInfos) do
  1760. if (v.valueType == "System.Byte[]" and value[v.name] and type(value[v.name]) == "string") then
  1761. local valueInfo = {
  1762. name = v.name,
  1763. valueType = "string",
  1764. valueStr = ZZBase64.encode(value[v.name])
  1765. }
  1766. table.insert(vinfos, valueInfo)
  1767. else
  1768. table.insert(vinfos, v)
  1769. end
  1770. if (#vinfos > 10) then
  1771. debugger_sendMsg(
  1772. server,
  1773. LuaDebugger.event.C2S_ReqVar,
  1774. {
  1775. variablesReference = variablesReference,
  1776. debugSpeedIndex = debugSpeedIndex,
  1777. vars = vinfos,
  1778. isComplete = 0
  1779. }
  1780. )
  1781. vinfos = {}
  1782. end
  1783. end
  1784. end
  1785. else
  1786. m = getmetatable(value)
  1787. vinfos = debugger_sendTableField(value, vinfos, server, variablesReference, debugSpeedIndex, valueType)
  1788. end
  1789. if (m) then
  1790. vinfos = debugger_getmetatable(value, m, vinfos, server, variablesReference, debugSpeedIndex, {})
  1791. end
  1792. debugger_sendMsg(
  1793. server,
  1794. LuaDebugger.event.C2S_ReqVar,
  1795. {
  1796. variablesReference = variablesReference,
  1797. debugSpeedIndex = debugSpeedIndex,
  1798. vars = vinfos,
  1799. isComplete = 1
  1800. }
  1801. )
  1802. end
  1803. --获取lua 变量的方法
  1804. local function debugger_getBreakVar(body, server)
  1805. local variablesReference = body.variablesReference
  1806. local debugSpeedIndex = body.debugSpeedIndex
  1807. local vinfos = {}
  1808. local function exe()
  1809. local frameId = body.frameId
  1810. local type_ = body.type
  1811. local keys = body.keys
  1812. --找到对应的var
  1813. local vars = nil
  1814. if (type_ == 1) then
  1815. vars = LuaDebugger.currentDebuggerData.vars[frameId + 1]
  1816. vars = vars.locals
  1817. elseif (type_ == 2) then
  1818. vars = LuaDebugger.currentDebuggerData.vars[frameId + 1]
  1819. vars = vars.ups
  1820. elseif (type_ == 3) then
  1821. vars = _G
  1822. end
  1823. if (#keys == 0) then
  1824. debugger_sendTableValues(vars, server, variablesReference, debugSpeedIndex)
  1825. return
  1826. end
  1827. local index, value = debugger_searchVarByKeys(vars, keys, keys)
  1828. if (value) then
  1829. local valueType = type(value)
  1830. if (valueType == "table" or valueType == "userdata") then
  1831. debugger_sendTableValues(value, server, variablesReference, debugSpeedIndex)
  1832. else
  1833. if (valueType == "function") then
  1834. value = tostring(value)
  1835. end
  1836. debugger_sendMsg(
  1837. server,
  1838. LuaDebugger.event.C2S_ReqVar,
  1839. {
  1840. variablesReference = variablesReference,
  1841. debugSpeedIndex = debugSpeedIndex,
  1842. vars = ZZBase64.encode(value),
  1843. isComplete = 1,
  1844. varType = valueType
  1845. }
  1846. )
  1847. end
  1848. else
  1849. debugger_sendMsg(
  1850. server,
  1851. LuaDebugger.event.C2S_ReqVar,
  1852. {
  1853. variablesReference = variablesReference,
  1854. debugSpeedIndex = debugSpeedIndex,
  1855. vars = {},
  1856. isComplete = 1,
  1857. varType = "nil"
  1858. }
  1859. )
  1860. end
  1861. end
  1862. xpcall(
  1863. exe,
  1864. function(error)
  1865. -- print("获取变量错误 错误消息-----------------")
  1866. -- print(error)
  1867. -- print(debug.traceback("", 2))
  1868. debugger_sendMsg(
  1869. server,
  1870. LuaDebugger.event.C2S_ReqVar,
  1871. {
  1872. variablesReference = variablesReference,
  1873. debugSpeedIndex = debugSpeedIndex,
  1874. vars = {
  1875. {
  1876. name = "error",
  1877. valueType = "string",
  1878. valueStr = ZZBase64.encode("无法获取属性值:" .. error .. "->" .. debug.traceback("", 2)),
  1879. isValue = false
  1880. }
  1881. },
  1882. isComplete = 1
  1883. }
  1884. )
  1885. end
  1886. )
  1887. end
  1888. local function ResetDebugInfo()
  1889. LuaDebugger.Run = false
  1890. LuaDebugger.StepIn = false
  1891. LuaDebugger.StepNext = false
  1892. LuaDebugger.StepOut = false
  1893. LuaDebugger.StepNextLevel = 0
  1894. end
  1895. local function debugger_loop(server)
  1896. server = debug_server
  1897. --命令
  1898. local command
  1899. local eval_env = {}
  1900. local arg
  1901. while true do
  1902. local line, status = server:receive()
  1903. if (status == "closed") then
  1904. if(LuaDebugger.isLaunch) then
  1905. os.exit()
  1906. else
  1907. debug.sethook()
  1908. coroutine.yield()
  1909. end
  1910. end
  1911. if (line) then
  1912. local netData = json.decode(line)
  1913. local event = netData.event
  1914. local body = netData.data
  1915. if (event == LuaDebugger.event.S2C_DebugClose) then
  1916. if(LuaDebugger.isLaunch) then
  1917. os.exit()
  1918. else
  1919. debug.sethook()
  1920. coroutine.yield()
  1921. end
  1922. elseif event == LuaDebugger.event.S2C_SetBreakPoints then
  1923. --设置断点信息
  1924. local function setB()
  1925. debugger_setBreak(body)
  1926. end
  1927. xpcall(
  1928. setB,
  1929. function(error)
  1930. print(error)
  1931. end
  1932. )
  1933. elseif event == LuaDebugger.event.S2C_RUN then --开始运行
  1934. LuaDebugger.runTimeType = body.runTimeType
  1935. LuaDebugger.isProntToConsole = body.isProntToConsole
  1936. LuaDebugger.isFoxGloryProject = body.isFoxGloryProject
  1937. LuaDebugger.isLaunch = body.isLaunch
  1938. ResetDebugInfo()
  1939. LuaDebugger.Run = true
  1940. local data = coroutine.yield()
  1941. LuaDebugger.serVarLevel = 4
  1942. LuaDebugger.currentDebuggerData = data
  1943. debugger_sendMsg(
  1944. server,
  1945. data.event,
  1946. {
  1947. stack = data.stack
  1948. }
  1949. )
  1950. elseif event == LuaDebugger.event.S2C_ReqVar then -- 获取变量信息
  1951. --请求数据信息
  1952. debugger_getBreakVar(body, server)
  1953. elseif event == LuaDebugger.event.S2C_NextRequest then -- 设置单步跳过
  1954. ResetDebugInfo()
  1955. LuaDebugger.StepNext = true
  1956. LuaDebugger.StepNextLevel = 0
  1957. --设置当前文件名和当前行数
  1958. local data = coroutine.yield()
  1959. LuaDebugger.serVarLevel = 4
  1960. --重置调试信息
  1961. LuaDebugger.currentDebuggerData = data
  1962. debugger_sendMsg(
  1963. server,
  1964. data.event,
  1965. {
  1966. stack = data.stack
  1967. }
  1968. )
  1969. elseif (event == LuaDebugger.event.S2C_StepInRequest) then --单步跳入
  1970. --单步跳入
  1971. ResetDebugInfo()
  1972. LuaDebugger.StepIn = true
  1973. local data = coroutine.yield()
  1974. LuaDebugger.serVarLevel = 4
  1975. --重置调试信息
  1976. LuaDebugger.currentDebuggerData = data
  1977. debugger_sendMsg(
  1978. server,
  1979. data.event,
  1980. {
  1981. stack = data.stack,
  1982. eventType = data.eventType
  1983. }
  1984. )
  1985. elseif (event == LuaDebugger.event.S2C_StepOutRequest) then
  1986. --单步跳出
  1987. ResetDebugInfo()
  1988. LuaDebugger.StepOut = true
  1989. local data = coroutine.yield()
  1990. LuaDebugger.serVarLevel = 4
  1991. --重置调试信息
  1992. LuaDebugger.currentDebuggerData = data
  1993. debugger_sendMsg(
  1994. server,
  1995. data.event,
  1996. {
  1997. stack = data.stack,
  1998. eventType = data.eventType
  1999. }
  2000. )
  2001. elseif event == LuaDebugger.event.S2C_LoadLuaScript then
  2002. LuaDebugger.loadScriptBody = body
  2003. LuaDebugger.isLoadLuaScript = true
  2004. local data = coroutine.yield()
  2005. debugger_sendMsg(
  2006. server,
  2007. LuaDebugger.event.C2S_LoadLuaScript,
  2008. LuaDebugger.loadScriptBody
  2009. )
  2010. elseif event == LuaDebugger.event.S2C_SerVar then
  2011. LuaDebugger.isSetVar = true
  2012. LuaDebugger.setVarBody = body
  2013. local data = coroutine.yield()
  2014. debugger_sendMsg(
  2015. server,
  2016. LuaDebugger.event.C2S_SerVar,
  2017. {
  2018. stack = data,
  2019. eventType = data.eventType
  2020. }
  2021. )
  2022. elseif event == LuaDebugger.event.S2C_ReLoadFile then
  2023. LuaDebugger.isReLoadFile = true
  2024. LuaDebugger.reLoadFileBody = body
  2025. local data = coroutine.yield()
  2026. debugger_sendMsg(
  2027. server,
  2028. LuaDebugger.event.C2S_ReLoadFile,
  2029. {
  2030. stack = data,
  2031. eventType = data.eventType
  2032. }
  2033. )
  2034. end
  2035. end
  2036. end
  2037. end
  2038. coro_debugger = coroutine.create(debugger_loop)
  2039. debug_hook = function(event, line)
  2040. if(not LuaDebugger.isHook) then
  2041. return
  2042. end
  2043. if(LuaDebugger.Run) then
  2044. if(event == "line") then
  2045. local isCheck = false
  2046. for k, breakInfo in pairs(LuaDebugger.breakInfos) do
  2047. for bk, linesInfo in pairs(breakInfo) do
  2048. if(linesInfo.lines and linesInfo.lines[line]) then
  2049. isCheck = true
  2050. break
  2051. end
  2052. end
  2053. if(isCheck) then
  2054. break
  2055. end
  2056. end
  2057. if(not isCheck) then
  2058. return
  2059. end
  2060. else
  2061. LuaDebugger.currentFileName = nil
  2062. LuaDebugger.currentTempFunc = nil
  2063. return
  2064. end
  2065. end
  2066. --跳出
  2067. if (LuaDebugger.StepOut) then
  2068. if (event == "line" or event == "call") then
  2069. return
  2070. end
  2071. local tempFun = getinfo(2, "f").func
  2072. if (LuaDebugger.currentDebuggerData.funcsLength == 1) then
  2073. ResetDebugInfo()
  2074. LuaDebugger.Run = true
  2075. else
  2076. if (LuaDebugger.currentDebuggerData.funcs[2] == tempFun) then
  2077. local data = debugger_stackInfo(3, LuaDebugger.event.C2S_StepInResponse)
  2078. --挂起等待调试器作出反应
  2079. _resume(coro_debugger, data)
  2080. checkSetVar()
  2081. end
  2082. end
  2083. return
  2084. end
  2085. -- debugger_dump(LuaDebugger,"LuaDebugger")
  2086. -- print(LuaDebugger.StepNextLevel,"LuaDebugger.StepNextLevel")
  2087. local file = nil
  2088. if (event == "call") then
  2089. -- end
  2090. -- if(not LuaDebugger.StepOut) then
  2091. if (not LuaDebugger.Run) then
  2092. LuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel + 1
  2093. end
  2094. -- print("stepIn",LuaDebugger.StepNextLevel)
  2095. local stepInfo = getinfo(2, "S")
  2096. local source = stepInfo.source
  2097. if (source:find(LuaDebugger.DebugLuaFie) or source == "=[C]") then
  2098. return
  2099. end
  2100. file = getSource(source)
  2101. LuaDebugger.currentFileName = file
  2102. elseif (event == "return" or event == "tail return") then
  2103. -- end
  2104. -- if(not LuaDebugger.StepOut) then
  2105. if (not LuaDebugger.Run) then
  2106. LuaDebugger.StepNextLevel = LuaDebugger.StepNextLevel - 1
  2107. end
  2108. LuaDebugger.currentFileName = nil
  2109. elseif (event == "line") then
  2110. --@region 判断命中断点
  2111. --判断命中断点
  2112. --判断命中断点
  2113. --判断命中断点
  2114. --判断命中断点
  2115. local isHit = false
  2116. local stepInfo = nil
  2117. if (not LuaDebugger.currentFileName) then
  2118. stepInfo = getinfo(2, "S")
  2119. local source = stepInfo.source
  2120. if (source == "=[C]" or source:find(LuaDebugger.DebugLuaFie)) then
  2121. return
  2122. end
  2123. file = getSource(source)
  2124. LuaDebugger.currentFileName = file
  2125. end
  2126. file = LuaDebugger.currentFileName
  2127. --判断断点
  2128. local breakInfo = LuaDebugger.breakInfos[file]
  2129. local breakData = nil
  2130. if (breakInfo) then
  2131. local ischeck = false
  2132. for k, lineInfo in pairs(breakInfo) do
  2133. local lines = lineInfo.lines
  2134. if (lines and lines[line]) then
  2135. ischeck = true
  2136. break
  2137. end
  2138. end
  2139. if (ischeck) then
  2140. --并且在断点中
  2141. local info = stepInfo
  2142. if (not info) then
  2143. info = getinfo(2)
  2144. end
  2145. local hitPathNames = splitFilePath(LuaDebugger.currentLineFile)
  2146. local hitCounts = {}
  2147. local debugHitCounts = nil
  2148. for k, lineInfo in pairs(breakInfo) do
  2149. local lines = lineInfo.lines
  2150. local pathNames = lineInfo.pathNames
  2151. debugHitCounts = lineInfo.hitCounts
  2152. if (lines and lines[line]) then
  2153. breakData = lines[line]
  2154. --判断路径
  2155. hitCounts[k] = 0
  2156. local hitPathNamesCount = #hitPathNames
  2157. local pathNamesCount = #pathNames
  2158. local checkCount = 0;
  2159. while (true) do
  2160. if (pathNames[pathNamesCount] ~= hitPathNames[hitPathNamesCount]) then
  2161. break
  2162. else
  2163. hitCounts[k] = hitCounts[k] + 1
  2164. end
  2165. pathNamesCount = pathNamesCount - 1
  2166. hitPathNamesCount = hitPathNamesCount - 1
  2167. checkCount = checkCount+1
  2168. if (pathNamesCount <= 0 or hitPathNamesCount <= 0) then
  2169. break
  2170. end
  2171. end
  2172. if(checkCount>0) then
  2173. break;
  2174. end
  2175. else
  2176. breakData = nil
  2177. end
  2178. end
  2179. if (breakData) then
  2180. local hitFieName = ""
  2181. local maxCount = 0
  2182. for k, v in pairs(hitCounts) do
  2183. if (v > maxCount) then
  2184. maxCount = v
  2185. hitFieName = k
  2186. end
  2187. end
  2188. local hitPathNamesLength = #hitPathNames
  2189. if (hitPathNamesLength == 1 or (hitPathNamesLength > 1 and maxCount > 1)) then
  2190. if (hitFieName ~= "") then
  2191. local hitCount = breakData.hitCondition
  2192. local clientHitCount = debugHitCounts[breakData.line]
  2193. clientHitCount = clientHitCount + 1
  2194. debugHitCounts[breakData.line] = clientHitCount
  2195. if (clientHitCount >= hitCount) then
  2196. isHit = true
  2197. end
  2198. end
  2199. end
  2200. end
  2201. end
  2202. end
  2203. --@endregion
  2204. if (LuaDebugger.StepIn) then
  2205. local data = debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)
  2206. --挂起等待调试器作出反应
  2207. if (data) then
  2208. LuaDebugger.currentTempFunc = data.funcs[1]
  2209. _resume(coro_debugger, data)
  2210. checkSetVar()
  2211. return
  2212. end
  2213. end
  2214. if (LuaDebugger.StepNext) then
  2215. if (LuaDebugger.StepNextLevel <= 0) then
  2216. local data = debugger_stackInfo(3, LuaDebugger.event.C2S_NextResponse)
  2217. -- 挂起等待调试器作出反应
  2218. if (data) then
  2219. LuaDebugger.currentTempFunc = data.funcs[1]
  2220. _resume(coro_debugger, data)
  2221. checkSetVar()
  2222. return
  2223. end
  2224. end
  2225. end
  2226. if (isHit) then
  2227. local data = debugger_stackInfo(3, LuaDebugger.event.C2S_HITBreakPoint)
  2228. if (breakData and breakData.condition) then
  2229. debugger_conditionStr(
  2230. breakData.condition,
  2231. data.vars,
  2232. function()
  2233. _resume(coro_debugger, data)
  2234. checkSetVar()
  2235. end
  2236. )
  2237. else
  2238. --挂起等待调试器作出反应
  2239. _resume(coro_debugger, data)
  2240. checkSetVar()
  2241. end
  2242. end
  2243. end
  2244. end
  2245. local function debugger_xpcall()
  2246. --调用 coro_debugger 并传入 参数
  2247. local data = debugger_stackInfo(4, LuaDebugger.event.C2S_HITBreakPoint)
  2248. if(data.stack and data.stack[1]) then
  2249. data.stack[1].isXpCall = true
  2250. end
  2251. --挂起等待调试器作出反应
  2252. _resume(coro_debugger, data)
  2253. checkSetVar()
  2254. end
  2255. --调试开始
  2256. local function start()
  2257. local fullName, dirName, fileName = debugger_getFilePathInfo(getinfo(1).source)
  2258. LuaDebugger.DebugLuaFie = fileName
  2259. local socket = createSocket()
  2260. print(controller_host)
  2261. print(controller_port)
  2262. local server = socket.connect(controller_host, controller_port)
  2263. debug_server = server
  2264. if server then
  2265. --创建breakInfo socket
  2266. socket = createSocket()
  2267. breakInfoSocket = socket.connect(controller_host, controller_port)
  2268. if (breakInfoSocket) then
  2269. breakInfoSocket:settimeout(0)
  2270. debugger_sendMsg(
  2271. breakInfoSocket,
  2272. LuaDebugger.event.C2S_SetSocketName,
  2273. {
  2274. name = "breakPointSocket"
  2275. }
  2276. )
  2277. debugger_sendMsg(
  2278. server,
  2279. LuaDebugger.event.C2S_SetSocketName,
  2280. {
  2281. name = "mainSocket",
  2282. version = LuaDebugger.version
  2283. }
  2284. )
  2285. xpcall(
  2286. function()
  2287. debug.sethook(debug_hook, "lrc")
  2288. end,
  2289. function(error)
  2290. print("error:", error)
  2291. end
  2292. )
  2293. if (jit) then
  2294. if (LuaDebugger.debugLuaType ~= "jit") then
  2295. print("error======================================================")
  2296. local msg = "当前luajit版本为: " .. jit.version .. " 请使用LuaDebugjit 进行调试!"
  2297. print(msg)
  2298. end
  2299. end
  2300. _resume(coro_debugger, server)
  2301. end
  2302. end
  2303. end
  2304. function StartDebug(host, port)
  2305. if (not host) then
  2306. print("error host nil")
  2307. end
  2308. if (not port) then
  2309. print("error prot nil")
  2310. end
  2311. if (type(host) ~= "string") then
  2312. print("error host not string")
  2313. end
  2314. if (type(port) ~= "number") then
  2315. print("error host not number")
  2316. end
  2317. controller_host = host
  2318. controller_port = port
  2319. xpcall(
  2320. start,
  2321. function(error)
  2322. -- body
  2323. print(error)
  2324. end
  2325. )
  2326. return debugger_receiveDebugBreakInfo, debugger_xpcall
  2327. end
  2328. --base64
  2329. local string = string
  2330. ZZBase64.__code = {
  2331. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  2332. 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  2333. 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  2334. 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
  2335. };
  2336. ZZBase64.__decode = {}
  2337. for k,v in pairs(ZZBase64.__code) do
  2338. ZZBase64.__decode[string.byte(v,1)] = k - 1
  2339. end
  2340. function ZZBase64.encode(text)
  2341. local len = string.len(text)
  2342. local left = len % 3
  2343. len = len - left
  2344. local res = {}
  2345. local index = 1
  2346. for i = 1, len, 3 do
  2347. local a = string.byte(text, i )
  2348. local b = string.byte(text, i + 1)
  2349. local c = string.byte(text, i + 2)
  2350. -- num = a<<16 + b<<8 + c
  2351. local num = a * 65536 + b * 256 + c
  2352. for j = 1, 4 do
  2353. --tmp = num >> ((4 -j) * 6)
  2354. local tmp = math.floor(num / (2 ^ ((4-j) * 6)))
  2355. --curPos = tmp&0x3f
  2356. local curPos = tmp % 64 + 1
  2357. res[index] = ZZBase64.__code[curPos]
  2358. index = index + 1
  2359. end
  2360. end
  2361. if left == 1 then
  2362. ZZBase64.__left1(res, index, text, len)
  2363. elseif left == 2 then
  2364. ZZBase64.__left2(res, index, text, len)
  2365. end
  2366. return table.concat(res)
  2367. end
  2368. function ZZBase64.__left2(res, index, text, len)
  2369. local num1 = string.byte(text, len + 1)
  2370. num1 = num1 * 1024 --lshift 10
  2371. local num2 = string.byte(text, len + 2)
  2372. num2 = num2 * 4 --lshift 2
  2373. local num = num1 + num2
  2374. local tmp1 = math.floor(num / 4096) --rShift 12
  2375. local curPos = tmp1 % 64 + 1
  2376. res[index] = ZZBase64.__code[curPos]
  2377. local tmp2 = math.floor(num / 64)
  2378. curPos = tmp2 % 64 + 1
  2379. res[index + 1] = ZZBase64.__code[curPos]
  2380. curPos = num % 64 + 1
  2381. res[index + 2] = ZZBase64.__code[curPos]
  2382. res[index + 3] = "="
  2383. end
  2384. function ZZBase64.__left1(res, index,text, len)
  2385. local num = string.byte(text, len + 1)
  2386. num = num * 16
  2387. local tmp = math.floor(num / 64)
  2388. local curPos = tmp % 64 + 1
  2389. res[index ] = ZZBase64.__code[curPos]
  2390. curPos = num % 64 + 1
  2391. res[index + 1] = ZZBase64.__code[curPos]
  2392. res[index + 2] = "="
  2393. res[index + 3] = "="
  2394. end
  2395. function ZZBase64.decode(text)
  2396. local len = string.len(text)
  2397. local left = 0
  2398. if string.sub(text, len - 1) == "==" then
  2399. left = 2
  2400. len = len - 4
  2401. elseif string.sub(text, len) == "=" then
  2402. left = 1
  2403. len = len - 4
  2404. end
  2405. local res = {}
  2406. local index = 1
  2407. local decode = ZZBase64.__decode
  2408. for i =1, len, 4 do
  2409. local a = decode[string.byte(text,i )]
  2410. local b = decode[string.byte(text,i + 1)]
  2411. local c = decode[string.byte(text,i + 2)]
  2412. local d = decode[string.byte(text,i + 3)]
  2413. --num = a<<18 + b<<12 + c<<6 + d
  2414. local num = a * 262144 + b * 4096 + c * 64 + d
  2415. local e = string.char(num % 256)
  2416. num = math.floor(num / 256)
  2417. local f = string.char(num % 256)
  2418. num = math.floor(num / 256)
  2419. res[index ] = string.char(num % 256)
  2420. res[index + 1] = f
  2421. res[index + 2] = e
  2422. index = index + 3
  2423. end
  2424. if left == 1 then
  2425. ZZBase64.__decodeLeft1(res, index, text, len)
  2426. elseif left == 2 then
  2427. ZZBase64.__decodeLeft2(res, index, text, len)
  2428. end
  2429. return table.concat(res)
  2430. end
  2431. function ZZBase64.__decodeLeft1(res, index, text, len)
  2432. local decode = ZZBase64.__decode
  2433. local a = decode[string.byte(text, len + 1)]
  2434. local b = decode[string.byte(text, len + 2)]
  2435. local c = decode[string.byte(text, len + 3)]
  2436. local num = a * 4096 + b * 64 + c
  2437. local num1 = math.floor(num / 1024) % 256
  2438. local num2 = math.floor(num / 4) % 256
  2439. res[index] = string.char(num1)
  2440. res[index + 1] = string.char(num2)
  2441. end
  2442. function ZZBase64.__decodeLeft2(res, index, text, len)
  2443. local decode = ZZBase64.__decode
  2444. local a = decode[string.byte(text, len + 1)]
  2445. local b = decode[string.byte(text, len + 2)]
  2446. local num = a * 64 + b
  2447. num = math.floor(num / 16)
  2448. res[index] = string.char(num)
  2449. end
  2450. return StartDebug