From fd40e8c9710c567e1553f757b694f0b42e054397 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Tue, 15 Jan 2019 14:26:00 +0200 Subject: [PATCH] [Client] Prevent ObjectState spam by not resending an already sent state --- apps/openmw/mwscript/interpretercontext.cpp | 22 ++++++++++------ apps/openmw/mwworld/refdata.hpp | 28 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index b0049e1b7..368049e2b 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -613,13 +613,17 @@ namespace MWScript Start of tes3mp addition Send an ID_OBJECT_STATE packet whenever an object is enabled, as long as - the player is logged in on the server and the object wasn't already - enabled previously + the player is logged in on the server, the object is still disabled, and our last + packet regarding its state did not already attempt to enable it (to prevent + packet spam) */ if (mwmp::Main::get().getLocalPlayer()->isLoggedIn()) { - if (ref.isInCell() && !ref.getRefData().isEnabled()) + if (ref.isInCell() && !ref.getRefData().isEnabled() && + ref.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Enabled) { + ref.getRefData().setLastCommunicatedState(MWWorld::RefData::StateCommunication::Enabled); + mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(getContextType()); @@ -650,14 +654,18 @@ namespace MWScript /* Start of tes3mp addition - Send an ID_OBJECT_STATE packet whenever an object is disabled, as long as - the player is logged in on the server and the object wasn't already - disabled previously + Send an ID_OBJECT_STATE packet whenever an object should be disabled, as long as + the player is logged in on the server, the object is still enabled, and our last + packet regarding its state did not already attempt to disable it (to prevent + packet spam) */ if (mwmp::Main::get().getLocalPlayer()->isLoggedIn()) { - if (ref.isInCell() && ref.getRefData().isEnabled()) + if (ref.isInCell() && ref.getRefData().isEnabled() && + ref.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Disabled) { + ref.getRefData().setLastCommunicatedState(MWWorld::RefData::StateCommunication::Disabled); + mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(getContextType()); diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 75eec6742..f857caf6c 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -138,6 +138,34 @@ namespace MWWorld const ESM::AnimationState& getAnimationState() const; ESM::AnimationState& getAnimationState(); + + /* + Start of tes3mp addition + + Track the last state communicated to the server for this reference, + to avoid packet spam when the server denies our state change request or + is slow to reply + */ + enum StateCommunication + { + None = 0, + Enabled = 1, + Disabled = 2 + }; + + private: + + short mLastCommunicatedState = StateCommunication::None; + + public: + + short getLastCommunicatedState() { return mLastCommunicatedState; }; + + void setLastCommunicatedState(short communicationState) { mLastCommunicatedState = communicationState; }; + /* + End of tes3mp addition + */ + }; }