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 )
|
||||
return string.char(b1, b2, b3, b4)
|
||||
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
|
||||
local global_env = _G
|
||||
|
||||
local ie = minetest.request_insecure_environment and minetest.request_insecure_environment()
|
||||
if ie then
|
||||
print("[mapsync] using insecure environment")
|
||||
@ -17,14 +16,21 @@ if ie then
|
||||
global_env = ie
|
||||
end
|
||||
|
||||
-- api surface
|
||||
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)
|
||||
loadfile(MP.."/functions.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
|
||||
dofile(MP.."/mtt.lua")
|
||||
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)
|
||||
|
||||
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 pos1 = { x=0, y=0, z=0 }
|
||||
local pos2 = { x=20, y=20, z=20 }
|
||||
local chunk_pos = {x=0, y=0, z=0}
|
||||
local filename = minetest.get_worldpath() .. "/chunk.zip"
|
||||
|
||||
minetest.emerge_area(pos1, pos2, function(_, _, calls_remaining)
|
||||
if calls_remaining == 0 then
|
||||
local success, err_msg = mapsync.serialize_chunk({x=0, y=0, z=0}, minetest.get_worldpath() .. "/chunk.zip")
|
||||
assert(success)
|
||||
assert(not err_msg)
|
||||
callback()
|
||||
end
|
||||
end)
|
||||
local success, err_msg = mapsync.serialize_chunk(chunk_pos, filename)
|
||||
assert(success)
|
||||
assert(not err_msg)
|
||||
|
||||
success, err_msg = mapsync.deserialize_chunk(chunk_pos, filename)
|
||||
assert(success)
|
||||
assert(not err_msg)
|
||||
|
||||
callback()
|
||||
end)
|
Loading…
x
Reference in New Issue
Block a user