From 68d922f040d9b080b95353108a54f5d8e6ea78f3 Mon Sep 17 00:00:00 2001 From: watilin Date: Sun, 30 Nov 2025 20:21:20 +0100 Subject: [PATCH 1/3] Make tp tubes use mod storage with prefixed keys --- tubes/teleport.lua | 50 +++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/tubes/teleport.lua b/tubes/teleport.lua index ec98ba5..c2bea51 100644 --- a/tubes/teleport.lua +++ b/tubes/teleport.lua @@ -2,6 +2,7 @@ local S = core.get_translator("pipeworks") local filename = core.get_worldpath().."/teleport_tubes" -- Only used for backward-compat local storage = core.get_mod_storage() +local STORAGE_PREFIX = "tptube_" local enable_logging = core.settings:get_bool("pipeworks_log_teleport_tubes", false) @@ -36,17 +37,19 @@ end local function save_tube_db() receiver_cache = {} - local fields = {version = tube_db_version} + storage:set_string("version", "") -- cleanup prefix-less entry + storage:set_int(STORAGE_PREFIX.."version", tube_db_version) for key, val in pairs(tube_db) do - fields[key] = serialize_tube(val) + storage:set_string(key, "") + storage:set_string(STORAGE_PREFIX..key, serialize_tube(val)) end - storage:from_table({fields = fields}) end local function save_tube(hash) local tube = tube_db[hash] receiver_cache[tube.channel] = nil - storage:set_string(hash, serialize_tube(tube)) + storage:set_string(hash, "") -- cleanup prefix-less entry + storage:set_string(STORAGE_PREFIX..hash, serialize_tube(tube)) end local function remove_tube(pos) @@ -55,6 +58,7 @@ local function remove_tube(pos) receiver_cache[tube_db[hash].channel] = nil tube_db[hash] = nil storage:set_string(hash, "") + storage:set_string(STORAGE_PREFIX..hash, "") end end @@ -93,17 +97,35 @@ local function migrate_tube_db() end local function read_tube_db() - local version = storage:get_int("version") - if version < tube_db_version then - migrate_tube_db() - elseif version > tube_db_version then - error("Cannot read teleport tube database of version "..version) - else + local version = storage:get_int(STORAGE_PREFIX.."version") + if version ~= 0 then + -- storage with prefix for key, val in pairs(storage:to_table().fields) do - if tonumber(key) then - tube_db[key] = deserialize_tube(key, val) - elseif key ~= "version" then - error("Unknown field in teleport tube database: "..key) + local short_key = string.match(key, "^"..STORAGE_PREFIX.."(.+)") + if short_key then -- only handle keys relevant to tp tubes + if tonumber(short_key) then + tube_db[short_key] = deserialize_tube(short_key, val) + elseif short_key ~= "version" then + error("Unknown field in teleport tube database: "..key) + end + end + end + else + -- legacy, prefix-less storage + version = storage:get_int("version") + if version < tube_db_version then + -- we also get here if no version number was found, + -- e.g. on a fresh new world + migrate_tube_db() + elseif version > tube_db_version then + error("Cannot read teleport tube database of version "..version) + else + for key, val in pairs(storage:to_table().fields) do + if tonumber(key) then + tube_db[key] = deserialize_tube(key, val) + elseif key ~= "version" then + error("Unknown field in teleport tube database: "..key) + end end end end From aeaf654ab19edb26c28e01064727bf60c5fbd1b9 Mon Sep 17 00:00:00 2001 From: watilin Date: Sun, 30 Nov 2025 22:19:30 +0100 Subject: [PATCH 2/3] Move migration code to `migrate_tube_db` --- tubes/teleport.lua | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/tubes/teleport.lua b/tubes/teleport.lua index c2bea51..db749c6 100644 --- a/tubes/teleport.lua +++ b/tubes/teleport.lua @@ -48,7 +48,6 @@ end local function save_tube(hash) local tube = tube_db[hash] receiver_cache[tube.channel] = nil - storage:set_string(hash, "") -- cleanup prefix-less entry storage:set_string(STORAGE_PREFIX..hash, serialize_tube(tube)) end @@ -57,18 +56,26 @@ local function remove_tube(pos) if tube_db[hash] then receiver_cache[tube_db[hash].channel] = nil tube_db[hash] = nil - storage:set_string(hash, "") storage:set_string(STORAGE_PREFIX..hash, "") end end local function migrate_tube_db() + -- check prefix-less version number + if storage:get_int("version") == 4 then + for key, val in pairs(storage:to_table().fields) do + if tonumber(key) then + tube_db[key] = deserialize_tube(key, val) + end + -- ignore other keys + end + save_tube_db() + return + end if storage:get_int("version") == 3 then for key, val in pairs(storage:to_table().fields) do if tonumber(key) then tube_db[key] = core.deserialize(val) - elseif key ~= "version" then - error("Unknown field in teleport tube database: "..key) end end save_tube_db() @@ -98,33 +105,18 @@ end local function read_tube_db() local version = storage:get_int(STORAGE_PREFIX.."version") - if version ~= 0 then - -- storage with prefix + if version < tube_db_version then + migrate_tube_db() + elseif version > tube_db_version then + error("Cannot read teleport tube database of version "..version) + else for key, val in pairs(storage:to_table().fields) do local short_key = string.match(key, "^"..STORAGE_PREFIX.."(.+)") if short_key then -- only handle keys relevant to tp tubes if tonumber(short_key) then tube_db[short_key] = deserialize_tube(short_key, val) elseif short_key ~= "version" then - error("Unknown field in teleport tube database: "..key) - end - end - end - else - -- legacy, prefix-less storage - version = storage:get_int("version") - if version < tube_db_version then - -- we also get here if no version number was found, - -- e.g. on a fresh new world - migrate_tube_db() - elseif version > tube_db_version then - error("Cannot read teleport tube database of version "..version) - else - for key, val in pairs(storage:to_table().fields) do - if tonumber(key) then - tube_db[key] = deserialize_tube(key, val) - elseif key ~= "version" then - error("Unknown field in teleport tube database: "..key) + error("Unknown field in teleport tube database: "..short_key) end end end From 379011f04678a9eddb60e1e7b9e6adf225c406e9 Mon Sep 17 00:00:00 2001 From: watilin Date: Mon, 1 Dec 2025 14:36:26 +0100 Subject: [PATCH 3/3] Fix precision loss when converting hashes to string --- tubes/teleport.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tubes/teleport.lua b/tubes/teleport.lua index db749c6..7d866b2 100644 --- a/tubes/teleport.lua +++ b/tubes/teleport.lua @@ -41,14 +41,20 @@ local function save_tube_db() storage:set_int(STORAGE_PREFIX.."version", tube_db_version) for key, val in pairs(tube_db) do storage:set_string(key, "") - storage:set_string(STORAGE_PREFIX..key, serialize_tube(val)) + storage:set_string( + string.format("%s%.0f", STORAGE_PREFIX, key), + serialize_tube(val) + ) end end local function save_tube(hash) local tube = tube_db[hash] receiver_cache[tube.channel] = nil - storage:set_string(STORAGE_PREFIX..hash, serialize_tube(tube)) + storage:set_string( + string.format("%s%.0f", STORAGE_PREFIX, hash), + serialize_tube(tube) + ) end local function remove_tube(pos) @@ -56,7 +62,7 @@ local function remove_tube(pos) if tube_db[hash] then receiver_cache[tube_db[hash].channel] = nil tube_db[hash] = nil - storage:set_string(STORAGE_PREFIX..hash, "") + storage:set_string(string.format("%s%.0f", STORAGE_PREFIX, hash), "") end end