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