1 local modname = minetest.get_current_modname()
2 local storage = minetest.get_mod_storage()
6 local opening_hours_default = {
13 day1_start_minute = 0,
17 day2_start_minute = 0,
21 day3_start_minute = 0,
25 day4_start_minute = 0,
29 day5_start_minute = 0,
33 day6_start_minute = 0,
40 local warn_cooldown = 0
42 local function get_date()
46 local function get_date_formated()
47 return os.date("%d.%m.%y")
50 local function is_weekend()
51 local d = os.date("%w")
52 return d == "0" or d == "6"
55 local function upgrade_configuration(old)
58 day0_start_hour = tonumber(old.weekend_start),
59 day0_start_minute = 0,
60 day0_end_hour = tonumber(old.weekend_end),
62 day1_start_hour = tonumber(old.weekday_start),
63 day1_start_minute = 0,
64 day1_end_hour = tonumber(old.weekday_end),
66 day2_start_hour = tonumber(old.weekday_start),
67 day2_start_minute = 0,
68 day2_end_hour = tonumber(old.weekday_end),
70 day3_start_hour = tonumber(old.weekday_start),
71 day3_start_minute = 0,
72 day3_end_hour = tonumber(old.weekday_end),
74 day4_start_hour = tonumber(old.weekday_start),
75 day4_start_minute = 0,
76 day4_end_hour = tonumber(old.weekday_end),
78 day5_start_hour = tonumber(old.weekday_start),
79 day5_start_minute = 0,
80 day5_end_hour = tonumber(old.weekday_end),
82 day6_start_hour = tonumber(old.weekend_start),
83 day6_start_minute = 0,
84 day6_end_hour = tonumber(old.weekend_end),
86 warn_offset = tonumber(old.warn_offset),
87 warn_interval = tonumber(old.warn_interval)
90 new.exception_today = old.today
91 new.exception_start_hour = old.today_start
92 new.exception_start_minute = 0
93 new.exception_end_hour = old.today_end
94 new.exception_end_minute = 0
99 local function save_data()
100 storage:from_table({fields = opening_hours})
103 local function load_data()
104 opening_hours = storage:to_table().fields
105 if opening_hours.weekday_start then
106 opening_hours = upgrade_configuration(opening_hours)
107 elseif not opening_hours.version then
108 opening_hours = opening_hours_default
112 local function reset_execption()
113 opening_hours.exception_today = nil
116 local function opening_today()
117 local exception = opening_hours.exception_today
119 if exception and exception == get_date_formated() then
120 day_key = "exception"
121 elseif is_weekend() then
127 start_hour = opening_hours[day_key .. "_start_hour"],
128 start_minute = opening_hours[day_key .. "_start_minute"],
129 end_hour = opening_hours[day_key .. "_end_hour"],
130 end_minute = opening_hours[day_key .. "_end_minute"]
134 local function create_exception()
135 local today = opening_today()
136 opening_hours.exception_today = get_date_formated()
137 opening_hours.exception_start_hour = today.start_hour
138 opening_hours.exception_start_minute = today.start_minute
139 opening_hours.exception_end_hour = today.end_hour
140 opening_hours.exception_end_minute = today.end_minute
143 local function tick(dtime)
145 local exception = opening_hours.exception_today
146 if exception and exception ~= get_date_formated() then
149 local today = opening_today()
150 local end_time = today.end_hour * 60 + today.end_minute
151 local now_time = d.hour * 60 + d.min
152 local minutes_remaining = end_time - now_time
153 if 0 < minutes_remaining
154 and minutes_remaining <= opening_hours.warn_offset then
155 if warn_cooldown <= 0 then
156 minetest.chat_send_all(minetest.colorize("#FF4D00", "Der Server schießt in " .. minutes_remaining .. " Minuten."))
157 warn_cooldown = tonumber(opening_hours.warn_interval) * 60
159 warn_cooldown = warn_cooldown - dtime
161 elseif minutes_remaining <= 0 then
162 for _, player in pairs(minetest.get_connected_players()) do
163 local name = player:get_player_name()
164 if not minetest.check_player_privs(name, {server = true}) then
165 minetest.kick_player(name, "Der Server schließt!")
171 local function on_join(name)
172 if minetest.check_player_privs(name, {server = true}) then return end
173 local today = opening_today()
175 local start_time = today.start_hour * 60 + today.start_minute
176 local end_time = today.end_hour * 60 + today.end_minute
177 local now_time = d.hour * 60 + d.min
178 local diff = start_time - now_time
180 return "Besuch erfolgte außerhalb der Öffnungszeiten. Der Server hat in " .. math.ceil(diff / 60) .. " Stunde(n) wieder geöffnet."
181 elseif end_time <= now_time then
182 return "Besuch erfolgte außerhalb der Öffnungszeiten. Der Server hat bereits geschlossen und hat Morgen wieder geöffnet."
186 local minute_step = 5
188 local function show_gui(name)
190 local fld_h = 0.82429501084599
191 local fld_sz = fld_w .. "," .. fld_h
192 local inline_off = 0.2427394885132
193 local lab_close_y = 6.3935847420893
194 local fld_close_y = lab_close_y + 0.2427394885132
195 local lab_day1_x = 0.1
196 local pre_colon_off = 0.4
197 local fld_day1_f_hour_x = 0.64
198 local minute_off = 0.04
200 local fld_day1_f_minute_x = fld_day1_f_hour_x + fld_w - minute_off
201 local lab_day1_f_colon_x = fld_day1_f_minute_x - pre_colon_off
202 local fld_day1_t_hour_x = lab_day1_f_colon_x + to_off
203 local fld_day1_t_minute_x = fld_day1_t_hour_x + fld_w - minute_off
204 local lab_day1_t_colon_x = fld_day1_t_minute_x - pre_colon_off
205 local below_off = 1.1530125704378
206 local lab_b_y = 0.28175119202427
207 local fld_b_y = lab_b_y + below_off
208 local lab_b_colon_y = fld_b_y - inline_off
209 local lab_w_y = 2.0156046814044
210 local fld_w_y = lab_w_y + below_off
211 local lab_w_colon_y = fld_w_y - inline_off
212 local lab_e_y = 3.7494581707846
213 local fld_e_y = lab_e_y + below_off
214 local lab_e_colon_y = fld_e_y - inline_off
215 local o = opening_hours
216 local formspec = "size[10.01,7.9267895878525]"
217 .. "label[-0.14,-0.23840485478977;Öffnungszeiten]"
218 .. "label[" .. lab_day1_x .. "," .. lab_b_y .. ";Mo.-Fr.]"
219 .. "field[" .. fld_day1_f_hour_x .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_start_hour;von;" .. string.format("%02d", o.day1_start_hour) .. "]"
220 .. "label[" .. lab_day1_f_colon_x .. "," .. lab_b_colon_y .. ";:]"
221 .. "field[" .. fld_day1_f_minute_x .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_start_minute;;" .. string.format("%02d", o.day1_start_minute) .. "]"
222 .. "field[" .. fld_day1_t_hour_x .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_end_hour;bis;" .. string.format("%02d", o.day1_end_hour) .. "]"
223 .. "label[" .. lab_day1_t_colon_x .. "," .. lab_b_colon_y .. ";:]"
224 .. "field[" .. fld_day1_t_minute_x .. "," .. fld_b_y .. ";" .. fld_sz .. ";fld_day1_end_minute;;" .. string.format("%02d", o.day1_end_minute) .. "]"
225 .. "label[" .. lab_day1_x .. "," .. lab_w_y .. ";Sa.-So.]"
226 .. "field[" .. fld_day1_f_hour_x .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_start_hour;von;" .. string.format("%02d", o.day0_start_hour) .. "]"
227 .. "label[" .. lab_day1_f_colon_x .. "," .. lab_w_colon_y .. ";:]"
228 .. "field[" .. fld_day1_f_minute_x .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_start_minute;;" .. string.format("%02d", o.day0_start_minute) .. "]"
229 .. "field[" .. fld_day1_t_hour_x .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_end_hour;bis;" .. string.format("%02d", o.day0_end_hour) .. "]"
230 .. "label[" .. lab_day1_t_colon_x .. "," .. lab_w_colon_y .. ";:]"
231 .. "field[" .. fld_day1_t_minute_x .. "," .. fld_w_y .. ";" .. fld_sz .. ";fld_day0_end_minute;;" .. string.format("%02d", o.day0_end_minute) .. "]"
232 .. "label[" .. lab_day1_x .. "," .. lab_e_y .. ";Heute]"
233 .. (o.exception_today
235 .. "field[" .. fld_day1_f_hour_x .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_start_hour;von;" .. string.format("%02d", o.exception_start_hour) .. "]"
236 .. "label[" .. lab_day1_f_colon_x .. "," .. lab_e_colon_y .. ";:]"
237 .. "field[" .. fld_day1_f_minute_x .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_start_minute;;" .. string.format("%02d", o.exception_start_minute) .. "]"
238 .. "field[" .. fld_day1_t_hour_x .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_end_hour;bis;" .. string.format("%02d", o.exception_end_hour) .. "]"
239 .. "label[" .. lab_day1_t_colon_x .. "," .. lab_e_colon_y .. ";:]"
240 .. "field[" .. fld_day1_t_minute_x .. "," .. fld_e_y .. ";" .. fld_sz .. ";fld_exception_end_minute;;" .. string.format("%02d", o.exception_end_minute) .. "]"
241 or "image_button[0.34,4.5296922410056;4.205,0.7835;;add_exception;Ausnahmeregelung hinzufügen]"
243 .. "label[" .. lab_day1_x .. ",5.4833116601647;Einstellungen]"
244 .. "label[0.34," .. lab_close_y .. ";Spieler ]"
245 .. "field[1.6," .. fld_close_y .. ";" .. fld_sz .. ";fld_warn_offset;;" .. o.warn_offset .. "]"
246 .. "label[2.18," .. lab_close_y .. ";Minuten vor Ablauf der Zeit alle]"
247 .. "field[6.0," .. fld_close_y .. ";" .. fld_sz .. ";fld_warn_interval;;" .. o.warn_interval .. "]"
248 .. "label[6.6," .. lab_close_y .. ";Minuten warnen.]"
249 .. "image_button[5.14,7.6072821846554;2.605,0.7835;;save;Speichern]"
250 .. "image_button_exit[7.62,7.6072821846554;2.605,0.7835;;close;Schließen]"
251 minetest.show_formspec(name, "lmz_opening_hours:gui", formspec)
254 local function progress_gui_input(player, formname, fields)
255 local name = player:get_player_name()
256 if formname ~= "lmz_opening_hours:gui" or not minetest.check_player_privs(name, {server = true}) then return end
257 if fields.add_exception then
260 for k, v in pairs(fields) do
261 if k:sub(1, 4) == "fld_" then
262 local field = k:gsub("fld_", "")
263 local old = opening_hours[field]
264 opening_hours[field] = tonumber(v) or old
267 for k, v in pairs(opening_hours) do
268 if k:match("_hour$") then
269 opening_hours[k] = math.max(0, math.min(23, v))
270 elseif k:match("_minute$") then
271 opening_hours[k] = math.max(
275 minute_step * math.floor(
276 v / minute_step + 0.5
282 for k, v in pairs(opening_hours) do
283 if k:match("_end_hour$") then
284 local start = opening_hours[k:gsub("_end_", "_start_")]
286 opening_hours[k] = start
288 elseif k:match("_end_minute$") then
289 local hour_k = k:gsub("_minute$", "_hour")
290 local hour_start_k = hour_k:gsub("_end_", "_start_")
291 local start_k = k:gsub("_end_", "_start_")
292 if opening_hours[hour_start_k] >= opening_hours[hour_k]
293 and opening_hours[start_k] > v then
294 opening_hours[k] = opening_hours[start_k]
298 if not fields.quit and not fields.close then show_gui(name) end
303 minetest.register_globalstep(tick)
304 minetest.register_on_shutdown(save_data)
305 minetest.register_on_prejoinplayer(on_join)
306 minetest.register_chatcommand("opening_hours", {privs = {server = true}, description = "Die Öffnungszeiten konfigurieren", func = show_gui})
307 minetest.register_chatcommand("öffnungszeiten", {privs = {server = true}, description = "Die Öffnungszeiten konfigurieren", func = show_gui})
308 minetest.register_on_player_receive_fields(progress_gui_input)