diff options
Diffstat (limited to '')
-rw-r--r-- | chatcommands.lua | 48 | ||||
-rw-r--r-- | hud.lua | 82 | ||||
-rw-r--r-- | init.lua | 12 | ||||
-rw-r--r-- | overrides.lua | 116 |
4 files changed, 191 insertions, 67 deletions
diff --git a/chatcommands.lua b/chatcommands.lua new file mode 100644 index 0000000..58792c3 --- /dev/null +++ b/chatcommands.lua @@ -0,0 +1,48 @@ + + +minetest.register_chatcommand("mesecons_hud", { + description = "mesecons_hud on/off", + func = function(name, params) + local enable = params == "on" + mesecons_debug.hud[name] = enable + if enable then + return true, "mesecons hud enabled" + else + return true, "mesecons hud disabled" + end + 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: " .. ctx.avg_micros .. " us/s " .. + "(across " .. mesecons_debug.context_store_size .." mapblocks)" + end +}) + +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.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.enabled = false + return true, "mesecons disabled" + end +}) @@ -0,0 +1,82 @@ + +local HUD_POSITION = {x = 0.1, y = 0.8} +local HUD_ALIGNMENT = {x = 1, y = 0} + +local hud = {} + + +minetest.register_on_joinplayer(function(player) + local hud_data = {} + hud[player:get_player_name()] = hud_data + + hud_data.txt = player:hud_add({ + hud_elem_type = "text", + position = HUD_POSITION, + offset = {x = 0, y = 0}, + text = "", + alignment = HUD_ALIGNMENT, + scale = {x = 100, y = 100}, + number = 0xFF0000 + }) + +end) + + +minetest.register_on_leaveplayer(function(player) + hud[player:get_player_name()] = nil +end) + + +local function get_blockpos(pos) + return {x = math.floor(pos.x / 16), + y = math.floor(pos.y / 16), + z = math.floor(pos.z / 16)} +end + +local function get_info(player) + local pos = player:get_pos() + local blockpos = get_blockpos(pos) + local ctx = mesecons_debug.get_context(pos) + + local percent = math.floor(ctx.avg_micros / mesecons_debug.max_usage_micros * 100) + + local txt = "Mesecons @ (" .. blockpos.x .. "/" .. blockpos.y .. "/" .. blockpos.z .. ") " .. + " usage: " .. ctx.avg_micros .. " us/s .. (" .. percent .. "%) " .. + "penalty: " .. math.floor(ctx.penalty*10)/10 .. " s" + + if ctx.penalty <= 0.1 then + return txt, 0x00FF00 + elseif ctx.penalty < 0.5 then + return txt, 0xFFFF00 + else + return txt, 0xFF0000 + end +end + +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < 1 then + return + end + timer = 0 + + for _, player in ipairs(minetest.get_connected_players()) do + local playername = player:get_player_name() + local hud_data = hud[playername] + local hud_enable = mesecons_debug.hud[playername] + if hud_enable then + local txt, color = get_info(player) + player:hud_change(hud_data.txt, "text", txt) + player:hud_change(hud_data.txt, "color", color) + + elseif hud_enable == false then + mesecons_debug.hud[playername] = nil + player:hud_change(hud_data.txt, "text", "") + + end + + end + + +end) @@ -1,10 +1,18 @@ local MP = minetest.get_modpath("mesecons_debug") -mesecons_debug = {} +mesecons_debug = { + enabled = true, + context_store_size = 0, + -- playername => true + hud = {}, + + max_usage_micros = 20000 +} ----- dofile(MP.."/add_action.lua") dofile(MP.."/privs.lua") dofile(MP.."/flush.lua") dofile(MP.."/overrides.lua") +dofile(MP.."/chatcommands.lua") +dofile(MP.."/hud.lua") print("[OK] mesecons_debug loaded") diff --git a/overrides.lua b/overrides.lua index 61fc2aa..5670e12 100644 --- a/overrides.lua +++ b/overrides.lua @@ -1,21 +1,46 @@ --- enable/disable mesecons entirely +local function get_blockpos(pos) + return {x = math.floor(pos.x / 16), + y = math.floor(pos.y / 16), + z = math.floor(pos.z / 16)} +end -local enabled = true -local reenable_seconds = 0 +-- blockpos-hash => context +local context_store = {} + +mesecons_debug.get_context = function(pos) + local blockpos = get_blockpos(pos) + local hash = minetest.hash_node_position(blockpos) + + local ctx = context_store[hash] + if not ctx then + ctx = { + -- usage in us + micros = 0, + -- average micros per second + avg_micros = 0, + -- time penalty + penalty = 0 + } + context_store[hash] = ctx + end -local cumulative_microseconds = 0 -local hit_count = 0 + return ctx +end -- execute() local old_execute = mesecon.queue.execute -mesecon.queue.execute = function(...) - if enabled then +mesecon.queue.execute = function(self, action) + if mesecons_debug.enabled then local t0 = minetest.get_us_time() - old_execute(...) + old_execute(self, action) local t1 = minetest.get_us_time() local micros = t1 - t0 - cumulative_microseconds = cumulative_microseconds + micros + + local ctx = mesecons_debug.get_context(action.pos) + ctx.micros = ctx.micros + micros + + --print("execute() func=" .. action.func .. " pos=" .. minetest.pos_to_string(action.pos) .. " micros=" .. micros) end end @@ -25,69 +50,30 @@ minetest.register_globalstep(function(dtime) timer = timer + dtime if timer < 1 then return end timer=0 - - local max_micros = tonumber(minetest.settings:get("mesecons_debug.max_micros")) or 100000 - local max_hit_count = tonumber(minetest.settings:get("mesecons_debug.max_hit_count")) or 5 - - if cumulative_microseconds > max_micros then - -- heat up - hit_count = hit_count + 1 - else - -- cooldown - max_hit_count = max_hit_count - 0.1 - end - - cumulative_microseconds = 0 - - - if hit_count > max_hit_count then - hit_count = 0 - enabled = false - - minetest.chat_send_all("[circuit-breaker] mesecons are disabled for a minute due to abuse, " .. - "please fix/optimize your circuits!") - - minetest.log("warning", "[mesecons_debug] circuit-breaker triggered -> disabled for 60 seconds") - - reenable_seconds = 60 - end - - if reenable_seconds > 0 then - reenable_seconds = reenable_seconds - 1 - if reenable_seconds < 1 then - -- re-enable again - enabled = true - mesecon.queue.actions = {} + mesecons_debug.context_store_size = 0 + for _, ctx in pairs(context_store) do + ctx.avg_micros = math.floor((ctx.avg_micros * 0.9) + (ctx.micros * 0.1)) + ctx.micros = 0 + if ctx.avg_micros > mesecons_debug.max_usage_micros then + ctx.penalty = math.min(ctx.penalty + 0.1, 10) + elseif ctx.penalty > 0 then + ctx.penalty = math.max(ctx.penalty - 0.01, 0) end + mesecons_debug.context_store_size = mesecons_debug.context_store_size + 1 end end) -- add_action() local old_add_action = mesecon.queue.add_action -mesecon.queue.add_action = function(...) - if enabled then - old_add_action(...) - end -end +mesecon.queue.add_action = function(self, pos, func, params, time, overwritecheck, priority) + if mesecons_debug.enabled then + local ctx = mesecons_debug.get_context(pos) + time = time or 0 + time = time + ctx.penalty -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 = {} - enabled = true - return true, "mesecons enabled" + old_add_action(self, pos, func, params, time, overwritecheck, priority) + --print("add_action() pos=" .. minetest.pos_to_string(pos)) end -}) - -minetest.register_chatcommand("mesecons_disable", { - description = "disables the mesecons globlastep", - privs = {mesecons_debug=true}, - func = function() - enabled = false - return true, "mesecons disabled" - end -}) +end |