2022-10-07 07:02:41 -04:00

85 lines
2.6 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs, rawset
= minetest, nodecore, pairs, rawset
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local exmachina = nodecore[modname]
local default = "group:lode_cube, group:tote"
local grouppref = "group:"
local function match(nodename)
for _, s in pairs((minetest.settings:get(modname .. "_protect") or default)
:split()) do
s = s:trim()
if (s:sub(1, #grouppref) == grouppref) then
if minetest.get_item_group(nodename, s:sub(#grouppref + 1)) > 0 then
return true
end
else
if nodename == s then return true end
end
end
end
local function check(pos, thingname, pname)
if minetest.get_player_privs(pname).protection_bypass then return end
if match(thingname) or match(nodecore.stack_get(pos):get_name()) then
local owned = exmachina.owner_search(pos)
if owned and owned ~= pname then
pos.alarm = true
return true
end
end
end
local placing
local function metacheck(pos, name)
return check(pos, minetest.get_node(pos).name, name)
or (placing and check(pos, placing, name))
end
-- Check on trying to dig/access a protected node, and
-- handle placement check from special cases.
local old_prot = minetest.is_protected
function minetest.is_protected(pos, name, ...)
if metacheck(pos, name) then return true end
return old_prot(pos, name, ...)
end
local old_exempt = nodecore.protection_exempt
function nodecore.protection_exempt(pos, name, ...)
local old = old_exempt(pos, name, ...)
if not old then return old end
if metacheck(pos, name) then return end
return old
end
-- Check on trying to place a protected node.
local old_place = minetest.item_place_node
function minetest.item_place_node(itemstack, placer, pointed_thing, ...)
local pos = nodecore.buildable_to(pointed_thing.under)
and pointed_thing.under or pointed_thing.above
local name = placer and placer:is_player() and placer:get_player_name()
if pos and name and check(pos, itemstack:get_name(), name) then
minetest.record_protection_violation(pos, name)
return itemstack
end
return old_place(itemstack, placer, pointed_thing, ...)
end
-- Search for special-case nodes like totes that have custom place logic.
local function placedone(...) placing = nil return ... end
local function checkdef(name, def)
if not (def.on_place and match(name)) then return end
local oldp = def.on_place
rawset(def, "on_place", function(...)
placing = name
return placedone(oldp(...))
end)
end
minetest.after(0, function()
for k, v in pairs(minetest.registered_nodes) do
checkdef(k, v)
end
end)