The mod will be rewritten from scratch with modern code for most recent
Minetest (feature-complete 5.0.0 pre-release version so when 5.0.0 will
be released the mod will be ready)

See https://gitlab.com/4w/mtimer/issues/3 for status
This commit is contained in:
Dirk Sohler 2019-02-15 19:22:59 +01:00
parent 684bce012f
commit ecfac04415
No known key found for this signature in database
GPG Key ID: B9751241BD7D4E1A
9 changed files with 3 additions and 414 deletions

@ -1 +0,0 @@
default

@ -1,5 +0,0 @@
Creates a timer section on the bottom right of the screen.
The timer allows to show several game related times and dates. Let's play creators can show their viewers when the recording was made, how long the recording was, the current time while recording, and the ingame time.
The timer output is configurable in the advanced configuration of Minetest and provides the user with a set of variables to use and allows the date/time to be formatted as the user wants.

@ -1,67 +0,0 @@
-- Load default configuration
local modpath = minetest.get_modpath(minetest.get_current_modname())..DIR_DELIM
local config = dofile(modpath..'system'..DIR_DELIM..'get_options.lua')
-- Load functions
dofile(modpath..'system'..DIR_DELIM..'timer_function.lua')
dofile(modpath..'system'..DIR_DELIM..'chat_commands.lua')
-- Set custom player attribute if not set
--
-- Sets a custom player attribute if the attribute is not set already.
--
-- @param player The player opbject of the player to set the attribute for
-- @param attribute The attribute to set if not present
-- @param value The value to be set if the attribute does not exist
local set_if_unset = function(player, attribute, value)
local current_value = player:get_attribute(attribute)
if current_value == nil then player:set_attribute(attribute, value) end
end
-- Get a position table from a comma-separated position string
--
-- @param position_string The desired position in `x,y` format
--
-- @return table The position table
mtimer_position = function (position_string)
local given_x = position_string:gsub(',[^,]+$', '')
local given_y = position_string:gsub('^[^,]+,', '')
return {x=given_x, y=given_y}
end
minetest.register_on_joinplayer(function(player)
-- Set default values if not present
set_if_unset(player, 'mtimer:runtime', config['mtimer_runtime'])
set_if_unset(player, 'mtimer:offset', config['mtimer_offset'])
set_if_unset(player, 'mtimer:ingame_time', config['mtimer_ingame_time'])
set_if_unset(player, 'mtimer:current_time', config['mtimer_current_time'])
set_if_unset(player, 'mtimer:font_color', config['mtimer_font_color'])
set_if_unset(player, 'mtimer:start', config['mtimer_start'])
set_if_unset(player, 'mtimer:show', config['mtimer_show'])
set_if_unset(player, 'mtimer:locale', config['mtimer_locale'])
set_if_unset(player, 'mtimer:position', config['mtimer_position'])
set_if_unset(player, 'mtimer:format', config['mtimer_format'])
set_if_unset(player, 'mtimer:alignment', config['mtimer_alignment'])
-- Set join timestamp for later calculations
player:set_attribute('mtimer:joined_timestamp', os.time())
-- Set the hud element ID for later usage and set text to the placeholder
player:set_attribute('mtimer:hud_id', player:hud_add({
hud_elem_type = 'text',
position = mtimer_position(player:get_attribute('mtimer:position')),
alignment = mtimer_position(player:get_attribute('mtimer:alignment')),
offset = mtimer_position(player:get_attribute('mtimer:offset')),
text = config['mtimer_placeholder'],
number = '0x'..player:get_attribute('mtimer:font_color')
}))
-- Run inital update for the player
minetest.after(1, mtimer_update, player)
end)
-- Start iteration after 5 seconds
minetest.after(5, mtimer_iterate, tonumber(config['mtimer_update_interval']))

3
mod.conf Normal file

@ -0,0 +1,3 @@
name = mtimer
depends = default
description = Ingame timer for showing current playtime, current day time, ingame time, etc.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

@ -1,96 +0,0 @@
# Since MT is no real-time application and Lua isn't super
# fast when accessed through the API there is no need in
# setting this to 1 second. The default of 30 seconds is
# absolutely fine.
mtimer_update_interval (Seconds between updates) int 30
# The string will be displayed as provided here. There
# are some variables.
#
# +s = Session start time as formatted
# +c = Current time as formatted
# +r = Runtime of the current session
# +i = Current ingame time in 24h format
# +n = Following output will be in a new line
mtimer_format (Output string formatting) string Session from +s+nCurrent time: +c+nPlaytime: +r, Ingame time: +i
# A placeholder text that is shown before the timer
# function gets executed the first time
mtimer_placeholder (Placeholder for the timer) string [Initializing MTimer]
# The font color for the timer text
#
# Because the timer text is shown all the time the default
# color is not white but a bit darker so it doesnt
# distract too much from the game.
#
# Use the hexadecimal color notation here (“HTML notation”
# but without the `#` sign in front).
mtimer_font_color (Font color for the timer text) string babdb6
[Time Formatting]
# Time when the current session was started. The session
# is based on when the user connected to the world. The
# format is this: https://www.lua.org/pil/22.1.html
mtimer_start ([+s] Session start time) string %c
# A hours:minutes timer that allows tracking of the
# current play time. The timer breaks if game time
# exceeds 24 hours.
#
# +h = Hours
# +m = Minutes
# +s = Seconds
mtimer_runtime ([+r] Session runtime) string +h:+m
# The current real-world time according to what the OS
# provides. Formatting this string is quite easy by using
# those tags: https://www.lua.org/pil/22.1.html
mtimer_current_time ([+c] Current time) string %c
# Ingame time in 24 hours format that was converted
# the provided decimal number and might not be 100
# percent exact.
#
# +h = hours with leading zeros
# +m = minutes with leading zeros
mtimer_ingame_time ([+i] Ingame time) string +h:+m Uhr
# Locale that will be used for the time formatting. The
# locale has to be provided by your system. On Linux see
# command `locale` for valid locales to use.
mtimer_locale (Format output locale) string C
[Positioning]
# Regardless of all other configuration: Show the timer
# in the GUI of the players - or do noit show it.
mtimer_show (Show at all) bool true
# "To account for differing resolutions, the position
# coordinates are the percentage of the screen, ranging
# in value from 0 to 1. 0 means left/top, 1 means
# right/bottom." Separate the numbers with a comma but
# without spaces.
#
# See http://dev.minetest.net/HUD#Fields
mtimer_position (Position) string 0,1
# "Specifies how the item will be aligned. It ranges
# from -1 to 1, with 0 being the center, -1 is moved to
# the left/up, and 1 is to the right/down." Separate the
# numbers with a comma but without spaces.
#
# See http://dev.minetest.net/HUD#Fields
mtimer_alignment (Alignment) string 1,-1
# "Specifies a pixel offset from the position. Not scaled
# to the screen size. [It adapts] to screen DPI as well
# as the user defined scaling factor!" Separate the
# numbers with a comma but without spaces.
#
# See http://dev.minetest.net/HUD#Fields
mtimer_offset (Offset) string 4,0

@ -1,155 +0,0 @@
-- Colorize a string in the given color
--
-- Colorizes a string in a given hexadecimal color coded color. The string will
-- be returned including a reset color escape (assumably white text color)
--
-- @param color The hexadecimal value for the color you want to use
-- @param string The string that has to be colorized
-- @return string The colorized string
local colorize = function (color, string)
local c = minetest.get_color_escape_sequence('#'..string.upper(color))
local r = minetest.get_color_escape_sequence('#FFFFFF')
return c..string..r
end
-- Validate a new value
--
-- 1. Check if setting is valid at all
-- 2. If `show` has to be set, validate for 'true' or 'false' string
-- 3. Validate against a simple regex
-- 4. If all of the above was not `nil`, return `true`
--
-- @param setting The setting the value is for
-- @param new_value The new value that has to be validated
-- @return bool If the new value for the setting is valid or not
local validate = function (setting, new_value)
local valid_values = {
runtime = '^[^%c]+$',
offset = '^%-?[0-9]+,%-?[0-9]+$',
ingame_time = '^[^%c]+$',
current_time = '^[^%c]+$',
font_color = '^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$',
start = '^[^%c]+$',
show = '^$', -- unmatchable, see below
locale = '^$', -- currently unsupported and not settable by user
position = '^%-?[0-9]+,%-?[0-9]+$',
format = '^[^%c]+$',
alignment = '^%-?[0-9]+,%-?[0-9]+$'
}
if valid_values[setting] == nil then return false end
-- Check if `new_value` for setting `show` is either 'true' or 'false' and
-- return true in both cases (because either 'true' or 'false' are valid).
if setting == 'show' and new_value == 'true' then return true end
if setting == 'show' and new_value == 'false' then return true end
if new_value:match(valid_values[setting]) == nil then return false end
return true
end
-- Show help to the player
--
-- @param player The player to show the help to
local show_help = function (player)
local help = colorize('729fcf', 'Mtimer Help')..'\n'
local name = player:get_player_name()
help = help..' '..colorize('73d216', '/mtimer help')..' = '
help = help..'Show this messaget\n'
help = help..' '..colorize('73d216', '/mtimer show')..' = '
help = help..'List the current configuration\n'
help = help..' '..colorize('73d216', '/mtimer set setting value')..' = '
help = help..'Set '..colorize('73d216', 'setting')..' to '
help = help..colorize('73d216', 'value')
minetest.chat_send_player(name, help)
end
-- Show the configuration to the player
--
-- Gathers all settable variables and prints them to the player
--
-- @param player The player object of the player to print to
local show_configuration = function (player)
local name = player:get_player_name()
local result_string = colorize('729fcf', 'MTimer Configuration')..'\n'
local font_color = player:get_attribute('mtimer:font_color')
local configuration = {
runtime = player:get_attribute('mtimer:runtime'),
offset = player:get_attribute('mtimer:offset'),
ingame_time = player:get_attribute('mtimer:ingame_time'),
current_time = player:get_attribute('mtimer:current_time'),
font_color = colorize(font_color, font_color),
start = player:get_attribute('mtimer:start'),
show = player:get_attribute('mtimer:show'),
locale = player:get_attribute('mtimer:locale'),
position = player:get_attribute('mtimer:position'),
format = player:get_attribute('mtimer:format'),
alignment = player:get_attribute('mtimer:alignment')
}
for setting,value in pairs(configuration) do
local s = colorize('73d216', setting)
result_string = result_string..' '..s..' = '..value..'\n'
end
minetest.chat_send_player(name, result_string)
end
local set = function (player, payload)
local name = player:get_player_name()
local setting = payload:match('[%a_]+')
local new_value = payload:gsub('^[%a_]+ ', '')
local old_value = player:get_attribute('mtimer:'..setting)
local status = ''
if old_value == nil then
minetest.chat_send_player(name, colorize('ef2929', 'Unknown setting!'))
show_configuration(player)
return
end
if validate(setting, new_value) == false then
minetest.chat_send_player(name, colorize('ef2929', 'Invalid value!'))
show_configuration(player)
return
end
status = status..colorize('729fcf', '[MTimer]')..' '
status = status..'Setting '..colorize('73d216', setting)..' to '
status = status..colorize('75507b', new_value)
print('[MTimer] '..name..' sets `'..setting..'` to `'..new_value..'`')
minetest.chat_send_player(name, status)
player:set_attribute('mtimer:'..setting, new_value)
mtimer_update(player)
end
-- Register the chat command that will be used to interact with MTimer.
--
-- The chat command has three actions:
--
-- help Show help to the user via the regular chat
-- show Show the current configuration to the user
-- set Set the given setting to the given value
minetest.register_chatcommand('mtimer', {
params = '<help>, <show>, <set setting value>',
description = 'Manage MTimer display',
func = function(name, parameters)
local player = minetest.get_player_by_name(name)
local action = parameters:match('%a+')
local payload = parameters:gsub('^%a+ ', '')
if action == 'help' then show_help(player) end
if action == 'show' then show_configuration(player) end
if action == 'set' and payload ~= nil then set(player, payload) end
end
})

@ -1,14 +0,0 @@
local path = minetest.get_modpath(minetest.get_current_modname())
local file = io.open(path..DIR_DELIM..'settingtypes.txt', 'rb')
local result = {}
for line in file:lines() do
if line:match("^([a-zA-Z])") then
local name = line:gsub(' .+', '')
local default_value = line:gsub('^[^ ]+ %b() %a+ ', '')
local set_value = minetest.setting_get(name)
result[name] = set_value or default_value
end
end
return result

@ -1,76 +0,0 @@
-- Update an idividual players timer display
--
-- When running the function the player data will be read from the players
-- `player` object and the output will be generated
--
-- @param player the player object to update
mtimer_update = function (player)
-- Formatting options
local runtime = player:get_attribute('mtimer:runtime')
local offset = mtimer_position(player:get_attribute('mtimer:offset'))
local ingame_time = player:get_attribute('mtimer:ingame_time')
local current_time = player:get_attribute('mtimer:current_time')
local font_color = player:get_attribute('mtimer:font_color')
local start = player:get_attribute('mtimer:start')
local show = player:get_attribute('mtimer:show')
local locale = player:get_attribute('mtimer:locale')
local position = mtimer_position(player:get_attribute('mtimer:position'))
local format = player:get_attribute('mtimer:format')
local alignment = mtimer_position(player:get_attribute('mtimer:alignment'))
-- Settings
local joined_timestamp = player:get_attribute('mtimer:joined_timestamp')
local hud_id = tonumber(player:get_attribute('mtimer:hud_id'))
-- Calculate ingame time
local ingame_timestamp = 24*60*minetest.get_timeofday()
local ingame_h = tostring((math.floor(ingame_timestamp/60) % 60))
local ingame_m = tostring((math.floor(ingame_timestamp) % 60))
-- Replace variables in output format if wanted by the user
local rendered_output_format = ''
if show == 'true' then
rendered_output_format = format:gsub('+.', {
['+s'] = os.date(start, joined_timestamp),
['+c'] = os.date(current_time),
['+r'] = os.date('!'..runtime:gsub('(+.)', {
['+h'] = '%H',
['+m'] = '%M',
['+s'] = '%S'
}), os.time() - joined_timestamp),
['+i'] = ingame_time:gsub('(+.)', {
['+h'] = string.rep('0', 2-#ingame_h)..ingame_h,
['+m'] = string.rep('0', 2-#ingame_m)..ingame_m
}),
['+n'] = "\n"
})
end
-- Render the output format as HUD element
player:hud_change(hud_id, 'text', rendered_output_format)
player:hud_change(hud_id, 'number', '0x'..font_color)
player:hud_change(hud_id, 'position', position)
player:hud_change(hud_id, 'alignment', alignment)
player:hud_change(hud_id, 'offset', offset)
end
-- Self-calling iteration function
--
-- The function iterates of all currentlz logged on players, checks if they
-- have the custom attribute `mtimer:hud_id` set (this is the last value that
-- will be set when a player joins so the player is set up completely if
-- `mtimer:hud_id` is present in the custom player attributes) and then runs
-- the function to update the timer display. After that the function calls
-- itself again, using the set interval.
--
-- @param interval The intervall used to self-calling again after execution
mtimer_iterate = function(interval)
for _,player in pairs(minetest.get_connected_players()) do
if player:get_attribute('mtimer:hud_id') ~= nil then
mtimer_update(player)
end
end
minetest.after(interval, mtimer_iterate, interval)
end