From 7851c4f7a2673477cf80a38842d77efbe5a0a915 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Tue, 24 Mar 2015 09:36:54 +0100 Subject: [PATCH] Don't send an InventoryAction at each setInventoryModified, we only need one SendInventory per inventory modification Client doesn't like to receive multiples SendInventory for one action, this can trigger glitches on clients (sometimes due to incorrect UDP packet ordering due to UDP protocol) This fix issue #2544 --- src/inventorymanager.cpp | 6 +++--- src/inventorymanager.h | 2 +- src/network/serverpackethandler.cpp | 10 ++++++---- src/server.cpp | 5 ++++- src/server.h | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 26cabc25f0..178985dfd2 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -455,9 +455,9 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame } } - mgr->setInventoryModified(from_inv); + mgr->setInventoryModified(from_inv, false); if(inv_from != inv_to) - mgr->setInventoryModified(to_inv); + mgr->setInventoryModified(to_inv, false); } void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef) @@ -597,7 +597,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame if(item2.count != actually_dropped_count) errorstream<<"Could not take dropped count of items"<setInventoryModified(from_inv); + mgr->setInventoryModified(from_inv, false); } } diff --git a/src/inventorymanager.h b/src/inventorymanager.h index 8e2abc9614..39cc6e50f3 100644 --- a/src/inventorymanager.h +++ b/src/inventorymanager.h @@ -112,7 +112,7 @@ public: // Get an inventory (server and client) virtual Inventory* getInventory(const InventoryLocation &loc){return NULL;} // Set modified (will be saved and sent over network; only on server) - virtual void setInventoryModified(const InventoryLocation &loc){} + virtual void setInventoryModified(const InventoryLocation &loc, bool playerSend = true){} // Send inventory action to server (only on client) virtual void inventoryAction(InventoryAction *a){} }; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index f6438d3119..7d5a9bc71e 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -952,8 +952,8 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt) ma->from_inv.applyCurrentPlayer(player->getName()); ma->to_inv.applyCurrentPlayer(player->getName()); - setInventoryModified(ma->from_inv); - setInventoryModified(ma->to_inv); + setInventoryModified(ma->from_inv, false); + setInventoryModified(ma->to_inv, false); bool from_inv_is_current_player = (ma->from_inv.type == InventoryLocation::PLAYER) && @@ -1006,7 +1006,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt) da->from_inv.applyCurrentPlayer(player->getName()); - setInventoryModified(da->from_inv); + setInventoryModified(da->from_inv, false); /* Disable dropping items out of craftpreview @@ -1033,7 +1033,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt) ca->craft_inv.applyCurrentPlayer(player->getName()); - setInventoryModified(ca->craft_inv); + setInventoryModified(ca->craft_inv, false); //bool craft_inv_is_current_player = // (ca->craft_inv.type == InventoryLocation::PLAYER) && @@ -1052,6 +1052,8 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt) a->apply(this, playersao, this); // Eat the action delete a; + + SendInventory(playersao); } void Server::handleCommand_ChatMessage(NetworkPacket* pkt) diff --git a/src/server.cpp b/src/server.cpp index 52183980f6..8c76fdc167 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1290,13 +1290,16 @@ Inventory* Server::getInventory(const InventoryLocation &loc) } return NULL; } -void Server::setInventoryModified(const InventoryLocation &loc) +void Server::setInventoryModified(const InventoryLocation &loc, bool playerSend) { switch(loc.type){ case InventoryLocation::UNDEFINED: break; case InventoryLocation::PLAYER: { + if (!playerSend) + return; + Player *player = m_env->getPlayer(loc.name.c_str()); if(!player) return; diff --git a/src/server.h b/src/server.h index f62b5b6607..0c0a5f91c0 100644 --- a/src/server.h +++ b/src/server.h @@ -237,7 +237,7 @@ public: Shall be called with the environment and the connection locked. */ Inventory* getInventory(const InventoryLocation &loc); - void setInventoryModified(const InventoryLocation &loc); + void setInventoryModified(const InventoryLocation &loc, bool playerSend = true); // Connection must be locked when called std::wstring getStatusString();