Check node updates whether the blocks are known (#7568)
authorSmallJoker <SmallJoker@users.noreply.github.com>
Thu, 16 Aug 2018 18:10:34 +0000 (20:10 +0200)
committerGitHub <noreply@github.com>
Thu, 16 Aug 2018 18:10:34 +0000 (20:10 +0200)
* Remove unused ignore_id

src/clientiface.h
src/map.h
src/server.cpp
src/server.h

index 291ccd4016f096c6d61c93355774a299ffbac756..5335fa6442ac601066bb27cc8c65adbc039492b1 100644 (file)
@@ -274,6 +274,11 @@ public:
 
        u32 getSendingCount() const { return m_blocks_sending.size(); }
 
+       bool isBlockSent(v3s16 p) const
+       {
+               return m_blocks_sent.find(p) != m_blocks_sent.end();
+       }
+
        // Increments timeouts and removes timed-out blocks from list
        // NOTE: This doesn't fix the server-not-sending-block bug
        //       because it is related to emerging, not sending.
index 7e1624e607581bbec48a88f5d565d763bf2f82f0..712a0a51a55e26bf4720809da8348b9984a3745e 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -76,7 +76,6 @@ struct MapEditEvent
        v3s16 p;
        MapNode n = CONTENT_AIR;
        std::set<v3s16> modified_blocks;
-       u16 already_known_by_peer = 0;
 
        MapEditEvent() = default;
 
index 04338df57b73d558af1386384608f949c9575bf5..37aad4bceccfa6ae48d87037a259dce801b58c0d 100644 (file)
@@ -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<u16> far_players;
+                       std::unordered_set<u16> 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<u16> *far_players, float far_d_nodes)
+void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *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<session_t> 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<u16> *far_players, float far_d_nodes,
-               bool remove_metadata)
+void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *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<session_t> 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,
index 8ac61aaad56ac407abf6a49373681cad6786cea9..751eaa5f2dce4f901b5831cb6be2c410208ce351 100644 (file)
@@ -416,11 +416,11 @@ private:
                far_d_nodes are ignored and their peer_ids are added to far_players
        */
        // Envlock and conlock should be locked when calling these
-       void sendRemoveNode(v3s16 p, u16 ignore_id=0,
-                       std::vector<u16> *far_players=NULL, float far_d_nodes=100);
-       void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
-                       std::vector<u16> *far_players=NULL, float far_d_nodes=100,
-                       bool remove_metadata=true);
+       void sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players = nullptr,
+                       float far_d_nodes = 100);
+       void sendAddNode(v3s16 p, MapNode n,
+                       std::unordered_set<u16> *far_players = nullptr,
+                       float far_d_nodes = 100, bool remove_metadata = true);
 
        // Environment and Connection must be locked when called
        void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version);