From 38b4505ad7298da2753dd9cb12d75120f9aed60f Mon Sep 17 00:00:00 2001 From: 1F616EMO~nya Date: Fri, 13 Sep 2024 05:42:46 +0800 Subject: [PATCH] Allow requesting reconnect when mods kick player (#14971) --- builtin/game/misc.lua | 6 +++--- doc/lua_api.md | 5 +++-- src/network/clientpackethandler.cpp | 31 +++++++++++------------------ src/script/lua_api/l_server.cpp | 6 ++++-- src/script/lua_api/l_server.h | 2 +- src/server.cpp | 11 +++------- src/server.h | 4 ++-- 7 files changed, 28 insertions(+), 37 deletions(-) diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index a8a6700f9..91ca738a4 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -6,14 +6,14 @@ local S = core.get_translator("__builtin") -- Misc. API functions -- --- @spec core.kick_player(String, String) :: Boolean -function core.kick_player(player_name, reason) +-- @spec core.kick_player(String, String, Boolean) :: Boolean +function core.kick_player(player_name, reason, reconnect) if type(reason) == "string" then reason = "Kicked: " .. reason else reason = "Kicked." end - return core.disconnect_player(player_name, reason) + return core.disconnect_player(player_name, reason, reconnect) end function core.check_player_privs(name, ...) diff --git a/doc/lua_api.md b/doc/lua_api.md index 2f94fd796..34af38abc 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -6999,10 +6999,11 @@ Bans * Returns boolean indicating success * `minetest.unban_player_or_ip(ip_or_name)`: remove ban record matching IP address or name -* `minetest.kick_player(name, [reason])`: disconnect a player with an optional +* `minetest.kick_player(name[, reason[, reconnect]])`: disconnect a player with an optional reason. * Returns boolean indicating success (false if player nonexistent) -* `minetest.disconnect_player(name, [reason])`: disconnect a player with an + * If `reconnect` is true, allow the user to reconnect. +* `minetest.disconnect_player(name[, reason[, reconnect]])`: disconnect a player with an optional reason, this will not prefix with 'Kicked: ' like kick_player. If no reason is given, it will default to 'Disconnected.' * Returns boolean indicating success (false if player nonexistent) diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 4eefd1c59..a1bffbb93 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -204,7 +204,6 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt) // to be processed even if the serialization format has // not been agreed yet, the same as TOCLIENT_INIT. m_access_denied = true; - m_access_denied_reason = "Unknown"; if (pkt->getCommand() != TOCLIENT_ACCESS_DENIED) { // Legacy code from 0.4.12 and older but is still used @@ -223,29 +222,23 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt) u8 denyCode; *pkt >> denyCode; - if (denyCode == SERVER_ACCESSDENIED_SHUTDOWN || - denyCode == SERVER_ACCESSDENIED_CRASH) { + if (pkt->getRemainingBytes() > 0) *pkt >> m_access_denied_reason; - if (m_access_denied_reason.empty()) + + if (m_access_denied_reason.empty()) { + if (denyCode >= SERVER_ACCESSDENIED_MAX) { + m_access_denied_reason = gettext("Unknown disconnect reason."); + } else if (denyCode != SERVER_ACCESSDENIED_CUSTOM_STRING) { m_access_denied_reason = gettext(accessDeniedStrings[denyCode]); + } + } + + if (denyCode == SERVER_ACCESSDENIED_TOO_MANY_USERS) { + m_access_denied_reconnect = true; + } else if (pkt->getRemainingBytes() > 0) { u8 reconnect; *pkt >> reconnect; m_access_denied_reconnect = reconnect & 1; - } else if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) { - *pkt >> m_access_denied_reason; - } else if (denyCode == SERVER_ACCESSDENIED_TOO_MANY_USERS) { - m_access_denied_reason = gettext(accessDeniedStrings[denyCode]); - m_access_denied_reconnect = true; - } else if (denyCode < SERVER_ACCESSDENIED_MAX) { - m_access_denied_reason = gettext(accessDeniedStrings[denyCode]); - } else { - // Allow us to add new error messages to the - // protocol without raising the protocol version, if we want to. - // Until then (which may be never), this is outside - // of the defined protocol. - *pkt >> m_access_denied_reason; - if (m_access_denied_reason.empty()) - m_access_denied_reason = "Unknown"; } } diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 69f5cf9a0..82170f936 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -365,7 +365,7 @@ int ModApiServer::l_ban_player(lua_State *L) return 1; } -// disconnect_player(name, [reason]) -> success +// disconnect_player(name[, reason[, reconnect]]) -> success int ModApiServer::l_disconnect_player(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -388,7 +388,9 @@ int ModApiServer::l_disconnect_player(lua_State *L) return 1; } - server->DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, message); + bool reconnect = readParam(L, 3, false); + + server->DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, message, reconnect); lua_pushboolean(L, true); return 1; } diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h index 505dce735..a0fae79bd 100644 --- a/src/script/lua_api/l_server.h +++ b/src/script/lua_api/l_server.h @@ -106,7 +106,7 @@ private: // unban_player_or_ip() static int l_unban_player_or_ip(lua_State *L); - // disconnect_player(name, [reason]) -> success + // disconnect_player(name[, reason[, reconnect]]) -> success static int l_disconnect_player(lua_State *L); // remove_player(name) diff --git a/src/server.cpp b/src/server.cpp index c76155015..92f97172b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1383,17 +1383,12 @@ void Server::SendBreath(session_t peer_id, u16 breath) } void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason, - const std::string &custom_reason, bool reconnect) + std::string_view custom_reason, bool reconnect) { assert(reason < SERVER_ACCESSDENIED_MAX); NetworkPacket pkt(TOCLIENT_ACCESS_DENIED, 1, peer_id); - pkt << (u8)reason; - if (reason == SERVER_ACCESSDENIED_CUSTOM_STRING) - pkt << custom_reason; - else if (reason == SERVER_ACCESSDENIED_SHUTDOWN || - reason == SERVER_ACCESSDENIED_CRASH) - pkt << custom_reason << (u8)reconnect; + pkt << (u8)reason << custom_reason << (u8)reconnect; Send(&pkt); } @@ -2829,7 +2824,7 @@ void Server::DenySudoAccess(session_t peer_id) void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason, - const std::string &custom_reason, bool reconnect) + std::string_view custom_reason, bool reconnect) { SendAccessDenied(peer_id, reason, custom_reason, reconnect); m_clients.event(peer_id, CSE_SetDenied); diff --git a/src/server.h b/src/server.h index 17eb9d769..58805c667 100644 --- a/src/server.h +++ b/src/server.h @@ -364,7 +364,7 @@ public: void DenySudoAccess(session_t peer_id); void DenyAccess(session_t peer_id, AccessDeniedCode reason, - const std::string &custom_reason = "", bool reconnect = false); + std::string_view custom_reason = "", bool reconnect = false); void kickAllPlayers(AccessDeniedCode reason, const std::string &str_reason, bool reconnect); void acceptAuth(session_t peer_id, bool forSudoMode); @@ -485,7 +485,7 @@ private: void SendHP(session_t peer_id, u16 hp, bool effect); void SendBreath(session_t peer_id, u16 breath); void SendAccessDenied(session_t peer_id, AccessDeniedCode reason, - const std::string &custom_reason, bool reconnect = false); + std::string_view custom_reason, bool reconnect = false); void SendDeathscreen(session_t peer_id, bool set_camera_point_target, v3f camera_point_target); void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version);