From a8cf1e02c480ec4c940768856a31e3a0013051d7 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Thu, 25 Oct 2018 22:38:45 +0300 Subject: [PATCH] [Client] Allow unilateral scripted container changes not from console This prevents infinite loops in certain client scripts from mods that use while loops to determine that all items of a certain type have been removed from a container, such as in the script BCSwap2Arg from Better_Clothes. --- apps/openmw/mwscript/containerextensions.cpp | 34 ++++++++++++-------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index ac58b77cb..57914e1bc 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -80,18 +80,24 @@ namespace MWScript /* Start of tes3mp change (major) - Disable unilateral item addition on this client and expect the server's reply to our - packet to do it instead, except for changes to player inventories which still require - the PlayerInventory to be reworked + Allow unilateral item removal on this client from client scripts and dialogue (but not console commands) + to prevent infinite loops in certain mods. Otherwise, expect the server's reply to our packet to do the + removal instead, except for changes to player inventories which still require the PlayerInventory to be + reworked. */ - // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) - if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() ) - { - MWWorld::Ptr itemPtr = *ptr.getClass().getContainerStore(ptr).add(item, count, ptr); + unsigned char packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType()); + + MWWorld::Ptr itemPtr; + + if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr() || packetOrigin != mwmp::CLIENT_CONSOLE) + itemPtr = *ptr.getClass().getContainerStore(ptr).add(item, count, ptr); /* End of tes3mp change (major) */ + // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) + if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) + { // 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); @@ -118,7 +124,7 @@ namespace MWScript { mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); - objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType()); + objectList->packetOrigin = packetOrigin; objectList->cell = *ptr.getCell()->getCell(); objectList->action = mwmp::BaseObjectList::ADD; objectList->containerSubAction = mwmp::BaseObjectList::NONE; @@ -203,13 +209,15 @@ namespace MWScript /* Start of tes3mp change (major) - Disable unilateral item removal on this client and expect the server's reply to our - packet to do it instead, except for changes to player inventories which still require - the PlayerInventory to be reworked + Allow unilateral item removal on this client from client scripts and dialogue (but not console commands) + to prevent infinite loops in certain mods. Otherwise, expect the server's reply to our packet to do the + removal instead, except for changes to player inventories which still require the PlayerInventory to be + reworked. */ + unsigned char packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType()); int numRemoved = 0; - if (ptr == MWMechanics::getPlayer()) + if (ptr == MWMechanics::getPlayer() || packetOrigin != mwmp::CLIENT_CONSOLE) numRemoved = store.remove(item, count, ptr); // Spawn a messagebox (only for items removed from player's inventory) @@ -246,7 +254,7 @@ namespace MWScript { mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); - objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType()); + objectList->packetOrigin = packetOrigin; objectList->cell = *ptr.getCell()->getCell(); objectList->action = mwmp::BaseObjectList::REMOVE; objectList->containerSubAction = mwmp::BaseObjectList::NONE;