From 49fd4216de769c44d9756c9d0fd3ee60ba86c34f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 16 Dec 2016 14:15:20 -0800 Subject: [PATCH 1/6] sessionDisplayName set at server and passed to all clients (including oneself) --- assignment-client/src/avatars/AvatarMixer.cpp | 64 +++++++++++++++---- assignment-client/src/avatars/AvatarMixer.h | 4 ++ .../src/avatars/AvatarMixerClientData.h | 8 +++ interface/src/avatar/Avatar.h | 5 ++ libraries/avatars/src/AvatarData.cpp | 6 +- libraries/avatars/src/AvatarData.h | 9 +++ .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- 8 files changed, 83 insertions(+), 18 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index a37c9f7dd5..ca7f931067 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,6 @@ #include #include -#include "AvatarMixerClientData.h" #include "AvatarMixer.h" const QString AVATAR_MIXER_LOGGING_NAME = "avatar-mixer"; @@ -67,6 +67,20 @@ AvatarMixer::~AvatarMixer() { // assuming 60 htz update rate. const float IDENTITY_SEND_PROBABILITY = 1.0f / 187.0f; +void AvatarMixer::sendIdentityPacket(AvatarMixerClientData* nodeData, const SharedNodePointer& destinationNode) { + QByteArray individualData = nodeData->getAvatar().identityByteArray(); + + auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size()); + + individualData.replace(0, NUM_BYTES_RFC4122_UUID, nodeData->getNodeID().toRfc4122()); + + identityPacket->write(individualData); + + DependencyManager::get()->sendPacket(std::move(identityPacket), *destinationNode); + + ++_sumIdentityPackets; +} + // NOTE: some additional optimizations to consider. // 1) use the view frustum to cull those avatars that are out of view. Since avatar data doesn't need to be present // if the avatar is not in view or in the keyhole. @@ -227,6 +241,27 @@ void AvatarMixer::broadcastAvatarData() { // setup a PacketList for the avatarPackets auto avatarPacketList = NLPacketList::create(PacketType::BulkAvatarData); + if (avatar.getSessionDisplayName().isEmpty() && // We haven't set it yet... + nodeData->getReceivedIdentity()) { // ... but we have processed identity (with possible displayName). + QString baseName = avatar.getDisplayName().trimmed(); + const QRegularExpression curses{ "fuck|shit|damn|cock|cunt" }; // POC. We may eventually want something much more elaborate (subscription?). + baseName = baseName.replace(curses, "*"); // Replace rather than remove, so that people have a clue that the person's a jerk. + const QRegularExpression trailingDigits{ "\\s*_\\d+$" }; // whitespace "_123" + baseName = baseName.remove(trailingDigits); + if (baseName.isEmpty()) { + baseName = "anonymous"; + } + + QPair& soFar = _sessionDisplayNames[baseName]; // Inserts and answers 0, 0 if not already present, which is what we want. + int& highWater = soFar.first; + nodeData->setBaseDisplayName(baseName); + avatar.setSessionDisplayName((highWater > 0) ? baseName + "_" + QString::number(highWater) : baseName); + highWater++; + soFar.second++; // refcount + nodeData->flagIdentityChange(); + sendIdentityPacket(nodeData, node); // Tell new node about its sessionUUID. Others will find out below. + } + // this is an AGENT we have received head data from // send back a packet with other active node data to this node nodeList->eachMatchingNode( @@ -295,17 +330,7 @@ void AvatarMixer::broadcastAvatarData() { || otherNodeData->getIdentityChangeTimestamp() > _lastFrameTimestamp || distribution(generator) < IDENTITY_SEND_PROBABILITY)) { - QByteArray individualData = otherNodeData->getAvatar().identityByteArray(); - - auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size()); - - individualData.replace(0, NUM_BYTES_RFC4122_UUID, otherNode->getUUID().toRfc4122()); - - identityPacket->write(individualData); - - nodeList->sendPacket(std::move(identityPacket), *node); - - ++_sumIdentityPackets; + sendIdentityPacket(otherNodeData, node); } AvatarData& otherAvatar = otherNodeData->getAvatar(); @@ -416,6 +441,16 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) { && killedNode->getLinkedData()) { auto nodeList = DependencyManager::get(); + { // decrement sessionDisplayNames table and possibly remove + QMutexLocker nodeDataLocker(&killedNode->getLinkedData()->getMutex()); + AvatarMixerClientData* nodeData = dynamic_cast(killedNode->getLinkedData()); + const QString& baseDisplayName = nodeData->getBaseDisplayName(); + // No sense guarding against very rare case of a node with no entry, as this will work without the guard and do one less lookup in the common case. + if (--_sessionDisplayNames[baseDisplayName].second <= 0) { + _sessionDisplayNames.remove(baseDisplayName); + } + } + // this was an avatar we were sending to other people // send a kill packet for it to our other nodes auto killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason)); @@ -467,8 +502,9 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer mes AvatarData::parseAvatarIdentityPacket(message->getMessage(), identity); if (avatar.processAvatarIdentity(identity)) { QMutexLocker nodeDataLocker(&nodeData->getMutex()); - nodeData->flagIdentityChange(); - } + nodeData->flagIdentityChange(); + nodeData->setReceivedIdentity(); + } } } } diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index f537cc9244..3c39380b3a 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -18,6 +18,7 @@ #include #include +#include "AvatarMixerClientData.h" /// Handles assignments of type AvatarMixer - distribution of avatar data to various clients class AvatarMixer : public ThreadedAssignment { @@ -46,6 +47,7 @@ private slots: private: void broadcastAvatarData(); void parseDomainServerSettings(const QJsonObject& domainSettings); + void sendIdentityPacket(AvatarMixerClientData* nodeData, const SharedNodePointer& destinationNode); QThread _broadcastThread; @@ -64,6 +66,8 @@ private: float _domainMaximumScale { MAX_AVATAR_SCALE }; QTimer* _broadcastTimer = nullptr; + + QHash> _sessionDisplayNames; }; #endif // hifi_AvatarMixer_h diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 20c1b6b647..538da4aab0 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -50,6 +50,8 @@ public: HRCTime getIdentityChangeTimestamp() const { return _identityChangeTimestamp; } void flagIdentityChange() { _identityChangeTimestamp = p_high_resolution_clock::now(); } + bool getReceivedIdentity() const { return _gotIdentity; } + void setReceivedIdentity() { _gotIdentity = true; } void setFullRateDistance(float fullRateDistance) { _fullRateDistance = fullRateDistance; } float getFullRateDistance() const { return _fullRateDistance; } @@ -87,6 +89,9 @@ public: void removeFromRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.erase(other); } void ignoreOther(SharedNodePointer self, SharedNodePointer other); + const QString& getBaseDisplayName() { return _baseDisplayName; } + void setBaseDisplayName(const QString& baseDisplayName) { _baseDisplayName = baseDisplayName; } + private: AvatarSharedPointer _avatar { new AvatarData() }; @@ -95,6 +100,7 @@ private: std::unordered_set _hasReceivedFirstPacketsFrom; HRCTime _identityChangeTimestamp; + bool _gotIdentity { false }; float _fullRateDistance = FLT_MAX; float _maxAvatarDistance = FLT_MAX; @@ -108,6 +114,8 @@ private: SimpleMovingAverage _avgOtherAvatarDataRate; std::unordered_set _radiusIgnoredOthers; + + QString _baseDisplayName{}; // The santized key used in determinging unique sessionDisplayName, so that we can remove from dictionary. }; #endif // hifi_AvatarMixerClientData_h diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 9f5ac392bc..dd0a9b2ab1 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -119,6 +119,7 @@ public: virtual void setAttachmentData(const QVector& attachmentData) override; void setShowDisplayName(bool showDisplayName); + virtual void setSessionDisplayName(const QString& sessionDisplayName) override { }; // no-op virtual int parseDataFromBuffer(const QByteArray& buffer) override; @@ -189,6 +190,10 @@ public slots: protected: friend class AvatarManager; + virtual const QString& getSessionDisplayNameForTransport() const override { return _empty; } // Save a tiny bit of bandwidth. Mixer won't look at what we send. + QString _empty{}; + virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter! + void setMotionState(AvatarMotionState* motionState); SkeletonModelPointer _skeletonModel; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f81a1169af..f1c5a3a5a4 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -984,7 +984,7 @@ QStringList AvatarData::getJointNames() const { void AvatarData::parseAvatarIdentityPacket(const QByteArray& data, Identity& identityOut) { QDataStream packetStream(data); - packetStream >> identityOut.uuid >> identityOut.skeletonModelURL >> identityOut.attachmentData >> identityOut.displayName >> identityOut.avatarEntityData; + packetStream >> identityOut.uuid >> identityOut.skeletonModelURL >> identityOut.attachmentData >> identityOut.displayName >> identityOut.sessionDisplayName >> identityOut.avatarEntityData; } static const QUrl emptyURL(""); @@ -1006,6 +1006,7 @@ bool AvatarData::processAvatarIdentity(const Identity& identity) { setDisplayName(identity.displayName); hasIdentityChanged = true; } + maybeUpdateSessionDisplayNameFromTransport(identity.sessionDisplayName); if (identity.attachmentData != _attachmentData) { setAttachmentData(identity.attachmentData); @@ -1030,7 +1031,7 @@ QByteArray AvatarData::identityByteArray() { const QUrl& urlToSend = cannonicalSkeletonModelURL(emptyURL); _avatarEntitiesLock.withReadLock([&] { - identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << _avatarEntityData; + identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << getSessionDisplayNameForTransport() << _avatarEntityData; }); return identityData; @@ -1385,6 +1386,7 @@ static const QString JSON_AVATAR_HEAD = QStringLiteral("head"); static const QString JSON_AVATAR_HEAD_MODEL = QStringLiteral("headModel"); static const QString JSON_AVATAR_BODY_MODEL = QStringLiteral("bodyModel"); static const QString JSON_AVATAR_DISPLAY_NAME = QStringLiteral("displayName"); +// It isn't meaningful to persist sessionDisplayName. static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments"); static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities"); static const QString JSON_AVATAR_SCALE = QStringLiteral("scale"); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b34b912f14..906d9b312a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -171,6 +171,9 @@ class AvatarData : public QObject, public SpatiallyNestable { Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness WRITE setAudioAverageLoudness) Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName) + // sessionDisplayName is sanitized, defaulted version displayName that is defined by the AvatarMixer rather than by Interface clients. + // The result is unique among all avatars present at the time. + Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName) Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript) Q_PROPERTY(QVector attachmentData READ getAttachmentData WRITE setAttachmentData) @@ -313,6 +316,7 @@ public: QUrl skeletonModelURL; QVector attachmentData; QString displayName; + QString sessionDisplayName; AvatarEntityMap avatarEntityData; }; @@ -325,9 +329,11 @@ public: const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } const QString& getDisplayName() const { return _displayName; } + const QString& getSessionDisplayName() const { return _sessionDisplayName; } virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); virtual void setDisplayName(const QString& displayName); + virtual void setSessionDisplayName(const QString& sessionDisplayName) { _sessionDisplayName = sessionDisplayName; }; Q_INVOKABLE QVector getAttachmentData() const; Q_INVOKABLE virtual void setAttachmentData(const QVector& attachmentData); @@ -390,6 +396,8 @@ public slots: protected: glm::vec3 _handPosition; + virtual const QString& getSessionDisplayNameForTransport() const { return _sessionDisplayName; } + virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) { } // No-op in AvatarMixer // Body scale float _targetScale; @@ -417,6 +425,7 @@ protected: QUrl _skeletonFBXURL; QVector _attachmentData; QString _displayName; + QString _sessionDisplayName { }; const QUrl& cannonicalSkeletonModelURL(const QUrl& empty); float _displayNameTargetAlpha; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 34a70f8da6..79776e2d54 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -53,7 +53,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AvatarData: case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::HasKillAvatarReason); + return static_cast(AvatarMixerPacketVersion::SessionDisplayName); case PacketType::ICEServerHeartbeat: return 18; // ICE Server Heartbeat signing case PacketType::AssetGetInfo: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index dbeb1e63b0..778cce4c8d 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -203,7 +203,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { AbsoluteSixByteRotations, SensorToWorldMat, HandControllerJoints, - HasKillAvatarReason + HasKillAvatarReason, + SessionDisplayName }; enum class DomainConnectRequestVersion : PacketVersion { From 70af96669c77493af72231dea637c6e6e831d061 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 16 Dec 2016 14:59:54 -0800 Subject: [PATCH 2/6] update pal --- scripts/system/pal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 175418cd2e..61d3bb00e8 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -117,7 +117,7 @@ function populateUserList() { AvatarList.getAvatarIdentifiers().sort().forEach(function (id) { // sorting the identifiers is just an aid for debugging var avatar = AvatarList.getAvatar(id); var avatarPalDatum = { - displayName: avatar.displayName || ('anonymous ' + counter++), + displayName: avatar.sessionDisplayName, userName: "fakeAcct" + (id || "Me"), sessionId: id || '' }; From 36792e005a88ac0898f7b6936f65f0bf9b7d531c Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 19 Dec 2016 14:19:39 -0800 Subject: [PATCH 3/6] initial commit --- domain-server/src/DomainServerSettingsManager.cpp | 7 ++++++- libraries/networking/src/NodeList.cpp | 6 ++++-- libraries/networking/src/NodeList.h | 2 +- libraries/script-engine/src/UsersScriptingInterface.h | 6 +++--- scripts/system/pal.js | 4 ++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 05cec07f80..c8895839ff 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -800,7 +800,12 @@ void DomainServerSettingsManager::processUsernameFromIDRequestPacket(QSharedPoin usernameFromIDReplyPacket->write(nodeUUID.toRfc4122()); usernameFromIDReplyPacket->writeString(verifiedUsername); - qDebug() << "Sending username" << verifiedUsername << "associated with node" << nodeUUID; + // now put in the machine fingerprint + DomainServerNodeData* nodeData = reinterpret_cast(matchingNode->getLinkedData()); + QUuid machineFingerprint = nodeData ? nodeData->getMachineFingerprint() : QUuid(); + usernameFromIDReplyPacket->write(machineFingerprint.toRfc4122()); + + qDebug() << "Sending username" << verifiedUsername << "and machine fingerprint" << machineFingerprint << "associated with node" << nodeUUID; // Ship it! limitedNodeList->sendPacket(std::move(usernameFromIDReplyPacket), *sendingNode); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index f76189b13a..98798ba1b5 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -923,8 +923,10 @@ void NodeList::processUsernameFromIDReply(QSharedPointer messag QString nodeUUIDString = (QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID))).toString(); // read the username from the packet QString username = message->readString(); + // read the machine fingerprint from the packet + QString machineFingerprintString = (QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID))).toString(); - qDebug() << "Got username" << username << "for node" << nodeUUIDString; + qDebug() << "Got username" << username << "and machine fingerprint" << machineFingerprintString << "for node" << nodeUUIDString; - emit usernameFromIDReply(nodeUUIDString, username); + emit usernameFromIDReply(nodeUUIDString, username, machineFingerprintString); } diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index d10c790f45..d3f04cedd8 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -111,7 +111,7 @@ signals: void receivedDomainServerList(); void ignoredNode(const QUuid& nodeID); void ignoreRadiusEnabledChanged(bool isIgnored); - void usernameFromIDReply(const QString& nodeID, const QString& username); + void usernameFromIDReply(const QString& nodeID, const QString& username, const QString& machineFingerprint); private slots: void stopKeepalivePingTimer(); diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 1936a2e914..855dc06c11 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -101,10 +101,10 @@ signals: void enteredIgnoreRadius(); /**jsdoc - * Notifies scripts of the username associated with a UUID. - * @function Users.enteredIgnoreRadius + * Notifies scripts of the username and machine fingerprint associated with a UUID. + * @function Users.usernameFromIDReply */ - void usernameFromIDReply(const QString& nodeID, const QString& username); + void usernameFromIDReply(const QString& nodeID, const QString& username, const QString& machineFingerprint); }; diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 20f4167281..6df5531502 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -137,7 +137,7 @@ function populateUserList() { } // The function that handles the reply from the server -function usernameFromIDReply(id, username) { +function usernameFromIDReply(id, username, machineFingerprint) { var data; // If the ID we've received is our ID... if (AvatarList.getAvatar('').sessionUUID === id) { @@ -145,7 +145,7 @@ function usernameFromIDReply(id, username) { data = ['', username + ' (hidden)'] } else { // Set the data to contain the ID and the username+ID concat string. - data = [id, username + '/' + id]; + data = [id, username + '/' + machineFingerprint]; } print('Username Data:', JSON.stringify(data)); // Ship the data off to QML From a45e4da75f84bef73d0bf2ea5c65ee9b7620b997 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 19 Dec 2016 15:22:42 -0800 Subject: [PATCH 4/6] Initialize AvatarMixerClientData with the proper node id (should not be zeros for everyone). Then, in interface, check identity packets for self and make sure they're handled. --- assignment-client/src/avatars/AvatarMixer.cpp | 8 ++++---- assignment-client/src/avatars/AvatarMixerClientData.h | 2 ++ libraries/avatars/src/AvatarHashMap.cpp | 7 +++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index ca7f931067..70950dc8fc 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -502,9 +502,9 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer mes AvatarData::parseAvatarIdentityPacket(message->getMessage(), identity); if (avatar.processAvatarIdentity(identity)) { QMutexLocker nodeDataLocker(&nodeData->getMutex()); - nodeData->flagIdentityChange(); - nodeData->setReceivedIdentity(); - } + nodeData->flagIdentityChange(); + nodeData->setReceivedIdentity(); + } } } } @@ -600,7 +600,7 @@ void AvatarMixer::domainSettingsRequestComplete() { float domainMaximumScale = _domainMaximumScale; nodeList->linkedDataCreateCallback = [domainMinimumScale, domainMaximumScale] (Node* node) { - auto clientData = std::unique_ptr { new AvatarMixerClientData }; + auto clientData = std::unique_ptr { new AvatarMixerClientData(node->getUUID()) }; clientData->getAvatar().setDomainMinimumScale(domainMinimumScale); clientData->getAvatar().setDomainMaximumScale(domainMaximumScale); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 538da4aab0..16e886815f 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -34,6 +34,8 @@ const QString INBOUND_AVATAR_DATA_STATS_KEY = "inbound_av_data_kbps"; class AvatarMixerClientData : public NodeData { Q_OBJECT public: + AvatarMixerClientData(const QUuid& nodeID = QUuid()) : NodeData(nodeID) {} + virtual ~AvatarMixerClientData() {} using HRCTime = p_high_resolution_clock::time_point; int parseData(ReceivedMessage& message) override; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index ea9a4f42f8..24c701aeda 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -133,6 +133,13 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer // make sure this isn't for an ignored avatar auto nodeList = DependencyManager::get(); + static auto EMPTY = QUuid(); + if (identity.uuid == _avatarHash.value(EMPTY)->getSessionUUID()) { + // 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), + // we make things match here. + identity.uuid = EMPTY; + } if (!nodeList->isIgnoringNode(identity.uuid)) { // mesh URL for a UUID, find avatar in our list auto avatar = newOrExistingAvatar(identity.uuid, sendingNode); From 5b9c19b39e98ee43b2c0bc224d79f8a24dd3fa5e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 19 Dec 2016 16:06:12 -0800 Subject: [PATCH 5/6] Versioning --- libraries/networking/src/udt/PacketHeaders.cpp | 3 +++ libraries/networking/src/udt/PacketHeaders.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index d3347f8e53..b0061317a8 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -80,6 +80,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AudioStreamStats: return static_cast(AudioVersion::SpaceBubbleChanges); + case PacketType::UsernameFromIDReply: + return static_cast(UsernameFromIDReplyVersion::HasMachineFingerprint); + default: return 17; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 4a16e8ffe8..28b1b0417e 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -241,4 +241,8 @@ enum class AudioVersion : PacketVersion { SpaceBubbleChanges, }; +enum class UsernameFromIDReplyVersion : PacketVersion { + HasMachineFingerprint = 18 +}; + #endif // hifi_PacketHeaders_h From 4feec85337de18b98b763deb3b5404848710b397 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 19 Dec 2016 17:23:24 -0800 Subject: [PATCH 6/6] CR feedback Though this seems like a hard place to remember, when we make further changes. --- libraries/networking/src/udt/PacketHeaders.cpp | 5 +---- libraries/networking/src/udt/PacketHeaders.h | 7 ++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index b0061317a8..071e1026f5 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -44,7 +44,7 @@ const QSet NON_SOURCED_PACKETS = QSet() PacketVersion versionForPacketType(PacketType packetType) { switch (packetType) { case PacketType::DomainList: - return static_cast(DomainListVersion::GetUsernameFromUUIDSupport); + return static_cast(DomainListVersion::GetMachineFingerprintFromUUIDSupport); case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: @@ -80,9 +80,6 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AudioStreamStats: return static_cast(AudioVersion::SpaceBubbleChanges); - case PacketType::UsernameFromIDReply: - return static_cast(UsernameFromIDReplyVersion::HasMachineFingerprint); - default: return 17; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 28b1b0417e..d2f179b707 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -230,7 +230,8 @@ enum class DomainServerAddedNodeVersion : PacketVersion { enum class DomainListVersion : PacketVersion { PrePermissionsGrid = 18, PermissionsGrid, - GetUsernameFromUUIDSupport + GetUsernameFromUUIDSupport, + GetMachineFingerprintFromUUIDSupport }; enum class AudioVersion : PacketVersion { @@ -241,8 +242,4 @@ enum class AudioVersion : PacketVersion { SpaceBubbleChanges, }; -enum class UsernameFromIDReplyVersion : PacketVersion { - HasMachineFingerprint = 18 -}; - #endif // hifi_PacketHeaders_h