aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsapier <Sapier at GMX dot net>2014-07-12 20:20:11 +0200
committersapier <Sapier at GMX dot net>2014-08-22 20:56:16 +0200
commit8e9d896f2d4bd3c9579170d01e14f1dd5e514362 (patch)
tree69f53c3cb51e481ccd21418470f552b60b57ef11
parent247a1ebf2317556eea79a018fb236a0145e55121 (diff)
downloadminetest-8e9d896f2d4bd3c9579170d01e14f1dd5e514362.tar.gz
minetest-8e9d896f2d4bd3c9579170d01e14f1dd5e514362.tar.bz2
minetest-8e9d896f2d4bd3c9579170d01e14f1dd5e514362.zip
Fix "ghost" blocks if block update is "on wire" while player digs nodes
-rw-r--r--src/clientiface.cpp7
-rw-r--r--src/clientiface.h8
-rw-r--r--src/server.cpp23
3 files changed, 31 insertions, 7 deletions
diff --git a/src/clientiface.cpp b/src/clientiface.cpp
index 2841b212f..ebbbc65bc 100644
--- a/src/clientiface.cpp
+++ b/src/clientiface.cpp
@@ -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,
diff --git a/src/clientiface.h b/src/clientiface.h
index 5452ccddb..cb3dae04b 100644
--- a/src/clientiface.h
+++ b/src/clientiface.h
@@ -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();
diff --git a/src/server.cpp b/src/server.cpp
index 920b9aa2d..9bd8e70f3 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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
/*