From 297beea5bf95c8ea0b6fe08aed287b94487d24ea Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 16 Aug 2018 20:10:34 +0200 Subject: Check node updates whether the blocks are known (#7568) * Remove unused ignore_id --- src/server.cpp | 103 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 49 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index 04338df57..37aad4bce 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -868,20 +868,20 @@ void Server::AsyncRunStep(bool initial_step) // Players far away from the change are stored here. // Instead of sending the changes, MapBlocks are set not sent // for them. - std::vector far_players; + std::unordered_set far_players; switch (event->type) { case MEET_ADDNODE: case MEET_SWAPNODE: prof.add("MEET_ADDNODE", 1); - sendAddNode(event->p, event->n, event->already_known_by_peer, - &far_players, disable_single_change_sending ? 5 : 30, + sendAddNode(event->p, event->n, &far_players, + disable_single_change_sending ? 5 : 30, event->type == MEET_ADDNODE); break; case MEET_REMOVENODE: prof.add("MEET_REMOVENODE", 1); - sendRemoveNode(event->p, event->already_known_by_peer, - &far_players, disable_single_change_sending ? 5 : 30); + sendRemoveNode(event->p, &far_players, + disable_single_change_sending ? 5 : 30); break; case MEET_BLOCK_NODE_METADATA_CHANGED: infostream << "Server: MEET_BLOCK_NODE_METADATA_CHANGED" << std::endl; @@ -2079,76 +2079,81 @@ void Server::fadeSound(s32 handle, float step, float gain) } } -void Server::sendRemoveNode(v3s16 p, u16 ignore_id, - std::vector *far_players, float far_d_nodes) +void Server::sendRemoveNode(v3s16 p, std::unordered_set *far_players, + float far_d_nodes) { - float maxd = far_d_nodes*BS; + float maxd = far_d_nodes * BS; v3f p_f = intToFloat(p, BS); + v3s16 block_pos = getNodeBlockPos(p); NetworkPacket pkt(TOCLIENT_REMOVENODE, 6); pkt << p; std::vector clients = m_clients.getClientIDs(); + m_clients.lock(); + for (session_t client_id : clients) { - if (far_players) { - // Get player - if (RemotePlayer *player = m_env->getPlayer(client_id)) { - PlayerSAO *sao = player->getPlayerSAO(); - if (!sao) - continue; + RemoteClient *client = m_clients.lockedGetClientNoEx(client_id); + if (!client) + continue; - // If player is far away, only set modified blocks not sent - v3f player_pos = sao->getBasePosition(); - if (player_pos.getDistanceFrom(p_f) > maxd) { - far_players->push_back(client_id); - continue; - } - } + RemotePlayer *player = m_env->getPlayer(client_id); + PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr; + + // If player is far away, only set modified blocks not sent + if (!client->isBlockSent(block_pos) || (sao && + sao->getBasePosition().getDistanceFrom(p_f) > maxd)) { + if (far_players) + far_players->emplace(client_id); + else + client->SetBlockNotSent(block_pos); + continue; } // Send as reliable m_clients.send(client_id, 0, &pkt, true); } + + m_clients.unlock(); } -void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, - std::vector *far_players, float far_d_nodes, - bool remove_metadata) +void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set *far_players, + float far_d_nodes, bool remove_metadata) { - float maxd = far_d_nodes*BS; + float maxd = far_d_nodes * BS; v3f p_f = intToFloat(p, BS); + v3s16 block_pos = getNodeBlockPos(p); + + NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1); + pkt << p << n.param0 << n.param1 << n.param2 + << (u8) (remove_metadata ? 0 : 1); std::vector clients = m_clients.getClientIDs(); - for (const session_t client_id : clients) { - if (far_players) { - // Get player - if (RemotePlayer *player = m_env->getPlayer(client_id)) { - PlayerSAO *sao = player->getPlayerSAO(); - if (!sao) - continue; + m_clients.lock(); - // If player is far away, only set modified blocks not sent - v3f player_pos = sao->getBasePosition(); - if(player_pos.getDistanceFrom(p_f) > maxd) { - far_players->push_back(client_id); - continue; - } - } - } + for (session_t client_id : clients) { + RemoteClient *client = m_clients.lockedGetClientNoEx(client_id); + if (!client) + continue; - NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1); - m_clients.lock(); - RemoteClient* client = m_clients.lockedGetClientNoEx(client_id); - if (client) { - pkt << p << n.param0 << n.param1 << n.param2 - << (u8) (remove_metadata ? 0 : 1); + RemotePlayer *player = m_env->getPlayer(client_id); + PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr; + + // If player is far away, only set modified blocks not sent + if (!client->isBlockSent(block_pos) || (sao && + sao->getBasePosition().getDistanceFrom(p_f) > maxd)) { + if (far_players) + far_players->emplace(client_id); + else + client->SetBlockNotSent(block_pos); + continue; } - m_clients.unlock(); // Send as reliable - if (pkt.getSize() > 0) - m_clients.send(client_id, 0, &pkt, true); + m_clients.send(client_id, 0, &pkt, true); } + + m_clients.unlock(); } void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, -- cgit v1.2.3