Beds: priv/griefing fixes.
authorAuke Kok <sofar@foo-projects.org>
Sat, 19 Mar 2016 01:55:56 +0000 (18:55 -0700)
committerparamat <mat.gregory@virginmedia.com>
Mon, 21 Mar 2016 06:17:45 +0000 (06:17 +0000)
- disallow placing beds in protected areas
- fix rotation of beds(broken after 41c2b2ae)
- allow using others' beds, but don't change spawn location

Fixes #953. #943 isn't something I think was ever implemented, and
this does a fair job of addressing the main concern (spawning in
others' houses)

mods/beds/api.lua
mods/beds/spawns.lua

index be3cb97e47b8fa3afe329442ecb57d1df84a5cc8..e2dd7edf56342bd1ffd3fb4a13ee40e6ef625350 100644 (file)
@@ -44,23 +44,42 @@ function beds.register_bed(name, def)
                        fixed = def.selectionbox,
                },
 
-               after_place_node = function(pos, placer, itemstack)
-                       local n = minetest.get_node_or_nil(pos)
-                       if not n or not n.param2 then
-                               minetest.remove_node(pos)
-                               return true
+               on_place = function(itemstack, placer, pointed_thing)
+                       local under = pointed_thing.under
+                       local pos
+                       if minetest.registered_items[minetest.get_node(under).name].buildable_to then
+                               pos = under
+                       else
+                               pos = pointed_thing.above
                        end
-                       local dir = minetest.facedir_to_dir(n.param2)
-                       local p = vector.add(pos, dir)
-                       local n2 = minetest.get_node_or_nil(p)
-                       local def = n2 and minetest.registered_items[n2.name]
-                       if not def or not def.buildable_to then
-                               minetest.remove_node(pos)
-                               return true
+
+                       if minetest.is_protected(pos, placer:get_player_name()) and
+                                       not minetest.check_player_privs(placer, "protection_bypass") then
+                               minetest.record_protection_violation(pos, placer:get_player_name())
+                               return itemstack
+                       end
+
+                       local dir = minetest.dir_to_facedir(placer:get_look_dir())
+                       local botpos = vector.add(pos, minetest.facedir_to_dir(dir))
+
+                       if minetest.is_protected(botpos, placer:get_player_name()) and
+                                       not minetest.check_player_privs(placer, "protection_bypass") then
+                               minetest.record_protection_violation(botpos, placer:get_player_name())
+                               return itemstack
                        end
-                       minetest.set_node(p, {name = n.name:gsub("%_bottom", "_top"), param2 = n.param2})
-                       return false
-               end,    
+
+                       if not minetest.registered_nodes[minetest.get_node(botpos).name].buildable_to then
+                               return itemstack
+                       end
+
+                       minetest.set_node(pos, {name = name .. "_bottom", param2 = dir})
+                       minetest.set_node(botpos, {name = name .. "_top", param2 = dir})
+
+                       if not minetest.setting_getbool("creative_mode") then
+                               itemstack:take_item()
+                       end
+                       return itemstack
+               end,
 
                on_destruct = function(pos)
                        destruct_bed(pos, 1)
@@ -96,9 +115,10 @@ function beds.register_bed(name, def)
                                return false
                        end
                        node.param2 = new_param2
-                       minetest.swap_node(pos, node)
-                       minetest.remove_node(p)
-                       minetest.set_node(newp, {name = node.name:gsub("%_bottom", "_top"), param2 = new_param2})
+                       -- do not remove_node here - it will trigger destroy_bed()
+                       minetest.set_node(p, {name = "air"})
+                       minetest.set_node(pos, node)
+                       minetest.set_node(newp, {name = name .. "_top", param2 = new_param2})
                        return true
                end,
        })
index 14ec75bf2012c2378b0cc3a207fa56351454017f..f3980a7a0b93bee685b7bd3dcf2eefda0bc06410 100644 (file)
@@ -18,8 +18,8 @@ function beds.read_spawns()
                repeat
                        local x = input:read("*n")
                        if x == nil then
-                               break
-                       end
+                               break
+                       end
                        local y = input:read("*n")
                        local z = input:read("*n")
                        local name = input:read("*l")
@@ -52,7 +52,10 @@ function beds.set_spawns()
        for name,_ in pairs(beds.player) do
                local player = minetest.get_player_by_name(name)
                local p = player:getpos()
-               beds.spawn[name] = p
+               -- but don't change spawn location if borrowing a bed
+               if not minetest.is_protected(p, name) then
+                       beds.spawn[name] = p
+               end
        end
        beds.save_spawns()
 end