]> git.lizzy.rs Git - lmz_opening_hours.git/blob - init.lua
layout structure
[lmz_opening_hours.git] / init.lua
1 local modname = minetest.get_current_modname()
2 local storage = minetest.get_mod_storage()
3
4 opening_hours = {}
5
6 local opening_hours_default = {
7         version = 2,
8         day0_start_hour = 8,
9         day0_start_minute = 0,
10         day0_end_hour = 21,
11         day0_end_minute = 0,
12         day1_start_hour = 14,
13         day1_start_minute = 0,
14         day1_end_hour = 21,
15         day1_end_minute = 0,
16         day2_start_hour = 14,
17         day2_start_minute = 0,
18         day2_end_hour = 21,
19         day2_end_minute = 0,
20         day3_start_hour = 14,
21         day3_start_minute = 0,
22         day3_end_hour = 21,
23         day3_end_minute = 0,
24         day4_start_hour = 14,
25         day4_start_minute = 0,
26         day4_end_hour = 21,
27         day4_end_minute = 0,
28         day5_start_hour = 14,
29         day5_start_minute = 0,
30         day5_end_hour = 21,
31         day5_end_minute = 0,
32         day6_start_hour = 8,
33         day6_start_minute = 0,
34         day6_end_hour = 21,
35         day6_end_minute = 0,
36         warn_offset = 15,
37         warn_interval = 5
38 }
39
40 local warn_cooldown = 0
41
42 local function get_date()
43         return os.date("*t")
44 end
45
46 local function get_date_formated()
47         return os.date("%d.%m.%y")
48 end
49
50 local function upgrade_configuration(old)
51         local new = {
52                 version = 2,
53                 day0_start_hour = tonumber(old.weekend_start),
54                 day0_start_minute = 0,
55                 day0_end_hour = tonumber(old.weekend_end),
56                 day0_end_minute = 0,
57                 day1_start_hour = tonumber(old.weekday_start),
58                 day1_start_minute = 0,
59                 day1_end_hour = tonumber(old.weekday_end),
60                 day1_end_minute = 0,
61                 day2_start_hour = tonumber(old.weekday_start),
62                 day2_start_minute = 0,
63                 day2_end_hour = tonumber(old.weekday_end),
64                 day2_end_minute = 0,
65                 day3_start_hour = tonumber(old.weekday_start),
66                 day3_start_minute = 0,
67                 day3_end_hour = tonumber(old.weekday_end),
68                 day3_end_minute = 0,
69                 day4_start_hour = tonumber(old.weekday_start),
70                 day4_start_minute = 0,
71                 day4_end_hour = tonumber(old.weekday_end),
72                 day4_end_minute = 0,
73                 day5_start_hour = tonumber(old.weekday_start),
74                 day5_start_minute = 0,
75                 day5_end_hour = tonumber(old.weekday_end),
76                 day5_end_minute = 0,
77                 day6_start_hour = tonumber(old.weekend_start),
78                 day6_start_minute = 0,
79                 day6_end_hour = tonumber(old.weekend_end),
80                 day6_end_minute = 0,
81                 warn_offset = tonumber(old.warn_offset),
82                 warn_interval = tonumber(old.warn_interval)
83         }
84         if old.today then
85                 new.exception_today = old.today
86                 new.exception_start_hour = old.today_start
87                 new.exception_start_minute = 0
88                 new.exception_end_hour = old.today_end
89                 new.exception_end_minute = 0
90         end
91         return new
92 end
93
94 local function save_data()
95         storage:from_table({fields = opening_hours})
96 end
97
98 local function load_data()
99         opening_hours = storage:to_table().fields
100         if opening_hours.weekday_start then
101                 opening_hours = upgrade_configuration(opening_hours)
102         elseif not opening_hours.version then
103                 opening_hours = opening_hours_default
104         end
105 end
106
107 local function reset_execption()
108         opening_hours.exception_today = nil
109 end
110
111 local function opening_today()
112         local exception = opening_hours.exception_today
113         local day_key
114         if exception and exception == get_date_formated() then
115                 day_key = "exception"
116         else
117                 local d = os.date("%w")
118                 day_key = "day" .. d
119         end
120         return {
121                 start_hour = opening_hours[day_key .. "_start_hour"],
122                 start_minute = opening_hours[day_key .. "_start_minute"],
123                 end_hour = opening_hours[day_key .. "_end_hour"],
124                 end_minute = opening_hours[day_key .. "_end_minute"]
125         }
126 end
127
128 local function create_exception()
129         local today = opening_today()
130         opening_hours.exception_today = get_date_formated()
131         opening_hours.exception_start_hour = today.start_hour
132         opening_hours.exception_start_minute = today.start_minute
133         opening_hours.exception_end_hour = today.end_hour
134         opening_hours.exception_end_minute = today.end_minute
135 end
136
137 local function tick(dtime)
138         local d = get_date()
139         local exception = opening_hours.exception_today
140         if exception and exception ~= get_date_formated() then
141                 reset_execption()
142         end
143         local today = opening_today()
144         local end_time = today.end_hour * 60 + today.end_minute
145         local now_time = d.hour * 60 + d.min
146         local minutes_remaining = end_time - now_time
147         if 0 < minutes_remaining
148         and minutes_remaining <= opening_hours.warn_offset then
149                 if warn_cooldown <= 0 then
150                         minetest.chat_send_all(minetest.colorize("#FF4D00", "Der Server schießt in " .. minutes_remaining .. " Minuten."))
151                         warn_cooldown = tonumber(opening_hours.warn_interval) * 60
152                 else
153                         warn_cooldown = warn_cooldown - dtime
154                 end
155         elseif minutes_remaining <= 0 then
156                 for _, player in pairs(minetest.get_connected_players()) do
157                         local name = player:get_player_name()
158                         if not minetest.check_player_privs(name, {server = true}) then
159                                 minetest.kick_player(name, "Der Server schließt!")
160                         end
161                 end
162         end
163 end
164
165 local function on_join(name)
166         if minetest.check_player_privs(name, {server = true}) then return end
167         local today = opening_today()
168         local d = get_date()
169         local start_time = today.start_hour * 60 + today.start_minute
170         local end_time = today.end_hour * 60 + today.end_minute
171         local now_time = d.hour * 60 + d.min
172         local diff = start_time - now_time
173         if diff > 0 then
174                 return "Besuch erfolgte außerhalb der Öffnungszeiten. Der Server hat in " .. math.ceil(diff / 60) .. " Stunde(n) wieder geöffnet."
175         elseif end_time <= now_time then
176                 return "Besuch erfolgte außerhalb der Öffnungszeiten. Der Server hat bereits geschlossen und hat Morgen wieder geöffnet."
177         end
178 end
179
180 local minute_step = 5
181
182 local function show_gui(name)
183         local fld_w = 0.88
184         local fld_h = 0.82429501084599
185         local fld_sz = fld_w .. "," .. fld_h
186         local inline_off = 0.2427394885132
187         local lab_close_y = 6.3935847420893
188         local fld_close_y = lab_close_y + 0.2427394885132
189         local pre_colon_off = 0.4
190         local minute_off = 0.04
191         local to_off = 1.24
192         local day_off = 3.6
193         local x = {
194                 day1 = {}
195         }
196         x.day1.lab = 0.1
197         x.day1.fld_f_hour = 0.64
198         x.day1.fld_f_minute = x.day1.fld_f_hour + fld_w - minute_off
199         x.day1.lab_f_colon = x.day1.fld_f_minute - pre_colon_off
200         x.day1.fld_t_hour = x.day1.lab_f_colon + to_off
201         x.day1.fld_t_minute = x.day1.fld_t_hour + fld_w - minute_off
202         x.day1.lab_t_colon = x.day1.fld_t_minute - pre_colon_off
203         local last
204         for day = 1, 5, 1 do
205                 if last then
206                         x["day" .. day] = {}
207                         for k, v in pairs(x["day" .. last]) do
208                                 x["day" .. day][k] = v + day_off
209                         end
210                 end
211                 last = day
212         end
213         local below_off = 1.1530125704378
214         local lab_b_y = 0.28175119202427
215         local fld_b_y = lab_b_y + below_off
216         local lab_b_colon_y = fld_b_y - inline_off
217         local lab_w_y = 2.0156046814044
218         local fld_w_y = lab_w_y + below_off
219         local lab_w_colon_y = fld_w_y - inline_off
220         local lab_e_y = 3.7494581707846
221         local fld_e_y = lab_e_y + below_off
222         local lab_e_colon_y = fld_e_y - inline_off
223         local o = opening_hours
224         local formspec_day1 = ""
225         .. "label[" .. x.day1.lab .. "," .. lab_b_y .. ";Mo.]"
226         .. "field[" .. x.day1.fld_f_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_start_hour;von;" .. string.format("%02d", o.day1_start_hour) .. "]"
227         .. "label[" .. x.day1.lab_f_colon .. "," .. lab_b_colon_y .. ";:]"
228         .. "field[" .. x.day1.fld_f_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_start_minute;;" .. string.format("%02d", o.day1_start_minute) .. "]"
229         .. "field[" .. x.day1.fld_t_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_end_hour;bis;" .. string.format("%02d", o.day1_end_hour) .. "]"
230         .. "label[" .. x.day1.lab_t_colon .. "," .. lab_b_colon_y .. ";:]"
231         .. "field[" .. x.day1.fld_t_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_end_minute;;" .. string.format("%02d", o.day1_end_minute) .. "]"
232         local formspec_day2 = ""
233         .. "label[" .. x.day2.lab .. "," .. lab_b_y .. ";Di.]"
234         .. "field[" .. x.day2.fld_f_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day2_start_hour;von;" .. string.format("%02d", o.day2_start_hour) .. "]"
235         .. "label[" .. x.day2.lab_f_colon .. "," .. lab_b_colon_y .. ";:]"
236         .. "field[" .. x.day2.fld_f_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day2_start_minute;;" .. string.format("%02d", o.day2_start_minute) .. "]"
237         .. "field[" .. x.day2.fld_t_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day2_end_hour;bis;" .. string.format("%02d", o.day2_end_hour) .. "]"
238         .. "label[" .. x.day2.lab_t_colon .. "," .. lab_b_colon_y .. ";:]"
239         .. "field[" .. x.day2.fld_t_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day2_end_minute;;" .. string.format("%02d", o.day2_end_minute) .. "]"
240         local formspec_day3 = ""
241         .. "label[" .. x.day3.lab .. "," .. lab_b_y .. ";Mi.]"
242         .. "field[" .. x.day3.fld_f_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day3_start_hour;von;" .. string.format("%02d", o.day3_start_hour) .. "]"
243         .. "label[" .. x.day3.lab_f_colon .. "," .. lab_b_colon_y .. ";:]"
244         .. "field[" .. x.day3.fld_f_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day3_start_minute;;" .. string.format("%02d", o.day3_start_minute) .. "]"
245         .. "field[" .. x.day3.fld_t_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day3_end_hour;bis;" .. string.format("%02d", o.day3_end_hour) .. "]"
246         .. "label[" .. x.day3.lab_t_colon .. "," .. lab_b_colon_y .. ";:]"
247         .. "field[" .. x.day3.fld_t_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day3_end_minute;;" .. string.format("%02d", o.day3_end_minute) .. "]"
248         local formspec_day4 = ""
249         .. "label[" .. x.day4.lab .. "," .. lab_b_y .. ";Do.]"
250         .. "field[" .. x.day4.fld_f_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day4_start_hour;von;" .. string.format("%02d", o.day4_start_hour) .. "]"
251         .. "label[" .. x.day4.lab_f_colon .. "," .. lab_b_colon_y .. ";:]"
252         .. "field[" .. x.day4.fld_f_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day4_start_minute;;" .. string.format("%02d", o.day4_start_minute) .. "]"
253         .. "field[" .. x.day4.fld_t_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day4_end_hour;bis;" .. string.format("%02d", o.day4_end_hour) .. "]"
254         .. "label[" .. x.day4.lab_t_colon .. "," .. lab_b_colon_y .. ";:]"
255         .. "field[" .. x.day4.fld_t_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day4_end_minute;;" .. string.format("%02d", o.day4_end_minute) .. "]"
256         local formspec_day5 = ""
257         .. "label[" .. x.day5.lab .. "," .. lab_b_y .. ";Fr.]"
258         .. "field[" .. x.day5.fld_f_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day5_start_hour;von;" .. string.format("%02d", o.day5_start_hour) .. "]"
259         .. "label[" .. x.day5.lab_f_colon .. "," .. lab_b_colon_y .. ";:]"
260         .. "field[" .. x.day5.fld_f_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day5_start_minute;;" .. string.format("%02d", o.day5_start_minute) .. "]"
261         .. "field[" .. x.day5.fld_t_hour .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day5_end_hour;bis;" .. string.format("%02d", o.day5_end_hour) .. "]"
262         .. "label[" .. x.day5.lab_t_colon .. "," .. lab_b_colon_y .. ";:]"
263         .. "field[" .. x.day5.fld_t_minute .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day5_end_minute;;" .. string.format("%02d", o.day5_end_minute) .. "]"
264         local formspec_business_days = ""
265         .. formspec_day1
266         .. formspec_day2
267         .. formspec_day3
268         .. formspec_day4
269         .. formspec_day5
270         local formspec_day6 = ""
271         .. "label[" .. x.day1.lab .. "," .. lab_w_y .. ";Sa.]"
272         .. "field[" .. x.day1.fld_f_hour .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day6_start_hour;von;" .. string.format("%02d", o.day6_start_hour) .. "]"
273         .. "label[" .. x.day1.lab_f_colon .. "," .. lab_w_colon_y .. ";:]"
274         .. "field[" .. x.day1.fld_f_minute .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day6_start_minute;;" .. string.format("%02d", o.day6_start_minute) .. "]"
275         .. "field[" .. x.day1.fld_t_hour .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day6_end_hour;bis;" .. string.format("%02d", o.day6_end_hour) .. "]"
276         .. "label[" .. x.day1.lab_t_colon .. "," .. lab_w_colon_y .. ";:]"
277         .. "field[" .. x.day1.fld_t_minute .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day6_end_minute;;" .. string.format("%02d", o.day6_end_minute) .. "]"
278         local formspec_day0 = ""
279         .. "label[" .. x.day2.lab .. "," .. lab_w_y .. ";So.]"
280         .. "field[" .. x.day2.fld_f_hour .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_start_hour;von;" .. string.format("%02d", o.day0_start_hour) .. "]"
281         .. "label[" .. x.day2.lab_f_colon .. "," .. lab_w_colon_y .. ";:]"
282         .. "field[" .. x.day2.fld_f_minute .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_start_minute;;" .. string.format("%02d", o.day0_start_minute) .. "]"
283         .. "field[" .. x.day2.fld_t_hour .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_end_hour;bis;" .. string.format("%02d", o.day0_end_hour) .. "]"
284         .. "label[" .. x.day2.lab_t_colon .. "," .. lab_w_colon_y .. ";:]"
285         .. "field[" .. x.day2.fld_t_minute .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_end_minute;;" .. string.format("%02d", o.day0_end_minute) .. "]"
286         local formspec_exception = (o.exception_today
287                         and ""
288                                 .. "label[" .. x.day1.lab .. "," .. lab_e_y .. ";Heute]"
289                                 .. "field[" .. x.day1.fld_f_hour .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_start_hour;von;" .. string.format("%02d", o.exception_start_hour) .. "]"
290                                 .. "label[" .. x.day1.lab_f_colon .. "," .. lab_e_colon_y .. ";:]"
291                                 .. "field[" .. x.day1.fld_f_minute .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_start_minute;;" .. string.format("%02d", o.exception_start_minute) .. "]"
292                                 .. "field[" .. x.day1.fld_t_hour .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_end_hour;bis;" .. string.format("%02d", o.exception_end_hour) .. "]"
293                                 .. "label[" .. x.day1.lab_t_colon .. "," .. lab_e_colon_y .. ";:]"
294                                 .. "field[" .. x.day1.fld_t_minute .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_end_minute;;" .. string.format("%02d", o.exception_end_minute) .. "]"
295                         or "image_button[0.34,4.5296922410056;4.205,0.7835;;add_exception;Ausnahmeregelung hinzufügen]"
296                 )
297         local formspec = "size[18.01,7.9267895878525]"
298         .. "label[-0.14,-0.23840485478977;Öffnungszeiten]"
299         .. formspec_business_days
300         .. formspec_day6
301         .. formspec_day0
302         .. formspec_exception
303         .. "label[" .. x.day1.lab .. ",5.4833116601647;Einstellungen]"
304         .. "label[0.34," .. lab_close_y .. ";Spieler ]"
305         .. "field[1.6," .. fld_close_y .. ";" .. fld_sz .. ";fld_warn_offset;;" .. o.warn_offset .. "]"
306         .. "label[2.18," .. lab_close_y .. ";Minuten vor Ablauf der Zeit alle]"
307         .. "field[6.0," .. fld_close_y .. ";" .. fld_sz .. ";fld_warn_interval;;" .. o.warn_interval .. "]"
308         .. "label[6.6," .. lab_close_y .. ";Minuten warnen.]"
309         .. "image_button[5.14,7.6072821846554;2.605,0.7835;;save;Speichern]"
310         .. "image_button_exit[7.62,7.6072821846554;2.605,0.7835;;close;Schließen]"
311         minetest.show_formspec(name, "lmz_opening_hours:gui", formspec)
312 end
313
314 local function progress_gui_input(player, formname, fields)
315         local name = player:get_player_name()
316         if formname ~= "lmz_opening_hours:gui" or not minetest.check_player_privs(name, {server = true}) then return end
317         if fields.add_exception then
318                 create_exception()
319         end
320         for k, v in pairs(fields) do
321                 if k:sub(1, 4) == "fld_" then
322                         local field = k:gsub("fld_", "")
323                         local old = opening_hours[field]
324                         opening_hours[field] = tonumber(v) or old
325                 end
326         end
327         for k, v in pairs(opening_hours) do
328                 if k:match("_hour$") then
329                         opening_hours[k] = math.max(0, math.min(23, v))
330                 elseif k:match("_minute$") then
331                         opening_hours[k] = math.max(
332                                 0,
333                                 math.min(
334                                         60 - minute_step,
335                                         minute_step * math.floor(
336                                                 v / minute_step + 0.5
337                                         )
338                                 )
339                         )
340                 end
341         end
342         for k, v in pairs(opening_hours) do
343                 if k:match("_end_hour$") then
344                         local start = opening_hours[k:gsub("_end_", "_start_")]
345                         if start > v then
346                                 opening_hours[k] = start
347                         end
348                 elseif k:match("_end_minute$") then
349                         local hour_k = k:gsub("_minute$", "_hour")
350                         local hour_start_k = hour_k:gsub("_end_", "_start_")
351                         local start_k = k:gsub("_end_", "_start_")
352                         if opening_hours[hour_start_k] >= opening_hours[hour_k]
353                         and opening_hours[start_k] > v then
354                                 opening_hours[k] = opening_hours[start_k]
355                         end
356                 end
357         end
358         if not fields.quit and not fields.close then show_gui(name) end
359 end
360
361 load_data()
362
363 minetest.register_globalstep(tick)
364 minetest.register_on_shutdown(save_data)
365 minetest.register_on_prejoinplayer(on_join)
366 minetest.register_chatcommand("opening_hours", {privs = {server = true}, description = "Die Öffnungszeiten konfigurieren", func = show_gui})
367 minetest.register_chatcommand("öffnungszeiten", {privs = {server = true}, description = "Die Öffnungszeiten konfigurieren", func = show_gui})
368 minetest.register_on_player_receive_fields(progress_gui_input)
369
370