mod.simple_protection: Update to Git commit 5aa2f24

https://github.com/SmallJoker/simple_protection/tree/5aa2f24
master
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
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)
unclaim -> Unclaims the current area
delete <name> -> Removes all areas of <name> (requires "server" privilege)
```
/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 (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

@ -8,33 +8,29 @@ simple_protection/default_settings.lua
[world_path]/s_protect.conf
Contains the per-world specific settings.
You may modify thisone but pay attention, as some settings may cause
You may modify this one but pay attention, as some settings may cause
unwanted side effects when claims were made.
]]
-- 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?
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.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.",
s_protect.underground_limit.."m"))
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
minetest.chat_send_player(player_name,
S("You can not claim any further areas: Limit (@1) reached.",
tostring(claims_max)))
return
end
end
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
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)