2019-02-21 14:37:58 +01:00
|
|
|
|
local m = mtimer
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local S = m.translator
|
2021-02-11 21:49:26 +01:00
|
|
|
|
local ds = minetest.deserialize
|
2019-02-21 14:37:58 +01:00
|
|
|
|
|
|
|
|
|
|
2021-10-16 22:07:33 +02:00
|
|
|
|
-- Manually calculate am/pm
|
|
|
|
|
--
|
|
|
|
|
-- Because %p returns am/pm or nothing depending on current locale it is not
|
|
|
|
|
-- reliable to use it. This function takes a 24h hours value and returns the
|
|
|
|
|
-- correct meridiem indicator.
|
|
|
|
|
--
|
|
|
|
|
-- @param hour The hour to get the indicator for in 24h format
|
|
|
|
|
-- @return string The meridiem indicator for that hour
|
|
|
|
|
local get_mi = function (hour)
|
|
|
|
|
local s_hour = tonumber(hour)
|
|
|
|
|
if s_hour >= 0 and s_hour <= 11 then return S('am') end -- midnight->noon
|
|
|
|
|
if s_hour >= 12 and s_hour <= 23 then return S('pm') end -- noon->midnight
|
|
|
|
|
return S('(ERROR)')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- Get translated date names
|
|
|
|
|
--
|
|
|
|
|
-- This helper function takes a table containing a numerical month and a
|
2019-03-16 22:48:49 +01:00
|
|
|
|
-- numerical day of the week and returns the respecive names that are ready
|
|
|
|
|
-- for being translated.
|
2019-02-22 20:33:42 +01:00
|
|
|
|
--
|
|
|
|
|
-- { day = 1, month = 6 } -> { day = S('Monday'), month = S('May') }
|
|
|
|
|
--
|
|
|
|
|
-- @param dates A table of dates as described
|
|
|
|
|
-- @return table The table containing the date names
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local get_date_names = function (dates)
|
|
|
|
|
-- %w -> weekday [0-6 = Sunday-Saturday]
|
|
|
|
|
local weekdays = {
|
|
|
|
|
S('Sunday'), S('Monday'), S('Tuesday'), S('Wednesday'), S('Thursday'),
|
|
|
|
|
S('Friday'), S('Saturday')
|
|
|
|
|
}
|
|
|
|
|
-- %m -> month [01-12 = January-December]
|
|
|
|
|
local months = {
|
|
|
|
|
S('January'), S('February'), S('March'), S('April'), S('May'),
|
2021-10-20 18:51:43 +02:00
|
|
|
|
S('June'), S('July'), S('August'), S('September'), S('October'),
|
2019-02-21 21:07:35 +01:00
|
|
|
|
S('November'), S('December')
|
|
|
|
|
}
|
|
|
|
|
return {
|
2019-03-24 09:54:58 +01:00
|
|
|
|
day = weekdays[tonumber(dates.day+1)],
|
2019-02-21 21:07:35 +01:00
|
|
|
|
month = months[tonumber(dates.month)]
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- Real-world time handling
|
|
|
|
|
--
|
2019-03-16 22:48:49 +01:00
|
|
|
|
-- This function returns the formatted string as well as the raw format string
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- and all the replacement values for the variables basing on what time type
|
|
|
|
|
-- was requested. The types are `real` for the real-world time or `session`
|
|
|
|
|
-- for the session start time.
|
|
|
|
|
--
|
|
|
|
|
-- Both of the times use the same syntax and have the same variables to set so
|
|
|
|
|
-- one function is used for both when getting the times with `mtimer.get_times`
|
|
|
|
|
-- where needed.
|
|
|
|
|
--
|
|
|
|
|
-- {
|
|
|
|
|
-- times = {
|
|
|
|
|
-- server_time = ISO 8601 date of the server’s timestamp,
|
|
|
|
|
-- server_local = ISO 8601 date of the local ofsetted timestamp,
|
|
|
|
|
-- offset = timezone offset as set by the player
|
|
|
|
|
-- },
|
|
|
|
|
-- variables = {
|
|
|
|
|
-- hours_24 = 24h representation of the time,
|
|
|
|
|
-- hours_12 = 12h representation of the time,
|
|
|
|
|
-- minutes = minutes for the requested time,
|
|
|
|
|
-- seconds = seconds for the requested time,
|
|
|
|
|
-- dayname = name of the day for the requested time,
|
|
|
|
|
-- monthname = name of the month for the requested time,
|
|
|
|
|
-- year = year of the requested time,
|
|
|
|
|
-- month = month of the requested time,
|
|
|
|
|
-- day = day of the requested time,
|
|
|
|
|
-- iso8601_date = ISO 8601 date part based on the requested time,
|
2019-03-16 22:48:49 +01:00
|
|
|
|
-- iso8601_time = ISO 8601 time part based on the requested time,
|
|
|
|
|
-- timestamp = the date’s timestamp
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- },
|
|
|
|
|
-- format = raw string for formatting the requeste time type,
|
|
|
|
|
-- formatted = the formatted (all variables replaced) string
|
|
|
|
|
-- }
|
|
|
|
|
--
|
|
|
|
|
-- @param player_name The name of the player to get the times for
|
|
|
|
|
-- @param time_type A Time type as described
|
|
|
|
|
-- @return table The table containing the data as described
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local get_real_time_universal = function (player_name, time_type)
|
2019-02-21 14:37:58 +01:00
|
|
|
|
local player = minetest.get_player_by_name(player_name)
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local player_meta = player:get_meta()
|
|
|
|
|
local m_meta = m.meta
|
|
|
|
|
local timezone_offset = player_meta:get_string(m_meta.timezone_offset.key)
|
|
|
|
|
local server_timestamp = ''
|
|
|
|
|
local local_timestamp = ''
|
|
|
|
|
local format = ''
|
2019-04-12 21:56:06 +02:00
|
|
|
|
local force_utc = '!'
|
2019-02-21 14:37:58 +01:00
|
|
|
|
|
2019-02-21 21:07:35 +01:00
|
|
|
|
if time_type == 'real' then
|
|
|
|
|
server_timestamp = os.time()
|
|
|
|
|
local_timestamp = server_timestamp + ((timezone_offset*60)*60)
|
2020-08-16 00:13:24 +02:00
|
|
|
|
format = player_meta:get_string(m_meta.real_time_format.key)
|
2019-02-21 21:07:35 +01:00
|
|
|
|
elseif time_type == 'session' then
|
|
|
|
|
server_timestamp = player_meta:get('mtimer:session_start')
|
|
|
|
|
local_timestamp = server_timestamp + ((timezone_offset*60)*60)
|
2020-08-16 00:13:24 +02:00
|
|
|
|
format = player_meta:get_string(m_meta.session_start_time_format.key)
|
2019-04-12 21:56:06 +02:00
|
|
|
|
elseif time_type == 'host' then
|
|
|
|
|
server_timestamp = os.time()
|
|
|
|
|
local_timestamp = server_timestamp
|
2020-08-16 00:13:24 +02:00
|
|
|
|
format = player_meta:get_string(m_meta.host_time_format.key)
|
2019-04-12 21:56:06 +02:00
|
|
|
|
force_utc = ''
|
2019-02-21 21:07:35 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local date_names = get_date_names({
|
|
|
|
|
day = os.date('!%w', local_timestamp),
|
|
|
|
|
month = os.date('!%m', local_timestamp)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
local values = {
|
|
|
|
|
times = {
|
2019-03-12 21:41:53 +01:00
|
|
|
|
server_time = os.date('%Y-%m-%dT%H:%M:%S', server_timestamp),
|
|
|
|
|
local_time = os.date('!%Y-%m-%dT%H:%M:%S', local_timestamp),
|
2019-02-21 21:07:35 +01:00
|
|
|
|
offset = timezone_offset,
|
|
|
|
|
},
|
|
|
|
|
variables = {
|
2019-04-12 21:56:06 +02:00
|
|
|
|
hours_24 = os.date(force_utc..'%H', local_timestamp),
|
|
|
|
|
hours_12 = os.date(force_utc..'%I', local_timestamp),
|
|
|
|
|
minutes = os.date(force_utc..'%M', local_timestamp),
|
|
|
|
|
seconds = os.date(force_utc..'%S', local_timestamp),
|
2021-10-16 22:07:33 +02:00
|
|
|
|
indicator = get_mi(os.date(force_utc..'%H', local_timestamp)),
|
2019-02-21 21:07:35 +01:00
|
|
|
|
dayname = date_names.day,
|
|
|
|
|
monthname = date_names.month,
|
2019-04-12 21:56:06 +02:00
|
|
|
|
year = os.date(force_utc..'%Y', local_timestamp),
|
|
|
|
|
month = os.date(force_utc..'%m', local_timestamp),
|
|
|
|
|
day = os.date(force_utc..'%d', local_timestamp),
|
|
|
|
|
iso8601_date = os.date(force_utc..'%Y-%m-%d', local_timestamp),
|
|
|
|
|
iso8601_time = os.date(force_utc..'%H:%M:%S', local_timestamp),
|
2019-02-21 21:07:35 +01:00
|
|
|
|
timestamp = local_timestamp
|
|
|
|
|
},
|
|
|
|
|
format = format
|
2019-02-21 14:37:58 +01:00
|
|
|
|
}
|
2019-02-21 21:07:35 +01:00
|
|
|
|
|
|
|
|
|
values['formatted'] = format:gsub('{[a-z0-9]+}', {
|
|
|
|
|
['{24h}'] = values.variables.hours_24,
|
|
|
|
|
['{12h}'] = values.variables.hours_12,
|
|
|
|
|
['{min}'] = values.variables.minutes,
|
|
|
|
|
['{sec}'] = values.variables.seconds,
|
2021-10-16 22:07:33 +02:00
|
|
|
|
['{mi}'] = values.variables.indicator,
|
2019-02-21 21:07:35 +01:00
|
|
|
|
['{dname}'] = values.variables.dayname,
|
|
|
|
|
['{mname}'] = values.variables.monthname,
|
|
|
|
|
['{year}'] = values.variables.year,
|
|
|
|
|
['{month}'] = values.variables.month,
|
|
|
|
|
['{day}'] = values.variables.day,
|
|
|
|
|
['{isodate}'] = values.variables.iso8601_date,
|
|
|
|
|
['{isotime}'] = values.variables.iso8601_time,
|
|
|
|
|
['{timestamp}'] = values.variables.timestamp
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return values
|
2019-02-21 14:37:58 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- Getting the ingame time
|
|
|
|
|
--
|
|
|
|
|
-- This function gets and parses the ingame time based on the configuration set
|
|
|
|
|
-- by the player. The following table is returned.
|
|
|
|
|
--
|
|
|
|
|
-- {
|
|
|
|
|
-- hours_24 = 24h representation of the time,
|
|
|
|
|
-- hours_12 = 12h representation of the time,
|
|
|
|
|
-- minutes = minutes for the requested time,
|
|
|
|
|
-- ingame_timestamp = timestamp of the ingame time (seconds since 0),
|
|
|
|
|
-- format = raw string for formatting the time,
|
|
|
|
|
-- formatted = the formatted (all variables replaced) string
|
|
|
|
|
-- }
|
|
|
|
|
--
|
|
|
|
|
-- Calculation: The function `minetest.get_timeofday()` returns a fraction
|
|
|
|
|
-- between 0 and 1 for the time of the day. Multiplication with
|
|
|
|
|
-- 24000 converts this number to a millihours value (mh). By
|
|
|
|
|
-- multiplication with 3.6 the mh value is converted into a
|
|
|
|
|
-- seconds value that can be used as timestamp.
|
|
|
|
|
--
|
|
|
|
|
-- Usabiliy: After 86400 seconds (or 24000 mh) the timestamp returns to 0 and
|
|
|
|
|
-- thus is only useful to represent the time of the day and nothing
|
|
|
|
|
-- else like the date or something like that.
|
|
|
|
|
--
|
2019-03-16 22:48:49 +01:00
|
|
|
|
-- The generated timestamp is then passed to the os.date() default Lua function
|
|
|
|
|
-- to parse the human-readable interpretations. Technically this is our own
|
|
|
|
|
-- epoch timestamp just being reset after 86400 seconds.
|
|
|
|
|
--
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- @param player_name The name of the player to get the time for
|
|
|
|
|
-- @return table The table as described
|
2019-02-21 16:16:10 +01:00
|
|
|
|
local get_ingame_time = function (player_name)
|
|
|
|
|
local player = minetest.get_player_by_name(player_name)
|
2020-08-16 00:13:24 +02:00
|
|
|
|
local format = player:get_meta():get_string(m.meta.ingame_time_format.key)
|
2021-10-20 18:58:24 +02:00
|
|
|
|
local time_of_day = math.floor((minetest.get_timeofday() * 24000) * 3.6)
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local ingame_timestamp = tonumber(string.format('%.0f', time_of_day))
|
2019-02-21 16:16:10 +01:00
|
|
|
|
|
|
|
|
|
local values = {
|
|
|
|
|
hours_24 = os.date('!%H', ingame_timestamp),
|
|
|
|
|
hours_12 = os.date('!%I', ingame_timestamp),
|
|
|
|
|
minutes = os.date('!%M', ingame_timestamp),
|
2021-10-16 22:07:33 +02:00
|
|
|
|
indicator = get_mi(os.date(os.date('!%H', ingame_timestamp))),
|
2019-02-21 16:16:10 +01:00
|
|
|
|
ingame_timestamp = ingame_timestamp,
|
|
|
|
|
format = format
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
values['formatted'] = format:gsub('{[a-z0-9]+}', {
|
|
|
|
|
['{24h}'] = values.hours_24,
|
|
|
|
|
['{12h}'] = values.hours_12,
|
|
|
|
|
['{min}'] = values.minutes,
|
2021-10-16 22:07:33 +02:00
|
|
|
|
['{mi}'] = values.indicator,
|
2019-02-21 16:16:10 +01:00
|
|
|
|
['{its}'] = values.ingame_timestamp
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return values
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- Getting the session duration
|
|
|
|
|
--
|
|
|
|
|
-- This function gets the session start timestamp and the current timestamp and
|
|
|
|
|
-- calculates the difference in days, hours, minutes, and seconds. The values
|
|
|
|
|
-- are added to the return table as shown below. Additionaly the format string
|
|
|
|
|
-- and the formatted result string are added to this table
|
|
|
|
|
--
|
|
|
|
|
-- {
|
|
|
|
|
-- format = raw string for formatting the time,
|
|
|
|
|
-- difference = the raw difference in seconds,
|
|
|
|
|
-- days = days the difference is long,
|
|
|
|
|
-- hours = hours the difference is long,
|
|
|
|
|
-- minutes = minutes the difference is long,
|
|
|
|
|
-- seconds = seconds the difference is long,
|
|
|
|
|
-- formatted = the formatted (all variables replaced) string
|
|
|
|
|
-- }
|
|
|
|
|
--
|
|
|
|
|
-- @param player_name The name of the player to get the duration for
|
|
|
|
|
-- @return table The table as described
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local get_session_duration = function (player_name)
|
|
|
|
|
local player = minetest.get_player_by_name(player_name)
|
|
|
|
|
local player_meta = player:get_meta()
|
2020-08-16 00:13:24 +02:00
|
|
|
|
local format = player_meta:get_string(m.meta.session_duration_format.key)
|
2019-02-21 21:07:35 +01:00
|
|
|
|
local start_timestamp = player_meta:get_string('mtimer:session_start')
|
|
|
|
|
local current_timestamp = os.time()
|
|
|
|
|
local difference = current_timestamp - start_timestamp
|
|
|
|
|
|
|
|
|
|
local values = {
|
|
|
|
|
format = format,
|
|
|
|
|
difference = difference,
|
|
|
|
|
days = string.format('%02d', math.floor(difference/86400)),
|
|
|
|
|
hours = string.format('%02d', math.floor((difference % 86400)/3600)),
|
|
|
|
|
minutes = string.format('%02d', math.floor((difference % 3600)/60)),
|
|
|
|
|
seconds = string.format('%02d', math.floor((difference % 60)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
values['formatted'] = format:gsub('{[a-z0-9]+}', {
|
|
|
|
|
['{days}'] = values.days,
|
|
|
|
|
['{hours}'] = values.hours,
|
|
|
|
|
['{minutes}'] = values.minutes,
|
|
|
|
|
['{seconds}'] = values.seconds
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return values
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2021-02-12 20:23:40 +01:00
|
|
|
|
-- Custom timer
|
|
|
|
|
--
|
|
|
|
|
-- The timer values are loaded from the meta entry and are calculated on
|
|
|
|
|
-- runtime. The timer knows thre modes.
|
|
|
|
|
--
|
|
|
|
|
-- 1. continuous run
|
|
|
|
|
--
|
|
|
|
|
-- In this mode the time just runs in a continuous way and all that is
|
|
|
|
|
-- calculated is the difference between the current timestamp and the
|
|
|
|
|
-- timestamp from when the timer was started.
|
|
|
|
|
--
|
|
|
|
|
-- 2. countdown
|
|
|
|
|
--
|
|
|
|
|
-- For the countdown the given input values and the start timestamp are
|
|
|
|
|
-- added together, then the current timestamp is substracted from this.
|
|
|
|
|
-- This results in the difference getting smaller and eventually being
|
|
|
|
|
-- equal or less than 0. In this case the format is changed to the “timer
|
|
|
|
|
-- finished” format.
|
|
|
|
|
--
|
|
|
|
|
-- 3. timer
|
|
|
|
|
--
|
|
|
|
|
-- The timer mode calculated the difference like the continuous run mode
|
|
|
|
|
-- but also calculates a target from the starting timestamp and the input
|
|
|
|
|
-- values. When the difference is equal or larger than the target the format
|
|
|
|
|
-- is changed to the “timer finished” format.
|
|
|
|
|
--
|
|
|
|
|
-- The output is parsed outside the mode-specific calculations. Also every
|
|
|
|
|
-- format is parsed with the output time parts. This automatically allows all
|
|
|
|
|
-- time parts in all formats – wich makes no sense because the difference
|
|
|
|
|
-- calculation is messed up outside the specific boundaries.
|
2021-02-10 21:34:11 +01:00
|
|
|
|
local get_custom_timer = function (player_name)
|
|
|
|
|
local player = minetest.get_player_by_name(player_name)
|
|
|
|
|
local player_meta = player:get_meta()
|
2021-02-11 21:49:26 +01:00
|
|
|
|
local ctv = ds(player_meta:get_string(m.meta.custom_timer_settings.key))
|
2021-02-12 20:23:40 +01:00
|
|
|
|
local current_timestamp = os.time(os.date('!*t'))
|
2021-02-10 21:34:11 +01:00
|
|
|
|
|
2021-02-12 20:23:40 +01:00
|
|
|
|
local running = ctv.running
|
|
|
|
|
local difference = 0
|
|
|
|
|
local format = ''
|
|
|
|
|
local finished = false
|
2021-02-10 21:34:11 +01:00
|
|
|
|
|
2021-02-12 20:23:40 +01:00
|
|
|
|
if running == false then format = ctv.format.stopped end
|
|
|
|
|
if running == true and finished == true then format=ctv.format.finished end
|
|
|
|
|
if running == true and finished == false then format=ctv.format.running end
|
|
|
|
|
|
|
|
|
|
-- Calculate seconds from the given input values
|
|
|
|
|
local value_seconds = 0
|
|
|
|
|
value_seconds = value_seconds + ctv.values.seconds
|
|
|
|
|
value_seconds = value_seconds + (ctv.values.minutes * 60)
|
|
|
|
|
value_seconds = value_seconds + (ctv.values.hours * 3600)
|
|
|
|
|
value_seconds = value_seconds + (ctv.values.days * 86400)
|
|
|
|
|
|
|
|
|
|
-- Continuous run
|
|
|
|
|
if running == true and ctv.timer_mode == 'continuous' then
|
|
|
|
|
difference = current_timestamp - (ctv.start_timestamp - value_seconds)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Countdown
|
|
|
|
|
if running == true and ctv.timer_mode == 'countdown' then
|
|
|
|
|
difference = (ctv.start_timestamp + value_seconds) - current_timestamp
|
|
|
|
|
if difference <= 0 then format = ctv.format.finished end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Timer
|
|
|
|
|
if running == true and ctv.timer_mode == 'timer' then
|
|
|
|
|
difference = current_timestamp - ctv.start_timestamp
|
|
|
|
|
local target = ctv.start_timestamp + value_seconds
|
|
|
|
|
if current_timestamp >= target then format = ctv.format.finished end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Parse values into time parts
|
|
|
|
|
local result_values = {
|
|
|
|
|
days = string.format('%02d', math.floor(difference/86400)),
|
|
|
|
|
hours = string.format('%02d', math.floor((difference % 86400)/3600)),
|
|
|
|
|
minutes = string.format('%02d', math.floor((difference % 3600)/60)),
|
|
|
|
|
seconds = string.format('%02d', math.floor((difference % 60)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
formatted = format:gsub('{[a-z0-9]+}', {
|
|
|
|
|
['{days}'] = result_values.days or 0,
|
|
|
|
|
['{hours}'] = result_values.hours or 0,
|
|
|
|
|
['{minutes}'] = result_values.minutes or 0,
|
|
|
|
|
['{seconds}'] = result_values.seconds or 0
|
|
|
|
|
})
|
|
|
|
|
}
|
2021-02-10 21:34:11 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2019-02-22 20:33:42 +01:00
|
|
|
|
-- Get the times
|
|
|
|
|
--
|
|
|
|
|
-- Returns the times for the given player referenced by the player’s name as
|
|
|
|
|
-- a table as shown below.
|
|
|
|
|
--
|
|
|
|
|
-- {
|
|
|
|
|
-- session_start_time = @see get_real_time_universal,
|
|
|
|
|
-- session_duration = @see get_session_duration,
|
|
|
|
|
-- real_time = @see get_real_time_universal,
|
|
|
|
|
-- ingame_time = @see get_ingame_time
|
|
|
|
|
-- }
|
|
|
|
|
--
|
|
|
|
|
-- @param player_name The name of the player to get the times for
|
|
|
|
|
-- @return table The table containing the times as described
|
2019-02-21 14:37:58 +01:00
|
|
|
|
mtimer.get_times = function (player_name)
|
|
|
|
|
return {
|
2019-04-12 21:56:06 +02:00
|
|
|
|
ingame_time = get_ingame_time(player_name),
|
2019-02-21 21:07:35 +01:00
|
|
|
|
real_time = get_real_time_universal(player_name, 'real'),
|
2019-04-12 21:56:06 +02:00
|
|
|
|
host_time = get_real_time_universal(player_name, 'host'),
|
|
|
|
|
session_start_time = get_real_time_universal(player_name, 'session'),
|
2021-02-10 21:34:11 +01:00
|
|
|
|
session_duration = get_session_duration(player_name),
|
|
|
|
|
custom_timer = get_custom_timer(player_name)
|
2019-02-21 14:37:58 +01:00
|
|
|
|
}
|
|
|
|
|
end
|