Don't send an InventoryAction at each setInventoryModified, we only need one SendInve...
authorLoic Blot <loic.blot@unix-experience.fr>
Tue, 24 Mar 2015 08:36:54 +0000 (09:36 +0100)
committerLoic Blot <loic.blot@unix-experience.fr>
Tue, 24 Mar 2015 13:13:17 +0000 (14:13 +0100)
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
src/inventorymanager.h
src/network/serverpackethandler.cpp
src/server.cpp
src/server.h

index 26cabc25f078a95a8a2d461f07c0645d2f0b2a32..178985dfd2b3bca8d797e74cfa200447b9357cfe 100644 (file)
@@ -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"<<std::endl;
 
-                       mgr->setInventoryModified(from_inv);
+                       mgr->setInventoryModified(from_inv, false);
                }
        }
 
index 8e2abc9614f13f339efac2fa4b5e96c6b0ef3f7d..39cc6e50f3b07423c48fc88c72efb70cace43ce0 100644 (file)
@@ -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){}
 };
index f6438d3119e304e28f97023fbdaf591cbb7591bb..7d5a9bc71ed39421fe6cbb1c0af87afa468c3533 100644 (file)
@@ -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)
index 52183980f6c9abff21e485980c607e6bf7c922b0..8c76fdc16749f8dc5fd6b334586d479b219ffb46 100644 (file)
@@ -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;
index f62b5b66070a6a03c1fde915371929efa4bd16ff..0c0a5f91c0022ec8f915ca39d9af5b40471ea1de 100644 (file)
@@ -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();