]> git.lizzy.rs Git - minetest.git/blob - builtin/game/misc.lua
Add more ways to pass data to check_player_privs
[minetest.git] / builtin / game / misc.lua
1 -- Minetest: builtin/misc.lua
2
3 --
4 -- Misc. API functions
5 --
6
7 local timers = {}
8 local mintime
9 local function update_timers(delay)
10         mintime = false
11         local sub = 0
12         for index = 1, #timers do
13                 index = index - sub
14                 local timer = timers[index]
15                 timer.time = timer.time - delay
16                 if timer.time <= 0 then
17                         core.set_last_run_mod(timer.mod_origin)
18                         timer.func(unpack(timer.args or {}))
19                         table.remove(timers, index)
20                         sub = sub + 1
21                 elseif mintime then
22                         mintime = math.min(mintime, timer.time)
23                 else
24                         mintime = timer.time
25                 end
26         end
27 end
28
29 local timers_to_add
30 local function add_timers()
31         for _, timer in ipairs(timers_to_add) do
32                 table.insert(timers, timer)
33         end
34         timers_to_add = false
35 end
36
37 local delay = 0
38 core.register_globalstep(function(dtime)
39         if not mintime then
40                 -- abort if no timers are running
41                 return
42         end
43         if timers_to_add then
44                 add_timers()
45         end
46         delay = delay + dtime
47         if delay < mintime then
48                 return
49         end
50         update_timers(delay)
51         delay = 0
52 end)
53
54 function core.after(time, func, ...)
55         assert(tonumber(time) and type(func) == "function",
56                         "Invalid core.after invocation")
57         if not mintime then
58                 mintime = time
59                 timers_to_add = {{
60                         time   = time+delay,
61                         func   = func,
62                         args   = {...},
63                         mod_origin = core.get_last_run_mod(),
64                 }}
65                 return
66         end
67         mintime = math.min(mintime, time)
68         timers_to_add = timers_to_add or {}
69         timers_to_add[#timers_to_add+1] = {
70                 time   = time+delay,
71                 func   = func,
72                 args   = {...},
73                 mod_origin = core.get_last_run_mod(),
74         }
75 end
76
77 function core.check_player_privs(player_or_name, ...)
78         local name = player_or_name
79         -- Check if we have been provided with a Player object.
80         if type(name) ~= "string" then
81                 name = name:get_player_name()
82         end
83         
84         local requested_privs = {...}
85         local player_privs = core.get_player_privs(name)
86         local missing_privileges = {}
87         
88         if type(requested_privs[1]) == "table" then
89                 -- We were provided with a table like { privA = true, privB = true }.
90                 for priv, value in pairs(requested_privs[1]) do
91                         if value and not player_privs[priv] then
92                                 table.insert(missing_privileges, priv)
93                         end
94                 end
95         else
96                 -- Only a list, we can process it directly.
97                 for key, priv in pairs(requested_privs) do
98                         if not player_privs[priv] then
99                                 table.insert(missing_privileges, priv)
100                         end
101                 end
102         end
103         
104         if #missing_privileges > 0 then
105                 return false, missing_privileges
106         end
107         
108         return true, ""
109 end
110
111 local player_list = {}
112
113 core.register_on_joinplayer(function(player)
114         player_list[player:get_player_name()] = player
115 end)
116
117 core.register_on_leaveplayer(function(player)
118         player_list[player:get_player_name()] = nil
119 end)
120
121 function core.get_connected_players()
122         local temp_table = {}
123         for index, value in pairs(player_list) do
124                 if value:is_player_connected() then
125                         table.insert(temp_table, value)
126                 end
127         end
128         return temp_table
129 end
130
131 -- Returns two position vectors representing a box of `radius` in each
132 -- direction centered around the player corresponding to `player_name`
133 function core.get_player_radius_area(player_name, radius)
134         local player = core.get_player_by_name(player_name)
135         if player == nil then
136                 return nil
137         end
138
139         local p1 = player:getpos()
140         local p2 = p1
141
142         if radius then
143                 p1 = vector.subtract(p1, radius)
144                 p2 = vector.add(p2, radius)
145         end
146
147         return p1, p2
148 end
149
150 function core.hash_node_position(pos)
151         return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
152 end
153
154 function core.get_position_from_hash(hash)
155         local pos = {}
156         pos.x = (hash%65536) - 32768
157         hash = math.floor(hash/65536)
158         pos.y = (hash%65536) - 32768
159         hash = math.floor(hash/65536)
160         pos.z = (hash%65536) - 32768
161         return pos
162 end
163
164 function core.get_item_group(name, group)
165         if not core.registered_items[name] or not
166                         core.registered_items[name].groups[group] then
167                 return 0
168         end
169         return core.registered_items[name].groups[group]
170 end
171
172 function core.get_node_group(name, group)
173         core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead")
174         return core.get_item_group(name, group)
175 end
176
177 function core.setting_get_pos(name)
178         local value = core.setting_get(name)
179         if not value then
180                 return nil
181         end
182         return core.string_to_pos(value)
183 end
184
185 -- To be overriden by protection mods
186 function core.is_protected(pos, name)
187         return false
188 end
189
190 function core.record_protection_violation(pos, name)
191         for _, func in pairs(core.registered_on_protection_violation) do
192                 func(pos, name)
193         end
194 end
195
196 local raillike_ids = {}
197 local raillike_cur_id = 0
198 function core.raillike_group(name)
199         local id = raillike_ids[name]
200         if not id then
201                 raillike_cur_id = raillike_cur_id + 1
202                 raillike_ids[name] = raillike_cur_id
203                 id = raillike_cur_id
204         end
205         return id
206 end