87 lines
2.3 KiB
Lua
87 lines
2.3 KiB
Lua
local f = string.format
|
|
|
|
local deserialize = minetest.deserialize
|
|
|
|
local pairs_by_key = futil.table.pairs_by_key
|
|
|
|
function futil.serialize(x)
|
|
if type(x) == "number" or type(x) == "boolean" or type(x) == "nil" then
|
|
return tostring(x)
|
|
elseif type(x) == "string" then
|
|
return f("%q", x)
|
|
elseif type(x) == "table" then
|
|
local parts = {}
|
|
for k, v in pairs_by_key(x) do
|
|
table.insert(parts, f("[%s] = %s", futil.serialize(k), futil.serialize(v)))
|
|
end
|
|
return f("{%s}", table.concat(parts, ", "))
|
|
else
|
|
error(f("can't serialize type %s", type(x)))
|
|
end
|
|
end
|
|
|
|
function futil.deserialize(data)
|
|
return deserialize(f("return %s", data))
|
|
end
|
|
|
|
function futil.serialize_invlist(inv, listname)
|
|
local itemstrings = {}
|
|
local list = inv:get_list(listname)
|
|
|
|
if not list then
|
|
error(f("couldn't find list %s of %s", listname, minetest.write_json(inv:get_location())))
|
|
end
|
|
|
|
for _, stack in ipairs(list) do
|
|
table.insert(itemstrings, stack:to_string())
|
|
end
|
|
|
|
return futil.serialize(itemstrings)
|
|
end
|
|
|
|
function futil.deserialize_invlist(serialized_list, inv, listname)
|
|
if not inv:is_empty(listname) then
|
|
error(("trying to deserialize into a non-empty list %s (%s)"):format(listname, serialized_list))
|
|
end
|
|
|
|
local itemstrings = futil.deserialize(serialized_list) or minetest.parse_json(serialized_list)
|
|
|
|
inv:set_size(listname, #itemstrings)
|
|
|
|
for i, itemstring in ipairs(itemstrings) do
|
|
inv:set_stack(listname, i, ItemStack(itemstring))
|
|
end
|
|
end
|
|
|
|
function futil.serialize_inv(inv)
|
|
local serialized_lists = {}
|
|
|
|
for listname in pairs(inv:get_lists()) do
|
|
serialized_lists[listname] = futil.serialize_invlist(inv, listname)
|
|
end
|
|
|
|
return futil.serialize(serialized_lists)
|
|
end
|
|
|
|
function futil.deserialize_inv(serialized_lists, inv)
|
|
for listname, serialized_list in pairs(futil.deserialize(serialized_lists)) do
|
|
futil.deserialize_invlist(serialized_list, inv, listname)
|
|
end
|
|
end
|
|
|
|
function futil.serialize_node_meta(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
return futil.serialize({
|
|
fields = meta:to_table().fields,
|
|
inventory = futil.serialize_inv(inv),
|
|
})
|
|
end
|
|
|
|
function futil.deserialize_node_meta(serialized_node_meta, pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local x = futil.deserialize(serialized_node_meta)
|
|
meta:from_table({ fields = x.fields })
|
|
local inv = meta:get_inventory()
|
|
futil.deserialize_inv(x.inventory, inv)
|
|
end
|