Fix "ghost" blocks if block update is "on wire" while player digs nodes 1475/head
authorsapier <Sapier at GMX dot net>
Sat, 12 Jul 2014 18:20:11 +0000 (20:20 +0200)
committersapier <Sapier at GMX dot net>
Fri, 22 Aug 2014 18:56:16 +0000 (20:56 +0200)
src/clientiface.cpp
src/clientiface.h
src/server.cpp

index 2841b212f95877cd02133d84b9f6cf4b18004ba2..ebbbc65bcf9a5f31c54a0bdfa41abe641a299aa4 100644 (file)
@@ -52,6 +52,13 @@ std::string ClientInterface::state2Name(ClientState state)
        return statenames[state];
 }
 
+void RemoteClient::ResendBlockIfOnWire(v3s16 p)
+{
+       // if this block is on wire, mark it for sending again as soon as possible
+       if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
+               SetBlockNotSent(p);
+       }
+}
 
 void RemoteClient::GetNextBlocks(
                ServerEnvironment *env,
index 5452ccddbdf5a08cb642ac35d3f4cab2adc8c129..cb3dae04b71355b95b0dd9996ac2a05a92cf32c6 100644 (file)
@@ -238,6 +238,14 @@ public:
        void SetBlockNotSent(v3s16 p);
        void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
 
+       /**
+        * tell client about this block being modified right now.
+        * this information is required to requeue the block in case it's "on wire"
+        * while modification is processed by server
+        * @param p position of modified block
+        */
+       void ResendBlockIfOnWire(v3s16 p);
+
        s32 SendingCount()
        {
                return m_blocks_sending.size();
index 920b9aa2d64c5e4ac9410ea8692774de3962371f..9bd8e70f3a157e52df11fdf379236fb430286f39 100644 (file)
@@ -2545,14 +2545,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                if(is_valid_dig && n.getContent() != CONTENT_IGNORE)
                                        m_script->node_on_dig(p_under, n, playersao);
 
+                               v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
+                               RemoteClient *client = getClient(peer_id);
                                // Send unusual result (that is, node not being removed)
                                if(m_env->getMap().getNodeNoEx(p_under).getContent() != CONTENT_AIR)
                                {
                                        // Re-send block to revert change on client-side
-                                       RemoteClient *client = getClient(peer_id);
-                                       v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
                                        client->SetBlockNotSent(blockpos);
                                }
+                               else {
+                                       client->ResendBlockIfOnWire(blockpos);
+                               }
                        }
                } // action == 2
 
@@ -2594,15 +2597,21 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                        // If item has node placement prediction, always send the
                        // blocks to make sure the client knows what exactly happened
-                       if(item.getDefinition(m_itemdef).node_placement_prediction != ""){
-                               RemoteClient *client = getClient(peer_id);
-                               v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
+                       RemoteClient *client = getClient(peer_id);
+                       v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
+                       v3s16 blockpos2 = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
+                       if(item.getDefinition(m_itemdef).node_placement_prediction != "") {
                                client->SetBlockNotSent(blockpos);
-                               v3s16 blockpos2 = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
-                               if(blockpos2 != blockpos){
+                               if(blockpos2 != blockpos) {
                                        client->SetBlockNotSent(blockpos2);
                                }
                        }
+                       else {
+                               client->ResendBlockIfOnWire(blockpos);
+                               if(blockpos2 != blockpos) {
+                                       client->ResendBlockIfOnWire(blockpos2);
+                               }
+                       }
                } // action == 3
 
                /*