From da0cc7f6f62c149363c319a7743a00a505da06d2 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 18 Mar 2016 18:55:56 -0700 Subject: [PATCH] Beds: priv/griefing fixes. - 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 | 56 ++++++++++++++++++++++++++++++-------------- mods/beds/spawns.lua | 9 ++++--- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/mods/beds/api.lua b/mods/beds/api.lua index be3cb97..e2dd7ed 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -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 - minetest.set_node(p, {name = n.name:gsub("%_bottom", "_top"), param2 = n.param2}) - return false - 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 + + 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, }) diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua index 14ec75b..f3980a7 100644 --- a/mods/beds/spawns.lua +++ b/mods/beds/spawns.lua @@ -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