mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 15:23:05 +02:00
don't unpack avatar identity that is old
This commit is contained in:
parent
9be016fd3e
commit
50b56ec761
7 changed files with 98 additions and 85 deletions
|
@ -510,12 +510,9 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer<ReceivedMessage> mes
|
||||||
AvatarData& avatar = nodeData->getAvatar();
|
AvatarData& avatar = nodeData->getAvatar();
|
||||||
|
|
||||||
// parse the identity packet and update the change timestamp if appropriate
|
// parse the identity packet and update the change timestamp if appropriate
|
||||||
AvatarData::Identity identity;
|
|
||||||
AvatarData::parseAvatarIdentityPacket(message->getMessage(), identity);
|
|
||||||
|
|
||||||
bool identityChanged = false;
|
bool identityChanged = false;
|
||||||
bool displayNameChanged = false;
|
bool displayNameChanged = false;
|
||||||
avatar.processAvatarIdentity(identity, identityChanged, displayNameChanged);
|
avatar.processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
||||||
if (identityChanged) {
|
if (identityChanged) {
|
||||||
QMutexLocker nodeDataLocker(&nodeData->getMutex());
|
QMutexLocker nodeDataLocker(&nodeData->getMutex());
|
||||||
nodeData->flagIdentityChange();
|
nodeData->flagIdentityChange();
|
||||||
|
|
|
@ -1473,27 +1473,6 @@ QStringList AvatarData::getJointNames() const {
|
||||||
return _jointNames;
|
return _jointNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::parseAvatarIdentityPacket(const QByteArray& data, Identity& identityOut) {
|
|
||||||
QDataStream packetStream(data);
|
|
||||||
|
|
||||||
packetStream >> identityOut.uuid
|
|
||||||
>> identityOut.skeletonModelURL
|
|
||||||
>> identityOut.attachmentData
|
|
||||||
>> identityOut.displayName
|
|
||||||
>> identityOut.sessionDisplayName
|
|
||||||
>> identityOut.avatarEntityData
|
|
||||||
>> identityOut.sequenceId;
|
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
|
||||||
qCDebug(avatars) << __FUNCTION__
|
|
||||||
<< "identityOut.uuid:" << identityOut.uuid
|
|
||||||
<< "identityOut.skeletonModelURL:" << identityOut.skeletonModelURL
|
|
||||||
<< "identityOut.displayName:" << identityOut.displayName
|
|
||||||
<< "identityOut.sessionDisplayName:" << identityOut.sessionDisplayName;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::quat AvatarData::getOrientationOutbound() const {
|
glm::quat AvatarData::getOrientationOutbound() const {
|
||||||
return (getLocalOrientation());
|
return (getLocalOrientation());
|
||||||
}
|
}
|
||||||
|
@ -1504,46 +1483,80 @@ QUrl AvatarData::cannonicalSkeletonModelURL(const QUrl& emptyURL) const {
|
||||||
return _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
|
return _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::processAvatarIdentity(const Identity& identity, bool& identityChanged, bool& displayNameChanged) {
|
void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged) {
|
||||||
|
|
||||||
if (identity.sequenceId < _identitySequenceId) {
|
QDataStream packetStream(identityData);
|
||||||
qCDebug(avatars) << "Ignoring older identity packet for avatar" << getSessionUUID()
|
|
||||||
<< "_identitySequenceId (" << _identitySequenceId << ") is greater than" << identity.sequenceId;
|
QUuid avatarSessionID;
|
||||||
return;
|
|
||||||
|
// peek the sequence number, this will tell us if we should be processing this identity packet at all
|
||||||
|
udt::SequenceNumber::Type incomingSequenceNumberType;
|
||||||
|
packetStream >> avatarSessionID >> incomingSequenceNumberType;
|
||||||
|
udt::SequenceNumber incomingSequenceNumber(incomingSequenceNumberType);
|
||||||
|
|
||||||
|
if (!_hasProcessedFirstIdentity) {
|
||||||
|
_identitySequenceNumber = incomingSequenceNumber - 1;
|
||||||
|
_hasProcessedFirstIdentity = true;
|
||||||
|
qCDebug(avatars) << "Processing first identity packet for" << avatarSessionID << "-"
|
||||||
|
<< (udt::SequenceNumber::Type) incomingSequenceNumber;
|
||||||
}
|
}
|
||||||
// otherwise, set the identitySequenceId to match the incoming identity
|
|
||||||
_identitySequenceId = identity.sequenceId;
|
|
||||||
|
|
||||||
if (_firstSkeletonCheck || (identity.skeletonModelURL != cannonicalSkeletonModelURL(emptyURL))) {
|
if (incomingSequenceNumber > _identitySequenceNumber) {
|
||||||
setSkeletonModelURL(identity.skeletonModelURL);
|
Identity identity;
|
||||||
identityChanged = true;
|
|
||||||
if (_firstSkeletonCheck) {
|
packetStream >> identity.skeletonModelURL
|
||||||
|
>> identity.attachmentData
|
||||||
|
>> identity.displayName
|
||||||
|
>> identity.sessionDisplayName
|
||||||
|
>> identity.avatarEntityData;
|
||||||
|
|
||||||
|
// set the store identity sequence number to match the incoming identity
|
||||||
|
_identitySequenceNumber = incomingSequenceNumber;
|
||||||
|
|
||||||
|
if (_firstSkeletonCheck || (identity.skeletonModelURL != cannonicalSkeletonModelURL(emptyURL))) {
|
||||||
|
setSkeletonModelURL(identity.skeletonModelURL);
|
||||||
|
identityChanged = true;
|
||||||
|
if (_firstSkeletonCheck) {
|
||||||
|
displayNameChanged = true;
|
||||||
|
}
|
||||||
|
_firstSkeletonCheck = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identity.displayName != _displayName) {
|
||||||
|
_displayName = identity.displayName;
|
||||||
|
identityChanged = true;
|
||||||
displayNameChanged = true;
|
displayNameChanged = true;
|
||||||
}
|
}
|
||||||
_firstSkeletonCheck = false;
|
maybeUpdateSessionDisplayNameFromTransport(identity.sessionDisplayName);
|
||||||
}
|
|
||||||
|
|
||||||
if (identity.displayName != _displayName) {
|
if (identity.attachmentData != _attachmentData) {
|
||||||
_displayName = identity.displayName;
|
setAttachmentData(identity.attachmentData);
|
||||||
identityChanged = true;
|
identityChanged = true;
|
||||||
displayNameChanged = true;
|
}
|
||||||
}
|
|
||||||
maybeUpdateSessionDisplayNameFromTransport(identity.sessionDisplayName);
|
|
||||||
|
|
||||||
if (identity.attachmentData != _attachmentData) {
|
bool avatarEntityDataChanged = false;
|
||||||
setAttachmentData(identity.attachmentData);
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
identityChanged = true;
|
avatarEntityDataChanged = (identity.avatarEntityData != _avatarEntityData);
|
||||||
}
|
});
|
||||||
|
|
||||||
bool avatarEntityDataChanged = false;
|
if (avatarEntityDataChanged) {
|
||||||
_avatarEntitiesLock.withReadLock([&] {
|
setAvatarEntityData(identity.avatarEntityData);
|
||||||
avatarEntityDataChanged = (identity.avatarEntityData != _avatarEntityData);
|
identityChanged = true;
|
||||||
});
|
}
|
||||||
if (avatarEntityDataChanged) {
|
|
||||||
setAvatarEntityData(identity.avatarEntityData);
|
|
||||||
identityChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#ifdef WANT_DEBUG
|
||||||
|
qCDebug(avatars) << __FUNCTION__
|
||||||
|
<< "identity.uuid:" << identity.uuid
|
||||||
|
<< "identity.skeletonModelURL:" << identity.skeletonModelURL
|
||||||
|
<< "identity.displayName:" << identity.displayName
|
||||||
|
<< "identity.sessionDisplayName:" << identity.sessionDisplayName;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
qCDebug(avatars) << "Refusing to process identity for" << uuidStringWithoutCurlyBraces(avatarSessionID) << "since"
|
||||||
|
<< (udt::SequenceNumber::Type) _identitySequenceNumber
|
||||||
|
<< "is later than" << (udt::SequenceNumber::Type) incomingSequenceNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AvatarData::identityByteArray() const {
|
QByteArray AvatarData::identityByteArray() const {
|
||||||
|
@ -1553,12 +1566,12 @@ QByteArray AvatarData::identityByteArray() const {
|
||||||
|
|
||||||
_avatarEntitiesLock.withReadLock([&] {
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
identityStream << getSessionUUID()
|
identityStream << getSessionUUID()
|
||||||
<< urlToSend
|
<< (udt::SequenceNumber::Type) _identitySequenceNumber
|
||||||
<< _attachmentData
|
<< urlToSend
|
||||||
<< _displayName
|
<< _attachmentData
|
||||||
<< getSessionDisplayNameForTransport() // depends on _sessionDisplayName
|
<< _displayName
|
||||||
<< _avatarEntityData
|
<< getSessionDisplayNameForTransport() // depends on _sessionDisplayName
|
||||||
<< _identitySequenceId;
|
<< _avatarEntityData;
|
||||||
});
|
});
|
||||||
|
|
||||||
return identityData;
|
return identityData;
|
||||||
|
@ -2340,6 +2353,8 @@ void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
|
||||||
_avatarEntityData = avatarEntityData;
|
_avatarEntityData = avatarEntityData;
|
||||||
setAvatarEntityDataChanged(true);
|
setAvatarEntityDataChanged(true);
|
||||||
|
|
||||||
|
qDebug() << "Current avatar entity data is" << _avatarEntityData.keys();
|
||||||
|
|
||||||
foreach (auto entityID, previousAvatarEntityIDs) {
|
foreach (auto entityID, previousAvatarEntityIDs) {
|
||||||
if (!_avatarEntityData.contains(entityID)) {
|
if (!_avatarEntityData.contains(entityID)) {
|
||||||
_avatarEntityDetached.insert(entityID);
|
_avatarEntityDetached.insert(entityID);
|
||||||
|
|
|
@ -52,15 +52,16 @@ typedef unsigned long long quint64;
|
||||||
#include <JointData.h>
|
#include <JointData.h>
|
||||||
#include <NLPacket.h>
|
#include <NLPacket.h>
|
||||||
#include <Node.h>
|
#include <Node.h>
|
||||||
#include <RegisteredMetaTypes.h>
|
|
||||||
#include <SimpleMovingAverage.h>
|
|
||||||
#include <SpatiallyNestable.h>
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <Packed.h>
|
#include <Packed.h>
|
||||||
#include <ThreadSafeValueCache.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <shared/RateCounter.h>
|
#include <SimpleMovingAverage.h>
|
||||||
|
#include <SpatiallyNestable.h>
|
||||||
|
#include <ThreadSafeValueCache.h>
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
|
#include <shared/RateCounter.h>
|
||||||
|
#include <udt/SequenceNumber.h>
|
||||||
|
|
||||||
#include "AABox.h"
|
#include "AABox.h"
|
||||||
#include "HeadData.h"
|
#include "HeadData.h"
|
||||||
|
@ -525,20 +526,16 @@ public:
|
||||||
const HeadData* getHeadData() const { return _headData; }
|
const HeadData* getHeadData() const { return _headData; }
|
||||||
|
|
||||||
struct Identity {
|
struct Identity {
|
||||||
QUuid uuid;
|
|
||||||
QUrl skeletonModelURL;
|
QUrl skeletonModelURL;
|
||||||
QVector<AttachmentData> attachmentData;
|
QVector<AttachmentData> attachmentData;
|
||||||
QString displayName;
|
QString displayName;
|
||||||
QString sessionDisplayName;
|
QString sessionDisplayName;
|
||||||
AvatarEntityMap avatarEntityData;
|
AvatarEntityMap avatarEntityData;
|
||||||
quint64 sequenceId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void parseAvatarIdentityPacket(const QByteArray& data, Identity& identityOut);
|
|
||||||
|
|
||||||
// identityChanged returns true if identity has changed, false otherwise.
|
// identityChanged returns true if identity has changed, false otherwise.
|
||||||
// displayNameChanged returns true if displayName has changed, false otherwise.
|
// displayNameChanged returns true if displayName has changed, false otherwise.
|
||||||
void processAvatarIdentity(const Identity& identity, bool& identityChanged, bool& displayNameChanged);
|
void processAvatarIdentity(const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged);
|
||||||
|
|
||||||
QByteArray identityByteArray() const;
|
QByteArray identityByteArray() const;
|
||||||
|
|
||||||
|
@ -626,7 +623,7 @@ public:
|
||||||
bool getIdentityDataChanged() const { return _identityDataChanged; } // has the identity data changed since the last time sendIdentityPacket() was called
|
bool getIdentityDataChanged() const { return _identityDataChanged; } // has the identity data changed since the last time sendIdentityPacket() was called
|
||||||
void markIdentityDataChanged() {
|
void markIdentityDataChanged() {
|
||||||
_identityDataChanged = true;
|
_identityDataChanged = true;
|
||||||
_identitySequenceId++;
|
++_identitySequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getDensity() const { return _density; }
|
float getDensity() const { return _density; }
|
||||||
|
@ -786,7 +783,8 @@ protected:
|
||||||
float _audioAverageLoudness { 0.0f };
|
float _audioAverageLoudness { 0.0f };
|
||||||
|
|
||||||
bool _identityDataChanged { false };
|
bool _identityDataChanged { false };
|
||||||
quint64 _identitySequenceId { 0 };
|
udt::SequenceNumber _identitySequenceNumber { 0 };
|
||||||
|
bool _hasProcessedFirstIdentity { false };
|
||||||
float _density;
|
float _density;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -126,8 +126,9 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
AvatarData::Identity identity;
|
|
||||||
AvatarData::parseAvatarIdentityPacket(message->getMessage(), identity);
|
// peek the avatar UUID from the incoming packet
|
||||||
|
QUuid identityUUID = message->peek(NUM_BYTES_RFC4122_UUID);
|
||||||
|
|
||||||
// make sure this isn't for an ignored avatar
|
// make sure this isn't for an ignored avatar
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
@ -136,20 +137,21 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_hashLock);
|
QReadLocker locker(&_hashLock);
|
||||||
auto me = _avatarHash.find(EMPTY);
|
auto me = _avatarHash.find(EMPTY);
|
||||||
if ((me != _avatarHash.end()) && (identity.uuid == me.value()->getSessionUUID())) {
|
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
|
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
|
||||||
// identity packet for ourself (such as when we are assigned a sessionDisplayName by the mixer upon joining),
|
// identity packet for ourself (such as when we are assigned a sessionDisplayName by the mixer upon joining),
|
||||||
// we make things match here.
|
// we make things match here.
|
||||||
identity.uuid = EMPTY;
|
identityUUID = EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nodeList->isIgnoringNode(identity.uuid) || nodeList->getRequestsDomainListData()) {
|
|
||||||
|
if (!nodeList->isIgnoringNode(identityUUID) || nodeList->getRequestsDomainListData()) {
|
||||||
// mesh URL for a UUID, find avatar in our list
|
// mesh URL for a UUID, find avatar in our list
|
||||||
auto avatar = newOrExistingAvatar(identity.uuid, sendingNode);
|
auto avatar = newOrExistingAvatar(identityUUID, sendingNode);
|
||||||
bool identityChanged = false;
|
bool identityChanged = false;
|
||||||
bool displayNameChanged = false;
|
bool displayNameChanged = false;
|
||||||
// In this case, the "sendingNode" is the Avatar Mixer.
|
// In this case, the "sendingNode" is the Avatar Mixer.
|
||||||
avatar->processAvatarIdentity(identity, identityChanged, displayNameChanged);
|
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::AvatarData:
|
case PacketType::AvatarData:
|
||||||
case PacketType::BulkAvatarData:
|
case PacketType::BulkAvatarData:
|
||||||
case PacketType::KillAvatar:
|
case PacketType::KillAvatar:
|
||||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::AvatarIdentitySequenceId);
|
return static_cast<PacketVersion>(AvatarMixerPacketVersion::AvatarIdentitySequenceFront);
|
||||||
case PacketType::MessagesData:
|
case PacketType::MessagesData:
|
||||||
return static_cast<PacketVersion>(MessageDataVersion::TextOrBinaryData);
|
return static_cast<PacketVersion>(MessageDataVersion::TextOrBinaryData);
|
||||||
case PacketType::ICEServerHeartbeat:
|
case PacketType::ICEServerHeartbeat:
|
||||||
|
|
|
@ -243,7 +243,8 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
AvatarAsChildFixes,
|
AvatarAsChildFixes,
|
||||||
StickAndBallDefaultAvatar,
|
StickAndBallDefaultAvatar,
|
||||||
IdentityPacketsIncludeUpdateTime,
|
IdentityPacketsIncludeUpdateTime,
|
||||||
AvatarIdentitySequenceId
|
AvatarIdentitySequenceId,
|
||||||
|
AvatarIdentitySequenceFront
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DomainConnectRequestVersion : PacketVersion {
|
enum class DomainConnectRequestVersion : PacketVersion {
|
||||||
|
|
|
@ -35,8 +35,8 @@ public:
|
||||||
explicit SequenceNumber(char* value) { _value = (*reinterpret_cast<int32_t*>(value)) & MAX; }
|
explicit SequenceNumber(char* value) { _value = (*reinterpret_cast<int32_t*>(value)) & MAX; }
|
||||||
explicit SequenceNumber(Type value) { _value = (value <= MAX) ? ((value >= 0) ? value : 0) : MAX; }
|
explicit SequenceNumber(Type value) { _value = (value <= MAX) ? ((value >= 0) ? value : 0) : MAX; }
|
||||||
explicit SequenceNumber(UType value) { _value = (value <= MAX) ? value : MAX; }
|
explicit SequenceNumber(UType value) { _value = (value <= MAX) ? value : MAX; }
|
||||||
explicit operator Type() { return _value; }
|
explicit operator Type() const { return _value; }
|
||||||
explicit operator UType() { return static_cast<UType>(_value); }
|
explicit operator UType() const { return static_cast<UType>(_value); }
|
||||||
|
|
||||||
inline SequenceNumber& operator++() {
|
inline SequenceNumber& operator++() {
|
||||||
_value = (_value + 1) % (MAX + 1);
|
_value = (_value + 1) % (MAX + 1);
|
||||||
|
|
Loading…
Reference in a new issue