mod.simple_protection: Update to Git commit 5aa2f24

https://github.com/SmallJoker/simple_protection/tree/5aa2f24
This commit is contained in:
Jordan Irwin 2018-07-03 18:38:34 -07:00
parent 061b81fdb6
commit 9c36aead5d
18 changed files with 1069 additions and 542 deletions

View File

@ -89,7 +89,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
* [playeranim][] ([BSD 2-Clause][lic.playeranim]) - version [59bcd38 Git][ver.playeranim] *2017-06-07* ([patched][patch.playeranim]) ***UPDATES***
* [wardrobe][] ([WTFPL][lic.wtfpl]) -- version: [1.1-2-c48b011 Git][ver.wardrobe] *2015-05-21*
* protection/
* [simple_protection][] ([WTFPL][lic.wtfpl]) -- version [2b35fbf Git][ver.simple_protection] *2017-08-31* ***UPDATES***
* [simple_protection][] ([CC0][lic.cc0]) -- version [5aa2f24 Git][ver.simple_protection] *2018-04-29*
* signs/
* [signs_lib][] ([BSD][lic.signs_lib] / [WTFPL][lic.wtfpl]) -- version: [f6b8c94 Git][ver.signs_lib] *2017-08-12* ***UPDATES***
* sound/
@ -460,7 +460,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[ver.rainbow_ore]: https://github.com/FsxShader2012/rainbow_ore/tree/6e77693
[ver.sfinv_buttons]: http://repo.or.cz/minetest_sfinv_buttons.git/tree/4f3b075
[ver.signs_lib]: https://github.com/minetest-mods/signs_lib/tree/f6b8c94
[ver.simple_protection]: https://github.com/SmallJoker/simple_protection/tree/2b35fbf
[ver.simple_protection]: https://github.com/SmallJoker/simple_protection/tree/5aa2f24
[ver.slingshot]: https://github.com/AntumMT/mod-slingshot/tree/bb77525
[ver.snowdrift]: https://github.com/paramat/snowdrift/tree/fcb0537
[ver.spawneggs]: https://github.com/thefamilygrog66/spawneggs/tree/4650370

View File

@ -1,38 +1,63 @@
simple_protection
=================
A Minetest area protection mod
A Minetest area protection mod, based on a fixed claim grid,
like seen in [landrush](https://github.com/Bremaweb/landrush).
You can claim areas by punching those with a claim stick.
Depends: default
![Screenshot](https://raw.githubusercontent.com/SmallJoker/simple_protection/master/screenshot.png)
License: WTFPL
Chat commands:
License: CC0
**Dependencies**
- default: Crafting recipes
**Optional dependencies**
- [intllib](https://github.com/minetest-mods/intllib/): Translations
- [areas](https://github.com/ShadowNinja/areas): HUD compatibility
Features
--------
- Easy, single-click protection
- Fixed claim grid: 16x80x16 by default
- To configure: see `default_settings.lua` header text
- Minimap-like radar to see areas nearby
- Visual area border feedback, as seen in the [protector](https://github.com/tenplus1/protector) mod
- List of claimed areas
- Shared Chest for exchanging items
- Translation support
- Optional setting to require an area before digging
Chat command(s)
--------------
/area <args ..>
show -> Shows up the information about the current area
radar -> Displays and provides information about the areas around you
```
/area <command> [<args> ...]
show -> Provides information about the current area
radar -> Displays a minimap-like area overview
share <name> -> Shares the current area with <name>
unshare <name> -> Unshares the current area with <name>
shareall <name> -> Shares all your areas with <name>
unshareall <name> -> Unshares all your areas with <name>
list [<name>] -> Lists all areas (<name> is optional)
list [<name>] -> Lists all areas (optional <name>)
unclaim -> Unclaims the current area
delete <name> -> Removes all areas of <name> (requires "server" privilege)
```
About /area show:
-----------------
Area status: Not claimable -> By default, it's not possible to claim areas in the underground
About "/area show"
------------------
Area status: Not claimable
- Shown when the area can not be claimed
- Happens (by default) in the underground
Players with access: foo, bar*, leprechaun, *all
^ foo, leprechaun: A regular /area share, only for this area
^ bar*: All areas with this owner are shared with that player
^ *all: Everybody can build and dig in the area
- foo, leprechaun: Regular single area share
- bar*: Has access to all areas with the same owner
- *all: Everybody can build and dig in the area

View File

@ -0,0 +1,80 @@
local S = s_protect.gettext
-- A shared chest for simple_protection but works with other protection mods too
local function get_item_count(pos, player, count)
local name = player and player:get_player_name()
if not name or minetest.is_protected(pos, name) then
return 0
end
return count
end
local tex_mod = "^[colorize:#FF2:50"
minetest.register_node("simple_protection:chest", {
description = S("Shared Chest") .. " " .. S("(by protection)"),
tiles = {
"default_chest_top.png" .. tex_mod,
"default_chest_top.png" .. tex_mod,
"default_chest_side.png" .. tex_mod,
"default_chest_side.png" .. tex_mod,
"default_chest_side.png" .. tex_mod,
"default_chest_lock.png" .. tex_mod
},
paramtype2 = "facedir",
sounds = default.node_sound_wood_defaults(),
groups = {choppy = 2, oddly_breakable_by_hand = 2},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Shared Chest"))
meta:set_string("formspec",
"size[8,9]" ..
default.gui_bg ..
default.gui_bg_img ..
"list[context;main;0,0.3;8,4;]" ..
"list[current_player;main;0,5;8,4;]" ..
"listring[context;main]" ..
"listring[current_player;main]"
)
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
end,
can_dig = function(pos, player)
return minetest.get_meta(pos):get_inventory():is_empty("main")
end,
on_blast = function() end,
allow_metadata_inventory_put = function(pos, fl, fi, stack, player)
return get_item_count(pos, player, stack:get_count())
end,
allow_metadata_inventory_take = function(pos, fl, fi, stack, player)
return get_item_count(pos, player, stack:get_count())
end,
allow_metadata_inventory_move = function(pos, fl, fi, tl, ti, count, player)
return get_item_count(pos, player, count)
end,
on_metadata_inventory_put = function(pos, fl, fi, stack, player)
minetest.log("action", player:get_player_name()
.. " moves " .. stack:get_name() .. " to shared chest at "
.. minetest.pos_to_string(pos))
end,
on_metadata_inventory_take = function(pos, fl, fi, stack, player)
minetest.log("action", player:get_player_name()
.. " takes " .. stack:get_name() .. " from shared chest at "
.. minetest.pos_to_string(pos))
end,
-- on_metadata_inventory_move logging is redundant: Same chest contents
})
minetest.register_craft({
type = "shapeless",
output = "simple_protection:shared_chest",
recipe = { "simple_protection:claim", "default:chest_locked" }
})
minetest.register_craft({
type = "shapeless",
output = "simple_protection:shared_chest",
recipe = { "simple_protection:claim", "default:chest" }
})

View File

@ -0,0 +1,281 @@
local S = s_protect.gettext
local commands = {}
function s_protect.register_subcommand(name, func)
if commands[name] then
minetest.log("info", "[simple_protection] Overwriting chat command " .. name)
end
assert(#name:split(" ") == 1, "Invalid name")
assert(type(func) == "function")
commands[name] = func
end
minetest.register_chatcommand("area", {
description = S("Manages all of your areas."),
privs = {interact = true},
func = function(name, param)
if param == "" or param == "help" then
local function chat_send(desc, cmd)
minetest.chat_send_player(name, S(desc) .. ": "
.. minetest.colorize("#0FF", cmd))
end
local privs = minetest.get_player_privs(name)
minetest.chat_send_player(name, minetest.colorize("#0F0",
"=> " .. S("Available area commands")))
chat_send("Information about this area", "/area show")
chat_send("View of surrounding areas", "/area radar")
chat_send("(Un)share one area", "/area (un)share <name>")
chat_send("(Un)share all areas", "/area (un)shareall <name>")
if s_protect.area_list or privs.simple_protection then
chat_send("List claimed areas", "/area list [<name>]")
end
chat_send("Unclaim this area", "/area unclaim")
if privs.server then
chat_send("Delete all areas of a player", "/area delete <name>")
end
return
end
local args = param:split(" ", 2)
local func = commands[args[1]]
if not func then
return false, S("Unknown command parameter: @1. Check '/area' for correct usage.", args[1])
end
return func(name, args[2])
end,
})
s_protect.register_subcommand("show", function(name, param)
print(param)
local player = minetest.get_player_by_name(name)
local player_pos = player:get_pos()
local data = s_protect.get_claim(player_pos)
minetest.add_entity(s_protect.get_center(player_pos), "simple_protection:marker")
local minp, maxp = s_protect.get_area_bounds(player_pos)
minetest.chat_send_player(name, S("Vertical area limit from Y @1 to @2",
tostring(minp.y), tostring(maxp.y)))
if not data then
if s_protect.underground_limit and minp.y < s_protect.underground_limit then
return true, S("Area status: @1", S("Not claimable"))
end
return true, S("Area status: @1", S("Unowned (!)"))
end
minetest.chat_send_player(name, S("Area status: @1", S("Owned by @1", data.owner)))
local text = ""
for i, player in ipairs(data.shared) do
text = text..player..", "
end
local shared = s_protect.share[data.owner]
if shared then
for i, player in ipairs(shared) do
text = text..player.."*, "
end
end
if text ~= "" then
return true, S("Players with access: @1", text)
end
end)
local function check_ownership(name)
local player = minetest.get_player_by_name(name)
local data, index = s_protect.get_claim(player:get_pos())
if not data then
return false, S("This area is not claimed yet.")
end
local priv = minetest.check_player_privs(name, {simple_protection=true})
if name ~= data.owner and not priv then
return false, S("You do not own this area.")
end
return true, data, index
end
s_protect.register_subcommand("share", function(name, param)
if not param or name == param then
return false, S("No player name given.")
end
if not minetest.builtin_auth_handler.get_auth(param) and param ~= "*all" then
return false, S("Unknown player.")
end
local success, data, index = check_ownership(name)
if not success then
return success, data
end
local shared = s_protect.share[name]
if shared and shared[param] then
return true, S("@1 already has access to all your areas.", param)
end
if table_contains(data.shared, param) then
return true, S("@1 already has access to this area.", param)
end
table.insert(data.shared, param)
s_protect.set_claim(data, index)
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 shared an area with you.", name))
end
return true, S("@1 has now access to this area.", param)
end)
s_protect.register_subcommand("unshare", function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
local success, data, index = check_ownership(name)
if not success then
return success, data
end
if not table_contains(data.shared, param) then
return true, S("That player has no access to this area.")
end
table_erase(data.shared, param)
s_protect.set_claim(data, index)
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 unshared an area with you.", name))
end
return true, S("@1 has no longer access to this area.", param)
end)
s_protect.register_subcommand("shareall", function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
if not minetest.builtin_auth_handler.get_auth(param) then
if param == "*all" then
return false, S("You can not share all your areas with everybody.")
end
return false, S("Unknown player.")
end
local shared = s_protect.share[name]
if table_contains(shared, param) then
return true, S("@1 already has now access to all your areas.", param)
end
if not shared then
s_protect.share[name] = {}
end
table.insert(s_protect.share[name], param)
s_protect.save_share_db()
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 shared all areas with you.", name))
end
return true, S("@1 has now access to all your areas.", param)
end)
s_protect.register_subcommand("unshareall", function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
local removed = false
local shared = s_protect.share[name]
if table_erase(shared, param) then
removed = true
s_protect.save_share_db()
end
-- Unshare each single claim
local claims = s_protect.get_player_claims(name)
for index, data in pairs(claims) do
if table_erase(data.shared, param) then
removed = true
end
end
if not removed then
return false, S("@1 does not have access to any of your areas.", param)
end
s_protect.update_claims(claims)
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 unshared all areas with you.", name))
end
return true, S("@1 has no longer access to your areas.", param)
end)
s_protect.register_subcommand("unclaim", function(name)
local success, data, index = check_ownership(name)
if not success then
return success, data
end
if s_protect.claim_return and name == data.owner then
local player = minetest.get_player_by_name(name)
local inv = player:get_inventory()
if inv:room_for_item("main", "simple_protection:claim") then
inv:add_item("main", "simple_protection:claim")
end
end
s_protect.set_claim(nil, index)
return true, S("This area is unowned now.")
end)
s_protect.register_subcommand("delete", function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
if not minetest.check_player_privs(name, {server=true}) then
return false, S("Missing privilege: @1", "server")
end
local removed = {}
if s_protect.share[param] then
s_protect.share[param] = nil
table.insert(removed, S("Globally shared areas"))
s_protect.save_share_db()
end
-- Delete all claims
local claims, count = s_protect.get_player_claims(param)
for index in pairs(claims) do
claims[index] = false
end
s_protect.update_claims(claims)
if count > 0 then
table.insert(removed, S("@1 claimed area(s)", tostring(count)))
end
if #removed == 0 then
return false, S("@1 does not own any claimed areas.", param)
end
return true, S("Removed")..": "..table.concat(removed, ", ")
end)
s_protect.register_subcommand("list", function(name, param)
local has_sp_priv = minetest.check_player_privs(name, {simple_protection=true})
if not s_protect.area_list and not has_sp_priv then
return false, S("This command is not available.")
end
if not param or param == "" then
param = name
end
if not has_sp_priv and param ~= name then
return false, S("Missing privilege: @1", "simple_protection")
end
local list = {}
local width = s_protect.claim_size
local height = s_protect.claim_height
local claims = s_protect.get_player_claims(param)
for index in pairs(claims) do
-- TODO: Add database-specific function to convert the index to a position
local abs_pos = minetest.string_to_pos(index)
table.insert(list, string.format("%5i,%5i,%5i",
abs_pos.x * width + (width / 2),
abs_pos.y * height - s_protect.start_underground + (height / 2),
abs_pos.z * width + (width / 2)
))
end
local text = S("Listing all areas of @1. Amount: @2", param, tostring(#list))
return true, text.."\n"..table.concat(list, "\n")
end)

View File

@ -0,0 +1,130 @@
--[[
File: database_raw.lua
lSQLite database functions:
load_db()
save_share_db()
get_claim(<pos or index>, direct access)
set_claim(data, index)
get_player_claims(player name)
update_claims(claims table)
]]
local worldpath = minetest.get_worldpath()
local ie = minetest.request_insecure_environment()
if not ie then
error("Cannot access insecure environment!")
end
local sql = ie.require("lsqlite3")
-- Remove public table
if sqlite3 then
sqlite3 = nil
end
local db = sql.open(worldpath .. "/s_protect.sqlite3")
local function sql_exec(q)
if db:exec(q) ~= sql.OK then
minetest.log("info", "[simple_protection] lSQLite: " .. db:errmsg())
end
end
local function sql_row(q)
q = q .. " LIMIT 1;"
for row in db:nrows(q) do
return row
end
end
sql_exec([[
CREATE TABLE IF NOT EXISTS claims (
id INTEGER PRIMARY KEY AUTOINCREMENT,
x INTEGER,
y INTEGER,
z INTEGER,
owner TEXT,
shared TEXT,
data TEXT
);
CREATE TABLE IF NOT EXISTS shares (
id INTEGER PRIMARY KEY AUTOINCREMENT,
owner TEXT,
shared TEXT,
data TEXT
);
]])
function s_protect.load_db() end
function s_protect.load_shareall() end
function s_protect.save_share_db() end
function s_protect.set_claim(cpos, claim)
local id, row = s_protect.get_claim(cpos)
if not claim then
if not id then
-- Claim never existed
return
end
-- Remove claim
sql_exec(
("DELETE FROM claims WHERE id = %i LIMIT 1;"):format(id)
)
end
if id then
local vals = {}
for k, v in pairs(claim) do
if row[k] ~= v and type(v) == "string" then
vals[#vals + 1] = ("%s = `%s`"):format(k, v)
end
end
if #vals == 0 then
return
end
sql_exec(
("UPDATE claims SET %s WHERE id = %i LIMIT 1;")
:format(table.concat(vals, ","), id)
)
else
sql_exec(
("INSERT INTO claims VALUES (%i, %i, %i, %s, %s, %s);")
:format(pos.x, pos.y, pos.z, claim.owner,
claim.shared or "", claim.data or "")
)
end
end
function s_protect.get_claim(cpos)
local q
if type(pos) == "number" then
-- Direct index
q = "id = " .. cpos
else
q = ("x = %i AND y = %i AND z = %z"):format(cpos.x, cpos.y, cpos.z)
end
local row = sql_row("SELECT id, owner, shared, data FROM claims WHERE " .. q)
if not row then
return
end
local id = row.id
row.id = nil
return id, row
end
function s_protect.get_player_claims(owner)
local q = ("SELECT * FROM claims WHERE owner = %s;"):format(owner)
local vals = {}
for row in db:nrows(q) do
vals[#vals + 1] = row
end
return vals
end
function s_protect.update_claims(updated)
error("Inefficient. To be removed.")
end

View File

@ -0,0 +1,165 @@
--[[
File: database_raw.lua
Raw text format database functions:
load_db()
save_share_db()
get_claim(<pos or index>, direct access)
set_claim(data, index)
get_player_claims(player name)
update_claims(claims table)
minetest.safe_file_write compatibility code
]]
local claim_data = {}
local claim_db = { time = os.time(), dirty = false }
local share_db = { time = os.time(), dirty = false }
function s_protect.load_db()
-- Don't forget the "parties"
s_protect.load_shareall()
local file = io.open(s_protect.file, "r")
if not file then
return
end
for line in file:lines() do
if line ~= "" then
local data = line:split(" ")
-- Line format: pos, owner, shared_player, shared_player2, ..
local _shared = {}
if #data > 2 then
for index = 3, #data do
if data[index] ~= "" then
table.insert(_shared, data[index])
end
end
end
claim_data[data[1]] = {owner=data[2], shared=_shared}
end
end
io.close(file)
minetest.log("action", "[simple_protection] Loaded claim data")
end
function s_protect.load_shareall()
local file = io.open(s_protect.sharefile, "r")
if not file then
return
end
for line in file:lines() do
if line ~= "" then
local data = line:split(" ")
-- Line format: owner, shared_player, shared_player2, ..
local _shared = {}
if #data > 1 then
for index = 2, #data do
if data[index] ~= "" then
table.insert(_shared, data[index])
end
end
s_protect.share[data[1]] = _shared
end
end
end
io.close(file)
minetest.log("action", "[simple_protection] Loaded shared claims")
end
-- <= 0.4.16 compatibility
local function write_file(path, content)
local file = io.open(path, "w")
file:write(content)
io.close(file)
end
-- Superior function
if minetest.safe_file_write then
write_file = minetest.safe_file_write
end
local function delay(db_info, func)
local dtime = os.time() - db_info.time
if dtime < 6 then
-- Excessive save requests. Delay them.
if not db_info.dirty then
minetest.after(6 - dtime, func)
end
db_info.dirty = true
return true
end
db_info.time = os.time()
db_info.dirty = false
end
local function save_claims()
if delay(claim_db, save_claims) then
return
end
local contents = {}
for pos, data in pairs(claim_data) do
if data.owner and data.owner ~= "" then
contents[#contents + 1] =
pos .. " ".. data.owner .. " " ..
table.concat(data.shared, " ")
end
end
write_file(s_protect.file, table.concat(contents, "\n"))
end
function s_protect.save_share_db()
if delay(share_db, s_protect.save_share_db) then
return
end
-- Save globally shared areas
local contents = {}
for name, players in pairs(s_protect.share) do
if #players > 0 then
contents[#contents + 1] = name .. " " ..
table.concat(players, " ")
end
end
write_file(s_protect.sharefile, table.concat(contents, "\n"))
end
-- Speed up the function access
local get_location = s_protect.get_location
function s_protect.get_claim(pos, direct_access)
if direct_access then
return claim_data[pos], pos
end
local pos = get_location(pos)
local index = pos.x..","..pos.y..","..pos.z
return claim_data[index], index
end
function s_protect.set_claim(data, index)
claim_data[index] = data
save_claims()
end
function s_protect.get_player_claims(owner)
local count = 0
local claims = {}
for index, data in pairs(claim_data) do
if data.owner == owner then
claims[index] = data
count = count + 1
end
end
return claims, count
end
function s_protect.update_claims(updated)
for index, data in pairs(updated) do
if not data then
claim_data[index] = nil
else
claim_data[index] = data
end
end
save_claims()
end

View File

@ -14,27 +14,23 @@ simple_protection/default_settings.lua
-- Width and length of claims in nodes
-- !! Disorts the claims locations' along the X and Z axis !!
-- !! Distorts the claim locations along the X and Z axis !!
-- Type: Integer, positive, even number
s_protect.claim_size = 16
-- Height of claims in nodes
-- !! Disorts the claims locations' along the Y axis !!
-- !! Distorts the claim locations along the Y axis !!
-- Type: Integer, positive
s_protect.claim_height = 80
s_protect.claim_height = 150
-- Defines the Y offset where the 0th claim should start in the underground
-- Example of claim (0,0,0): Ymin = -[20], Ymax = 80 - [20] = 60
-- Example of claim (0,0,0): Ymin = -(50) = -50, Ymax = 150 - (50) - 1 = 99
-- Type: Integer
s_protect.start_underground = 20
-- When set to 'true': Allows very deep underground claiming
-- Will make the protection mod to ignore 's_protect.underground_limit'
-- Type: Boolean
s_protect.underground_claim = false
s_protect.start_underground = 50
-- Only allows claiming above this Y value
-- Type: Integer
-- To disable this limit, set the value to 'nil'
-- Type: Integer or nil
s_protect.underground_limit = -300
-- Returns the claim stick when unclaiming the area
@ -42,8 +38,8 @@ s_protect.underground_limit = -300
s_protect.claim_return = true
-- Players will need to claim the area (or have access to it) to dig
-- Digging will be still allowed in the underground when
-- 's_protect.underground_claim == false'
-- Digging will be still allowed in the underground,
-- as defined by the setting 's_protect.underground_limit'
-- Type: Boolean
s_protect.claim_to_dig = false
@ -52,8 +48,7 @@ s_protect.claim_to_dig = false
s_protect.area_list = true
-- Limits the amount of claims per player
-- For values < 10: Open [world_path]/world.mt and modify
-- the setting value of 'load_mod_simple_protection' to 'false'
-- This value is doubled for users with the 'simple_protection' privilege
-- For values < 10: Stop this nonsense
-- Doubled limit for players with the 'simple_protection' privilege
-- Type: Integer
s_protect.max_claims = 100
s_protect.max_claims = 200

View File

@ -1,2 +1,3 @@
default
intllib?
areas?

View File

@ -0,0 +1,90 @@
--[[
File: hud.lua
areas HUD overlap compatibility
HUD display and refreshing
]]
local S = s_protect.gettext
s_protect.player_huds = {}
local hud_time = 0
local prefix = ""
local align_x = 1
local pos_x = 0.02
if minetest.get_modpath("areas") then
prefix = "Simple Protection:\n"
align_x = -1
pos_x = 0.95
end
local function generate_hud(player, current_owner, has_access)
-- green if access
local color = 0xFFFFFF
if has_access then
color = 0x00CC00
end
s_protect.player_huds[player:get_player_name()] = {
hudID = player:hud_add({
hud_elem_type = "text",
name = "area_hud",
number = color,
position = {x=pos_x, y=0.98},
text = prefix
.. S("Area owner: @1", current_owner),
scale = {x=100, y=25},
alignment = {x=align_x, y=-1},
}),
owner = current_owner,
had_access = has_access
}
end
minetest.register_globalstep(function(dtime)
hud_time = hud_time + dtime
if hud_time < 2.9 then
return
end
hud_time = 0
local shared = s_protect.share
for _, player in ipairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local current_owner = ""
local data = s_protect.get_claim(player:get_pos())
if data then
current_owner = data.owner
end
local has_access = (current_owner == player_name)
if not has_access and data then
-- Check if this area is shared with this player
has_access = table_contains(data.shared, player_name)
end
if not has_access then
-- Check if all areas are shared with this player
has_access = table_contains(shared[current_owner], player_name)
end
local changed = true
local hud_table = s_protect.player_huds[player_name]
if hud_table and hud_table.owner == current_owner
and hud_table.had_access == has_access then
-- still the same hud
changed = false
end
if hud_table and changed then
player:hud_remove(hud_table.hudID)
s_protect.player_huds[player_name] = nil
end
if current_owner ~= "" and changed then
generate_hud(player, current_owner, has_access)
end
end
end)

View File

@ -1,16 +1,18 @@
-- Based on ideas of the LandRush mod
-- Created by Krock
-- License: WTFPL
--[[
File: init.lua
Initialisations
Module loading
Glue
]]
local world_path = minetest.get_worldpath()
s_protect = {}
s_protect.claims = {}
s_protect.share = {}
s_protect.mod_path = minetest.get_modpath("simple_protection")
s_protect.conf = world_path.."/s_protect.conf"
s_protect.file = world_path.."/s_protect.data"
s_protect.sharefile = world_path.."/s_protect_share.data"
s_protect.store = false -- AreaStore support
-- INTTLIB SUPPORT START
s_protect.gettext = function(rawtext, replacements, ...)
@ -31,279 +33,16 @@ end
local S = s_protect.gettext
-- INTTLIB SUPPORT END
dofile(s_protect.mod_path.."/functions.lua")
s_protect.load_config()
dofile(s_protect.mod_path.."/protection.lua")
dofile(s_protect.mod_path.."/radar.lua")
minetest.register_privilege("simple_protection", S("Allows to modify and delete protected areas"))
minetest.register_chatcommand("area", {
description = S("Manages all of your areas."),
privs = {interact = true},
func = function(name, param)
if param == "" or param == "help" then
local function chat_send(text, raw_text)
if raw_text then
raw_text = ": "..raw_text
end
minetest.chat_send_player(name, S(text)..(raw_text or ""))
end
local privs = minetest.get_player_privs(name)
chat_send("Available area commands:")
chat_send("Information about this area", "/area show")
chat_send("View of surrounding areas", " /area radar")
chat_send("(Un)share one area", " /area (un)share <name>")
chat_send("(Un)share all areas", " /area (un)shareall <name>")
if s_protect.area_list or privs.simple_protection then
chat_send("List claimed areas", " /area list [<name>]")
end
chat_send("Unclaim this area", " /area unclaim")
if privs.server then
chat_send("Delete all areas of a player", "/area delete <name>")
end
return
end
dofile(s_protect.mod_path.."/misc_functions.lua")
s_protect.load_config()
local args = param:split(" ")
local func = s_protect["command_"..args[1]]
if not func then
return false, S("Unknown command parameter: @1. Check '/area' for correct usage.", args[1])
end
dofile(s_protect.mod_path.."/command_mgr.lua")
dofile(s_protect.mod_path.."/database_raw.lua")
minetest.after(0.5, s_protect.load_db)
return func(name, args[2])
end,
})
s_protect.command_show = function(name)
local player = minetest.get_player_by_name(name)
local player_pos = vector.round(player:getpos())
local data = s_protect.get_data(player_pos)
minetest.add_entity(s_protect.get_center(player_pos), "simple_protection:marker")
local minp, maxp = s_protect.get_area_bounds(player_pos)
minetest.chat_send_player(name, S("Vertical area limit from Y @1 to @2",
tostring(minp.y), tostring(maxp.y)))
if not data then
if minp.y < s_protect.underground_limit then
return true, S("Area status: @1", S("Not claimable"))
end
return true, S("Area status: @1", S("Unowned (!)"))
end
minetest.chat_send_player(name, S("Area status: @1", S("Owned by @1", data.owner)))
local text = ""
for i, player in ipairs(data.shared) do
text = text..player..", "
end
local shared = s_protect.share[data.owner]
if shared then
for i, player in ipairs(shared) do
text = text..player.."*, "
end
end
if text ~= "" then
return true, S("Players with access: @1", text)
end
end
s_protect.command_share = function(name, param)
if not param or name == param then
return false, S("No player name given.")
end
if not minetest.auth_table[param] and param ~= "*all" then
return false, S("Unknown player.")
end
local player = minetest.get_player_by_name(name)
local data = s_protect.get_data(player:getpos())
if not data then
return false, S("This area is not claimed yet.")
end
if name ~= data.owner and not minetest.check_player_privs(name, {s_protect=true}) then
return false, S("You do not own this area.")
end
local shared = s_protect.share[name]
if shared and shared[param] then
return true, S("@1 already has access to all your areas.", param)
end
if table_contains(data.shared, param) then
return true, S("@1 already has access to this area.", param)
end
table.insert(data.shared, param)
s_protect.save()
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 shared an area with you.", name))
end
return true, S("@1 has now access to this area.", param)
end
s_protect.command_unshare = function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
local player = minetest.get_player_by_name(name)
local data = s_protect.get_data(player:getpos())
if not data then
return false, S("This area is not claimed yet.")
end
if name ~= data.owner and not minetest.check_player_privs(name, {simple_protection=true}) then
return false, S("You do not own this area.")
end
if not table_contains(data.shared, param) then
return true, S("That player has no access to this area.")
end
table_delete(data.shared, param)
s_protect.save()
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 unshared an area with you.", name))
end
return true, S("@1 has no longer access to this area.", param)
end
s_protect.command_shareall = function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
if not minetest.auth_table[param] then
if param == "*all" then
return false, S("You can not share all your areas with everybody.")
end
return false, S("Unknown player.")
end
local shared = s_protect.share[name]
if table_contains(shared, param) then
return true, S("@1 already has now access to all your areas.", param)
end
if not shared then
s_protect.share[name] = {}
end
table.insert(s_protect.share[name], param)
s_protect.save()
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 shared all areas with you.", name))
end
return true, S("@1 has now access to all your areas.", param)
end
s_protect.command_unshareall = function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
local removed = false
local shared = s_protect.share[name]
if table_delete(shared, param) then
removed = true
end
-- Unshare each single claim
for pos, data in pairs(s_protect.claims) do
if data.owner == name then
if table_delete(data.shared, param) then
removed = true
end
end
end
if not removed then
return false, S("@1 does not have access to any of your areas.", param)
end
s_protect.save()
if minetest.get_player_by_name(param) then
minetest.chat_send_player(param, S("@1 unshared all areas with you.", name))
end
return true, S("@1 has no longer access to your areas.", param)
end
s_protect.command_unclaim = function(name)
local player = minetest.get_player_by_name(name)
local data, pos = s_protect.get_data(player:getpos())
if not data then
return false, S("You do not own this area.")
end
local priv = minetest.check_player_privs(name, {simple_protection=true})
if name ~= data.owner and not priv then
return false, S("You do not own this area.")
end
if s_protect.claim_return and name == data.owner then
local inv = player:get_inventory()
if inv:room_for_item("main", "simple_protection:claim") then
inv:add_item("main", "simple_protection:claim")
end
end
s_protect.claims[pos] = nil
s_protect.save()
return true, S("This area is unowned now.")
end
s_protect.command_delete = function(name, param)
if not param or name == param or param == "" then
return false, S("No player name given.")
end
if not minetest.check_player_privs(name, {server=true}) then
return false, S("Missing privilege: @1", "server")
end
local removed = {}
if s_protect.share[param] then
s_protect.share[param] = nil
table.insert(removed, S("Globally shared areas"))
end
-- Delete all claims
local counter = 0
local claims = s_protect.claims
for pos, data in pairs(claims) do
if data.owner == param then
claims[pos] = nil
counter = counter + 1
end
end
if counter > 0 then
table.insert(removed, S("@1 claimed area(s)", tostring(counter)))
end
if #removed == 0 then
return false, S("@1 does not own any claimed areas.", param)
end
s_protect.save()
return true, S("Removed")..": "..table.concat(removed, ", ")
end
s_protect.command_list = function(name, param)
local has_sp_priv = minetest.check_player_privs(name, {simple_protection=true})
if not s_protect.area_list and not has_sp_priv then
return false, S("This command is not available.")
end
if not param or param == "" then
param = name
end
if not has_sp_priv and param ~= name then
return false, S("Missing privilege: @1", "simple_protection")
end
local list = {}
local width = s_protect.claim_size
local height = s_protect.claim_height
for pos, data in pairs(s_protect.claims) do
if data.owner == param then
local abs_pos = minetest.string_to_pos(pos)
table.insert(list, string.format("%5i,%5i,%5i",
abs_pos.x * width + (width / 2),
abs_pos.y * height - s_protect.start_underground + (height / 2),
abs_pos.z * width + (width / 2)
))
end
end
local text = S("Listing all areas of @1. Amount: @2", param, tostring(#list))
return true, text.."\n"..table.concat(list, "\n")
end
dofile(s_protect.mod_path.."/protection.lua")
dofile(s_protect.mod_path.."/hud.lua")
dofile(s_protect.mod_path.."/radar.lua")
dofile(s_protect.mod_path.."/chest.lua")

View File

@ -10,10 +10,10 @@ Allows to modify and delete protected areas = Erlaubt das Abaendern und Entferne
Manages all of your areas. = Verwaltet alle deine geschuetzten Gebiete
# /area
Available area commands:
Information about this area = Informationen ueber dieses Gebiet:
(Un)share one area = Eine Zugriffs-Berechtigung eines Gebietes hinzufuegen/entfernen
(Un)share all areas = Eine Zugriffs-Berechtigung fuer alle Gebiete hinzufuegen/entfernen
Available area commands = Verfuegbare 'area' Befehle
Information about this area = Informationen ueber dieses Gebiet
(Un)share one area = Zugriffs-Berechtigung eines Gebietes hinzufuegen/entfernen
(Un)share all areas = Zugriffs-Berechtigung fuer alle Gebiete hinzufuegen/entfernen
List claimed areas = Geschuetzte Gebiete auflisten
Delete all areas of a player = Alle Gebiete eines Spielers loeschen
Unclaim this area = Den Schutz fuer dieses Gebiet aufheben
@ -33,6 +33,16 @@ Unowned (!) = Nicht geschuetzt (!)
Owned by @1 = Von @1 geschuetzt
Players with access: @1 = Spieler mit Zugriff: @1
# /area radar
North @1 = Nord @1
East @1 = Ost @1
South @1 = Sued @1
West @1 = West @1
Your position = Deine Position
Your area = Dein Gebiet
Area claimed\nNo access for you = Gebiet geschuetzt\nKeine Berechtigung
Access for everybody = Zugriff fuer jeden
# /area share <name>
@1 already has access to all your areas. = @1 hat bereits Zugriff auf alle deine Gebiete.
@1 already has access to this area. = @1 hat bereits Zugriff auf dieses Gebiet.
@ -78,10 +88,17 @@ Area owned by: @1 = Gebiet geschuetzt durch: @1
Area owner: @1 = Gebiets-Besitzer: @1
# Item: Claim stick
Claim stick = Gebiets-Besetzer-Tool
Claim Stick = Gebietsschutz
#(click to protect) = (kicken zum schuetzen)
This area is already protected by an other protection mod. = Dieses Gebiet ist bereits durch eine andere Mod geschuetzt.
You can not claim areas below @1. = Du kannst keine Gebiete unterhalb von @1 schuetzen.
This area is already owned by: @1 = @1 besitzt dieses Gebiet bereits.
Congratulations! You now own this area. = Glueckwunsch! Du besitzt dieses Gebiet jetzt.
You can not claim any further areas: Limit (@1) reached. = Du kannst keine weiteren Gebiete schuetzen lassen: Limit (@1) erreicht.
Please claim this area to modify it. = Bitte schuetze das Gebiet um dieses abaendern zu koennen.
#### Shared Chest ####
Shared Chest = Geteilte Truhe
(by protection) = (durch Gebietsschutz)

View File

@ -0,0 +1,106 @@
# Translated by: <d-stephane>
# Privilege description
Allows to modify and delete protected areas = Permet de modifier et supprimer des zones protégées
#### AREA COMMAND ####
# Command description
Manages all of your areas. = Gestion de toutes vos zones.
# /area
Available area commands = Commandes de zone disponibles
Information about this area = Informations sur cette zone
(Un)share one area = Partager (ou pas) une zone
(Un)share all areas = Partager (ou pas) toutes les zones
List claimed areas = Liste des zones revendiquées
Delete all areas of a player = Supprimer toutes les zones d'un joueur
Unclaim this area = Libérer cette zone
# Errors of /area
Unknown command parameter: @1. Check '/area' for correct usage. = Paramètre de commande inconnu : @1. Tappez '/area' pour voir les paramètres possible.
No player name given. = Aucun nom de joueur donné.
Unknown player. = Joueur inconnu.
This area is not claimed yet. = Cette zone n'est pas encore revendiquée.
You do not own this area. = Vous ne possédez pas cette zone.
# /area show
Vertical area limit from Y @1 to @2 = Limite verticale de zone pour Y @1 à @2
Area status: @1 = Statut de la zone : @1
Not claimable = Non revendiquable
Unowned (!) = Pas de propriétaire (!)
Owned by @1 = Possédée par @1
Players with access: @1 = Joueurs avec accès : @1
# /area radar
North @1 = Nord @1
East @1 = Est @1
South @1 = Sud @1
West @1 = Ouest @1
Your position = Votre position
Your area = Votre zone
Area claimed\nNo access for you = Zone revendiquée\nNon accessible pour vous
Access for everybody = Accès pour tout le monde
One area unit (@1m) up/down\n-> no claims on this Y level = Une unité de zone (@1m) haut/bas\n-> Rien de revendiqué à ce niveau Y
square \= 1 area \= @1x@2x@3 nodes (X,Y,Z) = carré \= 1 zone \= @1x@2x@3 blocs (X,Y,Z)
# /area share <name>
@1 already has access to all your areas. = @1 a déjà accès à toutes vos zones.
@1 already has access to this area. = @1 a déjà accès à cette zone.
@1 shared an area with you. = @1 a partagé une zone avec vous.
@1 has now access to this area. = @1 a maintenant accès à cette zone.
# /area unshare <name>
That player has no access to this area. = Ce joueur n'a pas accès à cette zone.
@1 unshared an area with you. = @1 a enlevé le partage de la zone avec vous.
@1 has no longer access to this area. = @1 n'a plus accès à cette zone.
# /area shareall <name>
You can not share all your areas with everybody. = Vous ne pouvez pas partager toutes vos zones avec tout le monde.
@1 already has now access to all your areas. = @1 a déjà accès à toutes vos zones.
@1 shared all areas with you. = @1 a partagé toutes les zones avec vous.
@1 has now access to all your areas. = @1 a maintenant accès à toutes vos zones.
# /area unshareall <name>
@1 does not have access to any of your areas. = @1 n'a accès à aucune de vos zones.
@1 unshared all areas with you. = @1 a enlevé le partage de toutes les zones avec vous.
@1 has no longer access to your areas. = @1 n'a plus accès à vos zones.
# /area unclaim
This area is unowned now. = Cette zone n'est plus revendiquée.
# /area delete <name>
Missing privilege: @1 = Privilège manquant : @1
Removed = Supprimé
Globally shared areas = Zones partagées globalement
@1 claimed area(s) = @1 a revendiqué des zones
@1 does not own any claimed areas. = @1 ne possède aucune zone revendiquée.
# /area list [name]
This command is not available. = Cette commande n'est pas disponible.
Listing all areas of @1. Amount: @2 = Liste de tous les zones de @1. Total : @2
#### Protection ####
# Item place information
Area owned by: @1 = Zone appartenant à : @1
# Hud text
Area owner: @1 = Propriétaire de la zone : @1
# Item: Claim stick
Claim Stick = Bâton de protection
(click to protect) = (cliquez pour protéger)
This area is already protected by an other protection mod. = Cette zone est déjà protégée par un autre mod de protection.
You can not claim areas below @1. = Vous ne pouvez pas revendiquer les zones ci-dessous @1.
This area is already owned by: @1 = Cette zone est déjà détenue par : @1.
Congratulations! You now own this area. = Félicitations ! Vous possédez maintenant cette zone.
You can not claim any further areas: Limit (@1) reached. = Vous ne pouvez pas revendiquer d'autres zones : La limite de @1 a été atteinte.
Please claim this area to modify it. = Veuillez revendiquer cette zone pour la modifier.
#### Shared Chest ####
Shared Chest = Coffre partagé
(by protection) = (par protection)

View File

@ -10,7 +10,7 @@ Allows to modify and delete protected areas = Permitir modificar e deletar areas
Manages all of your areas. = Gerencia todas as suas areas.
# /area
Available area commands: = Comandos disponiveis:
Available area commands = Comandos disponiveis
Information about this area = Dados sobre essa area
(Un)share one area = (Des)compartilha uma area
(Un)share all areas = (Des)compartilha todas areas
@ -33,6 +33,16 @@ Unowned (!) = Sem dono (!)
Owned by @1 = Reivindicada por @1
Players with access: @1 = Jogadores com acesso: @1
# /area radar
#North @1 =
#East @1 =
#South @1 =
#West @1 =
#Your position =
#Your area =
#Area claimed\nNo access for you =
#Access for everybody =
# /area share <name>
@1 already has access to all your areas. = @1 ja possui acesso a todas suas areas.
@1 already has access to this area. = @1 ja possui acesso a essa area.
@ -78,10 +88,17 @@ Area owned by: @1 = Area possuida por: @1
Area owner: @1 = Area de: @1
# Item: Claim stick
Claim stick = Graveto Reivindicador
Claim Stick = Graveto Reivindicador
#(click to protect) =
This area is already protected by an other protection mod. = Essa area ja foi protegida por um outro mod protetor.
You can not claim areas below @1. = Nao podes reivindicar areas abaixo @1.
This area is already owned by: @1 = Essa area ja foi reivindicada por: @1.
Congratulations! You now own this area. = Parabens! Agora reivindicaste essa area.
#You can not claim any further areas: Limit (@1) reached. =
#Please claim this area to modify it. =
#### Shared Chest ####
#Shared Chest =
#(by protection) =

View File

@ -10,7 +10,7 @@ Allows to modify and delete protected areas =
Manages all of your areas. =
# /area
Available area commands:
Available area commands: =
Information about this area =
(Un)share one area =
(Un)share all areas =
@ -33,6 +33,18 @@ Unowned (!) =
Owned by @1 =
Players with access: @1 =
# /area radar
North @1 =
East @1 =
South @1 =
West @1 =
Your position =
Your area =
Area claimed\nNo access for you =
Access for everybody =
One area unit (@1m) up/down\n-> no claims on this Y level =
square \= 1 area \= @1x@2x@3 nodes (X,Y,Z) =
# /area share <name>
@1 already has access to all your areas. =
@1 already has access to this area. =
@ -78,10 +90,17 @@ Area owned by: @1 =
Area owner: @1 =
# Item: Claim stick
Claim stick =
Claim Stick =
(click to protect) =
This area is already protected by an other protection mod. =
You can not claim areas below @1. =
This area is already owned by: @1 =
Congratulations! You now own this area. =
You can not claim any further areas: Limit (@1) reached. =
Please claim this area to modify it. =
#### Shared Chest ####
Shared Chest =
(by protection) =

View File

@ -1,11 +1,12 @@
function vector.floor(v)
return {
x = math.floor(v.x),
y = math.floor(v.y),
z = math.floor(v.z)
}
end
--[[
File: functions.lua
Table helper functions
Protection helper functions
Configuration loading
]]
-- Helper functions
function table_contains(t, e)
if not t or not e then
return false
@ -18,7 +19,7 @@ function table_contains(t, e)
return false
end
function table_delete(t, e)
function table_erase(t, e)
if not t or not e then
return false
end
@ -36,8 +37,9 @@ s_protect.can_access = function(pos, player_name)
if not player_name then
return false
end
-- Allow pipeworks access
if player_name == ":pipeworks" then
-- Allow access for pipeworks and unidentified mods
if player_name == ":pipeworks"
or player_name == "" then
return true
end
@ -48,7 +50,7 @@ s_protect.can_access = function(pos, player_name)
end
-- Data of current area
local data = s_protect.get_data(pos)
local data = s_protect.get_claim(pos)
-- Area is not claimed
if not data then
@ -57,8 +59,8 @@ s_protect.can_access = function(pos, player_name)
return true
end
-- Claim everywhere? Disallow everywhere.
if s_protect.underground_claim then
-- Must claim everywhere? Disallow everywhere.
if not s_protect.underground_limit then
return false
end
-- Is it in claimable area? Yes? Disallow.
@ -92,15 +94,8 @@ s_protect.get_location = function(pos_)
z = pos.z / s_protect.claim_size
})
end
-- Speed up the function access
local get_location = s_protect.get_location
s_protect.get_data = function(pos)
local pos = get_location(pos)
local str = pos.x..","..pos.y..","..pos.z
return s_protect.claims[str], str
end
s_protect.get_area_bounds = function(pos_)
local cs = s_protect.claim_size
local cy = s_protect.claim_height
@ -135,80 +130,6 @@ s_protect.get_center = function(pos1)
return pos
end
s_protect.load_claims = function()
local file = io.open(s_protect.file, "r")
if not file then
return
end
for line in file:lines() do
if line ~= "" then
local data = line:split(" ")
-- Line format: pos, owner, shared_player, shared_player2, ..
local _shared = {}
if #data > 2 then
for index = 3, #data do
if data[index] ~= "" then
table.insert(_shared, data[index])
end
end
end
s_protect.claims[data[1]] = {owner=data[2], shared=_shared}
end
end
io.close(file)
minetest.log("action", "Loaded claim data")
end
s_protect.load_shareall = function()
local file = io.open(s_protect.sharefile, "r")
if not file then
return
end
for line in file:lines() do
if line ~= "" then
local data = line:split(" ")
-- Line format: owner, shared_player, shared_player2, ..
local _shared = {}
if #data > 1 then
for index = 2, #data do
if data[index] ~= "" then
table.insert(_shared, data[index])
end
end
s_protect.share[data[1]] = _shared
end
end
end
io.close(file)
minetest.log("action", "Loaded shared claims")
end
s_protect.save = function()
local file = io.open(s_protect.file, "w")
for pos, data in pairs(s_protect.claims) do
if data.owner and data.owner ~= "" then
local shared = ""
for i, player in ipairs(data.shared) do
shared = shared.." "..player
end
file:write(pos.." "..data.owner..shared.."\n")
end
end
io.close(file)
-- Save globally shared areas
file = io.open(s_protect.sharefile, "w")
for name, players in pairs(s_protect.share) do
if #players > 0 then
local shared = ""
for i, player in ipairs(players) do
shared = shared.." "..player
end
file:write(name..shared.."\n")
end
end
io.close(file)
end
simple_protection = false
s_protect.load_config = function()
-- Load defaults
@ -226,8 +147,15 @@ s_protect.load_config = function()
end
simple_protection = nil
if s_protect.claim_heigh then
minetest.log("warning", "[simple_protection] "
.. "Loaded deprecated setting: claim_heigh")
s_protect.claim_height = s_protect.claim_heigh
end
if s_protect.underground_claim then
minetest.log("warning", "[simple_protection] "
.. "Loaded deprecated setting: underground_claim")
s_protect.underground_limit = nil
end
return
end
-- Duplicate configuration file on first time

View File

@ -0,0 +1 @@
name = simple_protection

View File

@ -1,17 +1,20 @@
--[[
File: protection.lua
Protection callback handler
Node placement checks
Claim Stick item definition
]]
local S = s_protect.gettext
minetest.after(1, function()
s_protect.load_claims()
s_protect.load_shareall()
end)
local function notify_player(pos, player_name)
local data = s_protect.get_data(pos)
local data = s_protect.get_claim(pos)
if not data and s_protect.claim_to_dig then
minetest.chat_send_player(player_name, S("Please claim this area to modify it."))
elseif not data then
minetest.log("warning", "[simple_protection] Access refused but no area was found "..
"near pos=".. minetest.pos_to_string(pos))
-- Access restricted by another protection mod. Not my job.
return
else
minetest.chat_send_player(player_name, S("Area owned by: @1", data.owner))
end
@ -27,7 +30,7 @@ end
local old_item_place = minetest.item_place
minetest.item_place = function(itemstack, placer, pointed_thing)
local player_name = placer:get_player_name()
local player_name = placer and placer:get_player_name() or ""
if s_protect.can_access(pointed_thing.above, player_name)
or not minetest.registered_nodes[itemstack:get_name()] then
@ -40,76 +43,9 @@ end
minetest.register_on_protection_violation(notify_player)
local hud_time = 0
s_protect.player_huds = {}
minetest.register_globalstep(function(dtime)
hud_time = hud_time + dtime
if hud_time < 3 then
return
end
hud_time = 0
local shared = s_protect.share
for _, player in ipairs(minetest.get_connected_players()) do
local pos = vector.round(player:getpos())
local player_name = player:get_player_name()
local current_owner = ""
local data = s_protect.get_data(pos)
if data then
current_owner = data.owner
end
local has_access = (current_owner == player_name)
if not has_access and data then
-- Check if this area is shared with this player
has_access = table_contains(data.shared, player_name)
end
if not has_access then
-- Check if all areas are shared with this player
has_access = table_contains(shared[current_owner], player_name)
end
local changed = true
local hud_table = s_protect.player_huds[player_name]
if hud_table and hud_table.owner == current_owner
and hud_table.had_access == has_access then
-- still the same hud
changed = false
end
if hud_table and changed then
player:hud_remove(hud_table.hudID)
s_protect.player_huds[player_name] = nil
end
if current_owner ~= "" and changed then
-- green if access
local color = 0xFFFFFF
if has_access then
color = 0x00CC00
end
s_protect.player_huds[player_name] = {
hudID = player:hud_add({
hud_elem_type = "text",
name = "area_hud",
number = color,
position = {x=0.15, y=0.97},
text = S("Area owner: @1", current_owner),
scale = {x=100, y=25},
alignment = {x=0, y=0},
}),
owner = current_owner,
had_access = has_access
}
end
end
end)
minetest.register_craftitem("simple_protection:claim", {
description = S("Claim stick"),
description = S("Claim Stick") .. " " .. S("(click to protect)"),
inventory_image = "simple_protection_claim.png",
stack_max = 10,
on_use = function(itemstack, user, pointed_thing)
@ -123,43 +59,40 @@ minetest.register_craftitem("simple_protection:claim", {
S("This area is already protected by an other protection mod."))
return
end
if not s_protect.underground_claim then
if s_protect.underground_limit then
local minp, maxp = s_protect.get_area_bounds(pos)
if minp.y < s_protect.underground_limit then
minetest.chat_send_player(player_name, S("You can not claim areas below @1.",
minetest.chat_send_player(player_name,
S("You can not claim areas below @1.",
s_protect.underground_limit .. "m"))
return
end
end
local data, area_pos = s_protect.get_data(pos)
local data, index = s_protect.get_claim(pos)
if data then
minetest.chat_send_player(player_name,
S("This area is already owned by: @1", data.owner))
return
end
-- Count number of claims for this user
local claims_count = 0
local claims_max = s_protect.max_claims
if minetest.check_player_privs(player_name, {simple_protection=true}) then
claims_max = claims_max * 2
end
for k, v in pairs(s_protect.claims) do
if v.owner == player_name then
claims_count = claims_count + 1
if claims_count >= claims_max then
local claims, count = s_protect.get_player_claims(player_name)
if count >= claims_max then
minetest.chat_send_player(player_name,
S("You can not claim any further areas: Limit (@1) reached.",
tostring(claims_max)))
return
end
end
end
itemstack:take_item(1)
s_protect.claims[area_pos] = {owner=player_name, shared={}}
s_protect.save()
s_protect.update_claims({
[index] = {owner=player_name, shared={}}
})
minetest.add_entity(s_protect.get_center(pos), "simple_protection:marker")
minetest.chat_send_player(player_name, S("Congratulations! You now own this area."))

View File

@ -1,5 +1,5 @@
-- /area radar
local S = s_protect.gettext
local data_cache
local function colorize_area(name, force)
@ -29,17 +29,17 @@ local function combine_escape(str)
return str:gsub("%^%[", "\\%^\\%["):gsub(":", "\\:")
end
s_protect.command_radar = function(name)
s_protect.register_subcommand("radar", function(name)
local player = minetest.get_player_by_name(name)
local player_pos = player:getpos()
local player_pos = player:get_pos()
local pos = s_protect.get_location(player_pos)
local map_w = 15 - 1
local map_wh = map_w / 2
local img_w = 20
local claims = s_protect.claims
local get_single = s_protect.get_claim
local function getter(x, ymod, z)
data_cache = claims[x .."," .. (pos.y + ymod) .. "," .. z]
data_cache = get_single(x .."," .. (pos.y + ymod) .. "," .. z, true)
return data_cache
end
@ -77,7 +77,7 @@ s_protect.command_radar = function(name)
combine_escape("object_marker_red.png^[resize:8x8"))
-- Rotation calculation
local dir_label = "North (Z+)"
local dir_label = S("North @1", "(Z+)")
local dir_mod = ""
local look_angle = player.get_look_horizontal and player:get_look_horizontal()
if not look_angle then
@ -86,42 +86,42 @@ s_protect.command_radar = function(name)
look_angle = look_angle * 180 / math.pi
if look_angle >= 45 and look_angle < 135 then
dir_label = "West (X-)"
dir_label = S("West @1", "(X-)")
dir_mod = "^[transformR270"
elseif look_angle >= 135 and look_angle < 225 then
dir_label = "South (Z-)"
dir_label = S("South @1", "(Z-)")
dir_mod = "^[transformR180"
elseif look_angle >= 225 and look_angle < 315 then
dir_label = "East (X+)"
dir_label = S("East @1", "(X+)")
dir_mod = "^[transformR90"
end
minetest.show_formspec(name, "covfefe",
"size[10.5,7]" ..
"button_exit[9.5,0;1,2;exit;X]" ..
"button_exit[9.5,0;1,1;exit;X]" ..
"label[2,0;"..dir_label.."]" ..
"image[0,0.5;7,7;" ..
minetest.formspec_escape("[combine:300x300"
.. parts .. marker_str)
.. dir_mod .. "]" ..
"label[0,6.8;1 square = 1 area = "
.. s_protect.claim_size .. "x"
.. s_protect.claim_height .. "x"
.. s_protect.claim_size .. " nodes (X,Y,Z)]" ..
"label[0,6.8;1 " .. S("square = 1 area = @1x@2x@3 nodes (X,Y,Z)",
s_protect.claim_size,
s_protect.claim_height,
s_protect.claim_size) .. "]" ..
"image[6.25,1.25;0.5,0.5;object_marker_red.png]" ..
"label[7,1.25;Your position]" ..
"label[7,1.25;" .. S("Your position") .. "]" ..
"image[6,2;1,1;simple_protection_radar.png^"
.. colorize_area(nil, "owner") .. "]" ..
"label[7,2.25;Your area]" ..
"label[7,2.25;" .. S("Your area") .. "]" ..
"image[6,3;1,1;simple_protection_radar.png^"
.. colorize_area(nil, "other") .. "]" ..
"label[7,3;Area claimed\nNo access for you]" ..
"label[7,3;" .. S("Area claimed\nNo access for you") .. "]" ..
"image[6,4;1,1;simple_protection_radar.png^"
.. colorize_area(nil, "*all") .. "]" ..
"label[7,4.25;Shared for everybody]" ..
"label[7,4.25;" .. S("Access for everybody") .. "]" ..
"image[6,5;1,1;simple_protection_radar_down.png]" ..
"image[7,5;1,1;simple_protection_radar_up.png]" ..
"label[6,6;One area unit ("..s_protect.claim_height
.. ") up/down\n= no claims on this Y level]"
"label[6,6;" .. S("One area unit (@1m) up/down\n-> no claims on this Y level",
s_protect.claim_height) .. "]"
)
end
end)