Fix connected_players on_shutdown (#14739)

This commit is contained in:
cx384 2024-06-15 16:00:33 +02:00 committed by GitHub
parent bc23a610d3
commit 7a64527db5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 25 deletions

@ -5720,6 +5720,8 @@ Call these functions only at load time!
aliases handled.
* `minetest.register_on_shutdown(function())`
* Called before server shutdown
* Players that were kicked by the shutdown procedure are still fully accessible
in `minetest.get_connected_players()`.
* **Warning**: If the server terminates abnormally (i.e. crashes), the
registered callbacks **will likely not be run**. Data should be saved at
semi-frequent intervals as well as on server shutdown.

@ -186,6 +186,7 @@ dofile(modpath .. "/metadata.lua")
dofile(modpath .. "/raycast.lua")
dofile(modpath .. "/inventory.lua")
dofile(modpath .. "/load_time.lua")
dofile(modpath .. "/on_shutdown.lua")
--------------

@ -0,0 +1,22 @@
-- Test whether players still exist on shutdown
local players = {}
core.register_on_joinplayer(function(player)
players[player:get_player_name()] = true
end)
core.register_on_leaveplayer(function(player)
local name = player:get_player_name();
assert(players[name], "Unrecorded player join.")
players[name] = nil
end)
core.register_on_shutdown(function()
for _, player in pairs(core.get_connected_players()) do
local name = player:get_player_name()
assert(players[name], "Unrecorded player join or left too early.")
players[name] = nil
end
assert(not next(players), "Invalid connected players on shutdown.")
end)

@ -329,27 +329,6 @@ Server::~Server()
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
L"*** Server shutting down"));
if (m_env) {
MutexAutoLock envlock(m_env_mutex);
infostream << "Server: Saving players" << std::endl;
m_env->saveLoadedPlayers();
infostream << "Server: Kicking players" << std::endl;
std::string kick_msg;
bool reconnect = false;
if (isShutdownRequested()) {
reconnect = m_shutdown_state.should_reconnect;
kick_msg = m_shutdown_state.message;
}
if (kick_msg.empty()) {
kick_msg = g_settings->get("kick_msg_shutdown");
}
m_env->saveLoadedPlayers(true);
kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
kick_msg, reconnect);
}
actionstream << "Server: Shutting down" << std::endl;
// Stop server step from happening
@ -369,16 +348,33 @@ Server::~Server()
if (m_env) {
MutexAutoLock envlock(m_env_mutex);
infostream << "Server: Executing shutdown hooks" << std::endl;
try {
// Empty out the environment, this can also invoke callbacks.
m_env->deactivateBlocksAndObjects();
m_script->on_shutdown();
} catch (ModError &e) {
addShutdownError(e);
}
infostream << "Server: Executing shutdown hooks" << std::endl;
infostream << "Server: Saving players" << std::endl;
m_env->saveLoadedPlayers();
infostream << "Server: Kicking players" << std::endl;
std::string kick_msg;
bool reconnect = false;
if (isShutdownRequested()) {
reconnect = m_shutdown_state.should_reconnect;
kick_msg = m_shutdown_state.message;
}
if (kick_msg.empty()) {
kick_msg = g_settings->get("kick_msg_shutdown");
}
m_env->saveLoadedPlayers(true);
kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
kick_msg, reconnect);
try {
m_script->on_shutdown();
// Empty out the environment, this can also invoke callbacks.
m_env->deactivateBlocksAndObjects();
} catch (ModError &e) {
addShutdownError(e);
}