1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

RemotePlayer: make peer ID always reflect the validity of PlayerSAO (#14317)

Upon disconnect, RemotePlayer still had a peer ID assigned even though
the PlayerSAO object was maked as gone (for removal). This commit makes
that the following always holds true:

	(!sao || sao->isGone()) === (peer_id == PEER_ID_INEXISTENT)
This commit is contained in:
SmallJoker 2024-02-02 22:13:24 +01:00 committed by GitHub
parent 893594d81a
commit e7dbd325d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 86 additions and 61 deletions

View file

@ -343,7 +343,7 @@ Server::~Server()
kick_msg = g_settings->get("kick_msg_shutdown");
}
m_env->saveLoadedPlayers(true);
m_env->kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
kick_msg, reconnect);
}
@ -590,7 +590,7 @@ void Server::step()
std::string async_err = m_async_fatal_error.get();
if (!async_err.empty()) {
if (!m_simple_singleplayer_mode) {
m_env->kickAllPlayers(SERVER_ACCESSDENIED_CRASH,
kickAllPlayers(SERVER_ACCESSDENIED_CRASH,
g_settings->get("kick_msg_crash"),
g_settings->getBool("ask_reconnect_on_crash"));
}
@ -1105,7 +1105,7 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
/*
Send complete position information
*/
SendMovePlayer(peer_id);
SendMovePlayer(playersao);
// Send privileges
SendPlayerPrivileges(peer_id);
@ -1114,7 +1114,7 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
SendPlayerInventoryFormspec(peer_id);
// Send inventory
SendInventory(playersao, false);
SendInventory(player, false);
// Send HP
SendPlayerHP(playersao, false);
@ -1458,10 +1458,8 @@ void Server::SendNodeDef(session_t peer_id,
Non-static send methods
*/
void Server::SendInventory(PlayerSAO *sao, bool incremental)
void Server::SendInventory(RemotePlayer *player, bool incremental)
{
RemotePlayer *player = sao->getPlayer();
// Do not send new format to old clients
incremental &= player->protocol_version >= 38;
@ -1471,11 +1469,11 @@ void Server::SendInventory(PlayerSAO *sao, bool incremental)
Serialize it
*/
NetworkPacket pkt(TOCLIENT_INVENTORY, 0, sao->getPeerID());
NetworkPacket pkt(TOCLIENT_INVENTORY, 0, player->getPeerId());
std::ostringstream os(std::ios::binary);
sao->getInventory()->serialize(os, incremental);
sao->getInventory()->setModified(false);
player->inventory.serialize(os, incremental);
player->inventory.setModified(false);
player->setModified(true);
const std::string &s = os.str();
@ -1900,17 +1898,12 @@ void Server::SendPlayerBreath(PlayerSAO *sao)
SendBreath(sao->getPeerID(), sao->getBreath());
}
void Server::SendMovePlayer(session_t peer_id)
void Server::SendMovePlayer(PlayerSAO *sao)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
PlayerSAO *sao = player->getPlayerSAO();
assert(sao);
// Send attachment updates instantly to the client prior updating position
sao->sendOutdatedData();
NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id);
NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, sao->getPeerID());
pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y;
{
@ -2877,6 +2870,15 @@ void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason,
DisconnectPeer(peer_id);
}
void Server::kickAllPlayers(AccessDeniedCode reason,
const std::string &str_reason, bool reconnect)
{
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
DenyAccess(client_id, reason, str_reason, reconnect);
}
}
void Server::DisconnectPeer(session_t peer_id)
{
m_modchannel_mgr->leaveAllChannels(peer_id);
@ -3929,6 +3931,23 @@ PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_v
return NULL;
}
/*
Object construction sequence/hierarchy
--------------------------------------
1. RemoteClient (tightly connection-bound)
2. RemotePlayer (controls, in-game appearance)
3. PlayerSAO (movable object in-game)
PlayerSAO controls the peer_id assignment of RemotePlayer,
indicating whether the player is ready
Destruction sequence
--------------------
1. PlayerSAO pending removal flag
2. PlayerSAO save data before free
3. RemotePlayer, then PlayerSAO freed
4. RemoteClient freed
*/
if (!player) {
player = new RemotePlayer(name, idef());
}