-
Notifications
You must be signed in to change notification settings - Fork 4
/
lock.lua
118 lines (99 loc) · 4.2 KB
/
lock.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
--[[
Copyright (C) 2021 Jude Melton-Houghton
This file is part of area_containers. It implements container lock functions.
area_containers is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
area_containers is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with area_containers. If not, see <https://www.gnu.org/licenses/>.
]]
--[[
OVERVIEW
Locks can be added or removed from area containers by container owners or
people who can bypass protection (henceforth both called "admins".) Others
entering the container must hold an appropriate key to get in. These keys
can only be created by admins. Keys are bound to the node for its lifetime.
If an admin sets the lock on an unowned container, they take ownership.
This file contains only the business logic. See container.lua for the rest
of the implementation.
]]
local use = ...
local get_random_id = use("misc", {"get_random_id"})
local exports = {}
-- Returns whether the named player is an admin of the node owned as given.
-- A nil owner means that the node is unowned.
local function user_can_use(player_name, owner)
return minetest.check_player_privs(player_name, "protection_bypass") or
player_name == owner
end
-- Returns whether the given node is locked.
function exports.is_locked(pos)
return minetest.get_meta(pos):contains("area_containers:lock")
end
-- Returns whether the user can enter the node according to the (possible) lock.
-- The user may be wielding a key item.
function exports.lock_allows_enter(pos, user)
local meta = minetest.get_meta(pos)
if meta:contains("area_containers:lock") and
not user_can_use(user:get_player_name(), meta:get("owner")) then
local item_meta = user:get_wielded_item():get_meta()
local lock_try =
item_meta:get_string("area_containers:lock")
local lock = meta:get_string("area_containers:lock")
if lock_try ~= lock then return false end
end
return true
end
-- Sets the lock as the user. Returns whether doing so was successful.
function exports.set_lock(pos, user)
local player_name = user:get_player_name()
local meta = minetest.get_meta(pos)
local owner = meta:get("owner")
if not user_can_use(player_name, owner) then return false end
if meta:contains("area_containers:lock") then return false end
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
return false
end
meta:set_string("area_containers:lock",
meta:get("area_containers:lock_inactive") or get_random_id())
meta:set_string("area_containers:lock_inactive", "")
-- Take ownership if it's unowned:
if not owner then meta:set_string("owner", player_name) end
return true
end
-- Removes the lock as the user. Returns whether doing so was successful.
function exports.remove_lock(pos, user)
local player_name = user:get_player_name()
local meta = minetest.get_meta(pos)
local owner = meta:get("owner")
if not user_can_use(player_name, owner) then return false end
if not meta:contains("area_containers:lock") then return false end
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
return false
end
meta:set_string("area_containers:lock_inactive",
meta:get_string("area_containers:lock"))
meta:set_string("area_containers:lock", "")
return true
end
-- Sets up the user's wielded item as a key to the lock. Returns whether
-- doing so was successful.
function exports.fill_key(pos, user)
local meta = minetest.get_meta(pos)
if not user_can_use(user:get_player_name(), meta:get("owner")) then
return false
end
if not meta:contains("area_containers:lock") then return false end
local key = user:get_wielded_item()
key:get_meta():set_string("area_containers:lock",
meta:get_string("area_containers:lock"))
return user:set_wielded_item(key)
end
return exports