//set appears to respect area ownership

hard depend on commonlib to soft depend on areas
This commit is contained in:
khonkhortisan 2014-04-19 17:15:25 -07:00
parent 11647fca93
commit c473fbb6c1
3 changed files with 49 additions and 23 deletions

View File

@ -291,7 +291,7 @@ minetest.register_chatcommand("/set", {
privs = {}, privs = {},
func = worldedit.privs(safe_region(function(name, param) func = worldedit.privs(safe_region(function(name, param)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
if worldedit.can_edit_volume(VoxelArea:iterp(pos1, pos2)) then if worldedit.can_edit_volume(name, {pos1, pos2}) then
local node = get_node(name, param) local node = get_node(name, param)
local count = worldedit.set(pos1, pos2, node) local count = worldedit.set(pos1, pos2, node)
worldedit.player_notify(name, count .. " nodes set") worldedit.player_notify(name, count .. " nodes set")

View File

@ -1 +1,2 @@
worldedit worldedit
commonlib

View File

@ -1,13 +1,22 @@
--if there's no protection mod, no worldedit means no editing, worldedit means editing anywhere (old behaviour) --if there's no protection mod, no worldedit means no editing, worldedit means editing anywhere (old behaviour)
--if there's a protection mod (and it's creative mode), no worldedit means editing only in your area, worldedit means editing in no-man's land too, and areas means editing anywhere. --if there's a protection mod (and it's creative mode), no worldedit means editing only in your area, worldedit means editing in no-man's land too, and areas means editing anywhere.
--[[
--let the other mod load first --let the other mod load first
minetest.after(0, function() minetest.after(0, function()
--I would use mod.soft_depend from commonlib, but there are multiple mods that could create owned land --I would use mod.soft_depend from commonlib, but there are multiple mods that could create owned land
PROTECTION_MOD_EXISTS = minetest.is_protected == old_is_protected PROTECTION_MOD_EXISTS = minetest.is_protected ~= old_is_protected
--else fall back to old behaviour, where --else fall back to old behaviour, where
--worldedit privilege is permission to edit everything --worldedit privilege is permission to edit everything
end) end)
--]]
local PROTECTION_MOD_EXISTS = false
mod.soft_depend("areas", function()
PROTECTION_MOD_EXISTS = true
end)
--mod.soft_depend("other protection mod goes here", function()
-- PROTECTION_MOD_EXISTS = true
--end)
--[[ --[[
worldedit.privs replaces privs = {worldedit = true}, and also helps bypass volume permission checks. worldedit.privs replaces privs = {worldedit = true}, and also helps bypass volume permission checks.
@ -29,11 +38,9 @@ Returns:
--privs={worldedit=true [, server=true]} --privs={worldedit=true [, server=true]}
--privs={worldedit=worldedit.priv() [, server=true]} --privs={worldedit=worldedit.priv() [, server=true]}
--instead, I had to wrap the rest of func = . --instead, I had to wrap the rest of func = .
worldedit.privs = function(--[[name, ]]privsfunc--[[, param]]) worldedit.privs = function(privsfunc) --returns a function (the argument function wrapped in another) which takes the arguments (name, param).
--This runs a function for a chatcommand's func = ,
--or it can be used directly in an if statement.
if privsfunc == nil then if privsfunc == nil then
privsfunc = function(name, param) end privsfunc = function() --[[no-op]] end
end end
--this silly syntax was copied from safe_region, which is actually executed on chatcommand registration, and must return a function instead of the result of a function. --this silly syntax was copied from safe_region, which is actually executed on chatcommand registration, and must return a function instead of the result of a function.
@ -44,13 +51,17 @@ worldedit.privs = function(--[[name, ]]privsfunc--[[, param]])
--The ability to set the whole world as owned by yourself is already potentially destructive, what's more destructive capability? --The ability to set the whole world as owned by yourself is already potentially destructive, what's more destructive capability?
privsfunc(name, param) privsfunc(name, param)
return 2 --edit everywhere without checks return 2 --edit everywhere without checks
elseif not minetest.setting_getbool("creative_mode") or not PROTECTION_MOD_EXISTS then end
local is_creative = minetest.setting_getbool("creative_mode")
if not is_creative or not PROTECTION_MOD_EXISTS then
--no protection mod, or not the kind of world where people can just create nodes out of thin air, --no protection mod, or not the kind of world where people can just create nodes out of thin air,
--worldedit privilege means editing anywhere --worldedit privilege means editing anywhere
if minetest.check_player_privs(name, {worldedit=true}) then if minetest.check_player_privs(name, {worldedit=true}) then
privsfunc(name, param) privsfunc(name, param)
return 2 --edit everywhere without checks return 2 --edit everywhere without checks
else else
--default chatcommand failure message
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: worldedit)\nReasons:".. (is_creative and "" or " (not creative mode)") .. (PROTECTION_MOD_EXISTS and "" or " (no protection mod)"))
--func(name, param) placeholder --func(name, param) placeholder
return nil --edit nowhere return nil --edit nowhere
end end
@ -69,13 +80,10 @@ end
--so the region is defined per-command on exec. --so the region is defined per-command on exec.
--//move has disconnected sections, so it's passed as a list of points. --//move has disconnected sections, so it's passed as a list of points.
--which are deduplicated. --which are deduplicated.
worldedit.can_edit_volume = function(--[[name, ]]volume, volfunc--[[, param]]) worldedit.can_edit_volume = function(name, volume) --does not return a function like .privs does
--volume is before func, unlike safe_region having func before count --volume is before func, unlike safe_region having func before count
--because func may be removed to have can_edit_volume in an if statement --because func may be removed to have can_edit_volume in an if statement
--like worldedit.privs can be --like worldedit.privs can be
if volfunc == nil then
volfunc = function(name, param) end
end
--worldedit.privs was run once to prevent safe_region large area warnings, --worldedit.privs was run once to prevent safe_region large area warnings,
--then safe_region was run to prevent unnecessary large-scale permission checks --then safe_region was run to prevent unnecessary large-scale permission checks
@ -83,14 +91,14 @@ worldedit.can_edit_volume = function(--[[name, ]]volume, volfunc--[[, param]])
--then worldedit.privs is run again to attempt skipping checks (resusing the same code) --then worldedit.privs is run again to attempt skipping checks (resusing the same code)
--then set is finally run. --then set is finally run.
return function(name, param) --<==>--local returnfunc = function(name, param)
--worldedit.privs said that 'name' can use worldedit at least somewhere --worldedit.privs said that 'name' can use worldedit at least somewhere
-- return value 1 (or 2) before this function was run. -- return value 1 (or 2) before this function was run.
--Try skipping volume permission checks. --Try skipping volume permission checks.
local wp = worldedit.privs() local wp = worldedit.privs(nil)(name, nil)
if wp == 2 then if wp == 2 then
volfunc(name, param) --volfunc(name, param)
return true return true
elseif wp == nil then elseif wp == nil then
--safety feature in case worldedit.can_edit_volume is ever run alone, without being surrounded by worldedit.privs() --safety feature in case worldedit.can_edit_volume is ever run alone, without being surrounded by worldedit.privs()
@ -106,7 +114,15 @@ worldedit.can_edit_volume = function(--[[name, ]]volume, volfunc--[[, param]])
local has_worldedit = minetest.check_player_privs(name, {worldedit=true}) local has_worldedit = minetest.check_player_privs(name, {worldedit=true})
--all or nothing here --all or nothing here
for i in volume do --volume may be a single region (//set) or two possibly overlapping regions (//move)
--an overlapping //move is checked twice - any attempt to make it more efficient (by combining the volumes into a single two-pos one) may take into account that the format is //move axis amount, and break if the format is changed to //move xamount yamount zamount
for v = 1,3,2 do --volume[1] and volume[2]
if volume[v] ~= nil then --volume[3] and volume[4]
volume[v], volume[v+1] = worldedit.sort_pos(volume[v], volume[v+1])
for y = volume[v].y, volume[v+1].y do
for z = volume[v].z, volume[v+1].z do
for x = volume[v].x, volume[v+1].x do
local node = {x=x, y=y, z=z}
--[[ --[[
THIS SECTION IGNORES the distinction of area that is owned by someone else, but still editable THIS SECTION IGNORES the distinction of area that is owned by someone else, but still editable
this is treated as area owned by the editor, or no-man's land depending on if it's shared with one person or everyone this is treated as area owned by the editor, or no-man's land depending on if it's shared with one person or everyone
@ -117,11 +133,16 @@ worldedit.can_edit_volume = function(--[[name, ]]volume, volfunc--[[, param]])
--]] --]]
--Is it owned? --Is it owned?
if minetest.is_protected(i) then if minetest.is_protected(node, "") then
--Is it someone else's? --Is it someone else's?
if minetest.is_protected(i, name) then if minetest.is_protected(node, name) then
--already checked the ability to make it mine (areas) --already checked the ability to make it mine (areas)
minetest.chat_send_player(name, "Someone else owns at least part of what you want to edit") minetest.chat_send_player(name, "You don't have permission to run this command "..
"(Region "..minetest.pos_to_string(volume[1]).."-"..minetest.pos_to_string(volume[2])..
(volume[3] ~= nil and ("+"..minetest.pos_to_string(volume[3]).."-"..minetest.pos_to_string(volume[4])) or "")..
" overlaps (first match) areaname: (x, y, z)-(x, y, z) owned by playername)"..
"\nReasons: (missing areas privilege)"
)
--volfunc(name, param) placeholder --volfunc(name, param) placeholder
return false return false
end end
@ -130,18 +151,22 @@ worldedit.can_edit_volume = function(--[[name, ]]volume, volfunc--[[, param]])
--no-man's land --no-man's land
--can I edit that? --can I edit that?
elseif not has_worldedit then --use cached check elseif not has_worldedit then --using cached check
minetest.chat_send_player(name, "You can only edit area in which you own a plot (missing worldedit privilege)") minetest.chat_send_player(name, "You don't have permission to run this command (missing worldedit privilege)\nReasons: (At least part of this area is unowned (not owned by you)) (missing areas privilege)")
--volfunc(name, param) placeholder --volfunc(name, param) placeholder
return false return false
end end
end end -- for x
end -- for z
end -- for y
end -- if not nil
end -- for v
--the whole thing is --the whole thing is
--a) owned by me, and/or --a) owned by me, and/or
--b) owned by no one and I have the worldedit privilege. --b) owned by no one and I have the worldedit privilege.
--c) I have the areas privilege and it's possibly owned by someone else. (returned earlier) --c) I have the areas privilege and it's possibly owned by someone else. (returned earlier)
volfunc(name, param) --volfunc(name, param)
return true return true
end --<==>--end
end end