From 3bd8aa82fe7c1064623d0275168b80a90a4cb39e Mon Sep 17 00:00:00 2001 From: David Cernat Date: Tue, 28 Aug 2018 05:01:52 +0300 Subject: [PATCH] [General] Reduce inventory-sending hooks to just 2 in ContainerStore Whenever an item is added to or removed from the player's ContainerStore, that player sends a PlayerInventory packet with just that addition or removal. This eliminates all the unnecessary packet spam related to oversized PlayerInventory packets that had existed in one form or another since the initial implementation of inventory sync in 1b259e2d3309cc3868f97b3bb5ca685e2d17ba50 Additionally, move booleans from BasePlayer to LocalPlayer when they are only needed on the client, and make the usage of the isReceivingQuickKeys boolean consistent with the new isReceivingInventory boolean by having them both in the processors of their associated packets. --- apps/openmw/mwgui/container.cpp | 1 - apps/openmw/mwgui/hud.cpp | 5 -- apps/openmw/mwgui/inventorywindow.cpp | 8 --- apps/openmw/mwgui/tradewindow.cpp | 21 ------- apps/openmw/mwgui/trainingwindow.cpp | 21 ------- apps/openmw/mwmechanics/enchanting.cpp | 16 ------ apps/openmw/mwmp/LocalPlayer.cpp | 10 +--- apps/openmw/mwmp/LocalPlayer.hpp | 5 ++ .../player/ProcessorPlayerInventory.hpp | 10 ++-- .../player/ProcessorPlayerQuickKeys.hpp | 7 +++ apps/openmw/mwscript/containerextensions.cpp | 12 ---- apps/openmw/mwworld/actiontake.cpp | 9 --- apps/openmw/mwworld/containerstore.cpp | 55 +++++++++++++++++++ components/openmw-mp/Base/BasePlayer.hpp | 4 -- 14 files changed, 74 insertions(+), 110 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 8cbc00076..16ad6eb96 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -276,7 +276,6 @@ namespace MWGui Mark this container as closed for multiplayer logic purposes */ mwmp::Main::get().getLocalPlayer()->clearCurrentContainer(); - mwmp::Main::get().getLocalPlayer()->updateInventory(); /* End of tes3mp addition */ diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 08b9dd7f7..de1c2f326 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -15,7 +15,6 @@ #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" #include "../mwmp/ObjectList.hpp" -#include "../mwmp/LocalPlayer.hpp" #include "../mwworld/cellstore.hpp" /* End of tes3mp addition @@ -71,16 +70,12 @@ namespace MWGui Send an ID_OBJECT_PLACE packet every time an object is dropped into the world from the inventory screen - - Send an ID_PLAYER_INVENTORY packet about the item's removal */ mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectPlace(dropped, true); objectList->sendObjectPlace(); - - mwmp::Main::get().getLocalPlayer()->sendItemChange(dropped, count, mwmp::InventoryChanges::REMOVE); /* End of tes3mp addition */ diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index b15f6594e..7aea5860d 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -723,20 +723,12 @@ namespace MWGui Send an ID_OBJECT_DELETE packet every time an item from the world is picked up by the player through the inventory HUD - - Send an ID_PLAYER_INVENTORY packet as well because of the item thus gained - by the player */ mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectDelete(object); objectList->sendObjectDelete(); - - // If the item is gold, make sure we get the correct value - unsigned int itemCount = object.getClass().isGold(object) ? object.getCellRef().getGoldValue() : object.getRefData().getCount(); - - mwmp::Main::get().getLocalPlayer()->sendItemChange(object, itemCount, mwmp::InventoryChanges::ADD); /* End of tes3mp addition */ diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index fd1b9f0d7..e11147c74 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -6,17 +6,6 @@ #include #include -/* - Start of tes3mp addition - - Include additional headers for multiplayer purposes -*/ -#include "../mwmp/Main.hpp" -#include "../mwmp/LocalPlayer.hpp" -/* - End of tes3mp addition -*/ - #include #include "../mwbase/environment.hpp" @@ -367,16 +356,6 @@ namespace MWGui mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance ); } - /* - Start of tes3mp addition - - Send an ID_PLAYER_INVENTORY packet every time a player completes a trade - */ - mwmp::Main::get().getLocalPlayer()->sendInventory(); - /* - End of tes3mp addition - */ - eventTradeDone(); MWBase::Environment::get().getWindowManager()->playSound("Item Gold Up"); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 427c7f3fe..43414301c 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -2,17 +2,6 @@ #include -/* - Start of tes3mp addition - - Include additional headers for multiplayer purposes -*/ -#include "../mwmp/Main.hpp" -#include "../mwmp/LocalPlayer.hpp" -/* - End of tes3mp addition -*/ - #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -178,16 +167,6 @@ namespace MWGui // remove gold player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); - /* - Start of tes3mp addition - - Send an ID_PLAYER_INVENTORY packet with the gold lost - */ - mwmp::Main::get().getLocalPlayer()->sendItemChange(MWWorld::ContainerStore::sGoldId, price, mwmp::InventoryChanges::REMOVE); - /* - End of tes3mp addition - */ - // add gold to NPC trading gold pool npcStats.setGoldPool(npcStats.getGoldPool() + price); diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 3714d9a45..a3b5dba89 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -10,7 +10,6 @@ #include #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" -#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/Worldstate.hpp" /* End of tes3mp addition @@ -108,9 +107,6 @@ namespace MWMechanics Don't add the new item to the player's inventory and instead expect the server to add it - - Before using the applyEnchantment() method, send an ID_PLAYER_INVENTORY packet - removing the old item from the player's inventory The applyEnchantment() method is where the record of the newly enchanted will be sent to the server, causing the server to send back the player's inventory with the new item @@ -123,8 +119,6 @@ namespace MWMechanics if(!mSelfEnchanting) payForEnchantment(); - mwmp::Main::get().getLocalPlayer()->sendItemChange(mOldItemPtr, 1, mwmp::InventoryChanges::REMOVE); - std::string newItemId = mOldItemPtr.getClass().applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); /* End of tes3mp change (major) @@ -337,16 +331,6 @@ namespace MWMechanics store.remove(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), player); - /* - Start of tes3mp addition - - Send an ID_PLAYER_INVENTORY packet removing the gold from the player - */ - mwmp::Main::get().getLocalPlayer()->sendItemChange(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), mwmp::InventoryChanges::REMOVE); - /* - End of tes3mp addition - */ - // add gold to NPC trading gold pool CreatureStats& enchanterStats = mEnchanter.getClass().getCreatureStats(mEnchanter); enchanterStats.setGoldPool(enchanterStats.getGoldPool() + getEnchantPrice()); diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 5ee43fdf3..6568e4d80 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -76,6 +76,7 @@ LocalPlayer::LocalPlayer() scale = 1; isWerewolf = false; + isReceivingInventory = false; isReceivingQuickKeys = false; isPlayingAnimation = false; diedSinceArrestAttempt = false; @@ -456,9 +457,6 @@ void LocalPlayer::updateCell(bool forceUpdate) getNetworking()->getPlayerPacket(ID_PLAYER_CELL_CHANGE)->Send(); isChangingRegion = false; - - // Also check if the inventory needs to be updated - updateInventory(); } } @@ -1204,10 +1202,6 @@ void LocalPlayer::setQuickKeys() LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received ID_PLAYER_QUICKKEYS from server"); - // Because we send QuickKeys packets from the same OpenMW methods that we use to set received ones with, - // we need a boolean to prevent their sending here - isReceivingQuickKeys = true; - for (const auto &quickKey : quickKeyChanges.quickKeys) { LOG_APPEND(Log::LOG_INFO, "- slot: %i, type: %i, itemId: %s", quickKey.slot, quickKey.type, quickKey.itemId.c_str()); @@ -1245,8 +1239,6 @@ void LocalPlayer::setQuickKeys() else MWBase::Environment::get().getWindowManager()->setQuickKey(quickKey.slot, quickKey.type, 0); } - - isReceivingQuickKeys = false; } void LocalPlayer::setFactions() diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 8cc72d1e1..faa59a394 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -17,6 +17,11 @@ namespace mwmp time_t deathTime; + bool isReceivingInventory; + bool isReceivingQuickKeys; + bool isPlayingAnimation; + bool diedSinceArrestAttempt; + void update(); bool processCharGen(); diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp index 9595f01c4..000af982d 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp @@ -1,7 +1,3 @@ -// -// Created by koncord on 16.04.17. -// - #ifndef OPENMW_PROCESSORPLAYERUPDATEINVENTORY_HPP #define OPENMW_PROCESSORPLAYERUPDATEINVENTORY_HPP @@ -30,12 +26,18 @@ namespace mwmp LocalPlayer &localPlayer = static_cast(*player); int inventoryAction = localPlayer.inventoryChanges.action; + // Because we send PlayerInventory packets from the same OpenMW methods that we use to set the + // items received, we need to set a boolean to prevent resending the items set here + localPlayer.isReceivingInventory = true; + if (inventoryAction == InventoryChanges::ADD) localPlayer.addItems(); else if (inventoryAction == InventoryChanges::REMOVE) localPlayer.removeItems(); else // InventoryChanges::SET localPlayer.setInventory(); + + localPlayer.isReceivingInventory = false; } } }; diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerQuickKeys.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerQuickKeys.hpp index 5515162a6..bc2782449 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerQuickKeys.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerQuickKeys.hpp @@ -23,7 +23,14 @@ namespace mwmp if (!isRequest()) { LocalPlayer &localPlayer = static_cast(*player); + + // Because we send PlayerQuickKeys packets from the same OpenMW methods that we use to set the + // quick keys received, we need to set a boolean to prevent resending the keys set here + localPlayer.isReceivingQuickKeys = true; + localPlayer.setQuickKeys(); + + localPlayer.isReceivingQuickKeys = false; } } }; diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 3d8bed2ff..ae33e9457 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -92,17 +92,6 @@ namespace MWScript End of tes3mp change (major) */ - /* - Start of tes3mp addition - - Send an ID_PLAYER_INVENTORY packet every time a player gains an item - through a script - */ - mwmp::Main::get().getLocalPlayer()->sendItemChange(item, count, mwmp::InventoryChanges::ADD); - /* - End of tes3mp addition - */ - // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory std::string msgBox; std::string itemName = itemPtr.getClass().getName(itemPtr); @@ -226,7 +215,6 @@ namespace MWScript if ((numRemoved > 0) && (ptr == MWMechanics::getPlayer())) { - mwmp::Main::get().getLocalPlayer()->sendItemChange(item, count, mwmp::InventoryChanges::REMOVE); /* End of tes3mp change (major) */ diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index 7376347c6..31ee96c6f 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -8,7 +8,6 @@ #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" #include "../mwmp/ObjectList.hpp" -#include "../mwmp/LocalPlayer.hpp" /* End of tes3mp addition */ @@ -36,20 +35,12 @@ namespace MWWorld Send an ID_OBJECT_DELETE packet every time an item is taken from the world by the player outside of the inventory screen - - Send an ID_PLAYER_INVENTORY packet as well with the item thus gained - by the player */ mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectDelete(getTarget()); objectList->sendObjectDelete(); - - // If the item is gold, make sure we get the correct value - unsigned int itemCount = getTarget().getClass().isGold(newitem) ? getTarget().getCellRef().getGoldValue() : getTarget().getRefData().getCount(); - - mwmp::Main::get().getLocalPlayer()->sendItemChange(getTarget(), itemCount, mwmp::InventoryChanges::ADD); /* End of tes3mp addition */ diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 6c369a154..79ba30130 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -4,6 +4,18 @@ #include #include +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ +#include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" +#include "../mwmp/LocalPlayer.hpp" +/* + End of tes3mp addition +*/ + #include #include "../mwbase/environment.hpp" @@ -284,6 +296,31 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr // The copy of the original item we just made MWWorld::Ptr item = *it; + /* + Start of tes3mp addition + + Send an ID_PLAYER_INVENTORY packet every time an item gets added for a player here + */ + if (actorPtr == player && this == &player.getClass().getContainerStore(player)) + { + mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer(); + + if (!localPlayer->isReceivingInventory) + { + int realCount = count; + + if (itemPtr.getClass().isGold(itemPtr)) + { + realCount = realCount * itemPtr.getClass().getValue(itemPtr); + } + + localPlayer->sendItemChange(item, realCount, mwmp::InventoryChanges::ADD); + } + } + /* + End of tes3mp addition + */ + // we may have copied an item from the world, so reset a few things first item.getRefData().setBaseNode(NULL); // Especially important, otherwise scripts on the item could think that it's actually in a cell ESM::Position pos; @@ -422,6 +459,24 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor { assert(this == item.getContainerStore()); + /* + Start of tes3mp addition + + Send an ID_PLAYER_INVENTORY packet every time an item gets removed for a player here + */ + Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + + if (actor == player && this == &player.getClass().getContainerStore(player)) + { + mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer(); + + if (!localPlayer->isReceivingInventory) + localPlayer->sendItemChange(item, count, mwmp::InventoryChanges::REMOVE); + } + /* + End of tes3mp addition + */ + int toRemove = count; RefData& itemRef = item.getRefData(); diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 4392e39c2..6bc6e305c 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -325,10 +325,6 @@ namespace mwmp std::string selectedSpellId; mwmp::Item usedItem; - - bool isReceivingQuickKeys; - bool isPlayingAnimation; - bool diedSinceArrestAttempt; }; }