controls = { registered_on_press = {}, registered_on_hold = {}, registered_on_release = {}, players = {}, } function controls.register_on_press(callback) table.insert(controls.registered_on_press, callback) end function controls.register_on_hold(callback) table.insert(controls.registered_on_hold, callback) end function controls.register_on_release(callback) table.insert(controls.registered_on_release, callback) end minetest.register_on_joinplayer(function(player) local name = player:get_player_name() controls.players[name] = {} for key in pairs(player:get_player_control()) do controls.players[name][key] = {false} end end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() controls.players[name] = nil end) local function update_player_controls(player, player_controls) local time_now = minetest.get_us_time() for key, pressed in pairs(player:get_player_control()) do if pressed and not player_controls[key][1] then for _, callback in pairs(controls.registered_on_press) do callback(player, key) end player_controls[key] = {true, time_now} elseif pressed and player_controls[key][1] then for _, callback in pairs(controls.registered_on_hold) do callback(player, key, (time_now - player_controls[key][2]) / 1e6) end elseif not pressed and player_controls[key][1] then for _, callback in pairs(controls.registered_on_release) do callback(player, key, (time_now - player_controls[key][2]) / 1e6) end player_controls[key] = {false} end end end minetest.register_globalstep(function() for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() if controls.players[name] then update_player_controls(player, controls.players[name]) end end end) if minetest.settings:get_bool("controls_enable_debug", false) then dofile(minetest.get_modpath("controls") .. "/debug.lua") end