98 lines
3.2 KiB
Lua
98 lines
3.2 KiB
Lua
local global_env = ...
|
|
|
|
local function save_worker(ctx)
|
|
local chunk_pos = ctx.iterator()
|
|
if not chunk_pos then
|
|
-- done
|
|
minetest.chat_send_player(ctx.playername, "Async saving done with " .. ctx.count .. " chunks")
|
|
else
|
|
-- save pos
|
|
local success, err_msg = mapsync.save(chunk_pos)
|
|
if not success then
|
|
minetest.chat_send_player(
|
|
ctx.playername,
|
|
"Saving of chunk " .. minetest.pos_to_string(chunk_pos) .. "failed with: " .. err_msg
|
|
)
|
|
else
|
|
minetest.chat_send_player(
|
|
ctx.playername,
|
|
"Saving of chunk " .. minetest.pos_to_string(chunk_pos) .. " done (count: " .. ctx.count .. ")"
|
|
)
|
|
ctx.count = ctx.count + 1
|
|
|
|
-- re-schedule
|
|
minetest.after(0, save_worker, ctx)
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_chatcommand("mapsync_save", {
|
|
description = "saves the current chunk or a range around the current chunk (cubic)",
|
|
params = "[chunk-range]",
|
|
privs = { mapsync = true },
|
|
func = function(name, param)
|
|
local player = minetest.get_player_by_name(name)
|
|
if not player then
|
|
return
|
|
end
|
|
|
|
local range = tonumber(param) or 0
|
|
local ppos = player:get_pos()
|
|
local chunk_pos = mapsync.get_chunkpos(ppos)
|
|
local chunk_pos1 = vector.subtract(chunk_pos, range)
|
|
local chunk_pos2 = vector.add(chunk_pos, range)
|
|
|
|
if range == 0 then
|
|
-- just the one block
|
|
local success, err_msg = mapsync.save(chunk_pos)
|
|
if success then
|
|
return true, "Saved chunk: " .. minetest.pos_to_string(chunk_pos)
|
|
else
|
|
return true, "Error saving chunk: " ..
|
|
minetest.pos_to_string(chunk_pos) .. ", error: " ..
|
|
(err_msg and err_msg or "<no message>")
|
|
end
|
|
end
|
|
|
|
-- multiple blocks, execute async
|
|
minetest.after(0, save_worker, {
|
|
playername = name,
|
|
count = 0,
|
|
iterator = mapsync.pos_iterator(chunk_pos1, chunk_pos2),
|
|
})
|
|
|
|
return true, "dispatched saving to worker with range of " .. range .. " chunks around the current center"
|
|
end
|
|
})
|
|
|
|
function mapsync.save(chunk_pos)
|
|
local backend_def = mapsync.select_backend(chunk_pos)
|
|
if not backend_def then
|
|
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
|
|
end |