diff --git a/config/command_auth_admin.lua b/config/command_auth_admin.lua index 4817e643..19ef9198 100644 --- a/config/command_auth_admin.lua +++ b/config/command_auth_admin.lua @@ -8,7 +8,7 @@ Commands.add_authenticator(function(player,command,tags,reject) if player.admin then return true else - return reject('This command is for admins only!') + return reject{'command-auth.admin-only'} end else return true diff --git a/config/command_auth_runtime_disable.lua b/config/command_auth_runtime_disable.lua new file mode 100644 index 00000000..0f4861fb --- /dev/null +++ b/config/command_auth_runtime_disable.lua @@ -0,0 +1,25 @@ +--- This config for command auth allows commands to be globally enabled and disabled during runtime +-- this config adds Commands.disable and Commands.enable to enable and disable commands for all users +local Commands = require 'expcore.commands' +local Global = require 'utils.global' + +local disabled_commands = {} +Global.register(disabled_commands,function(tbl) + disabled_commands = tbl +end) + +function Commands.disable(command_name) + disabled_commands[command_name] = true +end + +function Commands.enable(command_name) + disabled_commands[command_name] = nil +end + +Commands.add_authenticator(function(player,command,tags,reject) + if disabled_commands[command] then + return reject{'command-auth.command-disabled'} + else + return true + end +end) \ No newline at end of file diff --git a/config/config.cfg b/config/config.cfg new file mode 100644 index 00000000..b12b17cf --- /dev/null +++ b/config/config.cfg @@ -0,0 +1,3 @@ +[command-auth] +admin-only=This command is for (game) admins only! +command-disabled=This command has been disabled by management! \ No newline at end of file diff --git a/config/death_logger.lua b/config/death_logger.lua new file mode 100644 index 00000000..4b5ba5f5 --- /dev/null +++ b/config/death_logger.lua @@ -0,0 +1,12 @@ +--- This config controls what happens when a player dies mostly about map markers and item collection +-- allow_teleport_to_body_command and allow_collect_bodies_command can be over ridden if command_auth_runtime_disable is present +-- if not present then the commands will not be loaded into the game +return { + --allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death + --allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body + --use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies + --auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death + show_map_markers=true, -- shows markers on the map where bodies are + include_time_of_death=true, -- weather to include the time of death on the map marker + map_icon=nil -- the icon that the map marker shows; nil means no icon; format as a SingleID +} \ No newline at end of file diff --git a/config/file_loader.lua b/config/file_loader.lua index 79f42801..db6b68bc 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -17,7 +17,9 @@ return { -- QoL Addons 'modules.addons.chat-popups', 'modules.addons.damage-popups', + 'modules.addons.death-markers', -- Config Files - 'config.command_auth_admin', -- commands tags with admin_only are blocked for non admins + 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins + 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups } \ No newline at end of file diff --git a/expcore/common.lua b/expcore/common.lua index 1f7f6448..74f2eb3a 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -135,4 +135,88 @@ function Public.ext_require(path,...) return Public.extract_keys(rtn,...) end +--- Formats tick into a clean format, denominations from highest to lowest +-- long will use words rather than letters +-- time will use : separates +-- string will return a string not a locale string +-- when a denomination is false it will overflow into the next one +-- @tparam ticks number the number of ticks that represents a time +-- @tparam options table a table of options to use for the format +-- @treturn string a locale string that can be used +function Public.format_time(ticks,options) + -- Sets up the options + options = options or { + days=false, + hours=true, + minutes=true, + seconds=false, + long=false, + time=false, + string=false + } + -- Basic numbers that are used in calculations + local max_days, max_hours, max_minutes, max_seconds = ticks/5184000, ticks/216000, ticks/3600, ticks/60 + local days, hours = max_days, max_hours-math.floor(max_days)*24 + local minutes, seconds = max_minutes-math.floor(max_hours)*60, max_seconds-math.floor(max_minutes)*60 + -- Handles overflow of disabled denominations + local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = math.floor(days), math.floor(hours), math.floor(minutes), math.floor(seconds) + if not options.days then + rtn_hours = rtn_hours + rtn_days*24 + end + if not options.hours then + rtn_minutes = rtn_minutes + rtn_hours*60 + end + if not options.minutes then + rtn_seconds = rtn_seconds + rtn_minutes*60 + end + -- Format options + local suffix = 'time-symbol-' + local suffix_2 = '-short' + if options.long then + suffix = '' + suffix_2 = '' + end + local div = options.string and ' ' or 'time-format.simple-format-tagged' + if options.time then + div = options.string and ':' or 'time-format.simple-format-div' + suffix = false + end + -- Adds formatting + if suffix ~= false then + if options.string then + -- format it as a string + local long = suffix == '' + rtn_days = long and rtn_days..' days' or rtn_days..'d' + rtn_hours = long and rtn_hours..' hours' or rtn_hours..'h' + rtn_minutes = long and rtn_minutes..' minutes' or rtn_minutes..'m' + rtn_seconds = long and rtn_seconds..' seconds' or rtn_seconds..'s' + else + rtn_days = {suffix..'days'..suffix_2,rtn_days} + rtn_hours = {suffix..'hours'..suffix_2,rtn_hours} + rtn_minutes = {suffix..'minutes'..suffix_2,rtn_minutes} + rtn_seconds = {suffix..'seconds'..suffix_2,rtn_seconds} + end + else + -- weather string or not it has same format + rtn_days = string.format('%02d',rtn_days) + rtn_hours = string.format('%02d',rtn_hours) + rtn_minutes = string.format('%02d',rtn_minutes) + rtn_seconds = string.format('%02d',rtn_seconds) + end + -- The final return is construed + local rtn + local append = function(dom,value) + if dom and options.string then + rtn = rtn and rtn..div..value or value + elseif dom then + rtn = rtn and {div,rtn,value} or value + end + end + append(options.day,rtn_days) + append(options.hours,rtn_hours) + append(options.minutes,rtn_minutes) + append(options.seconds,rtn_seconds) + return rtn +end + return Public \ No newline at end of file diff --git a/locale/en/config.cfg b/locale/en/config.cfg new file mode 100644 index 00000000..b12b17cf --- /dev/null +++ b/locale/en/config.cfg @@ -0,0 +1,3 @@ +[command-auth] +admin-only=This command is for (game) admins only! +command-disabled=This command has been disabled by management! \ No newline at end of file diff --git a/locale/en/expcore.cfg b/locale/en/expcore.cfg index b33e7ee3..e5572501 100644 --- a/locale/en/expcore.cfg +++ b/locale/en/expcore.cfg @@ -1,3 +1,5 @@ +time-symbol-days-short=__1__d + [expcore-commands] unauthorized=Unauthorized, Access is denied due to invalid credentials reject-string-options=Invalid Option, Must be one of: __1__ @@ -14,4 +16,9 @@ invalid-param=Invalid Param "__1__"; __2__ command-help=__1__ - __2__ command-ran=Command Complete command-fail=Command failed to run: __1__ -command-error-log-format=[ERROR] command/__1__ :: __2__ \ No newline at end of file +command-error-log-format=[ERROR] command/__1__ :: __2__ + +[time-format] +simple-format-none=__1__ +simple-format-div=__1__:__2__ +simple-format-tagged=__1__ __2__ diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua new file mode 100644 index 00000000..4743b99d --- /dev/null +++ b/modules/addons/death-logger.lua @@ -0,0 +1,84 @@ +local Event = require 'utils.event' +local Game = require 'utils.game' +local Global = require 'utils.global' +local config = require 'config.death_logger' +local format_time = ext_require('expcore.common','format_time') + +local deaths = { + archive={} -- deaths moved here after body is gone + --{player_name='Cooldude2606',time_of_death='15H 15M',position={x=0,y=0},corpse=LuaEntity,tag=LuaCustomChartTag} +} +Global.register(deaths,function(tbl) + deaths = tbl +end) + +--- Creates a new death marker and saves it to the given death +local function create_map_tag(death) + local player = Game.get_player_from_any(death.player_name) + local message = player.name..' died' + if config.include_time_of_death then + local time = format_time(death.time_of_death,{hours=true,minutes=true,string=true}) + message = message..' at '..time + end + death.tag = player.force.add_chart_tag(player.surface,{ + position=death.position, + icon=config.map_icon, + text=message + }) +end + +--- Checks that all map tags are present and valid +-- adds missing ones, deletes expired ones +local function check_map_tags() + for index,death in ipairs(deaths) do + local map_tag = death.tag + local corpse = death.corpse + -- Check the corpse is valid + if corpse and corpse.valid then + -- Corpse is valid check the map tag + if not map_tag or not map_tag.valid then + -- Map tag is not valid make a new one + create_map_tag(death) + end + else + -- Corpse is not valid so remove the map tag + if map_tag and map_tag.valid then + map_tag.destroy() + end + -- Move the death to the archive + death.corpse = nil + death.tag = nil + table.insert(deaths.archive,death) + table.remove(deaths,index) + end + end +end + +-- when a player dies a new death is added to the records and a map marker is made +Event.add(defines.events.on_player_died,function(event) + local player = Game.get_player_by_index(event.player_index) + local corpse = player.surface.find_entity('character-corpse',player.position) + local death = { + player_name = player.name, + time_of_death = event.tick, + position = player.position, + corpse = corpse + } + if config.show_map_markers then + create_map_tag(death) + end + table.insert(deaths,death) +end) + +-- every 5 min all bodies are checked for valid map tags +if config.show_map_markers then + local check_period = 60*60*5 -- five minutes + Event.on_nth_tick(check_period,function(event) + check_map_tags() + end) +end + +-- this is so other modules can access the logs +return function() + return deaths +end \ No newline at end of file diff --git a/modules/commands/interface.lua b/modules/commands/interface.lua index 24424ebf..da03fdd1 100644 --- a/modules/commands/interface.lua +++ b/modules/commands/interface.lua @@ -5,6 +5,7 @@ local Common = require 'expcore.common' -- modules that are loaded into the interface env to be accessed local interface_modules = { ['Game']='utils.game', + ['_C']=Common, ['Commands']=Commands, ['output']=Common.player_return, ['Group']='expcore.permission_groups' diff --git a/old/modules/DeathMarkers/control.lua b/old/modules/DONE/DeathMarkers/control.lua similarity index 100% rename from old/modules/DeathMarkers/control.lua rename to old/modules/DONE/DeathMarkers/control.lua diff --git a/old/modules/DeathMarkers/softmod.json b/old/modules/DONE/DeathMarkers/softmod.json similarity index 100% rename from old/modules/DeathMarkers/softmod.json rename to old/modules/DONE/DeathMarkers/softmod.json diff --git a/old/modules/ExpGamingLib/control.lua b/old/modules/DONE/ExpGamingLib/control.lua similarity index 100% rename from old/modules/ExpGamingLib/control.lua rename to old/modules/DONE/ExpGamingLib/control.lua diff --git a/old/modules/ExpGamingLib/softmod.json b/old/modules/DONE/ExpGamingLib/softmod.json similarity index 100% rename from old/modules/ExpGamingLib/softmod.json rename to old/modules/DONE/ExpGamingLib/softmod.json