First pass at requesting ID for unknown data

Keep list of AvatarData that was created from a
data packet without a matching ID. If items get
old enough send an ID request and remove them.
This commit is contained in:
Simon Walton 2018-06-20 12:21:39 -07:00
parent c8c135a985
commit d638bdd986
7 changed files with 52 additions and 5 deletions

View file

@ -639,6 +639,7 @@ void AvatarMixer::handleAvatarIdentityRequestPacket(QSharedPointer<ReceivedMessa
auto identityPackets = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
identityPackets->write(serializedAvatar);
nodeList->sendPacketList(std::move(identityPackets), *senderNode);
++_sumIdentityPackets;
}
}
}

View file

@ -54,6 +54,9 @@ static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND /
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
const QUuid MY_AVATAR_KEY; // NULL key
// For an unknown avatar-data packet, wait this long before requesting the identity (in µs).
const quint64 AvatarManager::REQUEST_UNKNOWN_IDENTITY_DELAY = 500 * 1000;
AvatarManager::AvatarManager(QObject* parent) :
_avatarsToFade(),
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
@ -118,6 +121,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
_lastSendAvatarDataTime = now;
_myAvatarSendRate.increment();
}
}
@ -276,6 +280,19 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
simulateAvatarFades(deltaTime);
const quint64 now = usecTimestampNow();
QWriteLocker writeLock(&_hashLock);
for (auto avatarData = _pendingAvatars.begin(); avatarData != _pendingAvatars.end(); ++avatarData) {
Avatar* pendingAvatar = dynamic_cast<Avatar*>(avatarData->get());
if (now - pendingAvatar->getLastRenderUpdateTime() >= REQUEST_UNKNOWN_IDENTITY_DELAY) {
pendingAvatar->sendIdentityRequest();
avatarData = _pendingAvatars.erase(avatarData);
if (avatarData == _pendingAvatars.end()) {
break;
}
}
}
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
}

View file

@ -194,6 +194,8 @@ private:
int _numAvatarsNotUpdated { 0 };
float _avatarSimulationTime { 0.0f };
bool _shouldRender { true };
static const quint64 REQUEST_UNKNOWN_IDENTITY_DELAY;
};
#endif // hifi_AvatarManager_h

View file

@ -1919,6 +1919,19 @@ void AvatarData::sendIdentityPacket() {
_identityDataChanged = false;
}
void AvatarData::sendIdentityRequest() const {
auto nodeList = DependencyManager::get<NodeList>();
auto packet = NLPacket::create(PacketType::AvatarIdentityRequest, NUM_BYTES_RFC4122_UUID, true);
packet->write(getID().toRfc4122());
nodeList->eachMatchingNode(
[&](const SharedNodePointer& node)->bool {
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
},
[&](const SharedNodePointer& node) {
nodeList->sendPacket(std::move(packet), *node);
});
}
void AvatarData::updateJointMappings() {
{
QWriteLocker writeLock(&_jointDataLock);

View file

@ -401,7 +401,7 @@ class AvatarData : public QObject, public SpatiallyNestable {
Q_PROPERTY(float sensorToWorldScale READ getSensorToWorldScale)
public:
void sendIdentityRequest() const;
virtual QString getName() const override { return QString("Avatar:") + _displayName; }
static const QString FRAME_NAME;

View file

@ -89,11 +89,15 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe
return avatar;
}
AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer,
bool& isNew) {
QWriteLocker locker(&_hashLock);
auto avatar = _avatarHash.value(sessionUUID);
if (!avatar) {
avatar = addAvatar(sessionUUID, mixerWeakPointer);
isNew = true;
} else {
isNew = false;
}
return avatar;
}
@ -125,8 +129,13 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
// make sure this isn't our own avatar data or for a previously ignored node
auto nodeList = DependencyManager::get<NodeList>();
bool isNewAvatar;
if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) {
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode);
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar);
if (isNewAvatar) {
QWriteLocker locker(&_hashLock);
_pendingAvatars.insert(sessionUUID, avatar);
}
// have the matching (or new) avatar parse the data from the packet
int bytesRead = avatar->parseDataFromBuffer(byteArray);
@ -157,6 +166,7 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
{
QReadLocker locker(&_hashLock);
_pendingAvatars.remove(identityUUID);
auto me = _avatarHash.find(EMPTY);
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
@ -168,7 +178,8 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
if (!nodeList->isIgnoringNode(identityUUID) || nodeList->getRequestsDomainListData()) {
// mesh URL for a UUID, find avatar in our list
auto avatar = newOrExistingAvatar(identityUUID, sendingNode);
bool isNewAvatar;
auto avatar = newOrExistingAvatar(identityUUID, sendingNode, isNewAvatar);
bool identityChanged = false;
bool displayNameChanged = false;
bool skeletonModelUrlChanged = false;
@ -189,6 +200,7 @@ void AvatarHashMap::processKillAvatar(QSharedPointer<ReceivedMessage> message, S
void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) {
QWriteLocker locker(&_hashLock);
_pendingAvatars.remove(sessionUUID);
auto removedAvatar = _avatarHash.take(sessionUUID);
if (removedAvatar) {

View file

@ -145,13 +145,15 @@ protected:
virtual AvatarSharedPointer parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
virtual AvatarSharedPointer newSharedAvatar();
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer,
bool& isNew);
virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock
virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason);
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
AvatarHash _avatarHash;
AvatarHash _pendingAvatars;
mutable QReadWriteLock _hashLock;
private: