223 lines
6.0 KiB
Lua
223 lines
6.0 KiB
Lua
|
|
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 = "[<playername>]",
|
|
func = cmd_god
|
|
},
|
|
["whois"] = {
|
|
description = "Get network information of player",
|
|
params = "[<playername>]",
|
|
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 = "[<playername>]",
|
|
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
|