full circle
This commit is contained in:
parent
42cd70a862
commit
0725bf67fc
61
deserialize.lua
Normal file
61
deserialize.lua
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
local global_env = ...
|
||||||
|
|
||||||
|
-- local vars for faster access
|
||||||
|
local insert, byte, decode_uint16 = table.insert, string.byte, mapsync.decode_uint16
|
||||||
|
|
||||||
|
function mapsync.deserialize_chunk(chunk_pos, filename)
|
||||||
|
local f = global_env.io.open(filename)
|
||||||
|
local zip, err_msg = mtzip.unzip(f)
|
||||||
|
if not zip then
|
||||||
|
return false, err_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
-- parse manifest
|
||||||
|
local manifest_str, m_err_msg = zip:get("manifest.json")
|
||||||
|
if not manifest_str then
|
||||||
|
return false, m_err_msg
|
||||||
|
end
|
||||||
|
local manifest = minetest.parse_json(manifest_str)
|
||||||
|
|
||||||
|
-- parse metadata
|
||||||
|
local metadata_str, md_err_msg = zip:get("metadata.json")
|
||||||
|
if not metadata_str then
|
||||||
|
return false, md_err_msg
|
||||||
|
end
|
||||||
|
local metadata = minetest.parse_json(metadata_str)
|
||||||
|
|
||||||
|
-- parse mapdata
|
||||||
|
local mapdata, map_err_msg = zip:get("mapdata.bin")
|
||||||
|
if not mapdata then
|
||||||
|
return false, map_err_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
local min_mapblock = mapsync.get_mapblock_bounds_from_chunk(chunk_pos)
|
||||||
|
local mapblock_count = #manifest.block_pos
|
||||||
|
|
||||||
|
for mbi, rel_mapblock_pos in ipairs(manifest.block_pos) do
|
||||||
|
local blockdata = {
|
||||||
|
node_ids = {},
|
||||||
|
param1 = {},
|
||||||
|
param2 = {},
|
||||||
|
metadata = metadata[minetest.pos_to_string(rel_mapblock_pos)]
|
||||||
|
}
|
||||||
|
|
||||||
|
for i=1,4096 do
|
||||||
|
local node_id = decode_uint16(mapdata, ((mbi-1) * 4096 * 2) + (i * 2) - 2)
|
||||||
|
local param1 = byte(mapdata, (4096 * 2 * mapblock_count) + ((mbi-1) * 4096) + i)
|
||||||
|
local param2 = byte(mapdata, (4096 * 3 * mapblock_count) + ((mbi-1) * 4096) + i)
|
||||||
|
|
||||||
|
insert(blockdata.node_ids, node_id)
|
||||||
|
insert(blockdata.param1, param1)
|
||||||
|
insert(blockdata.param2, param2)
|
||||||
|
end
|
||||||
|
|
||||||
|
mapsync.localize_nodeids(manifest.node_mapping, blockdata.node_ids)
|
||||||
|
|
||||||
|
local mapblock_pos = vector.add(rel_mapblock_pos, min_mapblock)
|
||||||
|
mapsync.deserialize_mapblock(mapblock_pos, blockdata)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
51
deserialize_mapblock.lua
Normal file
51
deserialize_mapblock.lua
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
function mapsync.deserialize_mapblock(mapblock_pos, blockdata)
|
||||||
|
local pos1 = vector.multiply(mapblock_pos, 16)
|
||||||
|
local pos2 = vector.add(pos1, 15) -- inclusive
|
||||||
|
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
local e1, e2 = manip:read_from_map(pos1, pos2)
|
||||||
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
||||||
|
|
||||||
|
local node_data = manip:get_data()
|
||||||
|
local param1 = manip:get_light_data()
|
||||||
|
local param2 = manip:get_param2_data()
|
||||||
|
|
||||||
|
local j = 1
|
||||||
|
for z=pos1.z,pos2.z do
|
||||||
|
for x=pos1.x,pos2.x do
|
||||||
|
for y=pos1.y,pos2.y do
|
||||||
|
local i = area:index(x,y,z)
|
||||||
|
node_data[i] = blockdata.node_ids[j]
|
||||||
|
param1[i] = blockdata.param1[j]
|
||||||
|
param2[i] = blockdata.param2[j]
|
||||||
|
j = j + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
manip:set_data(node_data)
|
||||||
|
manip:set_light_data(param1)
|
||||||
|
manip:set_param2_data(param2)
|
||||||
|
manip:write_to_map(false)
|
||||||
|
|
||||||
|
-- deserialize metadata
|
||||||
|
if blockdata.metadata and blockdata.metadata.meta then
|
||||||
|
for pos_str, md in pairs(blockdata.metadata.meta) do
|
||||||
|
local relative_pos = minetest.string_to_pos(pos_str)
|
||||||
|
local absolute_pos = vector.add(pos1, relative_pos)
|
||||||
|
minetest.get_meta(absolute_pos):from_table(md)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- deserialize node timers
|
||||||
|
if blockdata.metadata and blockdata.metadata.timers then
|
||||||
|
for pos_str, timer_data in pairs(blockdata.metadata.timers) do
|
||||||
|
local relative_pos = minetest.string_to_pos(pos_str)
|
||||||
|
local absolute_pos = vector.add(pos1, relative_pos)
|
||||||
|
minetest.get_node_timer(absolute_pos):set(timer_data.timeout, timer_data.elapsed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
@ -30,3 +30,9 @@ function mapsync.encode_uint32(v)
|
|||||||
local b4 = bitand( rshift(v, 24), 0xFF )
|
local b4 = bitand( rshift(v, 24), 0xFF )
|
||||||
return string.char(b1, b2, b3, b4)
|
return string.char(b1, b2, b3, b4)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mapsync.decode_uint16(str, ofs)
|
||||||
|
ofs = ofs or 0
|
||||||
|
local a, b = string.byte(str, ofs + 1, ofs + 2)
|
||||||
|
return a + b * 0x100
|
||||||
|
end
|
12
init.lua
12
init.lua
@ -9,7 +9,6 @@ mapsync = {
|
|||||||
|
|
||||||
-- secure/insecure environment
|
-- secure/insecure environment
|
||||||
local global_env = _G
|
local global_env = _G
|
||||||
|
|
||||||
local ie = minetest.request_insecure_environment and minetest.request_insecure_environment()
|
local ie = minetest.request_insecure_environment and minetest.request_insecure_environment()
|
||||||
if ie then
|
if ie then
|
||||||
print("[mapsync] using insecure environment")
|
print("[mapsync] using insecure environment")
|
||||||
@ -17,14 +16,21 @@ if ie then
|
|||||||
global_env = ie
|
global_env = ie
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- api surface
|
||||||
dofile(MP.."/api.lua")
|
dofile(MP.."/api.lua")
|
||||||
dofile(MP.."/encode.lua")
|
|
||||||
|
-- utilities / helpers
|
||||||
|
dofile(MP.."/encoding.lua")
|
||||||
|
dofile(MP.."/serialize_mapblock.lua")
|
||||||
|
dofile(MP.."/deserialize_mapblock.lua")
|
||||||
|
dofile(MP.."/localize_nodeids.lua")
|
||||||
|
|
||||||
-- pass on global env (secure/insecure)
|
-- pass on global env (secure/insecure)
|
||||||
loadfile(MP.."/functions.lua")(global_env)
|
loadfile(MP.."/functions.lua")(global_env)
|
||||||
loadfile(MP.."/serialize.lua")(global_env)
|
loadfile(MP.."/serialize.lua")(global_env)
|
||||||
dofile(MP.."/serialize_mapblock.lua")
|
loadfile(MP.."/deserialize.lua")(global_env)
|
||||||
|
|
||||||
|
-- testing
|
||||||
if minetest.get_modpath("mtt") and mtt.enabled then
|
if minetest.get_modpath("mtt") and mtt.enabled then
|
||||||
dofile(MP.."/mtt.lua")
|
dofile(MP.."/mtt.lua")
|
||||||
end
|
end
|
30
localize_nodeids.lua
Normal file
30
localize_nodeids.lua
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
local air_content_id = minetest.get_content_id("air")
|
||||||
|
|
||||||
|
-- local nodename->id cache
|
||||||
|
local local_nodename_to_id_mapping = {} -- name -> id
|
||||||
|
|
||||||
|
function mapsync.localize_nodeids(node_mapping, node_ids)
|
||||||
|
local foreign_nodeid_to_name_mapping = {} -- id -> name
|
||||||
|
for k, v in pairs(node_mapping) do
|
||||||
|
foreign_nodeid_to_name_mapping[v] = k
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, node_id in ipairs(node_ids) do
|
||||||
|
local node_name = foreign_nodeid_to_name_mapping[node_id]
|
||||||
|
local local_node_id = local_nodename_to_id_mapping[node_name]
|
||||||
|
if not local_node_id then
|
||||||
|
if minetest.registered_nodes[node_name] then
|
||||||
|
-- node is locally available
|
||||||
|
local_node_id = minetest.get_content_id(node_name)
|
||||||
|
else
|
||||||
|
-- node is not available here
|
||||||
|
-- TODO: make replacements configurable
|
||||||
|
local_node_id = air_content_id
|
||||||
|
end
|
||||||
|
local_nodename_to_id_mapping[node_name] = local_node_id
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
node_ids[i] = local_node_id
|
||||||
|
end
|
||||||
|
end
|
25
mtt.lua
25
mtt.lua
@ -17,17 +17,20 @@ mtt.register("register and export", function(callback)
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local pos = { x=0, y=0, z=0 }
|
||||||
|
mtt.emerge_area(pos, pos)
|
||||||
|
mtt.register("serialize and deserialize chunk", function(callback)
|
||||||
|
|
||||||
mtt.register("serialize_chunk", function(callback)
|
local chunk_pos = {x=0, y=0, z=0}
|
||||||
local pos1 = { x=0, y=0, z=0 }
|
local filename = minetest.get_worldpath() .. "/chunk.zip"
|
||||||
local pos2 = { x=20, y=20, z=20 }
|
|
||||||
|
|
||||||
minetest.emerge_area(pos1, pos2, function(_, _, calls_remaining)
|
local success, err_msg = mapsync.serialize_chunk(chunk_pos, filename)
|
||||||
if calls_remaining == 0 then
|
assert(success)
|
||||||
local success, err_msg = mapsync.serialize_chunk({x=0, y=0, z=0}, minetest.get_worldpath() .. "/chunk.zip")
|
assert(not err_msg)
|
||||||
assert(success)
|
|
||||||
assert(not err_msg)
|
success, err_msg = mapsync.deserialize_chunk(chunk_pos, filename)
|
||||||
callback()
|
assert(success)
|
||||||
end
|
assert(not err_msg)
|
||||||
end)
|
|
||||||
|
callback()
|
||||||
end)
|
end)
|
Loading…
x
Reference in New Issue
Block a user