2021.04.22-03.21
This commit is contained in:
		
							parent
							
								
									c356f3dbb3
								
							
						
					
					
						commit
						aabe905c73
					
				
							
								
								
									
										
											BIN
										
									
								
								authserver
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								authserver
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										115
									
								
								lua_scripts/extensions/ObjectVariables.ext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								lua_scripts/extensions/ObjectVariables.ext
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| -- | ||||
| -- Copyright (C) 2010 - 2016 Eluna Lua Engine <http://emudevs.com/> | ||||
| -- This program is free software licensed under GPL version 3 | ||||
| -- Please see the included DOCS/LICENSE.md for more information | ||||
| -- | ||||
| 
 | ||||
| -- filename.ext files are loaded before normal .lua files | ||||
| 
 | ||||
| -- | ||||
| -- This extension allows saving data to specific object for it's lifetime in current runtime session | ||||
| -- Supports Map, Player, Creature, GameObject | ||||
| -- | ||||
| -- SetData sets a value | ||||
| --  obj:SetData(key, val) | ||||
| -- | ||||
| -- GetData gets the data table or a specific value by key from it | ||||
| --  local tbl = obj:GetData() | ||||
| --  local val = obj:GetData(key) | ||||
| -- | ||||
| 
 | ||||
| local pairs = pairs | ||||
| 
 | ||||
| local variableStores = { | ||||
|     Map = {}, | ||||
|     Player = {}, | ||||
|     Creature = {}, | ||||
|     GameObject = {}, | ||||
| } | ||||
| 
 | ||||
| local function DestroyMapData(event, obj) | ||||
|     local map = obj:GetMapId() | ||||
|     local inst = obj:GetInstanceId() | ||||
|     for k,v in pairs(variableStores) do | ||||
|         local mapdata = v[map] | ||||
|         if mapdata then | ||||
|             mapdata[inst] = nil | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| local function DestroyObjData(event, obj) | ||||
|     local otype = obj:GetObjectType() | ||||
|     local guid = otype == "Map" and 1 or obj:GetGUIDLow() | ||||
| 
 | ||||
|     if otype == "Player" then | ||||
|         variableStores[otype][guid] = nil | ||||
|         return | ||||
|     end | ||||
| 
 | ||||
|     local map = obj:GetMapId() | ||||
|     local inst = obj:GetInstanceId() | ||||
|     local mapdata = variableStores[otype][map] | ||||
|     if mapdata then | ||||
|         local instancedata = mapdata[inst] | ||||
|         if instancedata then | ||||
|             instancedata[guid] = nil | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| local function GetData(self, field) | ||||
|     local otype = self:GetObjectType() | ||||
|     local guid = otype == "Map" and 1 or self:GetGUIDLow() | ||||
|     local varStore = variableStores[otype] | ||||
| 
 | ||||
|     if otype == "Player" then | ||||
|         varStore[guid] = varStore[guid] or {} | ||||
|         if field ~= nil then | ||||
|             return varStore[guid][field] | ||||
|         end | ||||
|         return varStore[guid] | ||||
|     end | ||||
| 
 | ||||
|     local map = self:GetMapId() | ||||
|     local inst = self:GetInstanceId() | ||||
|     varStore[map] = varStore[map] or {} | ||||
|     varStore[map][inst] = varStore[map][inst] or {} | ||||
|     varStore[map][inst][guid] = varStore[map][inst][guid] or {} | ||||
| 
 | ||||
|     if field ~= nil then | ||||
|         return varStore[map][inst][guid][field] | ||||
|     end | ||||
|     return varStore[map][inst][guid] | ||||
| end | ||||
| 
 | ||||
| local function SetData(self, field, val) | ||||
|     local otype = self:GetObjectType() | ||||
|     local guid = otype == "Map" and 1 or self:GetGUIDLow() | ||||
|     local varStore = variableStores[otype] | ||||
| 
 | ||||
|     if otype == "Player" then | ||||
|         varStore[guid] = varStore[guid] or {} | ||||
|         varStore[guid][field] = val | ||||
|         return | ||||
|     end | ||||
| 
 | ||||
|     local map = self:GetMapId() | ||||
|     local inst = self:GetInstanceId() | ||||
|     varStore[map] = varStore[map] or {} | ||||
|     varStore[map][inst] = varStore[map][inst] or {} | ||||
|     varStore[map][inst][guid] = varStore[map][inst][guid] or {} | ||||
| 
 | ||||
|     varStore[map][inst][guid][field] = val | ||||
| end | ||||
| 
 | ||||
| for k,v in pairs(variableStores) do | ||||
|     _G[k].GetData = GetData | ||||
|     _G[k].SetData = SetData | ||||
| end | ||||
| 
 | ||||
| RegisterPlayerEvent(4, DestroyObjData) -- logout | ||||
| RegisterServerEvent(31, DestroyObjData) -- creature delete | ||||
| RegisterServerEvent(32, DestroyObjData) -- gameobject delete | ||||
| RegisterServerEvent(17, DestroyMapData) -- map create | ||||
| RegisterServerEvent(18, DestroyMapData) -- map destroy | ||||
							
								
								
									
										21
									
								
								lua_scripts/extensions/StackTracePlus/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lua_scripts/extensions/StackTracePlus/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| The MIT License | ||||
| 
 | ||||
| Copyright (c) 2010 Ignacio Burgueño | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										128
									
								
								lua_scripts/extensions/StackTracePlus/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								lua_scripts/extensions/StackTracePlus/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| # StackTracePlus # | ||||
| 
 | ||||
| [](https://travis-ci.org/ignacio/StackTracePlus) | ||||
| 
 | ||||
| [StackTracePlus](https://github.com/ignacio/StackTracePlus) provides enhanced stack traces for [Lua 5.1, Lua 5.2][1] and [LuaJIT][2]. | ||||
| 
 | ||||
| StackTracePlus can be used as a replacement for debug.traceback. It gives detailed information about locals, tries to guess | ||||
| function names when they're not available, etc, so, instead of | ||||
| 
 | ||||
|     lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value | ||||
|     stack traceback: | ||||
| 	D:\trunk_git\sources\stacktraceplus\test\test.lua:10: in function <D:\trunk_git\sources\stacktraceplus\test\test.lua:7> | ||||
| 	(tail call): ? | ||||
| 	D:\trunk_git\sources\stacktraceplus\test\test.lua:15: in main chunk | ||||
| 	[C]: ? | ||||
| 
 | ||||
| you'll get | ||||
| 
 | ||||
|     lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value | ||||
|     Stack Traceback | ||||
|     =============== | ||||
|     (2)  C function 'function: 00A8F418' | ||||
|     (3) Lua function 'g' at file 'D:\trunk_git\sources\stacktraceplus\test\test.lua:10' (best guess) | ||||
| 	Local variables: | ||||
| 	 fun = table module | ||||
| 	 str = string: "hey" | ||||
| 	 tb = table: 027DCBE0  {dummy:1, blah:true, foo:bar} | ||||
| 	 (*temporary) = nil | ||||
| 	 (*temporary) = string: "text" | ||||
| 	 (*temporary) = string: "attempt to concatenate a nil value" | ||||
|     (4) tail call | ||||
|     (5) main chunk of file 'D:\trunk_git\sources\stacktraceplus\test\test.lua' at line 15 | ||||
|     (6)  C function 'function: 002CA480' | ||||
| 
 | ||||
| ## Usage # | ||||
| 
 | ||||
| StackTracePlus can be used as a replacement for `debug.traceback`, as an `xpcall` error handler or even from C code. Note that | ||||
| only the Lua 5.1 interpreter allows the traceback function to be replaced "on the fly". LuaJIT and Lua 5.2 always calls luaL_traceback internally so there is no easy way to override that. | ||||
| 
 | ||||
| ```lua | ||||
| local STP = require "StackTracePlus" | ||||
| 
 | ||||
| debug.traceback = STP.stacktrace | ||||
| function test() | ||||
| 	local s = "this is a string" | ||||
| 	local n = 42 | ||||
| 	local t = { foo = "bar" } | ||||
| 	local co = coroutine | ||||
| 	local cr = coroutine.create | ||||
| 
 | ||||
| 	error("an error") | ||||
| end | ||||
| test() | ||||
| ``` | ||||
| 
 | ||||
| That script will output (only with Lua 5.1): | ||||
| 
 | ||||
|     lua5.1: example.lua:11: an error | ||||
|     Stack Traceback | ||||
|     =============== | ||||
|     (2)  C function 'function: 006B5758' | ||||
|     (3) global C function 'error' | ||||
|     (4) Lua global 'test' at file 'example.lua:11' | ||||
|             Local variables: | ||||
|              s = string: "this is a string" | ||||
|              n = number: 42 | ||||
|              t = table: 006E5220  {foo:bar} | ||||
|              co = coroutine table | ||||
|              cr = C function: 003C7080 | ||||
|     (5) main chunk of file 'example.lua' at line 14 | ||||
|     (6)  C function 'function: 00637B30' | ||||
| 
 | ||||
| **StackTracePlus** is aware of the usual Lua libraries, like *coroutine*, *table*, *string*, *io*, etc and functions like | ||||
| *print*, *pcall*, *assert*, and so on. | ||||
| 
 | ||||
| You can also make STP aware of your own tables and functions by calling *add_known_function* and *add_known_table*. | ||||
| 
 | ||||
| ```lua | ||||
| local STP = require "StackTracePlus" | ||||
| 
 | ||||
| debug.traceback = STP.stacktrace | ||||
| local my_table = { | ||||
| 	f = function() end | ||||
| } | ||||
| function my_function() | ||||
| end | ||||
| 
 | ||||
| function test(data, func) | ||||
| 	local s = "this is a string" | ||||
| 
 | ||||
| 	error("an error") | ||||
| end | ||||
| 
 | ||||
| STP.add_known_table(my_table, "A description for my_table") | ||||
| STP.add_known_function(my_function, "A description for my_function") | ||||
| 
 | ||||
| test( my_table, my_function ) | ||||
| ``` | ||||
| 
 | ||||
| Will output: | ||||
| 
 | ||||
|     lua5.1: ..\test\example2.lua:13: an error | ||||
|     Stack Traceback | ||||
|     =============== | ||||
|     (2)  C function 'function: 0073AAA8' | ||||
|     (3) global C function 'error' | ||||
|     (4) Lua global 'test' at file '..\test\example2.lua:13' | ||||
|             Local variables: | ||||
|              data = A description for my_table | ||||
|              func = Lua function 'A description for my_function' (defined at line 7 of chunk ..\test\example2.lua) | ||||
|              s = string: "this is a string" | ||||
|     (5) main chunk of file '..\test\example2.lua' at line 19 | ||||
|     (6)  C function 'function: 00317B30' | ||||
| 
 | ||||
| 
 | ||||
| ## Installation # | ||||
| The easiest way to install is with [LuaRocks][3]. | ||||
| 
 | ||||
|   - luarocks install stacktraceplus | ||||
| 
 | ||||
| If you don't want to use LuaRocks, just copy StackTracePlus.lua to Lua's path. | ||||
| 
 | ||||
| ## License # | ||||
| **StackTracePlus** is available under the MIT license. | ||||
| 
 | ||||
| [1]: http://www.lua.org/ | ||||
| [2]: http://luajit.org/ | ||||
| [3]: http://luarocks.org/ | ||||
							
								
								
									
										411
									
								
								lua_scripts/extensions/StackTracePlus/StackTracePlus.ext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								lua_scripts/extensions/StackTracePlus/StackTracePlus.ext
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,411 @@ | ||||
| -- tables | ||||
| local _G = _G | ||||
| local string, io, debug, coroutine = string, io, debug, coroutine | ||||
| 
 | ||||
| -- functions | ||||
| local tostring, print, require = tostring, print, require | ||||
| local next, assert = next, assert | ||||
| local pcall, type, pairs, ipairs = pcall, type, pairs, ipairs | ||||
| local error = error | ||||
| 
 | ||||
| assert(debug, "debug table must be available at this point") | ||||
| 
 | ||||
| local io_open = io.open | ||||
| local string_gmatch = string.gmatch | ||||
| local string_sub = string.sub | ||||
| local table_concat = table.concat | ||||
| 
 | ||||
| local _M = { | ||||
| 	max_tb_output_len = 70	-- controls the maximum length of the 'stringified' table before cutting with ' (more...)' | ||||
| } | ||||
| 
 | ||||
| -- this tables should be weak so the elements in them won't become uncollectable | ||||
| local m_known_tables = { [_G] = "_G (global table)" } | ||||
| local function add_known_module(name, desc) | ||||
| 	local ok, mod = pcall(require, name) | ||||
| 	if ok then | ||||
| 		m_known_tables[mod] = desc | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| add_known_module("string", "string module") | ||||
| add_known_module("io", "io module") | ||||
| add_known_module("os", "os module") | ||||
| add_known_module("table", "table module") | ||||
| add_known_module("math", "math module") | ||||
| add_known_module("package", "package module") | ||||
| add_known_module("debug", "debug module") | ||||
| add_known_module("coroutine", "coroutine module") | ||||
| 
 | ||||
| -- lua5.2 | ||||
| add_known_module("bit32", "bit32 module") | ||||
| -- luajit | ||||
| add_known_module("bit", "bit module") | ||||
| add_known_module("jit", "jit module") | ||||
| 
 | ||||
| 
 | ||||
| local m_user_known_tables = {} | ||||
| 
 | ||||
| local m_known_functions = {} | ||||
| for _, name in ipairs{ | ||||
| 	-- Lua 5.2, 5.1 | ||||
| 	"assert", | ||||
| 	"collectgarbage", | ||||
| 	"dofile", | ||||
| 	"error", | ||||
| 	"getmetatable", | ||||
| 	"ipairs", | ||||
| 	"load", | ||||
| 	"loadfile", | ||||
| 	"next", | ||||
| 	"pairs", | ||||
| 	"pcall", | ||||
| 	"print", | ||||
| 	"rawequal", | ||||
| 	"rawget", | ||||
| 	"rawlen", | ||||
| 	"rawset", | ||||
| 	"require", | ||||
| 	"select", | ||||
| 	"setmetatable", | ||||
| 	"tonumber", | ||||
| 	"tostring", | ||||
| 	"type", | ||||
| 	"xpcall", | ||||
| 
 | ||||
| 	-- Lua 5.1 | ||||
| 	"gcinfo", | ||||
| 	"getfenv", | ||||
| 	"loadstring", | ||||
| 	"module", | ||||
| 	"newproxy", | ||||
| 	"setfenv", | ||||
| 	"unpack", | ||||
| 	-- TODO: add table.* etc functions | ||||
| } do | ||||
| 	if _G[name] then | ||||
| 		m_known_functions[_G[name]] = name | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| local m_user_known_functions = {} | ||||
| 
 | ||||
| local function safe_tostring (value) | ||||
| 	local ok, err = pcall(tostring, value) | ||||
| 	if ok then return err else return ("<failed to get printable value>: '%s'"):format(err) end | ||||
| end | ||||
| 
 | ||||
| -- Private: | ||||
| -- Parses a line, looking for possible function definitions (in a very na?ve way) | ||||
| -- Returns '(anonymous)' if no function name was found in the line | ||||
| local function ParseLine(line) | ||||
| 	assert(type(line) == "string") | ||||
| 	--print(line) | ||||
| 	local match = line:match("^%s*function%s+(%w+)") | ||||
| 	if match then | ||||
| 		--print("+++++++++++++function", match) | ||||
| 		return match | ||||
| 	end | ||||
| 	match = line:match("^%s*local%s+function%s+(%w+)") | ||||
| 	if match then | ||||
| 		--print("++++++++++++local", match) | ||||
| 		return match | ||||
| 	end | ||||
| 	match = line:match("^%s*local%s+(%w+)%s+=%s+function") | ||||
| 	if match then | ||||
| 		--print("++++++++++++local func", match) | ||||
| 		return match | ||||
| 	end | ||||
| 	match = line:match("%s*function%s*%(")	-- this is an anonymous function | ||||
| 	if match then | ||||
| 		--print("+++++++++++++function2", match) | ||||
| 		return "(anonymous)" | ||||
| 	end | ||||
| 	return "(anonymous)" | ||||
| end | ||||
| 
 | ||||
| -- Private: | ||||
| -- Tries to guess a function's name when the debug info structure does not have it. | ||||
| -- It parses either the file or the string where the function is defined. | ||||
| -- Returns '?' if the line where the function is defined is not found | ||||
| local function GuessFunctionName(info) | ||||
| 	--print("guessing function name") | ||||
| 	if type(info.source) == "string" and info.source:sub(1,1) == "@" then | ||||
| 		local file, err = io_open(info.source:sub(2), "r") | ||||
| 		if not file then | ||||
| 			print("file not found: "..tostring(err))	-- whoops! | ||||
| 			return "?" | ||||
| 		end | ||||
| 		local line | ||||
| 		for i = 1, info.linedefined do | ||||
| 			line = file:read("*l") | ||||
| 		end | ||||
| 		if not line then | ||||
| 			print("line not found")	-- whoops! | ||||
| 			return "?" | ||||
| 		end | ||||
| 		return ParseLine(line) | ||||
| 	else | ||||
| 		local line | ||||
| 		local lineNumber = 0 | ||||
| 		for l in string_gmatch(info.source, "([^\n]+)\n-") do | ||||
| 			lineNumber = lineNumber + 1 | ||||
| 			if lineNumber == info.linedefined then | ||||
| 				line = l | ||||
| 				break | ||||
| 			end | ||||
| 		end | ||||
| 		if not line then | ||||
| 			print("line not found")	-- whoops! | ||||
| 			return "?" | ||||
| 		end | ||||
| 		return ParseLine(line) | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| --- | ||||
| -- Dumper instances are used to analyze stacks and collect its information. | ||||
| -- | ||||
| local Dumper = {} | ||||
| 
 | ||||
| Dumper.new = function(thread) | ||||
| 	local t = { lines = {} } | ||||
| 	for k,v in pairs(Dumper) do t[k] = v end | ||||
| 
 | ||||
| 	t.dumping_same_thread = (thread == coroutine.running()) | ||||
| 
 | ||||
| 	-- if a thread was supplied, bind it to debug.info and debug.get | ||||
| 	-- we also need to skip this additional level we are introducing in the callstack (only if we are running | ||||
| 	-- in the same thread we're inspecting) | ||||
| 	if type(thread) == "thread" then | ||||
| 		t.getinfo = function(level, what) | ||||
| 			if t.dumping_same_thread and type(level) == "number" then | ||||
| 				level = level + 1 | ||||
| 			end | ||||
| 			return debug.getinfo(thread, level, what) | ||||
| 		end | ||||
| 		t.getlocal = function(level, loc) | ||||
| 			if t.dumping_same_thread then | ||||
| 				level = level + 1 | ||||
| 			end | ||||
| 			return debug.getlocal(thread, level, loc) | ||||
| 		end | ||||
| 	else | ||||
| 		t.getinfo = debug.getinfo | ||||
| 		t.getlocal = debug.getlocal | ||||
| 	end | ||||
| 
 | ||||
| 	return t | ||||
| end | ||||
| 
 | ||||
| -- helpers for collecting strings to be used when assembling the final trace | ||||
| function Dumper:add (text) | ||||
| 	self.lines[#self.lines + 1] = text | ||||
| end | ||||
| function Dumper:add_f (fmt, ...) | ||||
| 	self:add(fmt:format(...)) | ||||
| end | ||||
| function Dumper:concat_lines () | ||||
| 	return table_concat(self.lines) | ||||
| end | ||||
| 
 | ||||
| --- | ||||
| -- Private: | ||||
| -- Iterates over the local variables of a given function. | ||||
| -- | ||||
| -- @param level The stack level where the function is. | ||||
| -- | ||||
| function Dumper:DumpLocals (level) | ||||
| 	local prefix = "\t " | ||||
| 	local i = 1 | ||||
| 
 | ||||
| 	if self.dumping_same_thread then | ||||
| 		level = level + 1 | ||||
| 	end | ||||
| 
 | ||||
| 	local name, value = self.getlocal(level, i) | ||||
| 	if not name then | ||||
| 		return | ||||
| 	end | ||||
| 	self:add("\tLocal variables:\r\n") | ||||
| 	while name do | ||||
| 		if type(value) == "number" then | ||||
| 			self:add_f("%s%s = number: %g\r\n", prefix, name, value) | ||||
| 		elseif type(value) == "boolean" then | ||||
| 			self:add_f("%s%s = boolean: %s\r\n", prefix, name, tostring(value)) | ||||
| 		elseif type(value) == "string" then | ||||
| 			self:add_f("%s%s = string: %q\r\n", prefix, name, value) | ||||
| 		elseif type(value) == "userdata" then | ||||
| 			self:add_f("%s%s = %s\r\n", prefix, name, safe_tostring(value)) | ||||
| 		elseif type(value) == "nil" then | ||||
| 			self:add_f("%s%s = nil\r\n", prefix, name) | ||||
| 		elseif type(value) == "table" then | ||||
| 			if m_known_tables[value] then | ||||
| 				self:add_f("%s%s = %s\r\n", prefix, name, m_known_tables[value]) | ||||
| 			elseif m_user_known_tables[value] then | ||||
| 				self:add_f("%s%s = %s\r\n", prefix, name, m_user_known_tables[value]) | ||||
| 			else | ||||
| 				local txt = "{" | ||||
| 				for k,v in pairs(value) do | ||||
| 					txt = txt..safe_tostring(k)..":"..safe_tostring(v) | ||||
| 					if #txt > _M.max_tb_output_len then | ||||
| 						txt = txt.." (more...)" | ||||
| 						break | ||||
| 					end | ||||
| 					if next(value, k) then txt = txt..", " end | ||||
| 				end | ||||
| 				self:add_f("%s%s = %s  %s\r\n", prefix, name, safe_tostring(value), txt.."}") | ||||
| 			end | ||||
| 		elseif type(value) == "function" then | ||||
| 			local info = self.getinfo(value, "nS") | ||||
| 			local fun_name = info.name or m_known_functions[value] or m_user_known_functions[value] | ||||
| 			if info.what == "C" then | ||||
| 				self:add_f("%s%s = C %s\r\n", prefix, name, (fun_name and ("function: " .. fun_name) or tostring(value))) | ||||
| 			else | ||||
| 				local source = info.short_src | ||||
| 				if source:sub(2,7) == "string" then | ||||
| 					source = source:sub(9)	-- uno m?s, por el espacio que viene (string "Baragent.Main", por ejemplo) | ||||
| 				end | ||||
| 				--for k,v in pairs(info) do print(k,v) end | ||||
| 				fun_name = fun_name or GuessFunctionName(info) | ||||
| 				self:add_f("%s%s = Lua function '%s' (defined at line %d of chunk %s)\r\n", prefix, name, fun_name, info.linedefined, source) | ||||
| 			end | ||||
| 		elseif type(value) == "thread" then | ||||
| 			self:add_f("%sthread %q = %s\r\n", prefix, name, tostring(value)) | ||||
| 		end | ||||
| 		i = i + 1 | ||||
| 		name, value = self.getlocal(level, i) | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| --- | ||||
| -- Public: | ||||
| -- Collects a detailed stack trace, dumping locals, resolving function names when they're not available, etc. | ||||
| -- This function is suitable to be used as an error handler with pcall or xpcall | ||||
| -- | ||||
| -- @param thread An optional thread whose stack is to be inspected (defaul is the current thread) | ||||
| -- @param message An optional error string or object. | ||||
| -- @param level An optional number telling at which level to start the traceback (default is 1) | ||||
| -- | ||||
| -- Returns a string with the stack trace and a string with the original error. | ||||
| -- | ||||
| function _M.stacktrace(thread, message, level) | ||||
| 	if type(thread) ~= "thread" then | ||||
| 		-- shift parameters left | ||||
| 		thread, message, level = nil, thread, message | ||||
| 	end | ||||
| 
 | ||||
| 	thread = thread or coroutine.running() | ||||
| 
 | ||||
| 	level = level or 1 | ||||
| 
 | ||||
| 	local dumper = Dumper.new(thread) | ||||
| 
 | ||||
| 	local original_error | ||||
| 
 | ||||
| 	if type(message) == "table" then | ||||
| 		dumper:add("an error object {\r\n") | ||||
| 		local first = true | ||||
| 		for k,v in pairs(message) do | ||||
| 			if first then | ||||
| 				dumper:add("  ") | ||||
| 				first = false | ||||
| 			else | ||||
| 				dumper:add(",\r\n  ") | ||||
| 			end | ||||
| 			dumper:add(safe_tostring(k)) | ||||
| 			dumper:add(": ") | ||||
| 			dumper:add(safe_tostring(v)) | ||||
| 		end | ||||
| 		dumper:add("\r\n}") | ||||
| 		original_error = dumper:concat_lines() | ||||
| 	elseif type(message) == "string" then | ||||
| 		dumper:add(message) | ||||
| 		original_error = message | ||||
| 	end | ||||
| 
 | ||||
| 	dumper:add("\r\n") | ||||
| 	dumper:add[[ | ||||
| Stack Traceback | ||||
| =============== | ||||
| ]] | ||||
| 	--print(error_message) | ||||
| 
 | ||||
| 	local level_to_show = level | ||||
| 	if dumper.dumping_same_thread then level = level + 1 end | ||||
| 
 | ||||
| 	local info = dumper.getinfo(level, "nSlf") | ||||
| 	while info do | ||||
| 		if info.what == "main" then | ||||
| 			if string_sub(info.source, 1, 1) == "@" then | ||||
| 				dumper:add_f("(%d) main chunk of file '%s' at line %d\r\n", level_to_show, string_sub(info.source, 2), info.currentline) | ||||
| 			else | ||||
| 				dumper:add_f("(%d) main chunk of %s at line %d\r\n", level_to_show, info.short_src, info.currentline) | ||||
| 			end | ||||
| 		elseif info.what == "C" then | ||||
| 			--print(info.namewhat, info.name) | ||||
| 			--for k,v in pairs(info) do print(k,v, type(v)) end | ||||
| 			local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name or tostring(info.func) | ||||
| 			dumper:add_f("(%d) %s C function '%s'\r\n", level_to_show, info.namewhat, function_name) | ||||
| 			--dumper:add_f("%s%s = C %s\r\n", prefix, name, (m_known_functions[value] and ("function: " .. m_known_functions[value]) or tostring(value))) | ||||
| 		elseif info.what == "tail" then | ||||
| 			--print("tail") | ||||
| 			--for k,v in pairs(info) do print(k,v, type(v)) end--print(info.namewhat, info.name) | ||||
| 			dumper:add_f("(%d) tail call\r\n", level_to_show) | ||||
| 			dumper:DumpLocals(level) | ||||
| 		elseif info.what == "Lua" then | ||||
| 			local source = info.short_src | ||||
| 			local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name | ||||
| 			if source:sub(2, 7) == "string" then | ||||
| 				source = source:sub(9) | ||||
| 			end | ||||
| 			local was_guessed = false | ||||
| 			if not function_name or function_name == "?" then | ||||
| 				--for k,v in pairs(info) do print(k,v, type(v)) end | ||||
| 				function_name = GuessFunctionName(info) | ||||
| 				was_guessed = true | ||||
| 			end | ||||
| 			-- test if we have a file name | ||||
| 			local function_type = (info.namewhat == "") and "function" or info.namewhat | ||||
| 			if info.source and info.source:sub(1, 1) == "@" then | ||||
| 				dumper:add_f("(%d) Lua %s '%s' at file '%s:%d'%s\r\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "") | ||||
| 			elseif info.source and info.source:sub(1,1) == '#' then | ||||
| 				dumper:add_f("(%d) Lua %s '%s' at template '%s:%d'%s\r\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "") | ||||
| 			else | ||||
| 				dumper:add_f("(%d) Lua %s '%s' at line %d of chunk '%s'\r\n", level_to_show, function_type, function_name, info.currentline, source) | ||||
| 			end | ||||
| 			dumper:DumpLocals(level) | ||||
| 		else | ||||
| 			dumper:add_f("(%d) unknown frame %s\r\n", level_to_show, info.what) | ||||
| 		end | ||||
| 
 | ||||
| 		level = level + 1 | ||||
| 		level_to_show = level_to_show + 1 | ||||
| 		info = dumper.getinfo(level, "nSlf") | ||||
| 	end | ||||
| 
 | ||||
| 	return dumper:concat_lines(), original_error | ||||
| end | ||||
| 
 | ||||
| -- | ||||
| -- Adds a table to the list of known tables | ||||
| function _M.add_known_table(tab, description) | ||||
| 	if m_known_tables[tab] then | ||||
| 		error("Cannot override an already known table") | ||||
| 	end | ||||
| 	m_user_known_tables[tab] = description | ||||
| end | ||||
| 
 | ||||
| -- | ||||
| -- Adds a function to the list of known functions | ||||
| function _M.add_known_function(fun, description) | ||||
| 	if m_known_functions[fun] then | ||||
| 		error("Cannot override an already known function") | ||||
| 	end | ||||
| 	m_user_known_functions[fun] = description | ||||
| end | ||||
| 
 | ||||
| return _M | ||||
							
								
								
									
										14
									
								
								lua_scripts/extensions/_Misc.ext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								lua_scripts/extensions/_Misc.ext
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| -- | ||||
| -- Copyright (C) 2010 - 2016 Eluna Lua Engine <http://emudevs.com/> | ||||
| -- This program is free software licensed under GPL version 3 | ||||
| -- Please see the included DOCS/LICENSE.md for more information | ||||
| -- | ||||
| 
 | ||||
| -- filename.ext files are loaded before normal .lua files | ||||
| 
 | ||||
| -- Randomize random | ||||
| math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6))) | ||||
| 
 | ||||
| -- Set debug.traceback to use StackTracePlus to print full stack trace | ||||
| local trace = require("StackTracePlus") | ||||
| debug.traceback = trace.stacktrace | ||||
							
								
								
									
										
											BIN
										
									
								
								worldserver
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								worldserver
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user