Fix MS17811: Prevent frozen avatars in certain ignore cases

This commit is contained in:
Zach Fox 2018-12-11 14:52:11 -08:00
parent c401f3c8bd
commit d46b8d6471
2 changed files with 18 additions and 0 deletions

View file

@ -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;

View file

@ -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