Aaron Suen 543f5cfd5f Announce empty server on restart if needed
When an MT server shuts down, it doesn't always kick the players
and announce their departure before the shutdown process runs,
so it's possible for players to be "connected" at the time the
server actually stops running mod code.  This means that there is
no opportunity to announce that the server is now empty once it's
actually shut down.

Here we assume that in most cases, the server will be brought
back up immediately, and better late than never.  If there were any
players online at the time the server was shut down, announce the
server status (i.e. that it's now empty) upon the next startup.

This should mitigate the issue where a a player joins the server,
then the server is shutdown silently, and then the same player
joins again, making chat logs nonsensical.  At least this way
you will see that the player is no longer connected at some point
before they reconnect.
2024-08-20 07:46:38 -04:00

83 lines
2.3 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local math, minetest, pairs, table, tonumber, tostring
= math, minetest, pairs, table, tonumber, tostring
local math_random, table_concat, table_remove, table_sort
= math.random, table.concat, table.remove, table.sort
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local modstore = minetest.get_mod_storage()
local timedelay = tonumber(minetest.settings:get(modname .. "_time")) or 300
local linedelay = tonumber(minetest.settings:get(modname .. "_lines")) or 25
local maxnames = tonumber(minetest.settings:get(modname .. "_names")) or 50
local stpriv = minetest.settings:get(modname .. "_hide") or "stealth"
local function isstealth(p) return minetest.check_player_privs(p, stpriv) end
local lines = 0
local exp = 0
local anyonline = modstore:get_string("online") ~= ""
local function setanyonline(val)
if anyonline == val then return end
anyonline = val
return modstore:set_string("online", val and "1" or "")
end
local function announce()
local names = {}
for _, player in pairs(minetest.get_connected_players()) do
if not isstealth(player) then
names[#names + 1] = player:get_player_name()
end
end
table_sort(names)
local more = 0
while #names > maxnames do
table_remove(names, math_random(1, #names))
more = more + 1
end
if more > 0 then
names[#names + 1] = "(" .. more .. " more)"
end
if #names > 0 then
minetest.chat_send_all("*** Online: " .. table_concat(names, ", "))
setanyonline(true)
else
minetest.chat_send_all("*** Server is empty.")
setanyonline(false)
end
end
local function sendall(isann)
lines = lines + 1
if not isann then return end
local now = minetest.get_us_time() / 1000000
if (lines < linedelay) and (now < exp) then return end
exp = now + timedelay
lines = 0
minetest.after(0, announce)
end
if anyonline then sendall(true) end
do
local old_sendall = minetest.chat_send_all
function minetest.chat_send_all(text, ...)
sendall(tostring(text):match("^%s*%*%*%*%s"))
return old_sendall(text, ...)
end
end
minetest.register_on_chat_message(function(pname, text)
if text:sub(1, 1) ~= "/"
and minetest.check_player_privs(pname, "shout") then
sendall()
end
end)