From 3a5a7cfc05c984d79b973ffda5eca0492fd04f7c Mon Sep 17 00:00:00 2001 From: SweetBandits_Dufour Date: Mon, 29 Jun 2020 15:12:52 -0400 Subject: [PATCH 1/3] Update NetBindingSystemImpl.cpp When a client is deleting netbound entities (for which he is not the authority), this leaves the NetBinding system with pointers to invalid entities in the m_boundEntities. Causing either crashes or deletion of random entities when the authority actually signals destruction of the netreplicated slice. I'm working around this by storing entity Ids rather than storing pointers. --- .../Network/NetBindingSystemImpl.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp index 9fc9368080..4b87731fba 100644 --- a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp +++ b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp @@ -65,10 +65,11 @@ namespace AzFramework EBUS_EVENT(GameEntityContextRequestBus, CancelDynamicSliceInstantiation, m_ticket); } - for (AZ::Entity* entity : m_boundEntities) + for (AZ::EntityId boundEntityId : m_boundEntities) { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Cleanup - deleting %llu\n", entity->GetId()); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entity->GetId()); + AZ_Assert(boundEntityId != AZ::SystemEntityId, "NetBindingSliceInstantiationHandler is destroying the system entity"); + AZ_ExtraTracePrintf("NetBindingSystemImpl", "Cleanup - deleting %llu\n", boundEntityId); + EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, boundEntityId); } } @@ -123,9 +124,12 @@ namespace AzFramework bool NetBindingSliceInstantiationHandler::HasActiveEntities() const { - for (const AZ::Entity* entity : m_boundEntities) + for (const AZ::EntityId boundEntityId : m_boundEntities) { - if (entity->GetState() == AZ::Entity::ES_ACTIVE) + AZ::Entity* entity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, boundEntityId); + + if (entity && entity->GetState() == AZ::Entity::ES_ACTIVE) { return true; } @@ -196,7 +200,7 @@ namespace AzFramework } AZ_ExtraTracePrintf("NetBindingSystemImpl", "Adding %llu \n", sliceEntity->GetId()); - m_boundEntities.push_back(sliceEntity); + m_boundEntities.push_back(sliceEntity->GetId()); } m_state = State::Spawned; @@ -247,8 +251,8 @@ namespace AzFramework } const AZ::EntityId actualRuntimeEntityId = actualRuntimeIter->second; - const auto itCache = AZStd::find_if(m_boundEntities.begin(), m_boundEntities.end(), [&actualRuntimeEntityId](AZ::Entity* entity) { - return entity->GetId() == actualRuntimeEntityId; + const auto itCache = AZStd::find_if(m_boundEntities.begin(), m_boundEntities.end(), [&actualRuntimeEntityId](AZ::EntityId boundEntityId) { + return boundEntityId == actualRuntimeEntityId; }); if (itCache != m_boundEntities.end()) @@ -495,9 +499,12 @@ namespace AzFramework if (itSliceHandler != itCurrentContextQueue->second.end()) { NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - for (AZ::Entity* entity : sliceHandler.m_boundEntities) + for (AZ::EntityId boundEntityId : sliceHandler.m_boundEntities) { - if (entity->GetId() == entityId) + AZ::Entity* entity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, boundEntityId); + + if (entity) { entity->Deactivate(); return; From 9282d4a2c64513db99e36508688d5cc9de74e4c0 Mon Sep 17 00:00:00 2001 From: SweetBandits_Dufour Date: Mon, 29 Jun 2020 15:14:49 -0400 Subject: [PATCH 2/3] Update NetBindingSystemImpl.h The header file changing the m_boundEntities vector contents from Entity pointers to entity Ids --- .../AzFramework/AzFramework/Network/NetBindingSystemImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h index d2c473980b..da02943a15 100644 --- a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h +++ b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h @@ -103,7 +103,7 @@ namespace AzFramework * \breif a cache of entities that might be networked at some point * \note they might be bound and unbound if their replicas leave and come back in the view */ - AZStd::vector m_boundEntities; + AZStd::vector m_boundEntities; /** * \brief identifies which slice instance the instantiation will be performed for From a1c8704553300e69cb93c5da8ac11923ed729025 Mon Sep 17 00:00:00 2001 From: SweetBandits_Dufour Date: Wed, 15 Jul 2020 21:13:09 -0400 Subject: [PATCH 3/3] Update NetBindingSystemImpl.cpp Fixed bug where whole slice would get destroyed as soon as authority destroyed one of the slice's entities --- .../Network/NetBindingSystemImpl.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp index 4b87731fba..d61e1adc3a 100644 --- a/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp +++ b/dev/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp @@ -501,14 +501,17 @@ namespace AzFramework NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; for (AZ::EntityId boundEntityId : sliceHandler.m_boundEntities) { - AZ::Entity* entity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, boundEntityId); - - if (entity) - { - entity->Deactivate(); - return; - } + if(boundEntityId == entityId) + { + AZ::Entity* entity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, boundEntityId); + + if (entity) + { + entity->Deactivate(); + return; + } + } } // clean any relevant bind requests as well