From 57fc8c67f827a41ab1278fd0d25b2566032da61a Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Fri, 22 Dec 2017 17:13:50 +0000 Subject: teleport_tube.lua: fix 32-bit clamping issues on some systems for %d in string.format Some servers running ubuntu in particular were reporting issues with teleport tubes not working. On investigation, all tube entries were colliding as string.format("%d", ...) was returning either -2^31 or 2^31-1 depending on system bit width, causing hash entries to be overwritten. This is possibly related to the use of C sprintf within lua. Fix this by using %g instead to interpret as double without int conversion, with a large enough number of digits such that all possible 2^48 values from minetest.hash_node_position() can be correctly serialised. --- teleport_tube.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'teleport_tube.lua') diff --git a/teleport_tube.lua b/teleport_tube.lua index bb364db..9a66de2 100644 --- a/teleport_tube.lua +++ b/teleport_tube.lua @@ -4,7 +4,7 @@ local tp_tube_db = nil -- nil forces a read local tp_tube_db_version = 2.0 local function hash(pos) - return string.format("%d", minetest.hash_node_position(pos)) + return string.format("%.30g", minetest.hash_node_position(pos)) end local function save_tube_db() -- cgit v1.2.3 From 91bd0c7e985c6d5f98fddd22dccb6a4d30cae86f Mon Sep 17 00:00:00 2001 From: thetaepsilon-gamedev Date: Fri, 22 Dec 2017 17:57:00 +0000 Subject: teleport_tube.lua: add checks for hash collisions in positions table --- teleport_tube.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'teleport_tube.lua') diff --git a/teleport_tube.lua b/teleport_tube.lua index 9a66de2..d707717 100644 --- a/teleport_tube.lua +++ b/teleport_tube.lua @@ -50,6 +50,11 @@ local function read_tube_db() return tp_tube_db end +-- debug formatter for coordinates used below +local fmt = function(pos) + return pos.x..", "..pos.y..", "..pos.z +end + -- updates or adds a tube local function set_tube(pos, channel, can_receive) local tubes = tp_tube_db or read_tube_db() @@ -63,6 +68,19 @@ local function set_tube(pos, channel, can_receive) end -- we haven't found any tp tube to update, so lets add it + -- but sanity check that the hash has not already been inserted. + -- if so, complain very loudly and refuse the update so the player knows something is amiss. + -- to catch regressions of https://github.com/minetest-mods/pipeworks/issues/166 + local existing = tp_tube_db[hash] + if existing ~= nil then + local e = "error" + minetest.log(e, "pipeworks teleport tube update refused due to position hash collision") + minetest.log(e, "collided hash: "..hash) + minetest.log(e, "tried-to-place tube: "..fmt(pos)) + minetest.log(e, "existing tube: "..fmt(existing)) + return + end + tp_tube_db[hash] = {x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=can_receive} save_tube_db() end -- cgit v1.2.3