1
0
mirror of https://github.com/sys4-fr/server-nalc.git synced 2024-11-17 15:58:26 +01:00

Updated areas, including megabuilder-like privilege

- Added area_high_limits privilege, similar to (buggy) megabuilder
This commit is contained in:
LeMagnesium 2015-03-02 21:20:50 +01:00
parent b4f294fba2
commit 911f49faa4
8 changed files with 226 additions and 121 deletions

View File

@ -1,103 +1,104 @@
Areas mod for Minetest 0.4.8+ Areas mod for Minetest 0.4.8+
============================= =============================
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration Configuration
------------- -------------
If you wish to specify configuration options, such as whether players are If you wish to specify configuration options, such as whether players are
allowed to protect their own areas with /protect (Disabled by default), you allowed to protect their own areas with the `protect` command (disabled by
should check config.lua and set the appropriate settings in your minetest.conf. default), you should check config.lua and set the appropriate settings in your
server's configuration file (probably `minetest.conf`).
Tutorial Tutorial
-------- --------
To protect an area you must first set the corner positions of the area. To protect an area you must first set the corner positions of the area.
In order to set the corner positions you run: In order to set the corner positions you can run:
1. "/area\_pos set" punch the two border nodes. * `/area_pos set` and punch the two corner nodes to set them.
2. "/area\_pos set1/2" punch only the first or second border node. * `/area_pos set1/set2` and punch only the first or second corner node to
3. "/area\_pos1/2" set position one or two to your current position. set them one at a time.
4. "/area\_pos1/2 X Y Z" set position one or two to the specified coordinates. * `/area_pos1/2` to set one of the positions to your current position.
* `/area_pos1/2 X Y Z` to set one of the positions to the specified
coordinates.
Once you have set the border positions you can protect the area by running: Once you have set the border positions you can protect the area by running one
1. "/set\_owner <OwnerName> <AreaName>" of the following commands:
-- If you are a administrator or moderator with the "areas" privilege. * `/set_owner <OwnerName> <AreaName>` -- If you have the `areas` privilege.
2. "/protect &lt;AreaName&gt;" * `/protect <AreaName>` -- If you have the `areas` privilege or the server
-- If the server administraor has enabled area self-protection. administrator has enabled area self-protection.
The area name is used so that you can easily find the area that you want when The area name is used only for informational purposes (so that you know what
using a command like /list\_areas. It is not used for any other purpose. an area is for). It is not used for any other purpose.
For example: /set\_owner SomePlayer Diamond city For example: `/set_owner SomePlayer Mese city`
Now that you own an area you may want to add sub-owners to it. You can do this Now that you own an area you may want to add sub-owners to it. You can do this
with the /add\_owner command. Anyone with an area can use the add\_owner with the `add_owner` command. Anyone with an area can use the `add_owner`
command on their areas. Before using the add\_owner command you have to select command on their areas. Before using the `add_owner` command you have to
the corners of the sub-area as you did for set\_owner. If your markers are select the corners of the sub-area as you did for `set_owner`. If your markers
still around your original area and you want to grant access to your entire are still around your original area and you want to grant access to your
area you will not have to re-set them. You can also use select\_area to place entire area you will not have to re-set them. You can also use `select_area` to
the markers at the corners of an existing area. place the markers at the corners of an existing area if you've reset your
The add\_owner command expects three arguments: markers and want to grant access to a full area.
1. The id of the parent area. (The area that you want it to be a sub-area of) The `add_owner` command expects three arguments:
2. The name of the player that will own the sub-area. 1. The ID number of the parent area (the area that you want to add a
3. The name of the sub-area. sub-area to).
2. The name of the player that will own the sub-area.
3. The name of the sub-area. (can contain spaces)
For example: /add\_owner 123 BobTheBuilder Diamond lighthouse For example: `/add_owner 123 BobTheBuilder Diamond lighthouse`
Chat commands
-------------
* /protect &lt;AreaName&gt;
Protects an area for yourself. (If self-protection is enabled)
* /set\_owner &lt;OwnerName&gt; &lt;AreaName&gt; Commands
Protects an area. (Requires the "areas" privilege) --------
* /add\_owner &lt;ParentID&gt; &lt;OwnerName&gt; &lt;ChildName&gt; * `/protect <AreaName>` -- Protects an area for yourself. (if
Grants another player control over part (or all) of an area. self-protection is enabled)
* /rename\_area &lt;ID&gt; &lt;NewName&gt; * `/set_owner <OwnerName> <AreaName>` -- Protects an area for a specified
Renames an existing area, useful after converting from node_ownership player. (requires the `areas` privilege)
when all areas are unnamed.
* /list\_areas * `/add_owner <ParentID> <OwnerName> <ChildName>` -- Grants another player
Lists all of the areas that you own. control over part (or all) of an area.
(Or all of them if you have the "areas" privilege)
* /find\_areas &lt;Regex&gt; * `/rename_area <ID> <NewName>` -- Renames an existing area.
Finds areas using a Lua regular expresion.
For example:
/find_areas [Cc]astle To find castles.
* /remove\_area &lt;ID&gt; * `/list_areas` -- Lists all of the areas that you own, or all areas if you
Removes an area that you own. Any sub-areas of that area are made sub-areas have the `areas` privilege.
of the removed area's parent, if it exists. Otherwise they will have no
parent.
* /recursive\_remove\_areas &lt;ID&gt; * `/find_areas <Regex>` -- Finds areas using a Lua regular expresion.
Removes an area and all sub-areas of it. For example, to find castles:
* /change\_owner &lt;ID&gt; &lt;NewOwner&gt; /find_areas [Cc]astle
Change the owner of an area.
* /select\_area &lt;ID&gt; * `/remove_area <ID>` -- Removes an area that you own. Any sub-areas of that
Sets the area positions to those of an existing area. area are made sub-areas of the removed area's parent, if it exists.
If the removed area has no parent it's sub-areas will have no parent.
* /area\_pos {set,set1,set2,get} * `/recursive_remove_areas <ID>` -- Removes an area and all sub-areas of it.
Sets the area positions by punching nodes or shows the current area positions.
* /area\_pos1 \[X,Y,Z|X Y Z\] * `/change_owner <ID> <NewOwner>` -- Change the owner of an area.
Sets area position one to your position or the one supplied.
* /area\_pos2 \[X,Y,Z|X Y Z\] * `/area_info` -- Returns information about area configuration and usage.
Sets area position two to your position or the one supplied.
* `/area_open <ID>` -- Sets the area open, anyone can interact. * `/select_area <ID>` -- Sets the area positions to those of an existing
area.
* `/area_openfarming <ID>` -- Sets the area openfarming, anyone can interact only farming mod. * `/area_pos {set,set1,set2,get}` -- Sets the area positions by punching
nodes or shows the current area positions.
* `/area_pos1 [X,Y,Z|X Y Z]` -- Sets area position one to your position or
the one supplied.
* `/area_pos2 [X,Y,Z|X Y Z]` -- Sets area position two to your position or
the one supplied.
License License
------- -------
Copyright (C) 2013 ShadowNinja Copyright (C) 2013 ShadowNinja
Licensed under the GNU LGPL version 2.1 or higher. Licensed under the GNU LGPL version 2.1 or later.
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt

View File

@ -1,4 +1,3 @@
---
-- Returns a list of areas that include the provided position -- Returns a list of areas that include the provided position
function areas:getAreasAtPos(pos) function areas:getAreasAtPos(pos)
@ -72,7 +71,7 @@ function areas:canInteractInArea(pos1, pos2, name, allow_open)
end end
end end
end end
-- Then check for intersecting (non-owned) areas -- Then check for intersecting (non-owned) areas.
for id, area in pairs(self.areas) do for id, area in pairs(self.areas) do
local p1, p2 = area.pos1, area.pos2 local p1, p2 = area.pos1, area.pos2
if (p1.x <= pos2.x and p2.x >= pos1.x) and if (p1.x <= pos2.x and p2.x >= pos1.x) and

View File

@ -2,7 +2,7 @@
minetest.register_chatcommand("protect", { minetest.register_chatcommand("protect", {
params = "<AreaName>", params = "<AreaName>",
description = "Protect your own area", description = "Protect your own area",
privs = {[areas.self_protection_privilege]=true}, privs = {[areas.config.self_protection_privilege]=true},
func = function(name, param) func = function(name, param)
if param == "" then if param == "" then
return false, "Invalid usage, see /help protect." return false, "Invalid usage, see /help protect."
@ -157,8 +157,8 @@ minetest.register_chatcommand("find_areas", {
return false, "Invalid regular expression." return false, "Invalid regular expression."
end end
local matches = {} local matches = {}
for id, area in pairs(areas.areas) do for id, area in pairs(areas.areas) do
local str = areas:toString(id) local str = areas:toString(id)
if str:find(param) then if str:find(param) then
table.insert(matches, str) table.insert(matches, str)
@ -334,3 +334,93 @@ minetest.register_chatcommand("move_area", {
return true, "Area successfully moved." return true, "Area successfully moved."
end, end,
}) })
minetest.register_chatcommand("area_info", {
description = "Get information about area configuration and usage.",
func = function(name, param)
local lines = {}
local privs = minetest.get_player_privs(name)
-- Short (and fast to access) names
local cfg = areas.config
local self_prot = cfg.self_protection
local prot_priv = cfg.self_protection_privilege
local limit = cfg.self_protection_max_areas
local limit_high = cfg.self_protection_max_areas_high
local size_limit = cfg.self_protection_max_size
local size_limit_high = cfg.self_protection_max_size_high
local has_high_limit = privs.areas_high_limit
local has_prot_priv = not prot_priv or privs[prot_priv]
local can_prot = privs.areas or (self_prot and has_prot_priv)
local max_count = can_prot and
(has_high_limit and limit_high or limit) or 0
local max_size = has_high_limit and
size_limit_high or size_limit
-- Privilege information
local self_prot_line = ("Self protection is %sabled"):format(
self_prot and "en" or "dis")
if self_prot and prot_priv then
self_prot_line = self_prot_line..
(" %s have the neccessary privilege (%q).")
:format(
has_prot_priv and "and you" or
"but you don't",
prot_priv)
else
self_prot_line = self_prot_line.."."
end
table.insert(lines, self_prot_line)
if privs.areas then
table.insert(lines, "You are an area"..
" administrator (\"areas\" privilege).")
elseif has_high_limit then
table.insert(lines,
"You have extended area protection"..
" limits (\"areas_high_limit\" privilege).")
end
-- Area count
local area_num = 0
for id, area in pairs(areas.areas) do
if area.owner == name then
area_num = area_num + 1
end
end
local count_line = ("You have %d area%s"):format(
area_num, area_num == 1 and "" or "s")
if privs.areas then
count_line = count_line..
" and have no area protection limits."
elseif can_prot then
count_line = count_line..(", out of a maximum of %d.")
:format(max_count)
end
table.insert(lines, count_line)
-- Area size limits
local function size_info(str, size)
table.insert(lines, ("%s spanning up to %dx%dx%d.")
:format(str, size.x, size.y, size.z))
end
local function priv_limit_info(priv, max_count, max_size)
size_info(("Players with the %q privilege"..
" can protect up to %d areas"):format(
priv, max_count), max_size)
end
if self_prot then
if privs.areas then
priv_limit_info(prot_priv,
limit, size_limit)
priv_limit_info("areas_high_limit",
limit_high, size_limit_high)
elseif has_prot_priv then
size_info("You can protect areas", max_size)
end
end
return true, table.concat(lines, "\n")
end,
})

View File

@ -22,7 +22,7 @@ minetest.register_globalstep(function(dtime)
hud = {} hud = {}
areas.hud[name] = hud areas.hud[name] = hud
hud.areasId = player:hud_add({ hud.areasId = player:hud_add({
hud_elem_type = "text", hud_elem_type = "text",
name = "Areas", name = "Areas",
number = 0xFFFFFF, number = 0xFFFFFF,
position = {x=0, y=1}, position = {x=0, y=1},

View File

@ -19,11 +19,16 @@ dofile(areas.modpath.."/hud.lua")
areas:load() areas:load()
minetest.register_privilege("areas", {description = "Can administer areas"}) minetest.register_privilege("areas", {
description = "Can administer areas."
})
minetest.register_privilege("areas_high_limit", {
description = "Can can more, bigger areas."
})
if not minetest.registered_privileges[areas.self_protection_privilege] then if not minetest.registered_privileges[areas.config.self_protection_privilege] then
minetest.register_privilege(areas.self_protection_privilege, { minetest.register_privilege(areas.config.self_protection_privilege, {
description = "Can protect areas", description = "Can protect areas.",
}) })
end end

View File

@ -1,4 +1,3 @@
-- Mega_builder privilege -- Mega_builder privilege
minetest.register_privilege("megabuilder","Can protect an infinite amount of areas.") minetest.register_privilege("megabuilder","Can protect an infinite amount of areas.")
@ -13,7 +12,7 @@ function areas:save()
minetest.log("error", "[areas] Failed to serialize area data!") minetest.log("error", "[areas] Failed to serialize area data!")
return return
end end
local file, err = io.open(self.filename, "w") local file, err = io.open(self.config.filename, "w")
if err then if err then
return err return err
end end
@ -23,7 +22,7 @@ end
-- Load the areas table from the save file -- Load the areas table from the save file
function areas:load() function areas:load()
local file, err = io.open(self.filename, "r") local file, err = io.open(self.config.filename, "r")
if err then if err then
self.areas = self.areas or {} self.areas = self.areas or {}
return err return err
@ -55,12 +54,12 @@ end
-- Remove a area, and optionally it's children recursively. -- Remove a area, and optionally it's children recursively.
-- If a area is deleted non-recursively the children will -- If a area is deleted non-recursively the children will
-- have the removed area's parent as their new parent. -- have the removed area's parent as their new parent.
function areas:remove(id, recurse, secondrun) function areas:remove(id, recurse)
if recurse then if recurse then
-- Recursively find child entries and remove them -- Recursively find child entries and remove them
local cids = self:getChildren(id) local cids = self:getChildren(id)
for _, cid in pairs(cids) do for _, cid in pairs(cids) do
self:remove(cid, true, true) self:remove(cid, true)
end end
else else
-- Update parents -- Update parents
@ -112,23 +111,26 @@ end
-- Also checks the size of the area and if the user already -- Also checks the size of the area and if the user already
-- has more than max_areas. -- has more than max_areas.
function areas:canPlayerAddArea(pos1, pos2, name) function areas:canPlayerAddArea(pos1, pos2, name)
if minetest.check_player_privs(name, self.adminPrivs) then local privs = minetest.get_player_privs(name)
--return true if privs.areas then
return true
end end
-- Check self protection privilege, if it is enabled, -- Check self protection privilege, if it is enabled,
-- and if the area is too big. -- and if the area is too big.
--[[if (not self.self_protection) or if not self.config.self_protection or
(not minetest.check_player_privs(name, not privs[areas.config.self_protection_privilege] then
{[areas.self_protection_privilege]=true})) then
return false, "Self protection is disabled or you do not have" return false, "Self protection is disabled or you do not have"
.." the necessary privilege." .." the necessary privilege."
end]]-- end
if ((pos2.x - pos1.x) > self.self_protection_max_size.x or local max_size = privs.areas_high_limit and
(pos2.y - pos1.y) > self.self_protection_max_size.y or self.config.self_protection_max_size_high or
(pos2.z - pos1.z) > self.self_protection_max_size.z) self.config.self_protection_max_size
and minetest.get_player_privs(name)["megabuilder"] == false then if
(pos2.x - pos1.x) > max_size.x or
(pos2.y - pos1.y) > max_size.y or
(pos2.z - pos1.z) > max_size.z then
return false, "Area is too big." return false, "Area is too big."
end end
@ -139,8 +141,10 @@ function areas:canPlayerAddArea(pos1, pos2, name)
count = count + 1 count = count + 1
end end
end end
if count >= self.self_protection_max_areas local max_areas = privs.areas_high_limit and
and minetest.get_player_privs(name)["megabuilder"] == false then self.config.self_protection_max_areas_high or
self.config.self_protection_max_areas
if count >= max_areas and minetest.get_player_privs(name)["megabuilder"] == false then
return false, "You have reached the maximum amount of" return false, "You have reached the maximum amount of"
.." areas that you are allowed to protect." .." areas that you are allowed to protect."
end end
@ -149,7 +153,7 @@ function areas:canPlayerAddArea(pos1, pos2, name)
local can, id = self:canInteractInArea(pos1, pos2, name) local can, id = self:canInteractInArea(pos1, pos2, name)
if not can then if not can then
local area = self.areas[id] local area = self.areas[id]
return false, ("The area intersects with %s [%u] owned by %s.") return false, ("The area intersects with %s [%u] (%s).")
:format(area.name, id, area.owner) :format(area.name, id, area.owner)
end end

View File

@ -110,7 +110,7 @@ GetNodeOwnerName = areas.getNodeOwnerName
HasOwner = areas.hasOwner HasOwner = areas.hasOwner
-- This is entirely untested and may break in strange and new ways. -- This is entirely untested and may break in strange and new ways.
if areas.legacy_table then if areas.config.legacy_table then
owner_defs = setmetatable({}, { owner_defs = setmetatable({}, {
__index = function(table, key) __index = function(table, key)
local a = rawget(areas.areas, key) local a = rawget(areas.areas, key)

View File

@ -1,37 +1,43 @@
local worldpath = minetest.get_worldpath() local world_path = minetest.get_worldpath()
local function setting_getbool_default(setting, default) areas.config = {}
local value = minetest.setting_getbool(setting)
local function setting(tp, name, default)
local full_name = "areas."..name
local value
if tp == "boolean" then
value = minetest.setting_getbool(full_name)
elseif tp == "string" then
value = minetest.setting_get(full_name)
elseif tp == "position" then
value = minetest.setting_get_pos(full_name)
elseif tp == "number" then
value = tonumber(minetest.setting_get(full_name))
else
error("Invalid setting type!")
end
if value == nil then if value == nil then
value = default value = default
end end
return value areas.config[name] = value
end end
areas.filename = --------------
minetest.setting_get("areas.filename") or worldpath.."/areas.dat" -- Settings --
--------------
setting("string", "filename", world_path.."/areas.dat")
-- Allow players with a privilege create their own areas -- Allow players with a privilege create their own areas
-- within the max_size and number -- within the maximum size and number.
areas.self_protection = setting("boolean", "self_protection", false)
setting_getbool_default("areas.self_protection", false) setting("string", "self_protection_privilege", "interact")
areas.self_protection_privilege = setting("position", "self_protection_max_size", {x=64, y=128, z=64})
minetest.setting_get("areas.self_protection_privilege") or "interact" setting("number", "self_protection_max_areas", 4)
areas.self_protection_max_size = -- For players with the areas_high_limit privilege.
minetest.setting_get_pos("areas.self_protection_max_size") or setting("position", "self_protection_max_size_high", {x=512, y=512, z=512})
{x=50, y=100, z=50} setting("number", "self_protection_max_areas_high", 32)
areas.self_protection_max_areas =
tonumber(minetest.setting_get("areas.self_protection_max_areas")) or 3
-- Register compatability functions for node_ownership. -- legacy_table (owner_defs) compatibility. Untested and has known issues.
-- legacy_table (owner_defs) compatibility is untested setting("boolean", "legacy_table", false)
-- and can not be used if security_safe_mod_api is on.
areas.legacy_table =
setting_getbool_default("areas.legacy_table", false)
-- Prevent players from punching nodes in a protected area.
-- Usefull for things like delayers, usualy annoying and
-- prevents usage of things like buttons.
areas.protect_punches =
setting_getbool_default("areas.protect_punches", false)