Protect against frame leak.

Until now, it was possible for the player to obtain any item if
the frame was left unlocked. The items that are not obtainable
have significant placement liberties that can break many boxes and
potentially allow players to brick their box.

To secure this, we lock all frames automatically and do not allow
them to become unlocked unless they contain obtainable items.
This commit is contained in:
Auke Kok 2019-01-23 22:08:09 -08:00
parent 01b5b690df
commit a5962a296a

View File

@ -22,10 +22,24 @@ local function frame_on_punch(pos, node, puncher, pointed_thing)
end
end
local def = minetest.registered_nodes[node.name]
-- lock/unlock
local meta = minetest.get_meta(pos)
if puncher:get_player_control().sneak and (boxes.players_editing_boxes[name] or
minetest.check_player_privs(puncher, "server")) then
local idef = minetest.registered_nodes[def.frame_contents]
if not idef then
return false
end
if not(idef.groups.hand or idef.groups.axe or idef.groups.shovel or idef.groups.pickaxe) then
meta:set_int("locked", 1)
minetest.chat_send_player(name, "Item frame contains item the player can not obtain, is therefore locked")
return false
end
if meta:get_int("locked") == 1 then
meta:set_int("locked", 0)
minetest.chat_send_player(name, "Item frame is now unlocked")
@ -38,14 +52,14 @@ local function frame_on_punch(pos, node, puncher, pointed_thing)
end
if meta:get_int("locked") == 1 then
if not(boxes.players_editing_boxes[name] or minetest.check_player_privs(puncher, "server")) then
return false
end
local def = minetest.registered_nodes[node.name]
local item = ItemStack(def.frame_contents)
end
-- preserve itemstack metadata and wear
local wear = meta:get_int("wear")
local item = ItemStack(def.frame_contents)
if wear then
item:set_wear(wear)
end
@ -69,7 +83,7 @@ local frame_admin = {
["tools:grow"] = true,
}
-- handle node insertion into frame
-- handle node insertion into empty frame
local function frame_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then
local name = clicker:get_player_name()
@ -88,14 +102,23 @@ local function frame_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
return false
end
local idef = minetest.registered_nodes[nodename]
if not idef then
return false
end
local meta = minetest.get_meta(pos)
if not(idef.groups.hand or idef.groups.axe or idef.groups.shovel or idef.groups.pickaxe) then
meta:set_int("locked", 1)
minetest.chat_send_player(clicker:get_player_name(), "Item inserted into frame is not obtainable, frame locked")
end
local wear = itemstack:get_wear()
if wear then
local meta = minetest.get_meta(pos)
meta:set_int("wear", wear)
end
local metadata = itemstack:get_metadata()
if metadata ~= "" then
local meta = minetest.get_meta(pos)
meta:set_string("metadata", metadata)
end