From 2651262fa3134415f349f63840c89486fabd9063 Mon Sep 17 00:00:00 2001 From: fluxionary <25628292+fluxionary@users.noreply.github.com> Date: Sun, 13 Feb 2022 06:54:41 -0800 Subject: rework mesecons debug to be more flexible (#7) * add proper settings (untested) * more constants -> settings * normalize whitespace between code files * refactor globalsteps in order to simplify logic * minor refactoring * rename file * use mod_storage for persistent data; optimize context initialization * refactoring (moving files around) * rewrite penalty * add settings; document; allow changing while game is running * add command to update settings * update init after splitting commands into files * fix bugs; add debugging tools; too much for one commit... * fix whitelist conversion * add adjustable blinky plant to timer overrides * add some more mesecons nodes with repeating timers * resolve luacheck warnings * tweak hud * Update documentation; parameterize more things; refactor some logic for readability --- commands/admin_commands.lua | 122 ++++++++++++++++++++++++++++++++++++++++++++ commands/clear_penalty.lua | 33 ++++++++++++ commands/create_lag.lua | 28 ++++++++++ commands/flush.lua | 8 +++ commands/user_commands.lua | 60 ++++++++++++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 commands/admin_commands.lua create mode 100644 commands/clear_penalty.lua create mode 100644 commands/create_lag.lua create mode 100644 commands/flush.lua create mode 100644 commands/user_commands.lua (limited to 'commands') diff --git a/commands/admin_commands.lua b/commands/admin_commands.lua new file mode 100644 index 0000000..19a7cb6 --- /dev/null +++ b/commands/admin_commands.lua @@ -0,0 +1,122 @@ +minetest.register_chatcommand("mesecons_enable", { + description = "enables the mesecons globlastep", + privs = { mesecons_debug = true }, + func = function() + -- flush actions, while we are on it + mesecon.queue.actions = {} + mesecons_debug.mesecons_enabled = true + return true, "mesecons enabled" + end +}) + +minetest.register_chatcommand("mesecons_disable", { + description = "disables the mesecons globlastep", + privs = { mesecons_debug = true }, + func = function() + mesecons_debug.mesecons_enabled = false + return true, "mesecons disabled" + end +}) + +minetest.register_chatcommand("mesecons_whitelist_get", { + description = "shows the current mapblock whitelist", + privs = { mesecons_debug = true }, + func = function() + local count = 0 + local list = {} + for hash, _ in pairs(mesecons_debug.storage:to_table().fields) do + table.insert(list, minetest.pos_to_string(minetest.get_position_from_hash(hash))) + count = count + 1 + end + + return true, ( + "mesecons whitelist:\n" .. + "%s\n" .. + "%i mapblocks whitelisted" + ):format( + table.concat(list, "\n"), + count + ) + end +}) + +minetest.register_chatcommand("mesecons_whitelist_add", { + description = "adds the current mapblock to the whitelist", + privs = { mesecons_debug = true }, + func = function(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local hash = mesecons_debug.hashpos(player:get_pos()) + local ctx = mesecons_debug.get_context(hash) + ctx.whitelisted = true + mesecons_debug.storage:set_string(hash, "1") + + return true, "mapblock whitlisted" + end +}) + +minetest.register_chatcommand("mesecons_whitelist_remove", { + description = "removes the current mapblock from the whitelist", + privs = { mesecons_debug = true }, + func = function(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local hash = mesecons_debug.hashpos(player:get_pos()) + local ctx = mesecons_debug.get_context(hash) + ctx.whitelisted = false + mesecons_debug.storage:set_string(hash, "") + + return true, "mapblock removed from whitelist" + end +}) + +minetest.register_chatcommand("mesecons_debug_set", { + description = "modify mesecons_debug settings", + params = " ", + privs = { mesecons_debug = true }, + func = function(name, params) + local player = minetest.get_player_by_name(name) + if not player or not params then + return false + end + + local setting, value = params:match('^([a-zA-Z0-9_-]+)%s+(.*)$') + value = tonumber(value) + if not setting or not value then + return false + end + + if not mesecons_debug.settings[setting] then + return false, "unknown setting" + end + + mesecons_debug.settings.modify_setting(setting, value) + + return true, "setting updated" + end +}) + +minetest.register_chatcommand("mesecons_debug_get", { + description = "get mesecons_debug settings", + params = "", + privs = { mesecons_debug = true }, + func = function(name, setting) + local player = minetest.get_player_by_name(name) + if not player or not setting then + return false + end + + local value = mesecons_debug.settings[setting] + if value then + return true, tostring(value) + else + return false, "unknown setting" + end + end +}) diff --git a/commands/clear_penalty.lua b/commands/clear_penalty.lua new file mode 100644 index 0000000..cf64103 --- /dev/null +++ b/commands/clear_penalty.lua @@ -0,0 +1,33 @@ +local penalty_clear_cooldown = mesecons_debug.settings.penalty_clear_cooldown + +-- playername => time-of-last-cooldown +local cooldown_expiry_by_name = {} + + +minetest.register_chatcommand("mesecons_clear_penalty", { + description = "clears the penalty in the current mapblock " .. + "(cooldown: " .. penalty_clear_cooldown .. ")", + func = function(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local is_admin = minetest.check_player_privs(player, "mesecons_debug") + if not is_admin then + local now = os.time() + local expires = cooldown_expiry_by_name[name] or 0 + local remaining_time = math.floor(expires - now) + if remaining_time > 0 then + -- cooldown still in progress + return true, "cooldown still in progress, remaining time: " .. remaining_time .. " seconds" + end + cooldown_expiry_by_name[name] = now + penalty_clear_cooldown + end + + local ctx = mesecons_debug.get_context(player:get_pos()) + ctx.penalty = 0 + + return true, "penalty reset" + end +}) diff --git a/commands/create_lag.lua b/commands/create_lag.lua new file mode 100644 index 0000000..6598910 --- /dev/null +++ b/commands/create_lag.lua @@ -0,0 +1,28 @@ +local current_lag = 0 +local lag_chance = 0 + +local wait = mesecons_debug.wait + + +minetest.register_chatcommand("create_lag", { + description = "foce a wait of us for 1 / server steps", + params = " ", + privs = { mesecons_debug = true }, + func = function(_name, setting) + local lag, chance = setting:match('^(%S+)%s+(%S+)$') + lag = tonumber(lag) + chance = tonumber(chance) + if not (lag and chance) then + return false, "can't grok lag duration and chance" + end + current_lag = lag + lag_chance = chance + return true + end, +}) + +minetest.register_globalstep(function(_dtime) + if lag_chance > 0 and current_lag > 0 and math.random() < 1 / lag_chance then + wait(current_lag) + end +end) diff --git a/commands/flush.lua b/commands/flush.lua new file mode 100644 index 0000000..ba3f3cd --- /dev/null +++ b/commands/flush.lua @@ -0,0 +1,8 @@ +minetest.register_chatcommand("mesecons_flush", { + description = "flushes the mesecon actionqueue", + privs = { mesecons_debug = true }, + func = function(name) + minetest.log("warning", "Player " .. name .. " flushes mesecon actionqueue") + mesecon.queue.actions = {} + end +}) diff --git a/commands/user_commands.lua b/commands/user_commands.lua new file mode 100644 index 0000000..5836373 --- /dev/null +++ b/commands/user_commands.lua @@ -0,0 +1,60 @@ +minetest.register_chatcommand("mesecons_hud", { + description = "mesecons_hud toggle", + func = function(name) + local enabled = (not mesecons_debug.hud_enabled_by_playername[name]) or nil + mesecons_debug.hud_enabled_by_playername[name] = enabled + if enabled then + return true, "mesecons hud enabled" + else + return true, "mesecons hud disabled" + end + end +}) + +minetest.register_chatcommand("mesecons_global_stats", { + description = "shows the global mesecons stats", + func = function() + local top_ctx, top_hash + + for hash, ctx in pairs(mesecons_debug.context_store) do + if not top_ctx or top_ctx.avg_micros_per_second < ctx.avg_micros_per_second then + -- store context with the most average time + top_ctx = ctx + top_hash = hash + end + end + + local txt + if top_ctx then + txt = ( + "Most prominent mesecons usage at mapblock %s" .. + " with %f seconds penalty and %i us average use" + ):format( + minetest.pos_to_string(minetest.get_position_from_hash(top_hash)), + top_ctx.penalty, + top_ctx.avg_micros_per_second + ) + else + txt = "no context available" + end + + return true, txt + end +}) + +minetest.register_chatcommand("mesecons_stats", { + description = "shows some mesecons stats for the current position", + func = function(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local ctx = mesecons_debug.get_context(player:get_pos()) + return true, ("Mapblock usage: %i us/s (across %i mapblocks)"):format( + ctx.avg_micros_per_second, + mesecons_debug.context_store_size + ) + end +}) + -- cgit v1.2.3