random-stuff/computercraft/ULTRADUMP.lua

115 lines
2.6 KiB
Lua

local a=http.get"https://pastebin.com/raw/KXHSsHkt"local b=fs.open("ser","w")b.write(a.readAll())a.close()b.close()
local ultradump = {}
local ser = require "/ser"
local e = ser.serialize
local function copy(x)
if type(x) == "table" then
local out = {}
for k, v in pairs(x) do
out[k] = v
end
return out
else return x end
end
function ultradump.dump(x)
local objects = {}
local enclookup = {}
local count = 0
local function addobj(o)
objects[o] = count
local c = count
count = count + 1
return c
end
local function mkref(id)
return { _to = id }
end
local function recurse(x)
if enclookup[x] then print("Using From Cache", x) return enclookup[x] end -- If we already have an encoded copy cached, use it
local t = type(x)
if t == "string" or t == "number" then
return x
elseif t == "table" then
local mt = debug.getmetatable(x)
local out = {}
local id = addobj(out)
local ref = mkref(id)
enclookup[x] = ref
for k, v in pairs(x) do
out[recurse(k)] = recurse(v) -- copy table
end
if mt then out._mt = recurse(mt) end -- If table has metatable, add it to output table
return ref
elseif t == "function" then
local ok, code = pcall(string.dump, x)
if ok then
local info = debug.getinfo(x, "u") -- contains number of upvalues of function
local upvalues = {}
for i = 1, info.nups do
local name, value = debug.getupvalue(x, i)
upvalues[i] = value -- upvalues seem to be handled by index, so the name's not important
end
local env
if getfenv then env = getfenv(x)
else env = upvalues[1] end -- it seems that in Lua 5.3 the first upvalue is the function environment.
local out = {
_t = "f", -- type: function
c = code,
u = recurse(upvalues),
e = recurse(env)
}
local id = addobj(out)
local ref = mkref(id)
enclookup[x] = ref
return ref
else
return nil -- is a non-Lua-defined function, so we can't operate on it very much
end
end
end
local root = recurse(x)
local inverted = {}
for k, v in pairs(objects) do
inverted[v] = k
end
print(e(root), e(objects), e(inverted))
inverted._root = copy(root)
return inverted
end
function ultradump.load(objects)
local function recurse(x)
local t = type(x)
if t == "string" or t == "number" then
return x
elseif t == "table" then
else
error("Unexpected Type " .. t)
end
end
return recurse(objects._root)
end
local input = {
1, 2, 3, function() print "HI!" end
}
input[5] = input
local out = ultradump.dump(input)
--print(e(out))
return ultradump