diff --git a/apply_diff.lua b/apply_diff.lua deleted file mode 100644 index 1b0c960..0000000 --- a/apply_diff.lua +++ /dev/null @@ -1,53 +0,0 @@ - -function mapsync.apply_diff(chunk_pos, changed_nodes) - local min_mb, max_mb = mapsync.get_mapblock_bounds_from_chunk(chunk_pos) - local base_pos = mapsync.get_node_bounds_from_mapblock(min_mb) - local _, max_pos = mapsync.get_node_bounds_from_mapblock(max_mb) - - -- load chunk - local manip = minetest.get_voxel_manip() - local e1, e2 = manip:read_from_map(base_pos, max_pos) - local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) - - local node_data = manip:get_data() - local param2 = manip:get_param2_data() - - for _, changed_node in ipairs(changed_nodes) do - -- absolute node position - local pos = { - x = base_pos.x + changed_node.x, - y = base_pos.y + changed_node.y, - z = base_pos.z + changed_node.z - } - - local index = area:index(pos.x, pos.y, pos.z) - - if changed_node.name ~= nil then - if minetest.registered_nodes[changed_node.name] then - local id = minetest.get_content_id(changed_node.name) - node_data[index] = id - end - -- TODO: placeholder if not found - end - - if changed_node.param2 ~= nil then - param2[index] = changed_node.param2 - end - - if changed_node.timer ~= nil then - local timer = minetest.get_node_timer(pos) - timer:set(changed_node.timer.timeout, changed_node.timer.elapsed) - end - - if changed_node.meta ~= nil then - minetest.get_meta(pos):from_table(changed_node.meta) - end - end - - -- write back to map - manip:set_data(node_data) - manip:set_param2_data(param2) - manip:write_to_map(true) - - return true -end diff --git a/create_diff.lua b/create_diff.lua deleted file mode 100644 index 30ea624..0000000 --- a/create_diff.lua +++ /dev/null @@ -1,160 +0,0 @@ -local c_air = minetest.get_content_id("air") - -local function create_mapblock(mapblock_pos, mapblock, callback) - assert(#mapblock.node_ids == 4096) - assert(#mapblock.param2 == 4096) - - for i=1,4096 do - local nodeid = mapblock.node_ids[i] - if nodeid ~= c_air then - -- relative position in the mapblock - local rel_pos = mapsync.mapblock_index_to_pos(i) - - -- relative position in the chunk - local rel_chunk_pos = vector.add(rel_pos, vector.multiply(mapblock_pos, 16)) - - local nodename = minetest.get_name_from_content_id(nodeid) - - local node = { - x=rel_chunk_pos.x, - y=rel_chunk_pos.y, - z=rel_chunk_pos.z, - name = nodename, - param2 = mapblock.param2[i] - } - - if mapblock.metadata then - local rel_pos_str = minetest.pos_to_string(rel_pos) - if mapblock.metadata.meta then - node.meta = mapblock.metadata.meta[rel_pos_str] - end - if mapblock.metadata.meta then - node.timer = mapblock.metadata.timers[rel_pos_str] - end - end - - callback(node) - end - end -end - -local function air_mapblock(mapblock_pos, callback) - for i=1,4096 do - -- relative position in the mapblock - local rel_pos = mapsync.mapblock_index_to_pos(i) - -- relative position in the chunk - local rel_chunk_pos = vector.add(rel_pos, vector.multiply(mapblock_pos, 16)) - - local node = { - x=rel_chunk_pos.x, - y=rel_chunk_pos.y, - z=rel_chunk_pos.z, - name = "air", - param2 = 0 - } - - callback(node) - end -end - -local function diff_mapblock(mapblock_pos, baseline_mapblock, mapblock, callback) - assert(#baseline_mapblock.node_ids == 4096) - assert(#baseline_mapblock.param2 == 4096) - assert(#mapblock.node_ids == 4096) - assert(#mapblock.param2 == 4096) - - for i=1,4096 do - -- relative position in the mapblock - local rel_pos = mapsync.mapblock_index_to_pos(i) - -- relative position in the chunk - local rel_chunk_pos = vector.add(rel_pos, vector.multiply(mapblock_pos, 16)) - - local baseline_nodeid = baseline_mapblock.node_ids[i] - local new_nodeid = mapblock.node_ids[i] - local node = { x=rel_chunk_pos.x, y=rel_chunk_pos.y, z=rel_chunk_pos.z } - local changed = false - - -- node id - if baseline_nodeid ~= new_nodeid then - local new_nodename = minetest.get_name_from_content_id(new_nodeid) - node.name = new_nodename - changed = true - end - - -- param2 - if baseline_mapblock.param2[i] ~= mapblock.param2[i] then - node.param2 = mapblock.param2[i] - changed = true - end - - -- metadata - local rel_pos_str = minetest.pos_to_string(rel_pos) - local baseline_meta = baseline_mapblock.metadata - and baseline_mapblock.metadata.meta - and baseline_mapblock.metadata.meta[rel_pos_str] - - local new_meta = mapblock.metadata - and mapblock.metadata.meta - and mapblock.metadata.meta[rel_pos_str] - - if new_meta then - -- add empty inventory to baseline if not already there - if baseline_meta then - baseline_meta.inventory = baseline_meta.inventory or {} - end - - if not mapsync.deep_compare(baseline_meta, new_meta) then - -- metadata not equal or new - node.meta = new_meta - changed = true - end - end - - local timer = mapblock.metadata and mapblock.metadata.timers and mapblock.metadata.timers[rel_pos_str] - if timer then - node.timer = timer - end - - if changed then - callback(node) - end - end - - return true -end - -function mapsync.create_diff(baseline_chunk, chunk_pos, callback) - local node_mapping = {} - local mb_pos1, mb_pos2 = mapsync.get_mapblock_bounds_from_chunk(chunk_pos) - - for x=mb_pos1.x,mb_pos2.x do - for y=mb_pos1.y,mb_pos2.y do - for z=mb_pos1.z,mb_pos2.z do - local mapblock_pos = {x=x, y=y, z=z} - local rel_mapblock_pos = vector.subtract(mapblock_pos, mb_pos1) - local blockdata = mapsync.serialize_mapblock(mapblock_pos, node_mapping) - local baseline_mapblock = baseline_chunk and - baseline_chunk.mapblocks[minetest.pos_to_string(rel_mapblock_pos)] - - if blockdata.empty and baseline_mapblock then - -- block removed - air_mapblock(rel_mapblock_pos, callback) - - elseif not blockdata.empty and not baseline_mapblock then - -- block added - create_mapblock(rel_mapblock_pos, blockdata, callback) - - elseif not blockdata.empty and baseline_mapblock then - -- both blocks exist, compare - local success, err_msg = diff_mapblock(rel_mapblock_pos,baseline_mapblock,blockdata,callback) - if not success then - return false, err_msg - end - - end - end - end - end - - return true -end diff --git a/diff.spec.lua b/diff.spec.lua deleted file mode 100644 index c4a9568..0000000 --- a/diff.spec.lua +++ /dev/null @@ -1,55 +0,0 @@ - -mtt.register("diff", function(callback) - - local chunk_pos = { x=0, y=0, z=0 } - local filename = minetest.get_worldpath() .. "/mychunk.zip" - - -- serialize existing chunk - assert(mapsync.serialize_chunk(chunk_pos, filename)) - local baseline_chunk, err_msg = mapsync.parse_chunk(filename) - assert(baseline_chunk) - assert(not err_msg) - - -- change things - minetest.set_node({ x=10, y=0, z=0 }, { name = "default:mese" }) - - minetest.set_node({ x=10, y=1, z=0 }, { name = "default:chest" }) - local meta = minetest.get_meta({ x=10, y=1, z=0 }) - meta:set_int("x", 10) - - local changed_nodes = {} - local node_callback = function(node) - table.insert(changed_nodes, node) - -- print(dump(node)) - end - - -- create and validate diff - local success = mapsync.create_diff(baseline_chunk, chunk_pos, node_callback) - assert(success) - - local changes = 0 - for _, changed_node in ipairs(changed_nodes) do - if changed_node.name == "default:mese" then - changes = changes + 1 - elseif changed_node.name == "default:chest" then - changes = changes + 1 - assert(changed_node.meta.fields.x == "10") - else - callback("unexpected change") - end - end - assert(changes == 2) - - -- apply changes to another chunk - chunk_pos = { x=0, y=1, z=0 } - - success = mapsync.apply_diff(chunk_pos, changed_nodes) - assert(success) - - assert(minetest.get_node({ x=10, y=80, z=0 }).name == "default:mese") - assert(minetest.get_node({ x=10, y=81, z=0 }).name == "default:chest") - meta = minetest.get_meta({ x=10, y=81, z=0 }) - assert(meta:get_int("x") == 10) - - callback() -end) \ No newline at end of file diff --git a/init.lua b/init.lua index e79bdbf..f6b3a11 100644 --- a/init.lua +++ b/init.lua @@ -34,15 +34,10 @@ dofile(MP.."/deserialize_mapblock.lua") dofile(MP.."/localize_nodeids.lua") dofile(MP.."/functions.lua") --- diff / patch -dofile(MP.."/create_diff.lua") -dofile(MP.."/apply_diff.lua") -loadfile(MP.."/patch.lua")(global_env) - -- save/load dofile(MP.."/auto_save.lua") dofile(MP.."/auto_update.lua") -loadfile(MP.."/save.lua")(global_env) +dofile(MP.."/save.lua") loadfile(MP.."/data.lua")(global_env) dofile(MP.."/load.lua") dofile(MP.."/mapgen.lua") @@ -77,8 +72,6 @@ if minetest.get_modpath("mtt") and mtt.enabled then dofile(MP.."/init.spec.lua") dofile(MP.."/functions.spec.lua") dofile(MP.."/data.spec.lua") - dofile(MP.."/diff.spec.lua") - dofile(MP.."/patch.spec.lua") dofile(MP.."/api.spec.lua") dofile(MP.."/serialize_chunk.spec.lua") end \ No newline at end of file diff --git a/load.lua b/load.lua index 98ccbc2..7b5d6f5 100644 --- a/load.lua +++ b/load.lua @@ -5,36 +5,5 @@ function mapsync.load(chunk_pos, vmanip) return true, "No backend available" end - -- load baseline chunk (might be non-existent) mapsync.deserialize_chunk(chunk_pos, mapsync.get_chunk_zip_path(backend_def.path, chunk_pos), vmanip) - - if backend_def.patch_path then - -- load diff - local f = io.open(mapsync.get_chunk_json_path(backend_def.patch_path, chunk_pos), "r") - if not f then - -- no diff - return true - end - - local changed_nodes = {} - for line in f:lines() do - local changed_node = minetest.parse_json(line) - if changed_node then - table.insert(changed_nodes, changed_node) - end - end - f:close() - - -- apply diff - local success, msg = mapsync.apply_diff(chunk_pos, changed_nodes) - if not success then - return false, msg - end - - -- fix lighting - local mb_pos1, mb_pos2 = mapsync.get_mapblock_bounds_from_chunk(chunk_pos) - local pos1 = mapsync.get_node_bounds_from_mapblock(mb_pos1) - local _, pos2 = mapsync.get_node_bounds_from_mapblock(mb_pos2) - minetest.fix_light(pos1, pos2) - end end \ No newline at end of file diff --git a/patch.lua b/patch.lua deleted file mode 100644 index af6b80b..0000000 --- a/patch.lua +++ /dev/null @@ -1,87 +0,0 @@ -local global_env = ... - -function mapsync.apply_patches(backend_def, callback, progress_callback) - -- load all chunks and save back to fs - local files = minetest.get_dir_list(backend_def.patch_path, false) - - -- collect all chunks - local chunk_pos_list = {} - for _, filename in ipairs(files) do - if string.match(filename, "^[chunk_(].*[).json]$") then - local pos_str = string.gsub(filename, "chunk_", "") - pos_str = string.gsub(pos_str, ".json", "") - - local chunk_pos = minetest.string_to_pos(pos_str) - table.insert(chunk_pos_list, chunk_pos) - end - end - - local emerge_count = 0 - for i, chunk_pos in ipairs(chunk_pos_list) do - mapsync.delete_chunk(chunk_pos) - mapsync.emerge_chunk(chunk_pos, function() - -- save emerged chunk - mapsync.serialize_chunk(chunk_pos, mapsync.get_chunk_zip_path(backend_def.path, chunk_pos)) - - -- remove patch file - local patch_path = mapsync.get_chunk_json_path(backend_def.patch_path, chunk_pos) - global_env.os.remove(patch_path) - - -- report progress - if type(progress_callback) == "function" then - progress_callback(chunk_pos, #chunk_pos_list, i) - end - - emerge_count = emerge_count + 1 - if emerge_count < #chunk_pos_list then - --- not done yet - return - end - -- done - callback(emerge_count) - end) - end -end - - -minetest.register_chatcommand("mapsync_apply_patches", { - description = "applies all the patches in given backend (defaults to the one at the current position)", - params = "[backend-name]", - privs = { mapsync = true }, - func = function(name, backend_name) - local player = minetest.get_player_by_name(name) - if not player then - return - end - - local pos = player:get_pos() - - local backend_def - if backend_name and backend_name ~= "" then - backend_def = mapsync.get_backend(backend_name) - if not backend_def then - return true, "Backend not found: '" .. backend_name .. "'" - end - else - local chunk_pos = mapsync.get_chunkpos(pos) - backend_def = mapsync.select_backend(chunk_pos) - if not backend_def then - return true, "Backend for current position not found" - end - end - - if backend_def.type ~= "patch" then - return true, "Backend type is not of type 'patch'" - end - - -- apply patches back to shadowed backend - mapsync.apply_patches(backend_def, function(chunk_count) - minetest.chat_send_player(name, "Patching done with " .. chunk_count .. " chunk(s)") - end, function(chunk_pos, total_count, current_count) - minetest.chat_send_player(name, "Patched chunk " .. minetest.pos_to_string(chunk_pos) .. - " progress: " .. current_count .. "/" .. total_count) - end) - - return true, "Patching started" - end -}) \ No newline at end of file diff --git a/patch.spec.lua b/patch.spec.lua deleted file mode 100644 index 7c1de9a..0000000 --- a/patch.spec.lua +++ /dev/null @@ -1,45 +0,0 @@ - -mtt.register("patch backend", function(callback) - local chunk_pos = { x=0, y=0, z=0 } - - local path = minetest.get_worldpath() .. "/unpatched" - minetest.mkdir(path) - - mapsync.register_backend("my-backend", { - type = "fs", - path = path - }) - - -- write chunk - local success = mapsync.save(chunk_pos) - assert(success) - - -- unregister fs backend - mapsync.unregister_backend("my-backend") - - local patch_path = minetest.get_worldpath() .. "/patched" - minetest.mkdir(patch_path) - - mapsync.register_backend("my-patched-backend", { - type = "patch", - path = path, - patch_path = patch_path - }) - - minetest.set_node({ x=10, y=10, z=10 }, { name = "default:obsidianbrick" }) - - -- write patch - success = mapsync.save(chunk_pos) - assert(success) - - -- get patch handler - local patch_backend_def = mapsync.get_backend("my-patched-backend") - - -- apply patches back to shadowed backend - mapsync.apply_patches(patch_backend_def, function(chunk_count) - assert(chunk_count == 1) - -- cleanup - mapsync.unregister_backend("my-patched-backend") - callback() - end) -end) \ No newline at end of file diff --git a/readme.md b/readme.md index 42140ed..34064c8 100644 --- a/readme.md +++ b/readme.md @@ -12,7 +12,6 @@ Synchronize the ingame map with a lua-backend Features: * Writes and saves maps to/from zip-files * Auto-updates chunks if a newer version on the backend is found -* Patching/Merging support (with diff files) Planned features: * `placeholder` support diff --git a/save.lua b/save.lua index ab0b662..456bc81 100644 --- a/save.lua +++ b/save.lua @@ -1,4 +1,3 @@ -local global_env = ... local function save_worker(ctx) local chunk_pos = ctx.iterator() @@ -71,28 +70,6 @@ function mapsync.save(chunk_pos) return true, "No backend available" end - if not backend_def.patch_path then - -- direct save - return mapsync.serialize_chunk(chunk_pos, mapsync.get_chunk_zip_path(backend_def.path, chunk_pos)) - else - -- create patch file - local baseline_chunk = mapsync.parse_chunk(mapsync.get_chunk_zip_path(backend_def.path, chunk_pos)) - local filename = mapsync.get_chunk_json_path(backend_def.patch_path, chunk_pos) - local f = global_env.io.open(filename, "w") - - local no_diff = true - mapsync.create_diff(baseline_chunk, chunk_pos, function(changed_node) - no_diff = false - f:write(minetest.write_json(changed_node) .. '\n') - end) - - f:close() - - if no_diff then - -- remove empty diff file - global_env.os.remove(filename) - end - - return true - end + -- direct save + return mapsync.serialize_chunk(chunk_pos, mapsync.get_chunk_zip_path(backend_def.path, chunk_pos)) end \ No newline at end of file