From 1823690daded9ee94be2e71cd7f39772fd09d405 Mon Sep 17 00:00:00 2001 From: Jude Melton-Houghton Date: Sat, 13 Aug 2022 16:22:53 -0400 Subject: [PATCH] Store teleport tube DB in mod storage (#40) * Store teleport tube DB in mod storage * Prevent overwriting of tube DB backup file * Remove backup code * Slightly improve storage reading code * Log DB migration to mod storage * Add migration note in README * Improve pipeworks.logger --- README | 4 +++ init.lua | 2 +- teleport_tube.lua | 90 +++++++++++++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/README b/README index 4af070d..2c23c9f 100644 --- a/README +++ b/README @@ -20,3 +20,7 @@ This mod is a work in progress. Please note that owing to the nature of this mod, I have opted to use 64px textures. Anything less just looks terrible. + +The teleport tube database used to kept in a file named 'teleport_tubes'. +The database is now kept in mod storage. The migration from 'teleport_tubes' is +automatic. The old file is then kept around but is not used at all. diff --git a/init.lua b/init.lua index ed011ba..08c0875 100644 --- a/init.lua +++ b/init.lua @@ -128,7 +128,7 @@ function pipeworks.replace_name(tbl,tr,name) end pipeworks.logger = function(msg) - print("[pipeworks] "..msg) + minetest.log("action", "[pipeworks] "..msg) end ------------------------------------------- diff --git a/teleport_tube.lua b/teleport_tube.lua index ad6a51c..3dffdf5 100644 --- a/teleport_tube.lua +++ b/teleport_tube.lua @@ -1,8 +1,9 @@ local S = minetest.get_translator("pipeworks") -local filename=minetest.get_worldpath() .. "/teleport_tubes" +local filename=minetest.get_worldpath() .. "/teleport_tubes" -- Only used for backward-compat +local storage=minetest.get_mod_storage() local tp_tube_db = nil -- nil forces a read -local tp_tube_db_version = 2.0 +local tp_tube_db_version = 3.0 -- cached rceiver list: hash(pos) => {receivers} local cache = {} @@ -12,47 +13,78 @@ local function hash(pos) end local function save_tube_db() - local file, err = io.open(filename, "w") - if file then - tp_tube_db.version = tp_tube_db_version - file:write(minetest.serialize(tp_tube_db)) - tp_tube_db.version = nil - io.close(file) - else - error(err) - end -- reset tp-tube cache cache = {} + + local fields = {version = tp_tube_db_version} + for key, val in pairs(tp_tube_db) do + fields[key] = minetest.serialize(val) + end + storage:from_table({fields = fields}) +end + +local function save_tube_db_entry(hash) + -- reset tp-tube cache + cache = {} + + local val = tp_tube_db[hash] + storage:set_string(hash, val and minetest.serialize(val) or "") end local function migrate_tube_db() + local old_version = tp_tube_db.version or 0 + tp_tube_db.version = nil + if old_version < 2.0 then local tmp_db = {} - tp_tube_db.version = nil for _, val in pairs(tp_tube_db) do if(val.channel ~= "") then -- skip unconfigured tubes tmp_db[hash(val)] = val end end tp_tube_db = tmp_db - save_tube_db() + end + save_tube_db() end local function read_tube_db() - local file = io.open(filename, "r") - if file ~= nil then + local file = not storage:contains("version") and io.open(filename, "r") + if not file then + tp_tube_db = {} + + for key, val in pairs(storage:to_table().fields) do + if tonumber(key) then + tp_tube_db[key] = minetest.deserialize(val) + elseif key == "version" then + tp_tube_db.version = tonumber(val) + else + error("Unknown field in teleport tube DB: " .. key) + end + end + + if tp_tube_db.version == nil then + tp_tube_db.version = tp_tube_db_version + storage:set_string("version", tp_tube_db.version) + elseif tp_tube_db.version > tp_tube_db_version then + error("Cannot read teleport tube DB of version " .. tp_tube_db.version) + end + else local file_content = file:read("*all") io.close(file) + pipeworks.logger("Moving teleport tube DB into mod storage from " .. filename) + if file_content and file_content ~= "" then tp_tube_db = minetest.deserialize(file_content) - if(not tp_tube_db.version or tonumber(tp_tube_db.version) < tp_tube_db_version) then - migrate_tube_db() - end - tp_tube_db.version = nil -- we add it back when saving - return tp_tube_db -- we read sucessfully + else + tp_tube_db = {version = 2.0} end end - tp_tube_db = {} + + if(not tp_tube_db.version or tonumber(tp_tube_db.version) < tp_tube_db_version) then + migrate_tube_db() + end + tp_tube_db.version = nil + return tp_tube_db end @@ -69,7 +101,7 @@ local function set_tube(pos, channel, can_receive) if tube then tube.channel = channel tube.cr = can_receive - save_tube_db() + save_tube_db_entry(hash) return end @@ -88,13 +120,14 @@ local function set_tube(pos, channel, can_receive) end tp_tube_db[hash] = {x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=can_receive} - save_tube_db() + save_tube_db_entry(hash) end local function remove_tube(pos) local tubes = tp_tube_db or read_tube_db() - tubes[hash(pos)] = nil - save_tube_db() + local hash = hash(pos) + tubes[hash] = nil + save_tube_db_entry(hash) end local function read_node_with_vm(pos) @@ -114,7 +147,6 @@ local function get_receivers(pos, channel) local tubes = tp_tube_db or read_tube_db() local receivers = {} - local dirty = false for key, val in pairs(tubes) do -- skip all non-receivers and the tube that it came from as early as possible, as this is called often if (val.cr == 1 and val.channel == channel and (val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z)) then @@ -125,13 +157,10 @@ local function get_receivers(pos, channel) table.insert(receivers, val) else tp_tube_db[key] = nil - dirty = true + save_tube_db_entry(key) end end end - if dirty then - save_tube_db() - end -- cache the result for next time cache[hash] = receivers return receivers @@ -290,6 +319,7 @@ end pipeworks.tptube = { hash = hash, save_tube_db = save_tube_db, + save_tube_db_entry = save_tube_db_entry, get_db = function() return tp_tube_db or read_tube_db() end, set_tube = set_tube, update_meta = update_meta,