mtimer/system/on_receive_fields.lua

351 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local m = mtimer
local d = mtimer.dialog
-- When formspec data is sent to the server check for the formname and run the
-- specific action for the given form. See Individual descriptions. The code
-- for this is very simple because most of the logic is handled in the
-- timer functions and not in the formspec code.
minetest.register_on_player_receive_fields(function(player, formname, fields)
if not player:is_player() then return end
local meta = player:get_meta()
local name = player:get_player_name()
-- Select what formspec to show basing on main menu button
if formname == 'mtimer:main_menu' then
if fields.set_visibility then d.set_visibility(name) end
if fields.set_position then d.set_position(name) end
if fields.set_color then d.set_color(name) end
if fields.timezone_offset then d.timezone_offset(name) end
if fields.ingame_time_format then d.ingame_time_format(name) end
if fields.real_world_time_format then d.real_world_time_format(name) end
if fields.host_time_format then d.host_time_format(name) end
if fields.session_start_time_format then
d.session_start_time_format(name)
end
if fields.session_duration_format then
d.session_duration_format(name)
end
if fields.hud_element_scale then d.hud_element_scale(name) end
if fields.hud_element_offset then d.hud_element_offset(name) end
if fields.timer_format then d.timer_format(name) end
if fields.custom_timer then d.custom_timer(name) end
if fields.reset_everything then d.reset_everything(name) end
end
-- Set timer visibility
if formname == 'mtimer:set_visibility' then
local attr = m.meta.visible
if fields.set_visible then meta:set_string(attr.key, 'true') end
if fields.set_invisible then meta:set_string(attr.key, 'false') end
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.set_visibility(name) end
end
-- Set timer position
if formname == 'mtimer:set_position' then
local attr = m.meta.position
for p,_ in pairs(fields) do
if p == 'default' then
meta:set_string(attr.key, attr.default)
elseif p:gsub('_.*', '') == 'pos' then
local new_pos = p:gsub('pos_', '')
if new_pos ~= 'xx' then meta:set_string(attr.key, new_pos) end
end
end
if not fields.quit then d.set_position(name) end
end
-- Set timer text color
if formname == 'mtimer:set_color' then
local attr = m.meta.color
local color = ''
-- Set fields.color to predefined color if a button was clicked
if fields.set_color ~= nil then
fields.color = '#'..fields.set_color
end
-- Validate the given color and set it
if fields.color then
local valid = fields.color:match('^#'..('[0-9a-fA-F]'):rep(6)..'$')
local color = valid and fields.color or attr.default
meta:set_string(attr.key, color)
end
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.set_color(name) end
end
-- Configure timezone offset
if formname == 'mtimer:timezone_offset' then
local attr = m.meta.timezone_offset
local value = tonumber(fields.offset) or attr.default
-- Check if a timezone offset button was clicked
for p,_ in pairs(fields) do
if string.sub(p,1,11) == 'new_offset_' then
value = tonumber((p:gsub('new_offset_', '')))
end
end
-- Validate and set new timezone offset
if fields.offset then
if value > 12 then value = 12 end
if value < -12 then value = -12 end
meta:set_string(attr.key, value)
end
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.timezone_offset(name) end
end
-- Set ingame time format
if formname == 'mtimer:ingame_time_format' then
local attr = m.meta.ingame_time_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.ingame_time_format(name)end
end
-- Set real-time format
if formname == 'mtimer:real_world_time_format' then
local attr = m.meta.real_time_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.real_world_time_format(name) end
end
-- Set host time format
if formname == 'mtimer:host_time_format' then
local attr = m.meta.host_time_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.host_time_format(name) end
end
-- Set session start time format
if formname == 'mtimer:session_start_time_format' then
local attr = m.meta.session_start_time_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.session_start_time_format(name) end
end
-- Set session duration format
if formname == 'mtimer:session_duration_format' then
local attr = m.meta.session_duration_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.session_duration_format(name) end
end
-- Set scale of the timer HUD element
if formname == 'mtimer:hud_element_scale' then
local attr = m.meta.hud_element_scale
local value = tonumber(attr.default)
local nv_data = minetest.explode_scrollbar_event(fields.new_value)
-- Set new value if value was changed
if nv_data.type == 'CHG' then
value = nv_data.value
if value < 1 then value = 1 end
if value > 10 then value = 10 end
meta:set_string(attr.key, value)
end
-- DEVELOPERS: Ideally this formspec would fully reset (like when
-- closed and re-opened) to reflect the scale position when
-- clicking the “Default” button. But for whatever reason
-- this does not work. The scollbar position is simply
-- not set accordingly no matter what I tried.
--
-- A pesky pseudosolution is to accept what it is and just
-- inform the player about this fact.
--
-- Trust me, I tried for roughly 1-2 hours before giving
-- up, without having either the formspec not reset when
-- clicking the default button or not being able to drag
-- the scollbar because the formspec gets re-sent.
--
-- I even tried to manually closing the formspec and
-- re-opening it via `minetest.after` to prevent race
-- conditions. This worked with a delay of 0.1 seconds
-- every now and then and with smaller delays the whole
-- screen looked like it “flashed” because, well, the
-- formspec was closed and then re-opened after the delay.
--
-- But I absolutely hate the solution so I just accepted
-- how it works. If everyone ever reading this and knows
-- a proper solution to re-sent the formspec and have it
-- using the actual value instead of keeping the previous
-- value Id be glad hearing from you :)
--
-- Have awonderful day!
--
-- Kind regards,
-- Dirk
if fields.default then
-- This works as expected
meta:set_string(attr.key, attr.default)
-- it should reset the scrollbar position here when clicking the
-- default button but it doesnt …
d.hud_element_scale(name)
end
end
-- Set offset (used as border/padding) of the timer HUD element
if formname == 'mtimer:hud_element_offset' then
local attr = m.meta.hud_element_offset
local default = minetest.deserialize(attr.default)
local x_offset = tonumber(fields.x_offset) or default.x
local y_offset = tonumber(fields.y_offset) or default.y
if fields.x_add_1 then x_offset = x_offset + 1 end
if fields.y_add_1 then y_offset = y_offset + 1 end
if fields.x_substract_1 then x_offset = x_offset - 1 end
if fields.y_substract_1 then y_offset = y_offset - 1 end
meta:set_string(attr.key, minetest.serialize({
x = x_offset,
y = y_offset
}))
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.hud_element_offset(name) end
end
-- Set timer text
if formname == 'mtimer:timer_format' then
local attr = m.meta.timer_format
local value = fields.format or attr.default
meta:set_string(attr.key, value)
if fields.default then meta:set_string(attr.key, attr.default) end
if not fields.quit then d.timer_format(name) end
end
-- Custom timer setting and configuration
if formname == 'mtimer:custom_timer' then
local attr = m.meta.custom_timer_settings
local ctv = minetest.deserialize(meta:get_string(attr.key))
local entered = fields.key_enter_field or ''
-- Set mode
if fields.mode_countdown ~= nil then ctv.timer_mode='countdown' end
if fields.mode_timer ~= nil then ctv.timer_mode='timer' end
if fields.mode_continuous ~= nil then ctv.timer_mode='continuous' end
-- Validate direct input
local days = tonumber(fields.v_days) or 0
local hours = tonumber(fields.v_hours) or 0
local minutes = tonumber(fields.v_minutes) or 0
local seconds = tonumber(fields.v_seconds) or 0
-- Set values from plus/minus input
if fields.c_days_p then days = days + 1 end
if fields.c_hours_p then hours = hours + 1 end
if fields.c_minutes_p then minutes = minutes + 1 end
if fields.c_seconds_p then seconds = seconds + 1 end
if fields.c_days_m then days = days - 1 end
if fields.c_hours_m then hours = hours - 1 end
if fields.c_minutes_m then minutes = minutes - 1 end
if fields.c_seconds_m then seconds = seconds - 1 end
-- Validate values
if seconds >= 60 then seconds = 0 minutes = minutes + 1 end
if minutes >= 60 then minutes = 0 hours = hours + 1 end
if hours >= 24 then hours = 0 days = days + 1 end
if seconds < 0 then seconds = 59 minutes = minutes - 1 end
if minutes < 0 then minutes = 59 hours = hours - 1 end
if hours < 0 then hours = 23 days = days - 1 end
if days < 0 then days = 0 end
-- set relevant values
ctv.format = {
running = fields.v_format_running,
stopped = fields.v_format_stopped,
finished = fields.v_format_finished
}
ctv.values = {
days = days,
hours = hours,
minutes = minutes,
seconds = seconds
}
-- Set default values if requested and instantly return to prevent the
-- rest of the configuration to be executed. At this point only
-- resetting all values is desired.
if fields.default then
meta:set_string(attr.key, attr.default)
d.custom_timer(name)
m.update_timer(name)
return
end
-- Set values if not quitting
if not fields.quit then
meta:set_string(attr.key, minetest.serialize(ctv))
end
-- Control timer if one of the control buttons was pressed. This is run
-- after the values safing in order to use the new values instead of
-- the values that were stored before.
local ct_update = false
if fields.ct_start then ct_update = { action = 'start' } end
if fields.ct_stop then ct_update = { action = 'stop' } end
if fields.ct_restart then ct_update = { action = 'restart' } end
if ct_update~=false then mtimer.update_custom_timer(name,ct_update) end
-- Show the timer formspec if not quitting
if not fields.quit then d.custom_timer(name) end
end
-- Reset everything
if formname == 'mtimer:reset_everything' then
local kick_message = m.translator('You requested a hard reset of the mTimer configuration. This request was stored. As described, you were kicked from the server in order to have the hard reset performed. Please rejoin the server. On rejoin all previously stored configuration regarding mTimer will be deleted.')
-- Perform a soft reset
if fields.reset_soft then
for _,def in pairs(m.meta) do
meta:set_string(def.key, def.default)
end
end
-- Request hard reset and kick the player with informational message
if fields.reset_hard then
meta:set_int(m.meta.hard_reset_everything.key, os.time())
minetest.kick_player(name, kick_message)
end
-- Show main menu formspec when cancelled or close on fields.quit
if fields.reset_cancel then d.main_menu(name) return end
if not fields.quit then d.reset_everything(name) end
end
-- Back to menu from all formspecs and conditionally update timer
if fields.main_menu then d.main_menu(name) end
if formname ~= 'mtimer:main_menu' then m.update_timer(name) end
end)