diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index afbc68378a..8a86af384a 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -110,6 +110,8 @@ public: void setBaseDisplayName(const QString& baseDisplayName) { _baseDisplayName = baseDisplayName; } bool getRequestsDomainListData() { return _requestsDomainListData; } void setRequestsDomainListData(bool requesting) { _requestsDomainListData = requesting; } + bool getPrevRequestsDomainListData() { return _prevRequestsDomainListData; } + void setPrevRequestsDomainListData(bool requesting) { _prevRequestsDomainListData = requesting; } const ConicalViewFrustums& getViewFrustums() const { return _currentViewFrustums; } @@ -176,6 +178,7 @@ private: int _recentOtherAvatarsOutOfView { 0 }; QString _baseDisplayName{}; // The santized key used in determinging unique sessionDisplayName, so that we can remove from dictionary. bool _requestsDomainListData { false }; + bool _prevRequestsDomainListData{ false }; AvatarTraits::TraitVersions _lastReceivedTraitVersions; TraitsCheckTimestamp _lastReceivedTraitsChange; diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a037f24345..5df7758a0c 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -268,6 +268,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // When this is true, the AvatarMixer will send Avatar data to a client // about avatars they've ignored or that are out of view bool PALIsOpen = nodeData->getRequestsDomainListData(); + bool PALWasOpen = nodeData->getPrevRequestsDomainListData(); // When this is true, the AvatarMixer will send Avatar data to a client about avatars that have ignored them bool getsAnyIgnored = PALIsOpen && destinationNode->getCanKick(); @@ -392,6 +393,20 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) sortedAvatars.push(SortableAvatar(avatarNodeData, avatarNode, lastEncodeTime)); } + + // If Avatar A's PAL WAS open but is no longer open, AND + // Avatar A should be ignoring Avatar B... + if (PALWasOpen && !PALIsOpen && shouldIgnore) { + // ...send a Kill Packet to Node A, instructing Node A to kill Avatar B, + // then have Node A cleanup the killed Node B. + auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); + packet->write(avatarNode->getUUID().toRfc4122()); + packet->writePrimitive(KillAvatarReason::AvatarIgnored); + nodeList->sendPacket(std::move(packet), *destinationNode); + nodeData->cleanupKilledNode(avatarNode->getUUID(), avatarNode->getLocalID()); + } + + nodeData->setPrevRequestsDomainListData(PALIsOpen); } // loop through our sorted avatars and allocate our bandwidth to them accordingly