local player_cache = {} -- AFK local afk_check = minetest.settings:get_bool("ess_afk_check", true) local afk_max_time = tonumber(minetest.settings:get("ess_afk_time")) or 300 local afk_warn_time = tonumber(minetest.settings:get("ess_afk_warn_time")) or 20 local afk_check_interval = tonumber(minetest.settings:get("ess_afk_check_interval")) or 1 local afk_warn_msg = minetest.settings:get("ess_afk_warn_msg") if not afk_warn_msg then afk_warn_msg = "Warning, you have %d seconds to move or be kicked" end -- Disable AFK check in singleplayer, doesn't really make sense to have it if minetest.is_singleplayer() then ess_afk_check = false end -- Player local save_death = minetest.settings:get_bool("ess_save_death", false) local newplayer = minetest.settings:get("ess_new_player") if not newplayer then newplayer = "%s has joined the server for the first time! Welcome!" end -- Commands local function cmd_god(name, params, splitparams) local target = name if splitparams[1] then target = splitparams[1] end local player = minetest.get_player_by_name(target) if not player then return false, "No such player." end local grps = player:get_armor_groups() local status = not player_cache[target].god if grps["immortal"] == 1 then status = false end player_cache[target].god = status local msg = "God mode enabled." local grp = 1 if not status then grp = 0 msg = "God mode disabled." end grps["immortal"] = grp player:set_armor_groups(grps) if target ~= name then minetest.chat_send_player(target, msg) end ess.set_player_meta(target, "god", status) return true, msg end local commands = { ["god"] = { description = "Toggle invincibility mode.", aliases = {"godmode", "invincible"}, privs = true, params = "[]", func = cmd_god }, ["whois"] = { description = "Get network information of player", params = "[]", privs = true, func = function(name, param) if param == "" then param = name end if not player_cache[param] then return false, string.format("Player %s was not found!", param) end local player_info = minetest.get_player_information(param) minetest.chat_send_player(name, string.format("[%s] IP address: %s", param, player_info["address"])) minetest.chat_send_player(name, string.format("[%s] average round trip time: %d ms", param, player_info["avg_rtt"] * 1000)) minetest.chat_send_player(name, string.format("[%s] connected for: %d seconds", param, player_info["connection_uptime"])) return true end }, ["heal"] = { description = "Heal player", params = "[]", privs = { ["ess.player.heal"] = true, ["ess.player.heal.other"] = true, }, func = function(name, param) if param == "" then param = name elseif param ~= "" and param ~= name and not ess.priv_match(name, "ess.player.heal.other") then return ess.reject_permission() end local p = minetest.get_player_by_name(param) if not p then return false, string.format("Player %s was not found!", param) end p:set_hp(20) return true, string.format("Successfully healed %s.", param) end } } ess.autoregister(commands, "player") -- AFK kick immunity privilege minetest.register_privilege("ess.player.afk", { description = "AFK kick immunity", give_to_singleplayer = false, give_to_admin = true, }) if afk_check then local check_timer = 0 minetest.register_globalstep(function(dtime) check_timer = check_timer + dtime if check_timer > afk_check_interval then check_timer = 0 -- Loop through all connected players for _,player in ipairs(minetest.get_connected_players()) do local player_name = player:get_player_name() -- Only continue if the player has an entry in the player cache -- Check for afk players if player_cache[player_name] and not ess.priv_match(player_name, "ess.player.afk") then local kicked = false -- Kick player if he/she has been inactive for longer than afk_max_time seconds if player_cache[player_name].active + afk_max_time < minetest.get_gametime() then minetest.kick_player(player_name, "Kicked for inactivity") kicked = true end -- Warn player if he/she has less than afk_warn_time seconds to move or be kicked if not kicked and afk_warn_time > 0 and player_cache[player_name].active + afk_max_time - afk_warn_time < minetest.get_gametime() then local seconds = tostring(player_cache[player_name].active + afk_max_time - minetest.get_gametime()) minetest.chat_send_player(player_name, string.format(afk_warn_msg, seconds)) end -- Check if this player is doing an action if not kicked then for _,keyPressed in pairs(player:get_player_control()) do if keyPressed then player_cache[player_name].active = minetest.get_gametime() end end end end end end end) end -- New player message if newplayer ~= "" then minetest.register_on_newplayer(function (player) local player_name = player:get_player_name() minetest.chat_send_all(string.format(newplayer, player_name)) end) end -- Join minetest.register_on_joinplayer(function (player) local player_name = player:get_player_name() player_cache[player_name] = { active = minetest.get_gametime(), god = ess.get_player_meta(player_name, "god") == true, } -- Ensure god mode persistance local grps = player:get_armor_groups() if grps["immortal"] ~= 1 and player_cache[player_name].god then if not ess.priv_match(player_name, "ess.player.god") then player_cache[player_name].god = false ess.set_player_meta(player_name, "god", false) return end grps["immortal"] = 1 player:set_armor_groups(grps) end end) -- Leave minetest.register_on_leaveplayer(function(player) local player_name = player:get_player_name() player_cache[player_name] = nil end) -- Save death point for use with /back if save_death then minetest.register_on_dieplayer(function(player) local player_name = player:get_player_name() if player_cache[player_name] and player_cache[player_name].god then return end ess.save_player_pos(player) end) end