2014-04-16 22:35:46 +02:00
--if there's no protection mod, no worldedit means no editing, worldedit means editing anywhere (old behaviour)
2014-04-19 01:52:34 +02:00
--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.
2014-04-16 22:35:46 +02:00
2014-04-20 02:15:25 +02:00
--[[
2014-04-16 22:35:46 +02:00
--let the other mod load first
minetest.after ( 0 , function ( )
--I would use mod.soft_depend from commonlib, but there are multiple mods that could create owned land
2014-04-20 02:15:25 +02:00
PROTECTION_MOD_EXISTS = minetest.is_protected ~= old_is_protected
2014-04-16 22:35:46 +02:00
--else fall back to old behaviour, where
--worldedit privilege is permission to edit everything
end )
2014-04-20 02:15:25 +02:00
--]]
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)
2014-04-16 22:35:46 +02:00
2014-04-18 22:23:13 +02:00
--[[
2014-04-19 01:52:34 +02:00
worldedit.privs replaces privs = { worldedit = true } , and also helps bypass volume permission checks .
2014-04-18 22:23:13 +02:00
Usage :
In chatcommand :
privs = { }
func = worldedit.privs ( function ( name , param ) ... end )
In if statement :
name = minetest.get_player_name ( node )
if worldedit.privs ( ) then
2014-04-19 01:52:34 +02:00
Returns :
nil ( false ) for no permission to worldedit anywhere ,
1 ( true ) for permission to worldedit at least somewhere , and
2 ( extra true ) for worldediting everywhere without checking for further permission .
2014-04-18 22:23:13 +02:00
--]]
2014-04-17 19:37:24 +02:00
--I wanted this function to directly choose the privileges for the chat command, but it only applies once.
--privs={worldedit=true [, server=true]}
--privs={worldedit=worldedit.priv() [, server=true]}
--instead, I had to wrap the rest of func = .
2014-04-20 02:15:25 +02:00
worldedit.privs = function ( privsfunc ) --returns a function (the argument function wrapped in another) which takes the arguments (name, param).
2014-04-19 03:21:08 +02:00
if privsfunc == nil then
2014-04-20 02:15:25 +02:00
privsfunc = function ( ) --[[no-op]] end
2014-04-18 22:23:13 +02:00
end
2014-04-17 21:35:15 +02:00
--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.
--The innermost anonymous function is declared. Then safe_region executes, adding a function wrapper around that function. Then worldedit.privs gets that as an argument, and adds another wrapper. The doubly-wrapped function is the one registered as a chatcommand.
return function ( name , param )
2014-04-19 01:52:34 +02:00
if minetest.check_player_privs ( name , { areas = true } ) then
--You can set areas, so you are allowed to worldedit them too.
--The ability to set the whole world as owned by yourself is already potentially destructive, what's more destructive capability?
2014-04-19 03:21:08 +02:00
privsfunc ( name , param )
2014-04-19 01:52:34 +02:00
return 2 --edit everywhere without checks
2014-04-20 02:15:25 +02:00
end
local is_creative = minetest.setting_getbool ( " creative_mode " )
if not is_creative or not PROTECTION_MOD_EXISTS then
2014-04-17 21:35:15 +02:00
--no protection mod, or not the kind of world where people can just create nodes out of thin air,
--worldedit privilege means editing anywhere
if minetest.check_player_privs ( name , { worldedit = true } ) then
2014-04-19 03:21:08 +02:00
privsfunc ( name , param )
2014-04-19 01:52:34 +02:00
return 2 --edit everywhere without checks
2014-04-17 21:35:15 +02:00
else
2014-04-20 02:15:25 +02:00
--default chatcommand failure message
minetest.chat_send_player ( name , " You don't have permission to run this command (missing privileges: worldedit) \n Reasons: " .. ( is_creative and " " or " (not creative mode) " ) .. ( PROTECTION_MOD_EXISTS and " " or " (no protection mod) " ) )
2014-04-19 01:52:34 +02:00
--func(name, param) placeholder
return nil --edit nowhere
2014-04-17 21:35:15 +02:00
end
2014-04-17 19:37:24 +02:00
else
2014-04-17 21:35:15 +02:00
--protection mod, can edit inside your area without worldedit privilege
--(worldedit and areas let you edit in no-man's land and other-owned area)
2014-04-19 03:21:08 +02:00
privsfunc ( name , param )
2014-04-19 01:52:34 +02:00
return 1 --edit at least somewhere, with checks
2014-04-17 19:37:24 +02:00
end
2014-04-16 22:35:46 +02:00
end
end
2014-04-17 19:37:24 +02:00
--this is... within chatcommands that actually change land
--(should be the same functions as safe_region)
2014-04-18 22:06:55 +02:00
--also check for permission when region is set? no, //stack goes outside the boundaries.
--so the region is defined per-command on exec.
2014-04-19 01:52:34 +02:00
--//move has disconnected sections, so it's passed as a list of points.
--which are deduplicated.
2014-04-20 02:15:25 +02:00
worldedit.can_edit_volume = function ( name , volume ) --does not return a function like .privs does
2014-04-19 01:52:34 +02:00
--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
--like worldedit.privs can be
--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 can_edit_volume is run before //set to honor areas
--then worldedit.privs is run again to attempt skipping checks (resusing the same code)
--then set is finally run.
2014-04-20 02:15:25 +02:00
--<==>--local returnfunc = function(name, param)
2014-04-19 03:21:08 +02:00
--worldedit.privs said that 'name' can use worldedit at least somewhere
-- return value 1 (or 2) before this function was run.
2014-04-19 01:52:34 +02:00
2014-04-19 03:21:08 +02:00
--Try skipping volume permission checks.
2014-04-20 02:15:25 +02:00
local wp = worldedit.privs ( nil ) ( name , nil )
2014-04-19 03:21:08 +02:00
if wp == 2 then
2014-04-20 02:15:25 +02:00
--volfunc(name, param)
2014-04-19 03:21:08 +02:00
return true
elseif wp == nil then
--safety feature in case worldedit.can_edit_volume is ever run alone, without being surrounded by worldedit.privs()
--Shouldn't ever get here.
--Any volume-changing function is surrounded by this, then safe_region, then worldedit.privs()
--volfunc(name, param) placeholder
return false
end
2014-04-16 22:35:46 +02:00
2014-04-19 03:21:08 +02:00
--[[I need to use a special per-command region (think /stack, or even worse, /move), the same one safe_region uses, but corner points instead of count... instead of a for loop interpolating between pos1 and pos2]] --
2014-04-17 19:37:24 +02:00
2014-04-19 03:30:26 +02:00
--cache the result of this function for later
local has_worldedit = minetest.check_player_privs ( name , { worldedit = true } )
2014-04-19 03:21:08 +02:00
--all or nothing here
2014-04-20 02:15:25 +02:00
--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 }
2014-04-19 03:21:08 +02:00
--[[
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
2014-04-16 22:35:46 +02:00
2014-04-19 03:21:08 +02:00
If it was treated differently ( it ' s not), then single edits would not be able to cross the border between someone else ' s editable land , and no - man ' s land, to prevent accidental writes. It may cross the border between multiple people ' s editable land ( or should it ? ) , such as to create a bridge between two skyscrapers that were previously built separately .
2014-04-16 22:35:46 +02:00
2014-04-19 03:21:08 +02:00
This needs testing for the other changes first .
--]]
2014-04-19 03:30:26 +02:00
2014-04-19 03:21:08 +02:00
--Is it owned?
2014-04-20 02:15:25 +02:00
if minetest.is_protected ( node , " " ) then
2014-04-19 03:21:08 +02:00
--Is it someone else's?
2014-04-20 02:15:25 +02:00
if minetest.is_protected ( node , name ) then
2014-04-19 03:21:08 +02:00
--already checked the ability to make it mine (areas)
2014-04-20 02:15:25 +02:00
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) " ..
" \n Reasons: (missing areas privilege) "
)
2014-04-19 03:21:08 +02:00
--volfunc(name, param) placeholder
return false
end
--it's mine
--continue
--no-man's land
--can I edit that?
2014-04-20 02:15:25 +02:00
elseif not has_worldedit then --using cached check
minetest.chat_send_player ( name , " You don't have permission to run this command (missing worldedit privilege) \n Reasons: (At least part of this area is unowned (not owned by you)) (missing areas privilege) " )
2014-04-19 03:21:08 +02:00
--volfunc(name, param) placeholder
2014-04-16 22:35:46 +02:00
return false
end
2014-04-20 02:15:25 +02:00
end -- for x
end -- for z
end -- for y
end -- if not nil
end -- for v
2014-04-16 22:35:46 +02:00
2014-04-19 03:21:08 +02:00
--the whole thing is
--a) owned by me, and/or
--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)
2014-04-20 02:15:25 +02:00
--volfunc(name, param)
2014-04-19 03:21:08 +02:00
return true
2014-04-20 02:15:25 +02:00
--<==>--end
2014-04-16 22:35:46 +02:00
end