From 82b68fce8d61627a223c7a79359b64c9f756dff1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 15 Mar 2018 18:32:48 -0700 Subject: [PATCH 001/174] Quick attempt at using openssl HMAC in NLPacket --- libraries/networking/src/NLPacket.cpp | 12 ++++++ libraries/shared/src/HmacAuth.cpp | 55 +++++++++++++++++++++++++++ libraries/shared/src/HmacAuth.h | 32 ++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 libraries/shared/src/HmacAuth.cpp create mode 100644 libraries/shared/src/HmacAuth.h diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 5c5077691b..9df84e6abc 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -11,6 +11,8 @@ #include "NLPacket.h" +#include "HmacAuth.h" + int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); @@ -150,6 +152,14 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { } QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) { + HmacAuth hash; + int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; + hash.setKey(connectionSecret); + hash.addData(packet.getData() + offset, packet.getDataSize() - offset); + auto hashResult(hash.result()); + return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); + /* QCryptographicHash hash(QCryptographicHash::Md5); int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) @@ -161,6 +171,8 @@ QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUu // return the hash return hash.result(); + */ + } void NLPacket::writeTypeAndVersion() { diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp new file mode 100644 index 0000000000..6cc6835329 --- /dev/null +++ b/libraries/shared/src/HmacAuth.cpp @@ -0,0 +1,55 @@ +// +// HmacAuth.cpp + +#include + +#include "HmacAuth.h" + +#include + +HmacAuth::HmacAuth(AuthMethod authMethod) + : _hmacContext(new(HMAC_CTX)) + , _authMethod(authMethod) { + HMAC_CTX_init(_hmacContext.get()); +} + +HmacAuth::~HmacAuth() { + HMAC_CTX_cleanup(_hmacContext.get()); +} + +bool HmacAuth::setKey(const char * keyValue, int keyLen) { + const EVP_MD * sslStruct = nullptr; + + switch (_authMethod) + { + case SHA1: + sslStruct = EVP_sha1(); + break; + + case RIPEMD160: + sslStruct = EVP_ripemd160(); + break; + + default: + return false; + } + + return (bool) HMAC_Init(_hmacContext.get(), keyValue, keyLen, sslStruct); +} + +bool HmacAuth::setKey(const QUuid& uidKey) { + const QByteArray rfcBytes(uidKey.toRfc4122()); + return setKey(rfcBytes.constData(), rfcBytes.length()); +} + +bool HmacAuth::addData(const char * data, int dataLen) { + return (bool) HMAC_Update(_hmacContext.get(), reinterpret_cast(data), dataLen); +} + +HmacAuth::HmacHash HmacAuth::result() { + HmacHash hashValue(EVP_MAX_MD_SIZE); + unsigned int hashLen; + HMAC_Final(_hmacContext.get(), &hashValue[0], &hashLen); + hashValue.resize((size_t) hashLen); + return hashValue; +} diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h new file mode 100644 index 0000000000..9d90f5fb4d --- /dev/null +++ b/libraries/shared/src/HmacAuth.h @@ -0,0 +1,32 @@ +// +// HmacAuth.h +// libraries/shared/src + +#ifndef hifi_HmacAuth_h +#define hifi_HmacAuth_h + +#include +#include + +struct hmac_ctx_st; +class QUuid; + +class HmacAuth { +public: + enum AuthMethod { SHA1, RIPEMD160 }; + typedef std::vector HmacHash; + + HmacAuth(AuthMethod authMethod = SHA1); + ~HmacAuth(); + + bool setKey(const char * keyValue, int keyLen); + bool setKey(const QUuid& uidKey); + bool addData(const char * data, int dataLen); + HmacHash result(); + +private: + std::unique_ptr _hmacContext; + AuthMethod _authMethod { SHA1 }; +}; + +#endif // hifi_HmacAuth_h From 480f76c21aaa92f358691fa9fc296bd65f308523 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 16 Mar 2018 11:50:03 -0700 Subject: [PATCH 002/174] Quick trial of HMAC-MD5 auth + timings --- libraries/networking/src/NLPacket.cpp | 18 ++++++++++++++++++ libraries/shared/src/HmacAuth.cpp | 12 ++++++++++++ libraries/shared/src/HmacAuth.h | 6 +++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 9df84e6abc..988e86afc2 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -13,6 +13,12 @@ #include "HmacAuth.h" +#define HIFI_HASH_TIMINGS +#ifdef HIFI_HASH_TIMINGS +#include "NetworkLogging.h" +#include "SharedUtil.h" +#endif + int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); @@ -230,7 +236,19 @@ void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) c auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; +#ifdef HIFI_HASH_TIMINGS + static quint64 totalTime = 0; + static int timedHashes = 0; + quint64 startTime = usecTimestampNow(); +#endif QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret); +#ifdef HIFI_HASH_TIMINGS + quint64 endTime = usecTimestampNow(); + totalTime += endTime - startTime; + if ((++timedHashes % 20) == 0) { + qCDebug(networking) << "Average packet hash time " << (totalTime / timedHashes / 1000.0f) << " ms"; + } +#endif memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); } diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp index 6cc6835329..469d77c624 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HmacAuth.cpp @@ -22,10 +22,22 @@ bool HmacAuth::setKey(const char * keyValue, int keyLen) { switch (_authMethod) { + case MD5: + sslStruct = EVP_md5(); + break; + case SHA1: sslStruct = EVP_sha1(); break; + case SHA224: + sslStruct = EVP_sha224(); + break; + + case SHA256: + sslStruct = EVP_sha256(); + break; + case RIPEMD160: sslStruct = EVP_ripemd160(); break; diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h index 9d90f5fb4d..1ed6be0eb0 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HmacAuth.h @@ -13,10 +13,10 @@ class QUuid; class HmacAuth { public: - enum AuthMethod { SHA1, RIPEMD160 }; + enum AuthMethod { MD5, SHA1, SHA224, SHA256, RIPEMD160 }; typedef std::vector HmacHash; - HmacAuth(AuthMethod authMethod = SHA1); + explicit HmacAuth(AuthMethod authMethod = MD5); ~HmacAuth(); bool setKey(const char * keyValue, int keyLen); @@ -26,7 +26,7 @@ public: private: std::unique_ptr _hmacContext; - AuthMethod _authMethod { SHA1 }; + AuthMethod _authMethod { MD5 }; }; #endif // hifi_HmacAuth_h From db8a1ccb3e16a8f561d1eae4daa29f12d0b2878a Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 16 Mar 2018 18:03:13 -0700 Subject: [PATCH 003/174] Set HMAC key once and reuse OpenSSL context Store the HMAC wrapper in Node. Unfortunately requires a lot of plumbing down to NLPacket. Added a mutex to the wrapper since suspicious crashes occurred. Authentication times seem to be comparable to existing MD5. --- libraries/networking/src/LimitedNodeList.cpp | 38 +++++++++++--------- libraries/networking/src/LimitedNodeList.h | 8 ++--- libraries/networking/src/NLPacket.cpp | 15 ++++---- libraries/networking/src/NLPacket.h | 6 ++-- libraries/networking/src/Node.cpp | 7 +++- libraries/networking/src/Node.h | 7 +++- libraries/shared/src/HmacAuth.cpp | 5 +++ libraries/shared/src/HmacAuth.h | 2 ++ 8 files changed, 56 insertions(+), 32 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0803e380f2..861629fd72 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -36,6 +36,7 @@ #include "HifiSockAddr.h" #include "NetworkLogging.h" #include "udt/Packet.h" +#include "HmacAuth.h" static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); @@ -319,7 +320,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe if (verifiedPacket && !ignoreVerification) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); - QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getConnectionSecret()); + QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getConnectionSecret(), sourceNode->getAuthenticateHash()); // check if the md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { @@ -363,7 +364,7 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) { _numCollectedBytes += packet.getDataSize(); } -void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret) { +void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HmacAuth& hmacAuth, const QUuid& connectionSecret) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { packet.writeSourceID(getSessionUUID()); } @@ -371,7 +372,7 @@ void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& conn if (!connectionSecret.isNull() && !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType()) && !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) { - packet.writeVerificationHashGivenSecret(connectionSecret); + packet.writeVerificationHashGivenSecret(hmacAuth, connectionSecret); } } @@ -387,17 +388,18 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& emit dataSent(destinationNode.getType(), packet.getDataSize()); destinationNode.recordBytesSent(packet.getDataSize()); - return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getConnectionSecret()); + return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getAuthenticateHash(), + destinationNode.getConnectionSecret()); } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HmacAuth& hmacAuth, const QUuid& connectionSecret) { Q_ASSERT(!packet.isPartOfMessage()); Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); collectPacketStats(packet); - fillPacketHeader(packet, connectionSecret); + fillPacketHeader(packet, hmacAuth, connectionSecret); return _nodeSocket.writePacket(packet, sockAddr); } @@ -410,7 +412,8 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& emit dataSent(destinationNode.getType(), packet->getDataSize()); destinationNode.recordBytesSent(packet->getDataSize()); - return sendPacket(std::move(packet), *activeSocket, destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), *activeSocket, destinationNode.getAuthenticateHash(), + destinationNode.getConnectionSecret()); } else { qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending"; return ERROR_SENDING_PACKET_BYTES; @@ -418,18 +421,18 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& } qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HmacAuth& hmacAuth, const QUuid& connectionSecret) { Q_ASSERT(!packet->isPartOfMessage()); if (packet->isReliable()) { collectPacketStats(*packet); - fillPacketHeader(*packet, connectionSecret); + fillPacketHeader(*packet, hmacAuth, connectionSecret); auto size = packet->getDataSize(); _nodeSocket.writePacket(std::move(packet), sockAddr); return size; } else { - return sendUnreliablePacket(*packet, sockAddr, connectionSecret); + return sendUnreliablePacket(*packet, sockAddr, hmacAuth, connectionSecret); } } @@ -444,7 +447,8 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { - bytesSent += sendPacket(packetList.takeFront(), *activeSocket, connectionSecret); + bytesSent += sendPacket(packetList.takeFront(), *activeSocket, + destinationNode.getAuthenticateHash(), connectionSecret); } emit dataSent(destinationNode.getType(), bytesSent); @@ -457,14 +461,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi } qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HmacAuth& hmacAuth, const QUuid& connectionSecret) { qint64 bytesSent = 0; // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { - bytesSent += sendPacket(packetList.takeFront(), sockAddr, connectionSecret); + bytesSent += sendPacket(packetList.takeFront(), sockAddr, hmacAuth, connectionSecret); } return bytesSent; @@ -474,10 +478,11 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, // close the last packet in the list packetList->closeCurrentPacket(); + HmacAuth unusedHmac; for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket); + fillPacketHeader(*nlPacket, unusedHmac); } return _nodeSocket.writePacketList(std::move(packetList), sockAddr); @@ -492,7 +497,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, destinationNode.getConnectionSecret()); + fillPacketHeader(*nlPacket, destinationNode.getAuthenticateHash(), destinationNode.getConnectionSecret()); } return _nodeSocket.writePacketList(std::move(packetList), *activeSocket); @@ -515,7 +520,8 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket() : overridenSockAddr; - return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getAuthenticateHash(), + destinationNode.getConnectionSecret()); } int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 7165b3dd63..8e73440f5b 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -132,18 +132,18 @@ public: // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr @@ -364,7 +364,7 @@ protected: qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr, const QUuid& connectionSecret = QUuid()); void collectPacketStats(const NLPacket& packet); - void fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret = QUuid()); + void fillPacketHeader(const NLPacket& packet, HmacAuth& hmacAuth, const QUuid& connectionSecret = QUuid()); void setLocalSocket(const HifiSockAddr& sockAddr); diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 988e86afc2..b32c1f1f7f 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -157,15 +157,15 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } -QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) { - HmacAuth hash; +QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret, HmacAuth& hash) { +#define HIFI_USE_HMAC +#ifdef HIFI_USE_HMAC int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; - hash.setKey(connectionSecret); hash.addData(packet.getData() + offset, packet.getDataSize() - offset); auto hashResult(hash.result()); return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); - /* +#else QCryptographicHash hash(QCryptographicHash::Md5); int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) @@ -177,8 +177,7 @@ QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUu // return the hash return hash.result(); - */ - +#endif } void NLPacket::writeTypeAndVersion() { @@ -230,7 +229,7 @@ void NLPacket::writeSourceID(const QUuid& sourceID) const { _sourceID = sourceID; } -void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) const { +void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth, const QUuid& connectionSecret) const { Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) && !PacketTypeEnum::getNonVerifiedPackets().contains(_type)); @@ -241,7 +240,7 @@ void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) c static int timedHashes = 0; quint64 startTime = usecTimestampNow(); #endif - QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret); + QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret, hmacAuth); #ifdef HIFI_HASH_TIMINGS quint64 endTime = usecTimestampNow(); totalTime += endTime - startTime; diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index f49cc47645..f38f29ec36 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -18,6 +18,8 @@ #include "udt/Packet.h" +class HmacAuth; + class NLPacket : public udt::Packet { Q_OBJECT public: @@ -71,7 +73,7 @@ public: static QUuid sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); - static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret); + static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret, HmacAuth& hash); PacketType getType() const { return _type; } void setType(PacketType type); @@ -82,7 +84,7 @@ public: const QUuid& getSourceID() const { return _sourceID; } void writeSourceID(const QUuid& sourceID) const; - void writeVerificationHashGivenSecret(const QUuid& connectionSecret) const; + void writeVerificationHashGivenSecret(HmacAuth& hmacAuth, const QUuid& connectionSecret) const; protected: diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index bd895c8ef1..6669c68a2e 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -86,9 +86,10 @@ NodeType_t NodeType::fromString(QString type) { Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, - const HifiSockAddr& localSocket, QObject* parent) : + const HifiSockAddr& localSocket, QObject* parent) : NetworkPeer(uuid, publicSocket, localSocket, parent), _type(type), + _authenticateHash(new HmacAuth), _pingMs(-1), // "Uninitialized" _clockSkewUsec(0), _mutex(), @@ -192,3 +193,7 @@ QDebug operator<<(QDebug debug, const Node& node) { debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); return debug.nospace(); } + +void Node::_updateAuthenticateHash() { + _authenticateHash->setKey(_connectionSecret); +} diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 93b6a649d4..80d51202d5 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -33,6 +33,7 @@ #include "SimpleMovingAverage.h" #include "MovingPercentile.h" #include "NodePermissions.h" +#include "HmacAuth.h" class Node : public NetworkPeer { Q_OBJECT @@ -55,7 +56,8 @@ public: void setIsUpstream(bool isUpstream) { _isUpstream = isUpstream; } const QUuid& getConnectionSecret() const { return _connectionSecret; } - void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; } + void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; _updateAuthenticateHash(); } + HmacAuth& getAuthenticateHash() const { return *_authenticateHash; } NodeData* getLinkedData() const { return _linkedData.get(); } void setLinkedData(std::unique_ptr linkedData) { _linkedData = std::move(linkedData); } @@ -94,9 +96,12 @@ private: Node(const Node &otherNode); Node& operator=(Node otherNode); + void _updateAuthenticateHash(); + NodeType_t _type; QUuid _connectionSecret; + std::unique_ptr _authenticateHash; std::unique_ptr _linkedData; bool _isReplicated { false }; int _pingMs; diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp index 469d77c624..ca0ec39b94 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HmacAuth.cpp @@ -46,6 +46,7 @@ bool HmacAuth::setKey(const char * keyValue, int keyLen) { return false; } + QMutexLocker lock(&_lock); return (bool) HMAC_Init(_hmacContext.get(), keyValue, keyLen, sslStruct); } @@ -55,13 +56,17 @@ bool HmacAuth::setKey(const QUuid& uidKey) { } bool HmacAuth::addData(const char * data, int dataLen) { + QMutexLocker lock(&_lock); return (bool) HMAC_Update(_hmacContext.get(), reinterpret_cast(data), dataLen); } HmacAuth::HmacHash HmacAuth::result() { HmacHash hashValue(EVP_MAX_MD_SIZE); unsigned int hashLen; + QMutexLocker lock(&_lock); HMAC_Final(_hmacContext.get(), &hashValue[0], &hashLen); hashValue.resize((size_t) hashLen); + // Clear state for possible reuse. + HMAC_Init(_hmacContext.get(), nullptr, 0, nullptr); return hashValue; } diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h index 1ed6be0eb0..305e1a36ed 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HmacAuth.h @@ -7,6 +7,7 @@ #include #include +#include struct hmac_ctx_st; class QUuid; @@ -25,6 +26,7 @@ public: HmacHash result(); private: + QMutex _lock; std::unique_ptr _hmacContext; AuthMethod _authMethod { MD5 }; }; From d889384d946f8558f261084fc417cb6b2cc958da Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Mar 2018 09:41:57 -0700 Subject: [PATCH 004/174] Use elaborated type-specifier for openssl internal class --- libraries/shared/src/HmacAuth.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h index 305e1a36ed..b39423de95 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HmacAuth.h @@ -9,7 +9,6 @@ #include #include -struct hmac_ctx_st; class QUuid; class HmacAuth { @@ -27,7 +26,7 @@ public: private: QMutex _lock; - std::unique_ptr _hmacContext; + std::unique_ptr _hmacContext; AuthMethod _authMethod { MD5 }; }; From af21cac0c2a3587c2b3d6f12613d2b84ef6f0aa7 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Mar 2018 12:53:16 -0700 Subject: [PATCH 005/174] Fixes for gcc --- libraries/networking/src/LimitedNodeList.h | 6 +++--- libraries/shared/src/HmacAuth.cpp | 2 ++ libraries/shared/src/HmacAuth.h | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 8e73440f5b..638f3efefc 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -132,18 +132,18 @@ public: // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth(), const QUuid& connectionSecret = QUuid()); + HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp index ca0ec39b94..47f0e4d224 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HmacAuth.cpp @@ -7,6 +7,8 @@ #include +HmacAuth HmacAuth::nullHmacAuth; + HmacAuth::HmacAuth(AuthMethod authMethod) : _hmacContext(new(HMAC_CTX)) , _authMethod(authMethod) { diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h index b39423de95..4970f08ca6 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HmacAuth.h @@ -24,6 +24,8 @@ public: bool addData(const char * data, int dataLen); HmacHash result(); + static HmacAuth nullHmacAuth; + private: QMutex _lock; std::unique_ptr _hmacContext; From da7298b8bde004947d4a748d723f074b1f95d29b Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Mar 2018 15:28:44 -0700 Subject: [PATCH 006/174] Support only HMAC - take out passing around of secret UUID Also other clean-up for production use. --- libraries/networking/src/LimitedNodeList.cpp | 38 +++++++++----------- libraries/networking/src/LimitedNodeList.h | 13 +++---- libraries/networking/src/NLPacket.cpp | 21 ++--------- libraries/networking/src/NLPacket.h | 4 +-- libraries/shared/src/HmacAuth.cpp | 10 ++++-- libraries/shared/src/HmacAuth.h | 11 ++++-- 6 files changed, 43 insertions(+), 54 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 861629fd72..d09e379909 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -320,7 +320,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe if (verifiedPacket && !ignoreVerification) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); - QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getConnectionSecret(), sourceNode->getAuthenticateHash()); + QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getAuthenticateHash()); // check if the md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { @@ -364,15 +364,15 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) { _numCollectedBytes += packet.getDataSize(); } -void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HmacAuth& hmacAuth, const QUuid& connectionSecret) { +void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HmacAuth * hmacAuth) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { packet.writeSourceID(getSessionUUID()); } - if (!connectionSecret.isNull() + if (hmacAuth && !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType()) && !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) { - packet.writeVerificationHashGivenSecret(hmacAuth, connectionSecret); + packet.writeVerificationHashGivenSecret(*hmacAuth); } } @@ -388,18 +388,17 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& emit dataSent(destinationNode.getType(), packet.getDataSize()); destinationNode.recordBytesSent(packet.getDataSize()); - return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getAuthenticateHash(), - destinationNode.getConnectionSecret()); + return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), &destinationNode.getAuthenticateHash()); } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth, const QUuid& connectionSecret) { + HmacAuth * hmacAuth) { Q_ASSERT(!packet.isPartOfMessage()); Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); collectPacketStats(packet); - fillPacketHeader(packet, hmacAuth, connectionSecret); + fillPacketHeader(packet, hmacAuth); return _nodeSocket.writePacket(packet, sockAddr); } @@ -412,8 +411,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& emit dataSent(destinationNode.getType(), packet->getDataSize()); destinationNode.recordBytesSent(packet->getDataSize()); - return sendPacket(std::move(packet), *activeSocket, destinationNode.getAuthenticateHash(), - destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), *activeSocket, &destinationNode.getAuthenticateHash()); } else { qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending"; return ERROR_SENDING_PACKET_BYTES; @@ -421,18 +419,18 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& } qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth, const QUuid& connectionSecret) { + HmacAuth * hmacAuth) { Q_ASSERT(!packet->isPartOfMessage()); if (packet->isReliable()) { collectPacketStats(*packet); - fillPacketHeader(*packet, hmacAuth, connectionSecret); + fillPacketHeader(*packet, hmacAuth); auto size = packet->getDataSize(); _nodeSocket.writePacket(std::move(packet), sockAddr); return size; } else { - return sendUnreliablePacket(*packet, sockAddr, hmacAuth, connectionSecret); + return sendUnreliablePacket(*packet, sockAddr, hmacAuth); } } @@ -448,7 +446,7 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi while (!packetList._packets.empty()) { bytesSent += sendPacket(packetList.takeFront(), *activeSocket, - destinationNode.getAuthenticateHash(), connectionSecret); + &destinationNode.getAuthenticateHash()); } emit dataSent(destinationNode.getType(), bytesSent); @@ -461,14 +459,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi } qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth, const QUuid& connectionSecret) { + HmacAuth * hmacAuth) { qint64 bytesSent = 0; // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { - bytesSent += sendPacket(packetList.takeFront(), sockAddr, hmacAuth, connectionSecret); + bytesSent += sendPacket(packetList.takeFront(), sockAddr, hmacAuth); } return bytesSent; @@ -478,11 +476,10 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, // close the last packet in the list packetList->closeCurrentPacket(); - HmacAuth unusedHmac; for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, unusedHmac); + fillPacketHeader(*nlPacket, nullptr); } return _nodeSocket.writePacketList(std::move(packetList), sockAddr); @@ -497,7 +494,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, destinationNode.getAuthenticateHash(), destinationNode.getConnectionSecret()); + fillPacketHeader(*nlPacket, &destinationNode.getAuthenticateHash()); } return _nodeSocket.writePacketList(std::move(packetList), *activeSocket); @@ -520,8 +517,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket() : overridenSockAddr; - return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getAuthenticateHash(), - destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), destinationSockAddr, &destinationNode.getAuthenticateHash()); } int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 638f3efefc..6d546d4d65 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -128,22 +128,19 @@ public: virtual QUuid getDomainUUID() const { assert(false); return QUuid(); } virtual HifiSockAddr getDomainSockAddr() const { assert(false); return HifiSockAddr(); } - // use sendUnreliablePacket to send an unrelaible packet (that you do not need to move) + // use sendUnreliablePacket to send an unreliable packet (that you do not need to move) // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); - qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); + qint64 sendUnreliablePacket(const NLPacket & packet, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth = nullptr); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); - qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); + qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth = nullptr); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); - qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - HmacAuth& hmacAuth = HmacAuth::nullHmacAuth, const QUuid& connectionSecret = QUuid()); + qint64 sendUnreliableUnorderedPacketList(NLPacketList & packetList, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr @@ -364,7 +361,7 @@ protected: qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr, const QUuid& connectionSecret = QUuid()); void collectPacketStats(const NLPacket& packet); - void fillPacketHeader(const NLPacket& packet, HmacAuth& hmacAuth, const QUuid& connectionSecret = QUuid()); + void fillPacketHeader(const NLPacket& packet, HmacAuth * hmacAuth); void setLocalSocket(const HifiSockAddr& sockAddr); diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index b32c1f1f7f..99313247e9 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -157,27 +157,12 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } -QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret, HmacAuth& hash) { -#define HIFI_USE_HMAC -#ifdef HIFI_USE_HMAC +QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, HmacAuth& hash) { int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; hash.addData(packet.getData() + offset, packet.getDataSize() - offset); auto hashResult(hash.result()); return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); -#else - QCryptographicHash hash(QCryptographicHash::Md5); - - int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) - + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; - - // add the packet payload and the connection UUID - hash.addData(packet.getData() + offset, packet.getDataSize() - offset); - hash.addData(connectionSecret.toRfc4122()); - - // return the hash - return hash.result(); -#endif } void NLPacket::writeTypeAndVersion() { @@ -229,7 +214,7 @@ void NLPacket::writeSourceID(const QUuid& sourceID) const { _sourceID = sourceID; } -void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth, const QUuid& connectionSecret) const { +void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth) const { Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) && !PacketTypeEnum::getNonVerifiedPackets().contains(_type)); @@ -240,7 +225,7 @@ void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth, const QUuid& static int timedHashes = 0; quint64 startTime = usecTimestampNow(); #endif - QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret, hmacAuth); + QByteArray verificationHash = hashForPacketAndSecret(*this, hmacAuth); #ifdef HIFI_HASH_TIMINGS quint64 endTime = usecTimestampNow(); totalTime += endTime - startTime; diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index f38f29ec36..8f73475530 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -73,7 +73,7 @@ public: static QUuid sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); - static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret, HmacAuth& hash); + static QByteArray hashForPacketAndSecret(const udt::Packet & packet, HmacAuth & hash); PacketType getType() const { return _type; } void setType(PacketType type); @@ -84,7 +84,7 @@ public: const QUuid& getSourceID() const { return _sourceID; } void writeSourceID(const QUuid& sourceID) const; - void writeVerificationHashGivenSecret(HmacAuth& hmacAuth, const QUuid& connectionSecret) const; + void writeVerificationHashGivenSecret(HmacAuth& hmacAuth) const; protected: diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp index 47f0e4d224..5d04bb96a4 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HmacAuth.cpp @@ -1,5 +1,13 @@ // // HmacAuth.cpp +// libraries/shared/src +// +// Created by Simon Walton on 3/19/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// #include @@ -7,8 +15,6 @@ #include -HmacAuth HmacAuth::nullHmacAuth; - HmacAuth::HmacAuth(AuthMethod authMethod) : _hmacContext(new(HMAC_CTX)) , _authMethod(authMethod) { diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HmacAuth.h index 4970f08ca6..dfc79e8e47 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HmacAuth.h @@ -1,6 +1,13 @@ // // HmacAuth.h // libraries/shared/src +// +// Created by Simon Walton on 3/19/2018. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// #ifndef hifi_HmacAuth_h #define hifi_HmacAuth_h @@ -14,7 +21,7 @@ class QUuid; class HmacAuth { public: enum AuthMethod { MD5, SHA1, SHA224, SHA256, RIPEMD160 }; - typedef std::vector HmacHash; + using HmacHash = std::vector; explicit HmacAuth(AuthMethod authMethod = MD5); ~HmacAuth(); @@ -24,8 +31,6 @@ public: bool addData(const char * data, int dataLen); HmacHash result(); - static HmacAuth nullHmacAuth; - private: QMutex _lock; std::unique_ptr _hmacContext; From 020a6a65852c7d56d4520199388895e9aa288248 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Mar 2018 15:57:32 -0700 Subject: [PATCH 007/174] Take out hash timing code --- libraries/networking/src/NLPacket.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 99313247e9..37bb465ca9 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -13,12 +13,6 @@ #include "HmacAuth.h" -#define HIFI_HASH_TIMINGS -#ifdef HIFI_HASH_TIMINGS -#include "NetworkLogging.h" -#include "SharedUtil.h" -#endif - int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); @@ -220,19 +214,8 @@ void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth) const { auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; -#ifdef HIFI_HASH_TIMINGS - static quint64 totalTime = 0; - static int timedHashes = 0; - quint64 startTime = usecTimestampNow(); -#endif + QByteArray verificationHash = hashForPacketAndSecret(*this, hmacAuth); -#ifdef HIFI_HASH_TIMINGS - quint64 endTime = usecTimestampNow(); - totalTime += endTime - startTime; - if ((++timedHashes % 20) == 0) { - qCDebug(networking) << "Average packet hash time " << (totalTime / timedHashes / 1000.0f) << " ms"; - } -#endif memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); } From 2a486a4c1419f974c1a11b55fdb266d8c42e84c1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Mar 2018 17:48:11 -0700 Subject: [PATCH 008/174] Bump packet version numbers --- libraries/networking/src/LimitedNodeList.h | 3 ++- .../networking/src/udt/PacketHeaders.cpp | 21 ++++++++-------- libraries/networking/src/udt/PacketHeaders.h | 25 +++++++++++++------ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 6d546d4d65..612a6ce947 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -140,7 +140,8 @@ public: // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); - qint64 sendUnreliableUnorderedPacketList(NLPacketList & packetList, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth); + qint64 sendUnreliableUnorderedPacketList(NLPacketList & packetList, const HifiSockAddr & sockAddr, + HmacAuth * hmacAuth = nullptr); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a83924ee58..d6b59d59f9 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -25,30 +25,29 @@ int packetTypeMetaTypeId = qRegisterMetaType(); PacketVersion versionForPacketType(PacketType packetType) { switch (packetType) { case PacketType::DomainList: - return static_cast(DomainListVersion::GetMachineFingerprintFromUUIDSupport); + return static_cast(DomainListVersion::UseHmacAuthentication); case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::ShadowControl); + return static_cast(EntityVersion::UseHmacAuthentication); case PacketType::EntityQuery: - return static_cast(EntityQueryPacketVersion::RemovedJurisdictions); + return static_cast(EntityQueryPacketVersion::UseHmacAuthentication); case PacketType::AvatarIdentity: case PacketType::AvatarData: case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::FBXReaderNodeReparenting); + return static_cast(AvatarMixerPacketVersion::UseHmacAuthentication); case PacketType::MessagesData: - return static_cast(MessageDataVersion::TextOrBinaryData); + return static_cast(MessageDataVersion::UseHmacAuthentication); case PacketType::ICEServerHeartbeat: return 18; // ICE Server Heartbeat signing case PacketType::AssetMappingOperation: case PacketType::AssetMappingOperationReply: - return static_cast(AssetServerPacketVersion::RedirectedMappings); case PacketType::AssetGetInfo: case PacketType::AssetGet: case PacketType::AssetUpload: - return static_cast(AssetServerPacketVersion::RangeRequestSupport); + return static_cast(AssetServerPacketVersion::UseHmacAuthentication); case PacketType::NodeIgnoreRequest: return 18; // Introduction of node ignore request (which replaced an unused packet tpye) @@ -59,10 +58,10 @@ PacketVersion versionForPacketType(PacketType packetType) { return static_cast(DomainConnectRequestVersion::AlwaysHasMachineFingerprint); case PacketType::DomainServerAddedNode: - return static_cast(DomainServerAddedNodeVersion::PermissionsGrid); + return static_cast(DomainServerAddedNodeVersion::UseHmacAuthentication); case PacketType::EntityScriptCallMethod: - return static_cast(EntityScriptCallMethodVersion::ClientCallable); + return static_cast(EntityScriptCallMethodVersion::UseHmacAuthentication); case PacketType::MixedAudio: case PacketType::SilentAudioFrame: @@ -70,13 +69,13 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::MicrophoneAudioNoEcho: case PacketType::MicrophoneAudioWithEcho: case PacketType::AudioStreamStats: - return static_cast(AudioVersion::HighDynamicRangeVolume); + return static_cast(AudioVersion::UseHmacAuthentication); case PacketType::ICEPing: return static_cast(IcePingVersion::SendICEPeerID); case PacketType::DomainSettings: return 18; // replace min_avatar_scale and max_avatar_scale with min_avatar_height and max_avatar_height default: - return 17; + return 18; } } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 98a9087d37..9dc3f2befd 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -231,25 +231,29 @@ enum class EntityVersion : PacketVersion { ZoneStageRemoved, SoftEntities, MaterialEntities, - ShadowControl + ShadowControl, + UseHmacAuthentication }; enum class EntityScriptCallMethodVersion : PacketVersion { ServerCallable = 18, - ClientCallable = 19 + ClientCallable = 19, + UseHmacAuthentication = 20 }; enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, JSONFilterWithFamilyTree = 19, ConnectionIdentifier = 20, - RemovedJurisdictions = 21 + RemovedJurisdictions = 21, + UseHmacAuthentication = 22 }; enum class AssetServerPacketVersion: PacketVersion { VegasCongestionControl = 19, RangeRequestSupport, - RedirectedMappings + RedirectedMappings, + UseHmacAuthentication }; enum class AvatarMixerPacketVersion : PacketVersion { @@ -274,7 +278,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { AvatarIdentityLookAtSnapping, UpdatedMannequinDefaultAvatar, AvatarJointDefaultPoseFlags, - FBXReaderNodeReparenting + FBXReaderNodeReparenting, + UseHmacAuthentication }; enum class DomainConnectRequestVersion : PacketVersion { @@ -294,14 +299,16 @@ enum class DomainConnectionDeniedVersion : PacketVersion { enum class DomainServerAddedNodeVersion : PacketVersion { PrePermissionsGrid = 17, - PermissionsGrid + PermissionsGrid, + UseHmacAuthentication }; enum class DomainListVersion : PacketVersion { PrePermissionsGrid = 18, PermissionsGrid, GetUsernameFromUUIDSupport, - GetMachineFingerprintFromUUIDSupport + GetMachineFingerprintFromUUIDSupport, + UseHmacAuthentication }; enum class AudioVersion : PacketVersion { @@ -312,10 +319,12 @@ enum class AudioVersion : PacketVersion { SpaceBubbleChanges, HasPersonalMute, HighDynamicRangeVolume, + UseHmacAuthentication, }; enum class MessageDataVersion : PacketVersion { - TextOrBinaryData = 18 + TextOrBinaryData = 18, + UseHmacAuthentication }; enum class IcePingVersion : PacketVersion { From 8ce03d65b76493ddc4c8d8a92bd3eea6abfc938a Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 20 Mar 2018 18:16:45 -0700 Subject: [PATCH 009/174] Only update the connection secret UUID if it changes Rekeying the openssl HMAC context occasionally causes hash generation errors. It is not clear why. The Node secret never seems to change to check for this before rekeying. Also other clean-up for PR. --- libraries/networking/src/LimitedNodeList.cpp | 4 ++-- libraries/networking/src/NLPacket.h | 2 +- libraries/networking/src/Node.cpp | 8 +++++++- libraries/networking/src/Node.h | 4 +--- libraries/shared/src/HmacAuth.cpp | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index d09e379909..7d4ac574da 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -439,14 +439,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi if (activeSocket) { qint64 bytesSent = 0; - auto connectionSecret = destinationNode.getConnectionSecret(); + auto& connectionHash = destinationNode.getAuthenticateHash(); // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { bytesSent += sendPacket(packetList.takeFront(), *activeSocket, - &destinationNode.getAuthenticateHash()); + &connectionHash); } emit dataSent(destinationNode.getType(), bytesSent); diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 8f73475530..88b856cfda 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -73,7 +73,7 @@ public: static QUuid sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); - static QByteArray hashForPacketAndSecret(const udt::Packet & packet, HmacAuth & hash); + static QByteArray hashForPacketAndSecret(const udt::Packet& packet, HmacAuth& hash); PacketType getType() const { return _type; } void setType(PacketType type); diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 6669c68a2e..5af5172580 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -109,6 +109,7 @@ void Node::setType(char type) { _symmetricSocket.setObjectName(typeString); } + void Node::updateClockSkewUsec(qint64 clockSkewSample) { _clockSkewMovingPercentile.updatePercentile(clockSkewSample); _clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile(); @@ -194,6 +195,11 @@ QDebug operator<<(QDebug debug, const Node& node) { return debug.nospace(); } -void Node::_updateAuthenticateHash() { +void Node::setConnectionSecret(const QUuid & connectionSecret) { + if (_connectionSecret == connectionSecret) { + return; + } + + _connectionSecret = connectionSecret; _authenticateHash->setKey(_connectionSecret); } diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 80d51202d5..fe99e9c1ca 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -56,7 +56,7 @@ public: void setIsUpstream(bool isUpstream) { _isUpstream = isUpstream; } const QUuid& getConnectionSecret() const { return _connectionSecret; } - void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; _updateAuthenticateHash(); } + void setConnectionSecret(const QUuid& connectionSecret); HmacAuth& getAuthenticateHash() const { return *_authenticateHash; } NodeData* getLinkedData() const { return _linkedData.get(); } @@ -96,8 +96,6 @@ private: Node(const Node &otherNode); Node& operator=(Node otherNode); - void _updateAuthenticateHash(); - NodeType_t _type; QUuid _connectionSecret; diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HmacAuth.cpp index 5d04bb96a4..f3ffec2c05 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HmacAuth.cpp @@ -55,7 +55,7 @@ bool HmacAuth::setKey(const char * keyValue, int keyLen) { } QMutexLocker lock(&_lock); - return (bool) HMAC_Init(_hmacContext.get(), keyValue, keyLen, sslStruct); + return (bool) HMAC_Init_ex(_hmacContext.get(), keyValue, keyLen, sslStruct, nullptr); } bool HmacAuth::setKey(const QUuid& uidKey) { From eb04f77c3dc71990ea6e4fb21a0b156c234dab98 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 14:04:34 -0700 Subject: [PATCH 010/174] HMAC Auth - code modifications requested by reviewer --- libraries/networking/src/LimitedNodeList.cpp | 16 ++++++------- libraries/networking/src/LimitedNodeList.h | 8 +++---- libraries/networking/src/NLPacket.cpp | 10 ++++---- libraries/networking/src/NLPacket.h | 6 ++--- libraries/networking/src/Node.cpp | 5 ++-- libraries/networking/src/Node.h | 6 ++--- .../shared/src/{HmacAuth.cpp => HMACAuth.cpp} | 23 +++++++++---------- .../shared/src/{HmacAuth.h => HMACAuth.h} | 16 ++++++------- 8 files changed, 44 insertions(+), 46 deletions(-) rename libraries/shared/src/{HmacAuth.cpp => HMACAuth.cpp} (78%) rename libraries/shared/src/{HmacAuth.h => HMACAuth.h} (74%) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 7d4ac574da..ab66b7ae92 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -36,7 +36,7 @@ #include "HifiSockAddr.h" #include "NetworkLogging.h" #include "udt/Packet.h" -#include "HmacAuth.h" +#include "HMACAuth.h" static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); @@ -320,7 +320,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe if (verifiedPacket && !ignoreVerification) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); - QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getAuthenticateHash()); + QByteArray expectedHash = NLPacket::hashForPacketAndHMAC(packet, sourceNode->getAuthenticateHash()); // check if the md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { @@ -364,7 +364,7 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) { _numCollectedBytes += packet.getDataSize(); } -void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HmacAuth * hmacAuth) { +void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { packet.writeSourceID(getSessionUUID()); } @@ -372,7 +372,7 @@ void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HmacAuth * hmacAu if (hmacAuth && !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType()) && !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) { - packet.writeVerificationHashGivenSecret(*hmacAuth); + packet.writeVerificationHash(*hmacAuth); } } @@ -392,7 +392,7 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - HmacAuth * hmacAuth) { + HMACAuth * hmacAuth) { Q_ASSERT(!packet.isPartOfMessage()); Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); @@ -419,7 +419,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& } qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - HmacAuth * hmacAuth) { + HMACAuth* hmacAuth) { Q_ASSERT(!packet->isPartOfMessage()); if (packet->isReliable()) { collectPacketStats(*packet); @@ -459,7 +459,7 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi } qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - HmacAuth * hmacAuth) { + HMACAuth* hmacAuth) { qint64 bytesSent = 0; // close the last packet in the list @@ -479,7 +479,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, nullptr); + fillPacketHeader(*nlPacket); } return _nodeSocket.writePacketList(std::move(packetList), sockAddr); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 612a6ce947..eb70fbcbdf 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -131,17 +131,17 @@ public: // use sendUnreliablePacket to send an unreliable packet (that you do not need to move) // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); - qint64 sendUnreliablePacket(const NLPacket & packet, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth = nullptr); + qint64 sendUnreliablePacket(const NLPacket & packet, const HifiSockAddr & sockAddr, HMACAuth * hmacAuth = nullptr); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); - qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr & sockAddr, HmacAuth * hmacAuth = nullptr); + qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr & sockAddr, HMACAuth * hmacAuth = nullptr); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); qint64 sendUnreliableUnorderedPacketList(NLPacketList & packetList, const HifiSockAddr & sockAddr, - HmacAuth * hmacAuth = nullptr); + HMACAuth * hmacAuth = nullptr); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr @@ -362,7 +362,7 @@ protected: qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr, const QUuid& connectionSecret = QUuid()); void collectPacketStats(const NLPacket& packet); - void fillPacketHeader(const NLPacket& packet, HmacAuth * hmacAuth); + void fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth = nullptr); void setLocalSocket(const HifiSockAddr& sockAddr); diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 37bb465ca9..93274843a6 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -11,7 +11,7 @@ #include "NLPacket.h" -#include "HmacAuth.h" +#include "HMACAuth.h" int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); @@ -151,11 +151,11 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } -QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, HmacAuth& hash) { +QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash) { int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; hash.addData(packet.getData() + offset, packet.getDataSize() - offset); - auto hashResult(hash.result()); + auto hashResult { hash.result() }; return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); } @@ -208,14 +208,14 @@ void NLPacket::writeSourceID(const QUuid& sourceID) const { _sourceID = sourceID; } -void NLPacket::writeVerificationHashGivenSecret(HmacAuth& hmacAuth) const { +void NLPacket::writeVerificationHash(HMACAuth& hmacAuth) const { Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) && !PacketTypeEnum::getNonVerifiedPackets().contains(_type)); auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; - QByteArray verificationHash = hashForPacketAndSecret(*this, hmacAuth); + QByteArray verificationHash = hashForPacketAndHMAC(*this, hmacAuth); memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); } diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 88b856cfda..302598f77c 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -18,7 +18,7 @@ #include "udt/Packet.h" -class HmacAuth; +class HMACAuth; class NLPacket : public udt::Packet { Q_OBJECT @@ -73,7 +73,7 @@ public: static QUuid sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); - static QByteArray hashForPacketAndSecret(const udt::Packet& packet, HmacAuth& hash); + static QByteArray hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash); PacketType getType() const { return _type; } void setType(PacketType type); @@ -84,7 +84,7 @@ public: const QUuid& getSourceID() const { return _sourceID; } void writeSourceID(const QUuid& sourceID) const; - void writeVerificationHashGivenSecret(HmacAuth& hmacAuth) const; + void writeVerificationHash(HMACAuth& hmacAuth) const; protected: diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 5af5172580..132d27d311 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -89,8 +89,7 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, QObject* parent) : NetworkPeer(uuid, publicSocket, localSocket, parent), _type(type), - _authenticateHash(new HmacAuth), - _pingMs(-1), // "Uninitialized" + _authenticateHash(new HMACAuth), _pingMs(-1), // "Uninitialized" _clockSkewUsec(0), _mutex(), _clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples @@ -195,7 +194,7 @@ QDebug operator<<(QDebug debug, const Node& node) { return debug.nospace(); } -void Node::setConnectionSecret(const QUuid & connectionSecret) { +void Node::setConnectionSecret(const QUuid& connectionSecret) { if (_connectionSecret == connectionSecret) { return; } diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index fe99e9c1ca..5b3b559582 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -33,7 +33,7 @@ #include "SimpleMovingAverage.h" #include "MovingPercentile.h" #include "NodePermissions.h" -#include "HmacAuth.h" +#include "HMACAuth.h" class Node : public NetworkPeer { Q_OBJECT @@ -57,7 +57,7 @@ public: const QUuid& getConnectionSecret() const { return _connectionSecret; } void setConnectionSecret(const QUuid& connectionSecret); - HmacAuth& getAuthenticateHash() const { return *_authenticateHash; } + HMACAuth& getAuthenticateHash() const { return *_authenticateHash; } NodeData* getLinkedData() const { return _linkedData.get(); } void setLinkedData(std::unique_ptr linkedData) { _linkedData = std::move(linkedData); } @@ -99,7 +99,7 @@ private: NodeType_t _type; QUuid _connectionSecret; - std::unique_ptr _authenticateHash; + std::unique_ptr _authenticateHash; std::unique_ptr _linkedData; bool _isReplicated { false }; int _pingMs; diff --git a/libraries/shared/src/HmacAuth.cpp b/libraries/shared/src/HMACAuth.cpp similarity index 78% rename from libraries/shared/src/HmacAuth.cpp rename to libraries/shared/src/HMACAuth.cpp index f3ffec2c05..9abce7b954 100644 --- a/libraries/shared/src/HmacAuth.cpp +++ b/libraries/shared/src/HMACAuth.cpp @@ -1,5 +1,5 @@ // -// HmacAuth.cpp +// HMACAuth.cpp // libraries/shared/src // // Created by Simon Walton on 3/19/2018. @@ -11,25 +11,24 @@ #include -#include "HmacAuth.h" +#include "HMACAuth.h" #include -HmacAuth::HmacAuth(AuthMethod authMethod) +HMACAuth::HMACAuth(AuthMethod authMethod) : _hmacContext(new(HMAC_CTX)) , _authMethod(authMethod) { HMAC_CTX_init(_hmacContext.get()); } -HmacAuth::~HmacAuth() { +HMACAuth::~HMACAuth() { HMAC_CTX_cleanup(_hmacContext.get()); } -bool HmacAuth::setKey(const char * keyValue, int keyLen) { - const EVP_MD * sslStruct = nullptr; +bool HMACAuth::setKey(const char * keyValue, int keyLen) { + const EVP_MD* sslStruct = nullptr; - switch (_authMethod) - { + switch (_authMethod) { case MD5: sslStruct = EVP_md5(); break; @@ -58,18 +57,18 @@ bool HmacAuth::setKey(const char * keyValue, int keyLen) { return (bool) HMAC_Init_ex(_hmacContext.get(), keyValue, keyLen, sslStruct, nullptr); } -bool HmacAuth::setKey(const QUuid& uidKey) { +bool HMACAuth::setKey(const QUuid& uidKey) { const QByteArray rfcBytes(uidKey.toRfc4122()); return setKey(rfcBytes.constData(), rfcBytes.length()); } -bool HmacAuth::addData(const char * data, int dataLen) { +bool HMACAuth::addData(const char * data, int dataLen) { QMutexLocker lock(&_lock); return (bool) HMAC_Update(_hmacContext.get(), reinterpret_cast(data), dataLen); } -HmacAuth::HmacHash HmacAuth::result() { - HmacHash hashValue(EVP_MAX_MD_SIZE); +HMACAuth::HMACHash HMACAuth::result() { + HMACHash hashValue(EVP_MAX_MD_SIZE); unsigned int hashLen; QMutexLocker lock(&_lock); HMAC_Final(_hmacContext.get(), &hashValue[0], &hashLen); diff --git a/libraries/shared/src/HmacAuth.h b/libraries/shared/src/HMACAuth.h similarity index 74% rename from libraries/shared/src/HmacAuth.h rename to libraries/shared/src/HMACAuth.h index dfc79e8e47..4bb20a6464 100644 --- a/libraries/shared/src/HmacAuth.h +++ b/libraries/shared/src/HMACAuth.h @@ -1,6 +1,6 @@ // -// HmacAuth.h -// libraries/shared/src +// HMACAuth.h +// libraries/shared/src // // Created by Simon Walton on 3/19/2018. // Copyright 2018 High Fidelity, Inc. @@ -18,23 +18,23 @@ class QUuid; -class HmacAuth { +class HMACAuth { public: enum AuthMethod { MD5, SHA1, SHA224, SHA256, RIPEMD160 }; - using HmacHash = std::vector; + using HMACHash = std::vector; - explicit HmacAuth(AuthMethod authMethod = MD5); - ~HmacAuth(); + explicit HMACAuth(AuthMethod authMethod = MD5); + ~HMACAuth(); bool setKey(const char * keyValue, int keyLen); bool setKey(const QUuid& uidKey); bool addData(const char * data, int dataLen); - HmacHash result(); + HMACHash result(); private: QMutex _lock; std::unique_ptr _hmacContext; - AuthMethod _authMethod { MD5 }; + AuthMethod _authMethod; }; #endif // hifi_HmacAuth_h From adbb2400ab5c01ca2da0a6b47e286f73b63b8eff Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 14:58:14 -0700 Subject: [PATCH 011/174] HMAC Auth - add openssl to cmake file for lib shared --- libraries/shared/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 713501aa77..bff842fdd8 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -2,6 +2,7 @@ set(TARGET_NAME shared) # TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp) setup_hifi_library(Gui Network Script) +include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) From fb16e772ba45f84b1b7dbdfdd3024caa13784e62 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 15:25:50 -0700 Subject: [PATCH 012/174] Move HMACAuth class to networking lib Also reverts addition of openssl headers to shared lib. Commit will require rerunning cmake. --- libraries/{shared => networking}/src/HMACAuth.cpp | 0 libraries/{shared => networking}/src/HMACAuth.h | 0 libraries/shared/CMakeLists.txt | 1 - 3 files changed, 1 deletion(-) rename libraries/{shared => networking}/src/HMACAuth.cpp (100%) rename libraries/{shared => networking}/src/HMACAuth.h (100%) diff --git a/libraries/shared/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp similarity index 100% rename from libraries/shared/src/HMACAuth.cpp rename to libraries/networking/src/HMACAuth.cpp diff --git a/libraries/shared/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h similarity index 100% rename from libraries/shared/src/HMACAuth.h rename to libraries/networking/src/HMACAuth.h diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index bff842fdd8..713501aa77 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -2,7 +2,6 @@ set(TARGET_NAME shared) # TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp) setup_hifi_library(Gui Network Script) -include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) From 64973aa334f5f6582ea183c5e026f6dd19b5db31 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 17:06:15 -0700 Subject: [PATCH 013/174] OpenSSL HMAC changes for Android Looks like Android uses OpenSSL 1.1.0, which provides an allocator for its HMAC context. --- libraries/networking/src/HMACAuth.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 9abce7b954..52c43fe574 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include "HMACAuth.h" @@ -16,7 +17,11 @@ #include HMACAuth::HMACAuth(AuthMethod authMethod) +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + : _hmacContext(HMAC_CTX_new()) +#else : _hmacContext(new(HMAC_CTX)) +#endif , _authMethod(authMethod) { HMAC_CTX_init(_hmacContext.get()); } From 755d89464fb326e74311cd68ba648cc4a17e0dbe Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 17:15:49 -0700 Subject: [PATCH 014/174] HMAC Auth - reviewer-requested changes --- libraries/networking/src/HMACAuth.cpp | 2 +- libraries/networking/src/HMACAuth.h | 8 ++++---- libraries/networking/src/LimitedNodeList.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 52c43fe574..dc6d790425 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -30,7 +30,7 @@ HMACAuth::~HMACAuth() { HMAC_CTX_cleanup(_hmacContext.get()); } -bool HMACAuth::setKey(const char * keyValue, int keyLen) { +bool HMACAuth::setKey(const char* keyValue, int keyLen) { const EVP_MD* sslStruct = nullptr; switch (_authMethod) { diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index 4bb20a6464..57f9dd64b8 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -1,6 +1,6 @@ // // HMACAuth.h -// libraries/shared/src +// libraries/networking/src // // Created by Simon Walton on 3/19/2018. // Copyright 2018 High Fidelity, Inc. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_HmacAuth_h -#define hifi_HmacAuth_h +#ifndef hifi_HMACAuth_h +#define hifi_HMACAuth_h #include #include @@ -37,4 +37,4 @@ private: AuthMethod _authMethod; }; -#endif // hifi_HmacAuth_h +#endif // hifi_HMACAuth_h diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index ab66b7ae92..d2de034d0e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -392,7 +392,7 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - HMACAuth * hmacAuth) { + HMACAuth* hmacAuth) { Q_ASSERT(!packet.isPartOfMessage()); Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); From ef087702352784848b93bd60e6a2adcc76dd9121 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 17:17:24 -0700 Subject: [PATCH 015/174] Missed reviewer change --- libraries/networking/src/HMACAuth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index dc6d790425..1096098cdd 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -67,7 +67,7 @@ bool HMACAuth::setKey(const QUuid& uidKey) { return setKey(rfcBytes.constData(), rfcBytes.length()); } -bool HMACAuth::addData(const char * data, int dataLen) { +bool HMACAuth::addData(const char* data, int dataLen) { QMutexLocker lock(&_lock); return (bool) HMAC_Update(_hmacContext.get(), reinterpret_cast(data), dataLen); } From 3ced1c89237b5706b5365b06f4d2810e8d8aa565 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 17:31:54 -0700 Subject: [PATCH 016/174] More Openssl 1.1 (Android) fixes --- libraries/networking/src/HMACAuth.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 1096098cdd..77b4fb67b2 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -16,12 +16,17 @@ #include -HMACAuth::HMACAuth(AuthMethod authMethod) #if OPENSSL_VERSION_NUMBER >= 0x10100000 +HMACAuth::HMACAuth(AuthMethod authMethod) : _hmacContext(HMAC_CTX_new()) + , _authMethod(authMethod) { } + +HMACAuth::~HMACAuth() { } + #else + +HMACAuth::HMACAuth(AuthMethod authMethod) : _hmacContext(new(HMAC_CTX)) -#endif , _authMethod(authMethod) { HMAC_CTX_init(_hmacContext.get()); } @@ -29,6 +34,7 @@ HMACAuth::HMACAuth(AuthMethod authMethod) HMACAuth::~HMACAuth() { HMAC_CTX_cleanup(_hmacContext.get()); } +#endif bool HMACAuth::setKey(const char* keyValue, int keyLen) { const EVP_MD* sslStruct = nullptr; @@ -79,6 +85,6 @@ HMACAuth::HMACHash HMACAuth::result() { HMAC_Final(_hmacContext.get(), &hashValue[0], &hashLen); hashValue.resize((size_t) hashLen); // Clear state for possible reuse. - HMAC_Init(_hmacContext.get(), nullptr, 0, nullptr); + HMAC_Init_ex(_hmacContext.get(), nullptr, 0, nullptr, nullptr); return hashValue; } From d58b2acc8ce5c7ee8fd3211d41e8937656052e79 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 18:25:26 -0700 Subject: [PATCH 017/174] Use raw pointer for possibly-opaque openssl context type --- libraries/networking/src/HMACAuth.cpp | 18 +++++++++++------- libraries/networking/src/HMACAuth.h | 6 +++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 77b4fb67b2..baeffeadeb 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -21,18 +21,22 @@ HMACAuth::HMACAuth(AuthMethod authMethod) : _hmacContext(HMAC_CTX_new()) , _authMethod(authMethod) { } -HMACAuth::~HMACAuth() { } +HMACAuth::~HMACAuth() +{ + HMAC_CTX_free(_hmacContext); +} #else HMACAuth::HMACAuth(AuthMethod authMethod) : _hmacContext(new(HMAC_CTX)) , _authMethod(authMethod) { - HMAC_CTX_init(_hmacContext.get()); + HMAC_CTX_init(_hmacContext); } HMACAuth::~HMACAuth() { - HMAC_CTX_cleanup(_hmacContext.get()); + HMAC_CTX_cleanup(_hmacContext); + delete _hmacContext; } #endif @@ -65,7 +69,7 @@ bool HMACAuth::setKey(const char* keyValue, int keyLen) { } QMutexLocker lock(&_lock); - return (bool) HMAC_Init_ex(_hmacContext.get(), keyValue, keyLen, sslStruct, nullptr); + return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr); } bool HMACAuth::setKey(const QUuid& uidKey) { @@ -75,16 +79,16 @@ bool HMACAuth::setKey(const QUuid& uidKey) { bool HMACAuth::addData(const char* data, int dataLen) { QMutexLocker lock(&_lock); - return (bool) HMAC_Update(_hmacContext.get(), reinterpret_cast(data), dataLen); + return (bool) HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen); } HMACAuth::HMACHash HMACAuth::result() { HMACHash hashValue(EVP_MAX_MD_SIZE); unsigned int hashLen; QMutexLocker lock(&_lock); - HMAC_Final(_hmacContext.get(), &hashValue[0], &hashLen); + HMAC_Final(_hmacContext, &hashValue[0], &hashLen); hashValue.resize((size_t) hashLen); // Clear state for possible reuse. - HMAC_Init_ex(_hmacContext.get(), nullptr, 0, nullptr, nullptr); + HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); return hashValue; } diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index 57f9dd64b8..89c20a3906 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -26,14 +26,14 @@ public: explicit HMACAuth(AuthMethod authMethod = MD5); ~HMACAuth(); - bool setKey(const char * keyValue, int keyLen); + bool setKey(const char* keyValue, int keyLen); bool setKey(const QUuid& uidKey); - bool addData(const char * data, int dataLen); + bool addData(const char* data, int dataLen); HMACHash result(); private: QMutex _lock; - std::unique_ptr _hmacContext; + struct hmac_ctx_st * _hmacContext; AuthMethod _authMethod; }; From 29b4353397bdfa168d0d212738d333c8091e7392 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 18:26:32 -0700 Subject: [PATCH 018/174] Spacing clean-up --- libraries/networking/src/HMACAuth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index 89c20a3906..0bf7a86ec1 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -33,7 +33,7 @@ public: private: QMutex _lock; - struct hmac_ctx_st * _hmacContext; + struct hmac_ctx_st* _hmacContext; AuthMethod _authMethod; }; From 16b0c48b73bb5d5afb31c2efc904328497dc84b8 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 18:32:25 -0700 Subject: [PATCH 019/174] HMACAuth - improved syntax for new --- libraries/networking/src/HMACAuth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index baeffeadeb..fdc2588f62 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -29,7 +29,7 @@ HMACAuth::~HMACAuth() #else HMACAuth::HMACAuth(AuthMethod authMethod) - : _hmacContext(new(HMAC_CTX)) + : _hmacContext(new HMAC_CTX()) , _authMethod(authMethod) { HMAC_CTX_init(_hmacContext); } From 3e1a33377615fa097605125d6eea0ac1c22d3a2a Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 21 Mar 2018 18:40:54 -0700 Subject: [PATCH 020/174] Just bump default packet version --- .../networking/src/udt/PacketHeaders.cpp | 19 +++++++------- libraries/networking/src/udt/PacketHeaders.h | 25 ++++++------------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index d6b59d59f9..f09a049fc4 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -25,29 +25,30 @@ int packetTypeMetaTypeId = qRegisterMetaType(); PacketVersion versionForPacketType(PacketType packetType) { switch (packetType) { case PacketType::DomainList: - return static_cast(DomainListVersion::UseHmacAuthentication); + return static_cast(DomainListVersion::GetMachineFingerprintFromUUIDSupport); case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::UseHmacAuthentication); + return static_cast(EntityVersion::ShadowControl); case PacketType::EntityQuery: - return static_cast(EntityQueryPacketVersion::UseHmacAuthentication); + return static_cast(EntityQueryPacketVersion::RemovedJurisdictions); case PacketType::AvatarIdentity: case PacketType::AvatarData: case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::UseHmacAuthentication); + return static_cast(AvatarMixerPacketVersion::FBXReaderNodeReparenting); case PacketType::MessagesData: - return static_cast(MessageDataVersion::UseHmacAuthentication); + return static_cast(MessageDataVersion::TextOrBinaryData); case PacketType::ICEServerHeartbeat: return 18; // ICE Server Heartbeat signing case PacketType::AssetMappingOperation: case PacketType::AssetMappingOperationReply: + return static_cast(AssetServerPacketVersion::RedirectedMappings); case PacketType::AssetGetInfo: case PacketType::AssetGet: case PacketType::AssetUpload: - return static_cast(AssetServerPacketVersion::UseHmacAuthentication); + return static_cast(AssetServerPacketVersion::RangeRequestSupport); case PacketType::NodeIgnoreRequest: return 18; // Introduction of node ignore request (which replaced an unused packet tpye) @@ -58,10 +59,10 @@ PacketVersion versionForPacketType(PacketType packetType) { return static_cast(DomainConnectRequestVersion::AlwaysHasMachineFingerprint); case PacketType::DomainServerAddedNode: - return static_cast(DomainServerAddedNodeVersion::UseHmacAuthentication); + return static_cast(DomainServerAddedNodeVersion::PermissionsGrid); case PacketType::EntityScriptCallMethod: - return static_cast(EntityScriptCallMethodVersion::UseHmacAuthentication); + return static_cast(EntityScriptCallMethodVersion::ClientCallable); case PacketType::MixedAudio: case PacketType::SilentAudioFrame: @@ -69,7 +70,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::MicrophoneAudioNoEcho: case PacketType::MicrophoneAudioWithEcho: case PacketType::AudioStreamStats: - return static_cast(AudioVersion::UseHmacAuthentication); + return static_cast(AudioVersion::HighDynamicRangeVolume); case PacketType::ICEPing: return static_cast(IcePingVersion::SendICEPeerID); case PacketType::DomainSettings: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 9dc3f2befd..98a9087d37 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -231,29 +231,25 @@ enum class EntityVersion : PacketVersion { ZoneStageRemoved, SoftEntities, MaterialEntities, - ShadowControl, - UseHmacAuthentication + ShadowControl }; enum class EntityScriptCallMethodVersion : PacketVersion { ServerCallable = 18, - ClientCallable = 19, - UseHmacAuthentication = 20 + ClientCallable = 19 }; enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, JSONFilterWithFamilyTree = 19, ConnectionIdentifier = 20, - RemovedJurisdictions = 21, - UseHmacAuthentication = 22 + RemovedJurisdictions = 21 }; enum class AssetServerPacketVersion: PacketVersion { VegasCongestionControl = 19, RangeRequestSupport, - RedirectedMappings, - UseHmacAuthentication + RedirectedMappings }; enum class AvatarMixerPacketVersion : PacketVersion { @@ -278,8 +274,7 @@ enum class AvatarMixerPacketVersion : PacketVersion { AvatarIdentityLookAtSnapping, UpdatedMannequinDefaultAvatar, AvatarJointDefaultPoseFlags, - FBXReaderNodeReparenting, - UseHmacAuthentication + FBXReaderNodeReparenting }; enum class DomainConnectRequestVersion : PacketVersion { @@ -299,16 +294,14 @@ enum class DomainConnectionDeniedVersion : PacketVersion { enum class DomainServerAddedNodeVersion : PacketVersion { PrePermissionsGrid = 17, - PermissionsGrid, - UseHmacAuthentication + PermissionsGrid }; enum class DomainListVersion : PacketVersion { PrePermissionsGrid = 18, PermissionsGrid, GetUsernameFromUUIDSupport, - GetMachineFingerprintFromUUIDSupport, - UseHmacAuthentication + GetMachineFingerprintFromUUIDSupport }; enum class AudioVersion : PacketVersion { @@ -319,12 +312,10 @@ enum class AudioVersion : PacketVersion { SpaceBubbleChanges, HasPersonalMute, HighDynamicRangeVolume, - UseHmacAuthentication, }; enum class MessageDataVersion : PacketVersion { - TextOrBinaryData = 18, - UseHmacAuthentication + TextOrBinaryData = 18 }; enum class IcePingVersion : PacketVersion { From ab4f110ea4e68aea09eb6b4da01d281c0a941ec9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 Mar 2018 11:07:06 -0700 Subject: [PATCH 021/174] add single quote tests to JS baking tests --- tests/baking/src/JSBakerTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/baking/src/JSBakerTest.cpp b/tests/baking/src/JSBakerTest.cpp index 082ffb047f..e39ccc6b9a 100644 --- a/tests/baking/src/JSBakerTest.cpp +++ b/tests/baking/src/JSBakerTest.cpp @@ -66,12 +66,14 @@ void JSBakerTest::setTestCases() { _testCases.emplace_back("'abcd1234$%^&[](){}'\na", "'abcd1234$%^&[](){}'\na"); _testCases.emplace_back("\"abcd1234$%^&[](){}\"\na", "\"abcd1234$%^&[](){}\"\na"); _testCases.emplace_back("`abcd1234$%^&[](){}`\na", "`abcd1234$%^&[](){}`a"); + _testCases.emplace_back("\' \';", "\' \';"); + _testCases.emplace_back("\'//single line comment\nvar b=2;\';", "\'//single line comment\nvar b=2;\';"); // Edge Cases //No semicolon to terminate an expression, instead a new line used for termination _testCases.emplace_back("var x=5\nvar y=6;", "var x=5\nvar y=6;"); - + //a + ++b is minified as a+ ++b. _testCases.emplace_back("a + ++b", "a + ++b"); From 68ab0eed68dfe8b8b2b76472e8c0891d52e477ee Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 22 Mar 2018 14:44:25 -0700 Subject: [PATCH 022/174] HMACAuth - fix some more spacing issue --- libraries/networking/src/HMACAuth.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index fdc2588f62..42b5c48d93 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -1,6 +1,6 @@ // -// HMACAuth.cpp -// libraries/shared/src +// HMACAuth.cpp +// libraries/networking/src // // Created by Simon Walton on 3/19/2018. // Copyright 2018 High Fidelity, Inc. diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index eb70fbcbdf..64969862ee 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -131,17 +131,17 @@ public: // use sendUnreliablePacket to send an unreliable packet (that you do not need to move) // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); - qint64 sendUnreliablePacket(const NLPacket & packet, const HifiSockAddr & sockAddr, HMACAuth * hmacAuth = nullptr); + qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); - qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr & sockAddr, HMACAuth * hmacAuth = nullptr); + qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); - qint64 sendUnreliableUnorderedPacketList(NLPacketList & packetList, const HifiSockAddr & sockAddr, - HMACAuth * hmacAuth = nullptr); + qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, + HMACAuth* hmacAuth = nullptr); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr From b5f165d48176a4c55c66160ce2ec0136b96f6430 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 23 Mar 2018 16:55:19 -0700 Subject: [PATCH 023/174] Store a short ID with the Node on the domain-server side --- domain-server/src/DomainGatekeeper.cpp | 30 +++++++++++++++++++++++++- domain-server/src/DomainGatekeeper.h | 14 ++++++++++++ libraries/networking/src/NetworkPeer.h | 5 +++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 7d0b538f6e..748c089b21 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ using SharedAssignmentPointer = QSharedPointer; DomainGatekeeper::DomainGatekeeper(DomainServer* server) : _server(server) { - + initLocalIDManagement(); } void DomainGatekeeper::addPendingAssignedNode(const QUuid& nodeUUID, const QUuid& assignmentUUID, @@ -525,6 +526,7 @@ SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const Node SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeID, nodeConnection.nodeType, nodeConnection.publicSockAddr, nodeConnection.localSockAddr); + newNode->setLocalID(findOrCreateLocalID(nodeID)); // So that we can send messages to this node at will - we need to activate the correct socket on this node now newNode->activateMatchingOrNewSymmetricSocket(discoveredSocket); @@ -1014,3 +1016,29 @@ void DomainGatekeeper::refreshGroupsCache() { _server->_settingsManager.debugDumpGroupsState(); #endif } + +void DomainGatekeeper::initLocalIDManagement() { + std::uniform_int_distribution sixteenBitRand; + std::random_device randomDevice; + std::default_random_engine engine {randomDevice()}; + _currentLocalID = sixteenBitRand(engine); + // Ensure increment is odd. + _idIncrement = sixteenBitRand(engine) | 1; +} + +Node::LocalID DomainGatekeeper::findOrCreateLocalID(const QUuid& uuid) { + auto existingLocalIDIt = _uuidToLocalID.find(uuid); + if (existingLocalIDIt != _uuidToLocalID.end()) { + return existingLocalIDIt->second; + } + + Node::LocalID newLocalID; + do { + newLocalID = _currentLocalID; + _currentLocalID += _idIncrement; + } while (_localIDToUUID.find(newLocalID) != _localIDToUUID.end()); + + _uuidToLocalID.emplace(uuid, newLocalID); + _localIDToUUID.emplace(newLocalID, uuid); + return newLocalID; +} diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index 09db075e07..896997a0e7 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -120,6 +120,20 @@ private: void getGroupMemberships(const QString& username); // void getIsGroupMember(const QString& username, const QUuid groupID); void getDomainOwnerFriendsList(); + + // Local ID management. + void initLocalIDManagement(); + Node::LocalID findOrCreateLocalID(const QUuid& uuid); + struct UuidHash { + size_t operator()(const QUuid& uuid) const { return qHash(uuid); } + }; + using UUIDToLocalID = std::unordered_map ; + using LocalIDToUUID = std::unordered_map; + UUIDToLocalID _uuidToLocalID; + LocalIDToUUID _localIDToUUID; + + Node::LocalID _currentLocalID; + quint16 _idIncrement; }; diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index 9842768b37..f36db402ce 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -39,6 +39,10 @@ public: const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; } + using LocalID = quint16; + LocalID getLocalID() const { return _localID; } + void setLocalID(LocalID localID) { _localID = localID; } + void softReset(); void reset(); @@ -99,6 +103,7 @@ protected: void setActiveSocket(HifiSockAddr* discoveredSocket); QUuid _uuid; + LocalID _localID { 0 }; HifiSockAddr _publicSocket; HifiSockAddr _localSocket; From 4ec77e3af6f7752564e0cf8dc23d895e1079cc67 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 26 Mar 2018 14:57:59 -0700 Subject: [PATCH 024/174] WIP - assign short IDs to nodes and distribute them. --- domain-server/src/DomainGatekeeper.h | 3 ++- domain-server/src/DomainServer.cpp | 5 +++++ libraries/networking/src/LimitedNodeList.cpp | 9 +++++++++ libraries/networking/src/LimitedNodeList.h | 3 +++ libraries/networking/src/Node.cpp | 4 +++- libraries/networking/src/NodeList.cpp | 17 ++++++++++++----- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index 896997a0e7..afb848f271 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -41,6 +41,8 @@ public: void removeICEPeer(const QUuid& peerUUID) { _icePeers.remove(peerUUID); } + Node::LocalID findOrCreateLocalID(const QUuid& uuid); + static void sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr); public slots: void processConnectRequestPacket(QSharedPointer message); @@ -123,7 +125,6 @@ private: // Local ID management. void initLocalIDManagement(); - Node::LocalID findOrCreateLocalID(const QUuid& uuid); struct UuidHash { size_t operator()(const QUuid& uuid) const { return qHash(uuid); } }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 197ac7eac2..5ae2f8514c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -691,6 +691,10 @@ void DomainServer::setupNodeListAndAssignments() { } } + // Create our own short session ID. + Node::LocalID serverSessionLocalID = _gatekeeper.findOrCreateLocalID(nodeList->getSessionUUID()); + nodeList->setSessionLocalID(serverSessionLocalID); + if (isMetaverseDomain) { // see if we think we're a temp domain (we have an API key) or a full domain const auto& temporaryDomainKey = DependencyManager::get()->getTemporaryDomainKey(getID()); @@ -1165,6 +1169,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif extendedHeaderStream << limitedNodeList->getSessionUUID(); extendedHeaderStream << node->getUUID(); + extendedHeaderStream << node->getLocalID(); extendedHeaderStream << node->getPermissions(); auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0803e380f2..0b2fb9475d 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -131,6 +131,15 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) { } } +Node::LocalID LimitedNodeList::getSessionLocalID() const { + return _sessionLocalID; +} + +void LimitedNodeList::setSessionLocalID(Node::LocalID sessionLocalID) { + QWriteLocker lock { &_sessionUUIDLock }; // Necessary? + _sessionLocalID = sessionLocalID; +} + void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) { NodePermissions originalPermissions = _permissions; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 7165b3dd63..c725e8abb7 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -106,6 +106,8 @@ public: Q_ENUM(ConnectionStep); QUuid getSessionUUID() const; void setSessionUUID(const QUuid& sessionUUID); + Node::LocalID getSessionLocalID() const; + void setSessionLocalID(Node::LocalID localID); void setPermissions(const NodePermissions& newPermissions); bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); } @@ -427,6 +429,7 @@ private slots: private: mutable QReadWriteLock _sessionUUIDLock; QUuid _sessionUUID; + Node::LocalID _sessionLocalID { 0 }; }; #endif // hifi_LimitedNodeList_h diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index bd895c8ef1..73b7c44e7e 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -168,6 +168,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) { out << node._localSocket; out << node._permissions; out << node._isReplicated; + out << node._localID; return out; } @@ -178,6 +179,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) { in >> node._localSocket; in >> node._permissions; in >> node._isReplicated; + in >> node._localID; return in; } @@ -188,7 +190,7 @@ QDebug operator<<(QDebug debug, const Node& node) { } else { debug.nospace() << " (" << node.getType() << ")"; } - debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " "; + debug << " " << node.getUUID().toString().toLocal8Bit().constData() << "(" << node.getLocalID() << ") "; debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); return debug.nospace(); } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cb0d2e4cd5..752d420a4b 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -594,9 +594,13 @@ void NodeList::processDomainServerList(QSharedPointer message) return; } - // pull our owner UUID from the packet, it's always the first thing + // pull our owner (ie. session) UUID from the packet, it's always the first thing + // The short (16 bit) ID comes next. QUuid newUUID; + Node::LocalID newLocalID; packetStream >> newUUID; + packetStream >> newLocalID; + setSessionLocalID(newLocalID); setSessionUUID(newUUID); // if this was the first domain-server list from this domain, we've now connected @@ -638,12 +642,14 @@ void NodeList::processDomainServerRemovedNode(QSharedPointer me void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { // setup variables to read into from QDataStream qint8 nodeType; - QUuid nodeUUID, connectionUUID; + QUuid nodeUUID, connectionSecretUUID; HifiSockAddr nodePublicSocket, nodeLocalSocket; NodePermissions permissions; bool isReplicated; + Node::LocalID sessionLocalID; - packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> permissions >> isReplicated; + packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> permissions + >> isReplicated >> sessionLocalID; // if the public socket address is 0 then it's reachable at the same IP // as the domain server @@ -651,10 +657,11 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { nodePublicSocket.setAddress(_domainHandler.getIP()); } - packetStream >> connectionUUID; + packetStream >> connectionSecretUUID; SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, - nodeLocalSocket, isReplicated, false, connectionUUID, permissions); + nodeLocalSocket, isReplicated, false, connectionSecretUUID, permissions); + node->setLocalID(sessionLocalID); // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server // and always have their public socket as their active socket From d3464378b71e4a98a60cbaddda2be933008d7202 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 27 Mar 2018 13:46:58 -0700 Subject: [PATCH 025/174] Short local source IDs - checkpoint DS assigns 16-bit IDs as well as UUIDs; ACs track mappings; nodes use short IDs in packets. Initial setup works; then fails prob. due to DS UUID. --- assignment-client/src/assets/AssetServer.cpp | 2 +- assignment-client/src/audio/AudioMixer.cpp | 8 +++- assignment-client/src/avatars/AvatarMixer.cpp | 10 +++-- domain-server/src/DomainGatekeeper.cpp | 5 ++- domain-server/src/DomainServer.cpp | 20 +++++----- libraries/audio/src/InboundAudioStream.cpp | 6 +-- libraries/networking/src/LimitedNodeList.cpp | 39 ++++++++++++++----- libraries/networking/src/LimitedNodeList.h | 5 ++- libraries/networking/src/NLPacket.cpp | 18 +++++---- libraries/networking/src/NLPacket.h | 12 +++--- libraries/networking/src/NLPacketList.h | 4 +- libraries/networking/src/NodeList.cpp | 5 +-- libraries/networking/src/PacketReceiver.cpp | 5 +-- libraries/networking/src/ReceivedMessage.cpp | 2 +- libraries/networking/src/ReceivedMessage.h | 6 +-- libraries/octree/src/OctreeProcessor.cpp | 2 +- 16 files changed, 91 insertions(+), 58 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 87827a27d9..9d474c8c24 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -842,7 +842,7 @@ void AssetServer::handleAssetUpload(QSharedPointer message, Sha if (canWriteToAssetServer) { - qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(message->getSourceID()); + qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << message->getSourceID(); auto task = new UploadAssetTask(message, senderNode, _filesDirectory, _filesizeLimit); _transferTaskPool.start(task); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 8af4eec934..3b79eab06e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -118,7 +118,11 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer mess // make sure we have a replicated node for the original sender of the packet auto nodeList = DependencyManager::get(); - QUuid nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + QUuid nodeID; + SharedNodePointer sourceNode = nodeList->nodeWithLocalID(message->getSourceID()); + if (sourceNode) { + nodeID = sourceNode->getUUID(); + } auto replicatedNode = nodeList->addOrUpdateNode(nodeID, NodeType::Agent, message->getSenderSockAddr(), message->getSenderSockAddr(), @@ -136,7 +140,7 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer mess auto replicatedMessage = QSharedPointer::create(audioData, rewrittenType, versionForPacketType(rewrittenType), - message->getSenderSockAddr(), nodeID); + message->getSenderSockAddr(), message->getSourceID()); getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode); } diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 929941c05c..b0f1420472 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -112,8 +112,12 @@ void AvatarMixer::handleReplicatedPacket(QSharedPointer message void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer message) { while (message->getBytesLeftToRead()) { // first, grab the node ID for this replicated avatar - auto nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - + QUuid nodeID; + auto nodeList = DependencyManager::get(); + SharedNodePointer sourceNode = nodeList->nodeWithLocalID(message->getSourceID()); + if (sourceNode) { + nodeID = sourceNode->getUUID(); + } // make sure we have an upstream replicated node that matches auto replicatedNode = addOrUpdateReplicatedNode(nodeID, message->getSenderSockAddr()); @@ -127,7 +131,7 @@ void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer::create(avatarByteArray, PacketType::AvatarData, versionForPacketType(PacketType::AvatarData), - message->getSenderSockAddr(), nodeID); + message->getSenderSockAddr(), message->getSourceID()); // queue up the replicated avatar data with the client data for the replicated node auto start = usecTimestampNow(); diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 748c089b21..917d8a01c0 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -524,9 +524,10 @@ SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const Node auto limitedNodeList = DependencyManager::get(); + Node::LocalID newLocalID = findOrCreateLocalID(nodeID); SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeID, nodeConnection.nodeType, - nodeConnection.publicSockAddr, nodeConnection.localSockAddr); - newNode->setLocalID(findOrCreateLocalID(nodeID)); + nodeConnection.publicSockAddr, nodeConnection.localSockAddr, + newLocalID); // So that we can send messages to this node at will - we need to activate the correct socket on this node now newNode->activateMatchingOrNewSymmetricSocket(discoveredSocket); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5ae2f8514c..fee102d66a 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -593,8 +593,9 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) { if (!PacketTypeEnum::getNonSourcedPackets().contains(headerType)) { // this is a sourced packet - first check if we have a node that matches - QUuid sourceID = NLPacket::sourceIDInHeader(packet); - SharedNodePointer sourceNode = nodeList->nodeWithUUID(sourceID); + //QUuid sourceID = NLPacket::sourceIDInHeader(packet); + Node::LocalID localSourceID = NLPacket::sourceIDInHeader(packet); + SharedNodePointer sourceNode = nodeList->nodeWithLocalID(localSourceID); if (sourceNode) { // unverified DS packets (due to a lack of connection secret between DS + node) @@ -616,17 +617,17 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) { = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); qDebug() << "Packet of type" << headerType - << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceID); + << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceNode->getUUID()); return false; } } else { - static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with UUID"; + static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with Local ID"; static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); qDebug() << "Packet of type" << headerType - << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); + << "received from unknown node with Local ID" << localSourceID; return false; } @@ -3203,13 +3204,12 @@ void DomainServer::processNodeDisconnectRequestPacket(QSharedPointer(); - const QUuid& nodeUUID = message->getSourceID(); - - qDebug() << "Received a disconnect request from node with UUID" << nodeUUID; + auto localID = message->getSourceID(); + qDebug() << "Received a disconnect request from node with local ID" << localID; // we want to check what type this node was before going to kill it so that we can avoid sending the RemovedNode // packet to nodes that don't care about this type - auto nodeToKill = limitedNodeList->nodeWithUUID(nodeUUID); + auto nodeToKill = limitedNodeList->nodeWithLocalID(localID); if (nodeToKill) { handleKillNode(nodeToKill); @@ -3477,7 +3477,7 @@ void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer message) { - auto node = DependencyManager::get()->nodeWithUUID(message->getSourceID()); + auto node = DependencyManager::get()->nodeWithLocalID(message->getSourceID()); if (node->getCanReplaceContent()) { handleOctreeFileReplacement(message->readAll()); } diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 72acc7fcf6..983b5e1cb8 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -120,8 +120,8 @@ int InboundAudioStream::parseData(ReceivedMessage& message) { // parse sequence number and track it quint16 sequence; message.readPrimitive(&sequence); - SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, - message.getSourceID()); + SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, QUuid() // TBD + /*message.getSourceID()*/); QString codecInPacket = message.readString(); packetReceivedUpdateTimingStats(); @@ -186,7 +186,7 @@ int InboundAudioStream::parseData(ReceivedMessage& message) { _mismatchedAudioCodecCount = 0; // inform others of the mismatch - auto sendingNode = DependencyManager::get()->nodeWithUUID(message.getSourceID()); + auto sendingNode = DependencyManager::get()->nodeWithLocalID(message.getSourceID()); if (sendingNode) { emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket); qDebug(audio) << "Codec mismatch threshold exceeded, SelectedAudioFormat(" << _selectedCodecName << " ) sent"; diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0b2fb9475d..77daaa84ea 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -238,13 +238,16 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort()); } } else { - sourceID = NLPacket::sourceIDInHeader(packet); + SharedNodePointer sourceNode = nodeWithLocalID(NLPacket::sourceIDInHeader(packet)); + if (sourceNode) { + sourceID = sourceNode->getUUID(); - hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType); + hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType); - if (!hasBeenOutput) { - sourcedVersionDebugSuppressMap.insert(sourceID, headerType); - senderString = uuidStringWithoutCurlyBraces(sourceID.toString()); + if (!hasBeenOutput) { + sourcedVersionDebugSuppressMap.insert(sourceID, headerType); + senderString = uuidStringWithoutCurlyBraces(sourceID.toString()); + } } } @@ -302,14 +305,17 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; } } else { - QUuid sourceID = NLPacket::sourceIDInHeader(packet); // check if we were passed a sourceNode hint or if we need to look it up if (!sourceNode) { // figure out which node this is from - SharedNodePointer matchingNode = nodeWithUUID(sourceID); + NLPacket::LocalID sourceLocalID = NLPacket::sourceIDInHeader(packet); + + SharedNodePointer matchingNode = nodeWithLocalID(sourceLocalID); sourceNode = matchingNode.data(); } + + QUuid sourceID = sourceNode->getUUID(); if (!sourceNode && sourceID == getDomainUUID() && @@ -374,7 +380,7 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) { void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { - packet.writeSourceID(getSessionUUID()); + packet.writeSourceID(getSessionLocalID()); } if (!connectionSecret.isNull() @@ -557,6 +563,16 @@ SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) { return it == _nodeHash.cend() ? SharedNodePointer() : it->second; } +SharedNodePointer LimitedNodeList::nodeWithLocalID(Node::LocalID localID) const { + QReadLocker readLocker(&_nodeMutex); + + LocalIDMapping::const_iterator idIter = _localIDMap.find(localID); + if (idIter == _localIDMap.cend()) { + qCDebug(networking) << "No such Node with local ID " << localID; + } + return idIter == _localIDMap.cend() ? nullptr : idIter->second; +} + void LimitedNodeList::eraseAllNodes() { QSet killedNodes; @@ -565,6 +581,8 @@ void LimitedNodeList::eraseAllNodes() { // and then remove them from the hash QWriteLocker writeLocker(&_nodeMutex); + _localIDMap.erase(_localIDMap.begin(), _localIDMap.end()); + if (_nodeHash.size() > 0) { qCDebug(networking) << "LimitedNodeList::eraseAllNodes() removing all nodes from NodeList."; @@ -630,7 +648,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) { SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, - bool isReplicated, bool isUpstream, + Node::LocalID localID, bool isReplicated, bool isUpstream, const QUuid& connectionSecret, const NodePermissions& permissions) { QReadLocker readLocker(&_nodeMutex); NodeHash::const_iterator it = _nodeHash.find(uuid); @@ -644,6 +662,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t matchingNode->setConnectionSecret(connectionSecret); matchingNode->setIsReplicated(isReplicated); matchingNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); + matchingNode->setLocalID(localID); return matchingNode; } else { @@ -653,6 +672,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t newNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); newNode->setConnectionSecret(connectionSecret); newNode->setPermissions(permissions); + newNode->setLocalID(localID); // move the newly constructed node to the LNL thread newNode->moveToThread(thread()); @@ -693,6 +713,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t #else _nodeHash.emplace(newNode->getUUID(), newNodePointer); #endif + _localIDMap.emplace(localID, newNodePointer); readLocker.unlock(); qCDebug(networking) << "Added" << *newNode; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index c725e8abb7..51c8831e2b 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -157,10 +157,11 @@ public: size_t size() const { QReadLocker readLock(&_nodeMutex); return _nodeHash.size(); } SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); + SharedNodePointer nodeWithLocalID(Node::LocalID localID) const; SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, - bool isReplicated = false, bool isUpstream = false, + Node::LocalID localID = 0, bool isReplicated = false, bool isUpstream = false, const QUuid& connectionSecret = QUuid(), const NodePermissions& permissions = DEFAULT_AGENT_PERMISSIONS); @@ -429,6 +430,8 @@ private slots: private: mutable QReadWriteLock _sessionUUIDLock; QUuid _sessionUUID; + using LocalIDMapping = std::unordered_map; + LocalIDMapping _localIDMap; Node::LocalID _sessionLocalID { 0 }; }; diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 5c5077691b..66e74238aa 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -14,7 +14,7 @@ int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); - qint64 optionalSize = (nonSourced ? 0 : NUM_BYTES_RFC4122_UUID) + ((nonSourced || nonVerified) ? 0 : NUM_BYTES_MD5_HASH); + qint64 optionalSize = (nonSourced ? 0 : NUM_BYTES_LOCALID) + ((nonSourced || nonVerified) ? 0 : NUM_BYTES_MD5_HASH); return sizeof(PacketType) + sizeof(PacketVersion) + optionalSize; } int NLPacket::totalHeaderSize(PacketType type, bool isPartOfMessage) { @@ -139,13 +139,14 @@ PacketVersion NLPacket::versionInHeader(const udt::Packet& packet) { return *reinterpret_cast(packet.getData() + headerOffset + sizeof(PacketType)); } -QUuid NLPacket::sourceIDInHeader(const udt::Packet& packet) { +NLPacket::LocalID NLPacket::sourceIDInHeader(const udt::Packet& packet) { int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion); - return QUuid::fromRfc4122(QByteArray::fromRawData(packet.getData() + offset, NUM_BYTES_RFC4122_UUID)); + return *reinterpret_cast(packet.getData() + offset); } QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { - int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; + int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + + sizeof(PacketVersion) + NUM_BYTES_LOCALID; return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } @@ -153,7 +154,7 @@ QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUu QCryptographicHash hash(QCryptographicHash::Md5); int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) - + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; + + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH; // add the packet payload and the connection UUID hash.addData(packet.getData() + offset, packet.getDataSize() - offset); @@ -203,11 +204,12 @@ void NLPacket::readSourceID() { } } -void NLPacket::writeSourceID(const QUuid& sourceID) const { +void NLPacket::writeSourceID(LocalID sourceID) const { Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type)); auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion); - memcpy(_packet.get() + offset, sourceID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); + + memcpy(_packet.get() + offset, &sourceID, sizeof(sourceID)); _sourceID = sourceID; } @@ -217,7 +219,7 @@ void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) c !PacketTypeEnum::getNonVerifiedPackets().contains(_type)); auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) - + NUM_BYTES_RFC4122_UUID; + + NUM_BYTES_LOCALID; QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret); memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index f49cc47645..a4690a376c 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -43,10 +43,12 @@ public: // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | // NLPacket Header Format + using LocalID = qint16; + static const int NUM_BYTES_LOCALID = sizeof(LocalID); // this is used by the Octree classes - must be known at compile time static const int MAX_PACKET_HEADER_SIZE = sizeof(udt::Packet::SequenceNumberAndBitField) + sizeof(udt::Packet::MessageNumberAndBitField) + - sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH; static std::unique_ptr create(PacketType type, qint64 size = -1, bool isReliable = false, bool isPartOfMessage = false, PacketVersion version = 0); @@ -69,7 +71,7 @@ public: static PacketType typeInHeader(const udt::Packet& packet); static PacketVersion versionInHeader(const udt::Packet& packet); - static QUuid sourceIDInHeader(const udt::Packet& packet); + static LocalID sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret); @@ -79,9 +81,9 @@ public: PacketVersion getVersion() const { return _version; } void setVersion(PacketVersion version); - const QUuid& getSourceID() const { return _sourceID; } + LocalID getSourceID() const { return _sourceID; } - void writeSourceID(const QUuid& sourceID) const; + void writeSourceID(qint16 sourceID) const; void writeVerificationHashGivenSecret(const QUuid& connectionSecret) const; protected: @@ -106,7 +108,7 @@ protected: PacketType _type; PacketVersion _version; - mutable QUuid _sourceID; + mutable LocalID _sourceID; }; #endif // hifi_NLPacket_h diff --git a/libraries/networking/src/NLPacketList.h b/libraries/networking/src/NLPacketList.h index 910d39f71b..9c50033ca7 100644 --- a/libraries/networking/src/NLPacketList.h +++ b/libraries/networking/src/NLPacketList.h @@ -22,7 +22,7 @@ public: bool isReliable = false, bool isOrdered = false); PacketVersion getVersion() const { return _packetVersion; } - const QUuid& getSourceID() const { return _sourceID; } + NLPacket::LocalID getSourceID() const { return _sourceID; } qint64 getMaxSegmentSize() const override { return NLPacket::maxPayloadSize(_packetType, _isOrdered); } @@ -37,7 +37,7 @@ private: PacketVersion _packetVersion; - QUuid _sourceID; + NLPacket::LocalID _sourceID; }; Q_DECLARE_METATYPE(QSharedPointer) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 752d420a4b..4556b441f2 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -659,9 +659,8 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { packetStream >> connectionSecretUUID; - SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, - nodeLocalSocket, isReplicated, false, connectionSecretUUID, permissions); - node->setLocalID(sessionLocalID); + SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, + sessionLocalID, isReplicated, false, connectionSecretUUID, permissions); // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server // and always have their public socket as their active socket diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 27b57ef26c..3d35424316 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -261,10 +261,7 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei SharedNodePointer matchingNode; - if (!receivedMessage->getSourceID().isNull()) { - matchingNode = nodeList->nodeWithUUID(receivedMessage->getSourceID()); - } - + matchingNode = nodeList->nodeWithLocalID(receivedMessage->getSourceID()); QMutexLocker packetListenerLocker(&_packetListenerLock); auto it = _messageListenerMap.find(receivedMessage->getType()); diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index 00b16908ce..e1a036b041 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -43,7 +43,7 @@ ReceivedMessage::ReceivedMessage(NLPacket& packet) } ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, - const HifiSockAddr& senderSockAddr, QUuid sourceID) : + const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID) : _data(byteArray), _headData(_data.mid(0, HEAD_DATA_SIZE)), _numPackets(1), diff --git a/libraries/networking/src/ReceivedMessage.h b/libraries/networking/src/ReceivedMessage.h index ae51e7592a..f94985b7d3 100644 --- a/libraries/networking/src/ReceivedMessage.h +++ b/libraries/networking/src/ReceivedMessage.h @@ -25,7 +25,7 @@ public: ReceivedMessage(const NLPacketList& packetList); ReceivedMessage(NLPacket& packet); ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, - const HifiSockAddr& senderSockAddr, QUuid sourceID = QUuid()); + const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID = 0); QByteArray getMessage() const { return _data; } const char* getRawMessage() const { return _data.constData(); } @@ -40,7 +40,7 @@ public: bool failed() const { return _failed; } bool isComplete() const { return _isComplete; } - const QUuid& getSourceID() const { return _sourceID; } + NLPacket::LocalID getSourceID() const { return _sourceID; } const HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } qint64 getPosition() const { return _position; } @@ -93,7 +93,7 @@ private: std::atomic _position { 0 }; std::atomic _numPackets { 0 }; - QUuid _sourceID; + NLPacket::LocalID _sourceID; PacketType _packetType; PacketVersion _packetVersion; HifiSockAddr _senderSockAddr; diff --git a/libraries/octree/src/OctreeProcessor.cpp b/libraries/octree/src/OctreeProcessor.cpp index 65b30dd197..14c37d5116 100644 --- a/libraries/octree/src/OctreeProcessor.cpp +++ b/libraries/octree/src/OctreeProcessor.cpp @@ -96,7 +96,7 @@ void OctreeProcessor::processDatagram(ReceivedMessage& message, SharedNodePointe quint64 totalUncompress = 0; quint64 totalReadBitsteam = 0; - const QUuid& sourceUUID = message.getSourceID(); + const QUuid& sourceUUID = sourceNode->getUUID(); int subsection = 1; From f27e8868eb730b021c675294ec3ea20619d5f7ce Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:25:12 +1300 Subject: [PATCH 026/174] Add HMD JSDoc --- .../src/scripting/HMDScriptingInterface.h | 257 +++++++++++++++++- .../AbstractHMDScriptingInterface.h | 21 ++ tools/jsdoc/plugins/hifi.js | 5 +- 3 files changed, 278 insertions(+), 5 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index ef8ea95704..1acafab361 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -24,6 +24,36 @@ class QScriptEngine; #include +/**jsdoc + * The HMD API provides access to the HMD used in VR display mode. + * + * @namespace HMD + * @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise + * {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Quat} orientation - The orientation of the HMD if currently in VR display mode, otherwise + * {@link Quat(0)|Quat.IDENTITY}.Read-only. + * @property {boolean} active - true if the display mode is HMD, otherwise false. Read-only. + * @property {boolean} mounted - true if currently in VR display mode and the HMD is being worn, otherwise + * false. Read-only. + * + * @property {number} playerHeight - The real-world height of the user. Read-only. Currently always returns a + * value of 1.755. + * @property {number} eyeHeight - The real-world height of the user's eyes. Read-only. Currently always returns a + * value of 1.655. + * @property {number} ipd - The inter-pupillary distance (distance between eyes) of the user, used for rendering. Defaults to + * the human average of 0.064 unless set by the HMD. Read-only. + * @property {number} ipdScale=1.0 - A scale factor applied to the ipd property value. + * + * @property {boolean} showTablet - true if the tablet is being displayed, false otherwise. + * Read-only. + * @property {boolean} tabletContextualMode - true if the tablet has been opened in contextual mode, otherwise + * false. In contextual mode, the tablet has been opened at a specific world position and orientation rather + * than at a position and orientation relative to the user. Read-only. + * @property {Uuid} tabletID - The UUID of the tablet body model overlay. + * @property {Uuid} tabletScreenID - The UUID of the tablet's screen overlay. + * @property {Uuid} homeButtonID - The UUID of the tablet's "home" button overlay. + * @property {Uuid} homeButtonHighlightID - The UUID of the tablet's "home" button highlight overlay. + */ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition) @@ -37,26 +67,200 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID) public: + + /**jsdoc + * Calculate the intersection of a ray with the HUD overlay. + * @function HMD.calculateRayUICollisionPoint + * @param {Vec3} position - The origin of the ray. + * @param {Vec3} direction - The direction of the ray. + * @returns {Vec3} The point of intersection with the HUD overlay if it intersects, otherwise {@link Vec3(0)|Vec3.ZERO}. + */ Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const; + + /**jsdoc + * Get the 2D HUD overlay coordinates of a 3D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * @function HMD.overlayFromWorldPoint + * @param {Vec3} position - The point on the HUD overlay in world coordinates. + * @returns {Vec2} The point on the HUD overlay in HUD coordinates. + * @example Draw a square on the HUD overlay in the direction you're looking. + * var hudIntersection = HMD.calculateRayUICollisionPoint(MyAvatar.getHeadPosition(), + * Quat.getForward(MyAvatar.headOrientation)); + * var hudPoint = HMD.overlayFromWorldPoint(hudIntersection); + * + * var DIMENSIONS = { x: 50, y: 50 }; + * var square = Overlays.addOverlay("rectangle", { + * x: hudPoint.x - DIMENSIONS.x / 2, + * y: hudPoint.y - DIMENSIONS.y / 2, + * width: DIMENSIONS.x, + * height: DIMENSIONS.y, + * color: { red: 255, green: 0, blue: 0 } + * }); + * + * Script.scriptEnding.connect(function () { + * Overlays.deleteOverlay(square); + * }); + */ Q_INVOKABLE glm::vec2 overlayFromWorldPoint(const glm::vec3& position) const; + + /**jsdoc + * Get the 3D world coordinates of a 2D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * @function HMD.worldPointFromOverlay + * @param {Vec2} coordinates - The point on the HUD overlay in HUD coordinates. + * @returns {Vec3} The point on the HUD overlay in world coordinates. + */ Q_INVOKABLE glm::vec3 worldPointFromOverlay(const glm::vec2& overlay) const; + + /**jsdoc + * Get the 2D point on the HUD overlay represented by given spherical coordinates. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * Spherical coordinates are polar coordinates in radians with { x: 0, y: 0 } being the center of the HUD + * overlay. + * @function HMD.sphericalToOverlay + * @param {Vec2} sphericalPos - The point on the HUD overlay in spherical coordinates. + * @returns {Vec2} The point on the HUD overlay in HUD coordinates. + */ Q_INVOKABLE glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const; + + /**jsdoc + * Get the spherical coordinates of a 2D point on the HUD overlay. + * 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay. + * Spherical coordinates are polar coordinates in radians with { x: 0, y: 0 } being the center of the HUD + * overlay. + * @function HMD.overlayToSpherical + * @param {Vec2} overlayPos - The point on the HUD overlay in HUD coordinates. + * @returns {Vec2} The point on the HUD overlay in spherical coordinates. + */ Q_INVOKABLE glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const; + + /**jsdoc + * Recenter the HMD HUD to the current HMD position and orientation. + * @function HMD.centerUI + */ + Q_INVOKABLE void centerUI(); + + + /**jsdoc + * Get the name of the HMD audio input device. + * @function HMD.preferredAudioInput + * @returns {string} The name of the HMD audio input device if in HMD mode, otherwise an empty string. + */ Q_INVOKABLE QString preferredAudioInput() const; + + /**jsdoc + * Get the name of the HMD audio output device. + * @function HMD.preferredAudioOutput + * @returns {string} The name of the HMD audio output device if in HMD mode, otherwise an empty string. + */ Q_INVOKABLE QString preferredAudioOutput() const; + + /**jsdoc + * Check whether there is an HMD available. + * @function HMD.isHMDAvailable + * @param {string} [name=""] - The name of the HMD to check for, e.g., "Oculus Rift". The name is the same as + * may be displayed in Interface's "Display" menu. If no name is specified then any HMD matches. + * @returns {boolean} true if an HMD of the specified name is available, otherwise + * false. + * @example Report on HMD availability. + * print("Is any HMD available: " + HMD.isHMDAvailable()); + * print("Is an Oculus Rift HMD available: " + HMD.isHMDAvailable("Oculus Rift")); + * print("Is a Vive HMD available: " + HMD.isHMDAvailable("OpenVR (Vive)")); + */ Q_INVOKABLE bool isHMDAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there is an HMD head controller available. + * @function HMD.isHeadControllerAvailable + * @param {string} [name=""] - The name of the HMD head controller to check for, e.g., "Oculus". If no name is + * specified then any HMD head controller matches. + * @returns {boolean} true if an HMD head controller of the specified name is available, + * otherwise false. + * @example Report HMD head controller availability. + * print("Is any HMD head controller available: " + HMD.isHeadControllerAvailable()); + * print("Is an Oculus head controller available: " + HMD.isHeadControllerAvailable("Oculus")); + * print("Is a Vive head controller available: " + HMD.isHeadControllerAvailable("OpenVR")); + */ Q_INVOKABLE bool isHeadControllerAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there are HMD hand controllers available. + * @function HMD.isHandControllerAvailable + * @param {string} [name=""] - The name of the HMD hand controller to check for, e.g., "Oculus". If no name is + * specified then any HMD hand controller matches. + * @returns {boolean} true if an HMD hand controller of the specified name is available, + * otherwise false. + * @example Report HMD hand controller availability. + * print("Are any HMD hand controllers available: " + HMD.isHandControllerAvailable()); + * print("Are Oculus hand controllers available: " + HMD.isHandControllerAvailable("Oculus")); + * print("Are Vive hand controllers available: " + HMD.isHandControllerAvailable("OpenVR")); + */ Q_INVOKABLE bool isHandControllerAvailable(const QString& name = ""); + + /**jsdoc + * Check whether there are specific HMD controllers available. + * @function HMD.isSubdeviceContainingNameAvailable + * @param {string} - The name of the HMD controller to check for, e.g., "OculusTouch". + * @returns {boolean} true if an HMD controller with a name containing the specified name is + * available, otherwise false. + * @example Report if particular Oculus controllers are available. + * print("Is an Oculus Touch controller available: " + HMD.isSubdeviceContainingNameAvailable("Touch")); + * print("Is an Oculus Remote controller available: " + HMD.isSubdeviceContainingNameAvailable("Remote")); + */ Q_INVOKABLE bool isSubdeviceContainingNameAvailable(const QString& name); + /**jsdoc + * Signal that models of the HMD hand controllers being used should be displayed. The models are displayed at their actual, + * real-world locations. + * @function HMD.requestShowHandControllers + * @example Show your hand controllers for 10 seconds. + * HMD.requestShowHandControllers(); + * Script.setTimeout(function () { + * HMD.requestHideHandControllers(); + * }, 10000); + */ Q_INVOKABLE void requestShowHandControllers(); + + /**jsdoc + * Signal that it is no longer necessary to display models of the HMD hand controllers being used. If no other scripts + * want the models displayed then they are no longer displayed. + * @function HMD.requestHideHandControllers + */ Q_INVOKABLE void requestHideHandControllers(); + + /**jsdoc + * Check whether any script wants models of the HMD hand controllers displayed. Requests are made and canceled using + * {@link HMD.requestShowHandControllers|requestShowHandControllers} and + * {@link HMD.requestHideHandControllers|requestHideHandControllers}. + * @function HMD.shouldShowHandControllers + * @returns {boolean} true if any script is requesting that HMD hand controller models be displayed. + */ Q_INVOKABLE bool shouldShowHandControllers() const; + + /**jsdoc + * Causes the borders and decorations in HUD windows to be enlarged when the laser intersects them in HMD mode. By default, + * borders and decorations are not enlarged. + * @function HMD.activateHMDHandMouse + */ Q_INVOKABLE void activateHMDHandMouse(); + + /**jsdoc + * Causes the border and decorations in HUD windows to no longer be enlarged when the laser intersects them in HMD mode. By + * default, borders and decorations are not enlarged. + * @function HMD.deactivateHMDHandMouse + */ Q_INVOKABLE void deactivateHMDHandMouse(); + + /**jsdoc + * Suppress the activation of the HMD-provided keyboard, if any. Successful calls should be balanced with a call to + * {@link HMD.unspressKeyboard|unspressKeyboard} within a reasonable amount of time. + * @function HMD.suppressKeyboard + * @returns {boolean} true if the current HMD provides a keyboard and it was successfully suppressed (e.g., it + * isn't being displayed), otherwise false. + */ /// Suppress the activation of any on-screen keyboard so that a script operation will /// not be interrupted by a keyboard popup /// Returns false if there is already an active keyboard displayed. @@ -65,21 +269,68 @@ public: /// call to unsuppressKeyboard() within a reasonable amount of time Q_INVOKABLE bool suppressKeyboard(); + /**jsdoc + * Unsuppress the activation of the HMD-provided keyboard, if any. + * @function HMD.unsuppressKeyboard + */ /// Enable the keyboard following a suppressKeyboard call Q_INVOKABLE void unsuppressKeyboard(); + /**jsdoc + * Check whether the HMD-provided keyboard, if any, is visible. + * @function HMD.isKeyboardVisible + * @returns {boolean} true if the current HMD provides a keyboard and it is visible, otherwise + * false. + */ /// Query the display plugin to determine the current VR keyboard visibility Q_INVOKABLE bool isKeyboardVisible(); - // rotate the overlay UI sphere so that it is centered about the the current HMD position and orientation - Q_INVOKABLE void centerUI(); - + /**jsdoc + * Closes the tablet if it is open. + * @function HMD.closeTablet + */ Q_INVOKABLE void closeTablet(); + /**jsdoc + * Opens the tablet if the tablet is used in the current display mode and it isn't already showing, and sets the tablet to + * contextual mode if requested. In contextual mode, the page displayed on the tablet is wholly controlled by script (i.e., + * the user cannot navigate to another). + * @function HMD.openTablet + * @param {boolean} [contextualMode=false] - If true then the tablet is opened at a specific position and + * orientation already set by the script, otherwise it opens at a position and orientation relative to the user. For + * contextual mode, set the world or local position and orientation of the HMD.tabletID overlay. + */ Q_INVOKABLE void openTablet(bool contextualMode = false); signals: + /**jsdoc + * Triggered when a request to show or hide models of the HMD hand controllers is made using + * {@link HMD.requestShowHandControllers|requestShowHandControllers} or + * {@link HMD.requestHideHandControllers|requestHideHandControllers}. + * @function HMD.shouldShowHandControllersChanged + * @returns {Signal} + * @example Report when showing of hand controllers changes. + * function onShouldShowHandControllersChanged() { + * print("Should show hand controllers: " + HMD.shouldShowHandControllers()); + * } + * HMD.shouldShowHandControllersChanged.connect(onShouldShowHandControllersChanged); + * + * HMD.requestShowHandControllers(); + * Script.setTimeout(function () { + * HMD.requestHideHandControllers(); + * }, 10000); + */ bool shouldShowHandControllersChanged(); + + /**jsdoc + * Triggered when the HMD.mounted property value changes. + * @function HMD.mountedChanged + * @returns {Signal} + * @example Report when there's a change in the HMD being worn. + * HMD.mountedChanged.connect(function () { + * print("Mounted changed. HMD is mounted: " + HMD.mounted); + * }); + */ void mountedChanged(); public: diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h index f260fa959f..36e1952d3c 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h @@ -12,6 +12,7 @@ #include +// These properties have JSDoc documentation in HMDScriptingInterface.h. class AbstractHMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool active READ isHMDMode) @@ -30,7 +31,27 @@ public: bool isHMDMode() const; signals: + /**jsdoc + * Triggered when the HMD.ipdScale property value changes. + * @function HMD.IPDScaleChanged + * @returns {Signal} + */ void IPDScaleChanged(); + + /**jsdoc + * Triggered when Interface's display mode changes and when the user puts on or takes off their HMD. + * @function HMD.displayModeChanged + * @param {boolean} isHMDMode - true if the display mode is HMD, otherwise false. This is the + * same value as provided by HMD.active. + * @returns {Signal} + * @example Report when the display mode changes. + * HMD.displayModeChanged.connect(function (isHMDMode) { + * print("Display mode changed"); + * print("isHMD = " + isHMD); + * print("HMD.active = " + HMD.active); + * print("HMD.mounted = " + HMD.mounted); + * }); + */ void displayModeChanged(bool isHMDMode); private: diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js index 1f73f14b2b..e4da94ccd5 100644 --- a/tools/jsdoc/plugins/hifi.js +++ b/tools/jsdoc/plugins/hifi.js @@ -24,11 +24,12 @@ exports.handlers = { '../../libraries/animation/src', '../../libraries/avatars/src', '../../libraries/controllers/src/controllers/', - '../../libraries/graphics-scripting/src/graphics-scripting/', + '../../libraries/display-plugins/src/display-plugins/', '../../libraries/entities/src', + '../../libraries/graphics-scripting/src/graphics-scripting/', '../../libraries/model-networking/src/model-networking/', - '../../libraries/octree/src', '../../libraries/networking/src', + '../../libraries/octree/src', '../../libraries/physics/src', '../../libraries/pointers/src', '../../libraries/script-engine/src', From b35ee5ce8aece5472e7b8a650192ff6b6ffa667a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:25:49 +1300 Subject: [PATCH 027/174] Fix JSDoc links to Vec3 constants --- libraries/entities/src/EntityItemProperties.cpp | 16 ++++++++-------- .../entities/src/EntityScriptingInterface.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f9a96d2293..90d6d942fd 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -481,13 +481,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} position=0,0,0 - The position of the entity. * @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates. * @property {Vec3} registrationPoint=0.5,0.5,0.5 - The point in the entity that is set to the entity's position and is rotated - * about, {@link Vec3|Vec3.ZERO} – {@link Vec3|Vec3.ONE}. A value of {@link Vec3|Vec3.ZERO} is the entity's - * minimum x, y, z corner; a value of {@link Vec3|Vec3.ONE} is the entity's maximum x, y, z corner. + * about, {@link Vec3(0)|Vec3.ZERO} – {@link Vec3(0)|Vec3.ONE}. A value of {@link Vec3(0)|Vec3.ZERO} is the entity's + * minimum x, y, z corner; a value of {@link Vec3(0)|Vec3.ONE} is the entity's maximum x, y, z corner. * * @property {Vec3} naturalPosition=0,0,0 - The center of the entity's unscaled mesh model if it has one, otherwise - * {@link Vec3|Vec3.ZERO}. Read-only. + * {@link Vec3(0)|Vec3.ZERO}. Read-only. * @property {Vec3} naturalDimensions - The dimensions of the entity's unscaled mesh model if it has one, otherwise - * {@link Vec3|Vec3.ONE}. Read-only. + * {@link Vec3(0)|Vec3.ONE}. Read-only. * * @property {Vec3} velocity=0,0,0 - The linear velocity of the entity in m/s with respect to world coordinates. * @property {number} damping=0.39347 - How much to slow down the linear velocity of an entity over time, 0.0 @@ -504,13 +504,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s2 that the entity should move with, in * world coordinates. Set to { x: 0, y: -9.8, z: 0 } to simulate Earth's gravity. Gravity is applied to an * entity's motion only if its dynamic property is true. If changing an entity's - * gravity from {@link Vec3|Vec3.ZERO}, you need to give it a small velocity in order to kick off - * physics simulation. + * gravity from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small velocity in order to kick + * off physics simulation. * The gravity value is applied in addition to the acceleration value. * @property {Vec3} acceleration=0,0,0 - A general acceleration in m/s2 that the entity should move with, in world * coordinates. The acceleration is applied to an entity's motion only if its dynamic property is - * true. If changing an entity's acceleration from {@link Vec3|Vec3.ZERO}, you need to give it a - * small velocity in order to kick off physics simulation. + * true. If changing an entity's acceleration from {@link Vec3(0)|Vec3.ZERO}, you need to give it + * a small velocity in order to kick off physics simulation. * The acceleration value is applied in addition to the gravity value. * @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, 0.0 – * 0.99. The higher the value, the more bouncy. diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 9613a7a310..633f427342 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -699,7 +699,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. * @returns {Vec3} The world coordinates of the voxelCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. * @example Create a PolyVox cube with the 0,0,0 voxel replaced by a sphere. * // Cube PolyVox with 0,0,0 voxel missing. * var polyVox = Entities.addEntity({ @@ -734,7 +734,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} worldCoords - The world coordinates. May be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional. */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords); @@ -746,7 +746,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. * @returns {Vec3} The local coordinates of the voxelCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. * @example Get the world dimensions of a voxel in a PolyVox entity. * var polyVox = Entities.addEntity({ * type: "PolyVox", @@ -768,7 +768,7 @@ public slots: * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. * @param {Vec3} localCoords - The local coordinates. May be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a - * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional. */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); From 1bcb9738f0a5ee4e7ed50c6bb5581c2cde50f414 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 28 Mar 2018 12:26:08 +1300 Subject: [PATCH 028/174] Miscellaneous fixes noticed in passing --- interface/resources/qml/windows/Decoration.qml | 2 +- libraries/entities/src/EntityItemProperties.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/windows/Decoration.qml b/interface/resources/qml/windows/Decoration.qml index 843ae25596..f8fd9f4e6c 100644 --- a/interface/resources/qml/windows/Decoration.qml +++ b/interface/resources/qml/windows/Decoration.qml @@ -1,5 +1,5 @@ // -// DefaultFrame.qml +// Decoration.qml // // Created by Bradley Austin Davis on 12 Jan 2016 // Copyright 2016 High Fidelity, Inc. diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 90d6d942fd..8602f60e3d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -476,7 +476,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {boolean} visible=true - Whether or not the entity is rendered. If true then the entity is rendered. * @property {boolean} canCastShadows=true - Whether or not the entity casts shadows. Currently applicable only to * {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities. Shadows are cast if inside a - * {@link Entities.EntityType|Zone} entity with castShadows enabled in its {@link Entities.EntityProperties-Zone|keyLight} property. + * {@link Entities.EntityType|Zone} entity with castShadows enabled in its + * {@link Entities.EntityProperties-Zone|keyLight} property. * * @property {Vec3} position=0,0,0 - The position of the entity. * @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates. From bed403355461834e4768b3dfe459163df7826e6d Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 27 Mar 2018 18:18:14 -0700 Subject: [PATCH 029/174] Local node IDs now working correctly Move typedef to single location; fixes for replicated packets (probably still not correct); reserve zero as local ID; pass domain server's local ID in domain server list; other tweaks. --- assignment-client/src/audio/AudioMixer.cpp | 13 +++++-------- assignment-client/src/avatars/AvatarMixer.cpp | 10 +++------- domain-server/src/DomainGatekeeper.cpp | 2 +- domain-server/src/DomainServer.cpp | 4 +++- interface/src/octree/OctreePacketProcessor.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 4 ++-- libraries/networking/src/NLPacket.h | 4 ++-- libraries/networking/src/NetworkPeer.h | 3 ++- libraries/networking/src/NodeList.cpp | 3 +++ libraries/shared/src/UUID.h | 1 + 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 3b79eab06e..a50304e1d5 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -117,16 +117,13 @@ void AudioMixer::queueAudioPacket(QSharedPointer message, Share void AudioMixer::queueReplicatedAudioPacket(QSharedPointer message) { // make sure we have a replicated node for the original sender of the packet auto nodeList = DependencyManager::get(); - - QUuid nodeID; - SharedNodePointer sourceNode = nodeList->nodeWithLocalID(message->getSourceID()); - if (sourceNode) { - nodeID = sourceNode->getUUID(); - } + + // Node ID is now part of user data, since replicated audio packets are non-sourced. + QUuid nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); auto replicatedNode = nodeList->addOrUpdateNode(nodeID, NodeType::Agent, message->getSenderSockAddr(), message->getSenderSockAddr(), - true, true); + 0, true, true); replicatedNode->setLastHeardMicrostamp(usecTimestampNow()); // construct a "fake" audio received message from the byte array and packet list information @@ -140,7 +137,7 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer mess auto replicatedMessage = QSharedPointer::create(audioData, rewrittenType, versionForPacketType(rewrittenType), - message->getSenderSockAddr(), message->getSourceID()); + message->getSenderSockAddr(), nodeList->getSessionLocalID()); getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode); } diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index b0f1420472..f9f41822a5 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -74,7 +74,7 @@ SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const HifiSockA auto replicatedNode = DependencyManager::get()->addOrUpdateNode(nodeID, NodeType::Agent, senderSockAddr, senderSockAddr, - true, true); + 0, true, true); replicatedNode->setLastHeardMicrostamp(usecTimestampNow()); @@ -112,12 +112,8 @@ void AvatarMixer::handleReplicatedPacket(QSharedPointer message void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer message) { while (message->getBytesLeftToRead()) { // first, grab the node ID for this replicated avatar - QUuid nodeID; - auto nodeList = DependencyManager::get(); - SharedNodePointer sourceNode = nodeList->nodeWithLocalID(message->getSourceID()); - if (sourceNode) { - nodeID = sourceNode->getUUID(); - } + // Node ID is now part of user data, since ReplicatedBulkAvatarPacket is non-sourced. + auto nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); // make sure we have an upstream replicated node that matches auto replicatedNode = addOrUpdateReplicatedNode(nodeID, message->getSenderSockAddr()); diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 917d8a01c0..40130688fb 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -1037,7 +1037,7 @@ Node::LocalID DomainGatekeeper::findOrCreateLocalID(const QUuid& uuid) { do { newLocalID = _currentLocalID; _currentLocalID += _idIncrement; - } while (_localIDToUUID.find(newLocalID) != _localIDToUUID.end()); + } while (newLocalID == 0 || _localIDToUUID.find(newLocalID) != _localIDToUUID.end()); _uuidToLocalID.emplace(uuid, newLocalID); _localIDToUUID.emplace(newLocalID, uuid); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index fee102d66a..4514ed6fd6 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1159,7 +1159,8 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) { } void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) { - const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NUM_BYTES_RFC4122_UUID + 2; + const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + + NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 2; // setup the extended header for the domain list packets // this data is at the beginning of each of the domain list packets @@ -1169,6 +1170,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif auto limitedNodeList = DependencyManager::get(); extendedHeaderStream << limitedNodeList->getSessionUUID(); + extendedHeaderStream << limitedNodeList->getSessionLocalID(); extendedHeaderStream << node->getUUID(); extendedHeaderStream << node->getLocalID(); extendedHeaderStream << node->getPermissions(); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 122b58c057..0c2883a9a4 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -71,7 +71,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag if (message->getVersion() != versionForPacketType(message->getType())) { static QMultiMap versionDebugSuppressMap; - const QUuid& senderUUID = message->getSourceID(); + const QUuid& senderUUID = sendingNode->getUUID(); if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { qDebug() << "Was stats packet? " << wasStatsPacket; diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 77daaa84ea..e1f472e59c 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -315,10 +315,10 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe sourceNode = matchingNode.data(); } - QUuid sourceID = sourceNode->getUUID(); + QUuid sourceID = sourceNode ? sourceNode->getUUID() : QUuid(); if (!sourceNode && - sourceID == getDomainUUID() && + /*sourceID == getDomainUUID() &&*/ packet.getSenderSockAddr() == getDomainSockAddr() && PacketTypeEnum::getDomainSourcedPackets().contains(headerType)) { // This is a packet sourced by the domain server diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index a4690a376c..e3107fae3f 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -43,7 +43,7 @@ public: // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | // NLPacket Header Format - using LocalID = qint16; + using LocalID = NetworkLocalID; static const int NUM_BYTES_LOCALID = sizeof(LocalID); // this is used by the Octree classes - must be known at compile time static const int MAX_PACKET_HEADER_SIZE = @@ -83,7 +83,7 @@ public: LocalID getSourceID() const { return _sourceID; } - void writeSourceID(qint16 sourceID) const; + void writeSourceID(LocalID sourceID) const; void writeVerificationHashGivenSecret(const QUuid& connectionSecret) const; protected: diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index f36db402ce..972d2cbdd7 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -18,6 +18,7 @@ #include #include +#include "UUID.h" #include "HifiSockAddr.h" const QString ICE_SERVER_HOSTNAME = "localhost"; @@ -39,7 +40,7 @@ public: const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; } - using LocalID = quint16; + using LocalID = NetworkLocalID; LocalID getLocalID() const { return _localID; } void setLocalID(LocalID localID) { _localID = localID; } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 4556b441f2..86e3694669 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -594,6 +594,9 @@ void NodeList::processDomainServerList(QSharedPointer message) return; } + Node::LocalID domainLocalID; + packetStream >> domainLocalID; + // pull our owner (ie. session) UUID from the packet, it's always the first thing // The short (16 bit) ID comes next. QUuid newUUID; diff --git a/libraries/shared/src/UUID.h b/libraries/shared/src/UUID.h index 7e7048486f..55ac0866ee 100644 --- a/libraries/shared/src/UUID.h +++ b/libraries/shared/src/UUID.h @@ -15,6 +15,7 @@ #include const int NUM_BYTES_RFC4122_UUID = 16; +using NetworkLocalID = quint16; QString uuidStringWithoutCurlyBraces(const QUuid& uuid); From f823f632115c0d9db4a5a89ac5f82883342b7c91 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 28 Mar 2018 13:27:43 -0700 Subject: [PATCH 030/174] Add domain local ID to DomainServerList Also handle domain local ID for 'domain sourced' packets; bump packet version. --- domain-server/src/DomainServer.cpp | 1 - libraries/networking/src/DomainHandler.h | 4 ++++ libraries/networking/src/LimitedNodeList.cpp | 9 +++------ libraries/networking/src/LimitedNodeList.h | 1 + libraries/networking/src/NodeList.cpp | 1 + libraries/networking/src/NodeList.h | 1 + libraries/networking/src/udt/PacketHeaders.cpp | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 4514ed6fd6..4077becc57 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -593,7 +593,6 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) { if (!PacketTypeEnum::getNonSourcedPackets().contains(headerType)) { // this is a sourced packet - first check if we have a node that matches - //QUuid sourceID = NLPacket::sourceIDInHeader(packet); Node::LocalID localSourceID = NLPacket::sourceIDInHeader(packet); SharedNodePointer sourceNode = nodeList->nodeWithLocalID(localSourceID); diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index fbc60e2492..ef5b3116da 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -45,6 +45,9 @@ public: const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid); + const Node::LocalID getLocalID() const { return _localID; } + void setLocalID(Node::LocalID localID) { _localID = localID; } + QString getHostname() const { return _domainURL.host(); } const QHostAddress& getIP() const { return _sockAddr.getAddress(); } @@ -181,6 +184,7 @@ private: void hardReset(); QUuid _uuid; + Node::LocalID _localID; QUrl _domainURL; HifiSockAddr _sockAddr; QUuid _assignmentUUID; diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index e1f472e59c..31345c3c14 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -305,11 +305,11 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; } } else { - + NLPacket::LocalID sourceLocalID = 0; // check if we were passed a sourceNode hint or if we need to look it up if (!sourceNode) { // figure out which node this is from - NLPacket::LocalID sourceLocalID = NLPacket::sourceIDInHeader(packet); + sourceLocalID = NLPacket::sourceIDInHeader(packet); SharedNodePointer matchingNode = nodeWithLocalID(sourceLocalID); sourceNode = matchingNode.data(); @@ -318,7 +318,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe QUuid sourceID = sourceNode ? sourceNode->getUUID() : QUuid(); if (!sourceNode && - /*sourceID == getDomainUUID() &&*/ + sourceLocalID == getDomainLocalID() && packet.getSenderSockAddr() == getDomainSockAddr() && PacketTypeEnum::getDomainSourcedPackets().contains(headerType)) { // This is a packet sourced by the domain server @@ -567,9 +567,6 @@ SharedNodePointer LimitedNodeList::nodeWithLocalID(Node::LocalID localID) const QReadLocker readLocker(&_nodeMutex); LocalIDMapping::const_iterator idIter = _localIDMap.find(localID); - if (idIter == _localIDMap.cend()) { - qCDebug(networking) << "No such Node with local ID " << localID; - } return idIter == _localIDMap.cend() ? nullptr : idIter->second; } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 51c8831e2b..95d0e8b559 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -128,6 +128,7 @@ public: virtual bool isDomainServer() const { return true; } virtual QUuid getDomainUUID() const { assert(false); return QUuid(); } + virtual Node::LocalID getDomainLocalID() const { assert(false); return 0; } virtual HifiSockAddr getDomainSockAddr() const { assert(false); return HifiSockAddr(); } // use sendUnreliablePacket to send an unrelaible packet (that you do not need to move) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 86e3694669..4b3595b279 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -608,6 +608,7 @@ void NodeList::processDomainServerList(QSharedPointer message) // if this was the first domain-server list from this domain, we've now connected if (!_domainHandler.isConnected()) { + _domainHandler.setLocalID(newLocalID); _domainHandler.setUUID(domainUUID); _domainHandler.setIsConnected(true); diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 7e3a7c2bd7..9595c5da84 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -94,6 +94,7 @@ public: virtual bool isDomainServer() const override { return false; } virtual QUuid getDomainUUID() const override { return _domainHandler.getUUID(); } + virtual Node::LocalID getDomainLocalID() const override { return _domainHandler.getLocalID(); } virtual HifiSockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); } public slots: diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a83924ee58..8a3592de45 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -76,7 +76,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::DomainSettings: return 18; // replace min_avatar_scale and max_avatar_scale with min_avatar_height and max_avatar_height default: - return 17; + return 19; } } From b409e04734d4240968fe221981ceac70fd659630 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 28 Mar 2018 17:42:23 -0700 Subject: [PATCH 031/174] Handle all case of nodes being deleted from nodelist Delete erased nodes from local ID mapping, as this uses SharedPointer. Don't keep the mapping from local IDs to UUIDs in GateKeeper as it isn't used. --- domain-server/src/DomainGatekeeper.cpp | 6 ++++-- domain-server/src/DomainGatekeeper.h | 5 +++-- domain-server/src/DomainServer.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 4 ++++ libraries/networking/src/NLPacket.h | 18 +++++++++++++++++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 40130688fb..fb3c305b84 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -1033,13 +1033,15 @@ Node::LocalID DomainGatekeeper::findOrCreateLocalID(const QUuid& uuid) { return existingLocalIDIt->second; } + assert(_localIDs.size() < std::numeric_limits::max() - 2); + Node::LocalID newLocalID; do { newLocalID = _currentLocalID; _currentLocalID += _idIncrement; - } while (newLocalID == 0 || _localIDToUUID.find(newLocalID) != _localIDToUUID.end()); + } while (newLocalID == 0 || _localIDs.find(newLocalID) != _localIDs.end()); _uuidToLocalID.emplace(uuid, newLocalID); - _localIDToUUID.emplace(newLocalID, uuid); + _localIDs.insert(newLocalID); return newLocalID; } diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index afb848f271..edd976a77b 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -15,6 +15,7 @@ #define hifi_DomainGatekeeper_h #include +#include #include #include @@ -129,9 +130,9 @@ private: size_t operator()(const QUuid& uuid) const { return qHash(uuid); } }; using UUIDToLocalID = std::unordered_map ; - using LocalIDToUUID = std::unordered_map; + using LocalIDs = std::unordered_set; + LocalIDs _localIDs; UUIDToLocalID _uuidToLocalID; - LocalIDToUUID _localIDToUUID; Node::LocalID _currentLocalID; quint16 _idIncrement; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 4077becc57..77f25d4c7e 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2905,7 +2905,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction) // manually add the replication node to our node list auto node = nodeList->addOrUpdateNode(QUuid::createUuid(), replicationServer.nodeType, replicationServer.sockAddr, replicationServer.sockAddr, - false, direction == Upstream); + 0, false, direction == Upstream); node->setIsForcedNeverSilent(true); qDebug() << "Adding" << (direction == Upstream ? "upstream" : "downstream") diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 31345c3c14..6ef119bf3b 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -695,6 +695,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t auto oldSoloNode = previousSoloIt->second; + _localIDMap.erase(oldSoloNode->getLocalID()); _nodeHash.unsafe_erase(previousSoloIt); handleNodeKill(oldSoloNode); @@ -850,6 +851,9 @@ void LimitedNodeList::removeSilentNodes() { }); foreach(const SharedNodePointer& killedNode, killedNodes) { + _nodeMutex.lockForWrite(); + _localIDMap.erase(killedNode->getLocalID()); + _nodeMutex.unlock(); handleNodeKill(killedNode); } } diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index e3107fae3f..a994b7bde0 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -21,6 +21,22 @@ class NLPacket : public udt::Packet { Q_OBJECT public: + // + // Current NLPacket format: + // + // | BYTE | BYTE | BYTE | BYTE | + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Packet Type | Version | Local Node ID - sourced only | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | | + // | MD5 Verification - 16 bytes | + // | (ONLY FOR VERIFIED PACKETS) | + // | | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + // Old NLPacket format: // // | BYTE | BYTE | BYTE | BYTE | // @@ -41,7 +57,7 @@ public: // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | - // NLPacket Header Format + // using LocalID = NetworkLocalID; static const int NUM_BYTES_LOCALID = sizeof(LocalID); From 1b0b280f3a17d55f5a55e043066c768dcd56d9eb Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 29 Mar 2018 10:47:11 -0700 Subject: [PATCH 032/174] Fix SequenceNumberStats, misc. clean-up --- domain-server/src/DomainGatekeeper.cpp | 2 +- domain-server/src/DomainGatekeeper.h | 2 +- domain-server/src/DomainServer.cpp | 2 +- libraries/audio/src/InboundAudioStream.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/networking/src/SequenceNumberStats.cpp | 12 ++++++------ libraries/networking/src/SequenceNumberStats.h | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index fb3c305b84..b4ce467e0a 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -1021,7 +1021,7 @@ void DomainGatekeeper::refreshGroupsCache() { void DomainGatekeeper::initLocalIDManagement() { std::uniform_int_distribution sixteenBitRand; std::random_device randomDevice; - std::default_random_engine engine {randomDevice()}; + std::default_random_engine engine { randomDevice() }; _currentLocalID = sixteenBitRand(engine); // Ensure increment is odd. _idIncrement = sixteenBitRand(engine) | 1; diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index edd976a77b..ec7ec5701f 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -135,7 +135,7 @@ private: UUIDToLocalID _uuidToLocalID; Node::LocalID _currentLocalID; - quint16 _idIncrement; + Node::LocalID _idIncrement; }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 77f25d4c7e..7265dff15c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1159,7 +1159,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) { void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) { const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + - NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 2; + NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4; // setup the extended header for the domain list packets // this data is at the beginning of each of the domain list packets diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 983b5e1cb8..172ec9411a 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -120,8 +120,8 @@ int InboundAudioStream::parseData(ReceivedMessage& message) { // parse sequence number and track it quint16 sequence; message.readPrimitive(&sequence); - SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, QUuid() // TBD - /*message.getSourceID()*/); + SequenceNumberStats::ArrivalInfo arrivalInfo = + _incomingSequenceNumberStats.sequenceNumberReceived(sequence, message.getSourceID()); QString codecInPacket = message.readString(); packetReceivedUpdateTimingStats(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 6ef119bf3b..177bc729cd 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -136,7 +136,7 @@ Node::LocalID LimitedNodeList::getSessionLocalID() const { } void LimitedNodeList::setSessionLocalID(Node::LocalID sessionLocalID) { - QWriteLocker lock { &_sessionUUIDLock }; // Necessary? + QWriteLocker lock { &_sessionUUIDLock }; _sessionLocalID = sessionLocalID; } diff --git a/libraries/networking/src/SequenceNumberStats.cpp b/libraries/networking/src/SequenceNumberStats.cpp index 6d7b271606..052cdf1a4e 100644 --- a/libraries/networking/src/SequenceNumberStats.cpp +++ b/libraries/networking/src/SequenceNumberStats.cpp @@ -25,7 +25,7 @@ SequenceNumberStats::SequenceNumberStats(int statsHistoryLength, bool canDetectO : _lastReceivedSequence(0), _missingSet(), _stats(), - _lastSenderUUID(), + _lastSenderID(0), _statsHistory(statsHistoryLength), _lastUnreasonableSequence(0), _consecutiveUnreasonableOnTime(0) @@ -35,7 +35,7 @@ SequenceNumberStats::SequenceNumberStats(int statsHistoryLength, bool canDetectO void SequenceNumberStats::reset() { _missingSet.clear(); _stats = PacketStreamStats(); - _lastSenderUUID = QUuid(); + _lastSenderID = 0; _statsHistory.clear(); _lastUnreasonableSequence = 0; _consecutiveUnreasonableOnTime = 0; @@ -43,18 +43,18 @@ void SequenceNumberStats::reset() { static const int UINT16_RANGE = std::numeric_limits::max() + 1; -SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderUUID, const bool wantExtraDebugging) { +SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(quint16 incoming, NetworkLocalID senderID, const bool wantExtraDebugging) { SequenceNumberStats::ArrivalInfo arrivalInfo; // if the sender node has changed, reset all stats - if (senderUUID != _lastSenderUUID) { + if (senderID != _lastSenderID) { if (_stats._received > 0) { qCDebug(networking) << "sequence number stats was reset due to new sender node"; - qCDebug(networking) << "previous:" << _lastSenderUUID << "current:" << senderUUID; + qCDebug(networking) << "previous:" << _lastSenderID << "current:" << senderID; reset(); } - _lastSenderUUID = senderUUID; + _lastSenderID = senderID; } // determine our expected sequence number... handle rollover appropriately diff --git a/libraries/networking/src/SequenceNumberStats.h b/libraries/networking/src/SequenceNumberStats.h index 46149d4307..ba9db2a225 100644 --- a/libraries/networking/src/SequenceNumberStats.h +++ b/libraries/networking/src/SequenceNumberStats.h @@ -14,7 +14,7 @@ #include "SharedUtil.h" #include "RingBufferHistory.h" -#include +#include "UUID.h" const int MAX_REASONABLE_SEQUENCE_GAP = 1000; @@ -73,7 +73,7 @@ public: SequenceNumberStats(int statsHistoryLength = 0, bool canDetectOutOfSync = true); void reset(); - ArrivalInfo sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false); + ArrivalInfo sequenceNumberReceived(quint16 incoming, NetworkLocalID senderID = 0, const bool wantExtraDebugging = false); void pruneMissingSet(const bool wantExtraDebugging = false); void pushStatsToHistory() { _statsHistory.insert(_stats); } @@ -100,7 +100,7 @@ private: PacketStreamStats _stats; - QUuid _lastSenderUUID; + NetworkLocalID _lastSenderID; RingBufferHistory _statsHistory; From e9ec4df36f75ff54577c9ddcb76a5032077a18fe Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 29 Mar 2018 14:10:31 -0700 Subject: [PATCH 033/174] Gcc complained about superfluous const qualifier --- libraries/networking/src/DomainHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index ef5b3116da..c447e9a79b 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -45,7 +45,7 @@ public: const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid); - const Node::LocalID getLocalID() const { return _localID; } + Node::LocalID getLocalID() const { return _localID; } void setLocalID(Node::LocalID localID) { _localID = localID; } QString getHostname() const { return _domainURL.host(); } From 734b48eee0f02ad8a0b30f4ad6fd5908d2feaa44 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 30 Mar 2018 17:27:52 -0700 Subject: [PATCH 034/174] Local IDs - Reviewer's suggested improvements --- assignment-client/src/audio/AudioMixer.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 10 ++++---- libraries/networking/src/NLPacket.h | 24 +------------------- libraries/networking/src/PacketReceiver.cpp | 4 +++- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index a50304e1d5..a18df68f90 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -137,7 +137,7 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer mess auto replicatedMessage = QSharedPointer::create(audioData, rewrittenType, versionForPacketType(rewrittenType), - message->getSenderSockAddr(), nodeList->getSessionLocalID()); + message->getSenderSockAddr(), message->getSourceID()); getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode); } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 177bc729cd..c30952c344 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -132,6 +132,7 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) { } Node::LocalID LimitedNodeList::getSessionLocalID() const { + QReadLocker readLock { &_sessionUUIDLock }; return _sessionLocalID; } @@ -578,7 +579,7 @@ void LimitedNodeList::eraseAllNodes() { // and then remove them from the hash QWriteLocker writeLocker(&_nodeMutex); - _localIDMap.erase(_localIDMap.begin(), _localIDMap.end()); + _localIDMap.clear(); if (_nodeHash.size() > 0) { qCDebug(networking) << "LimitedNodeList::eraseAllNodes() removing all nodes from NodeList."; @@ -851,9 +852,10 @@ void LimitedNodeList::removeSilentNodes() { }); foreach(const SharedNodePointer& killedNode, killedNodes) { - _nodeMutex.lockForWrite(); - _localIDMap.erase(killedNode->getLocalID()); - _nodeMutex.unlock(); + { + QWriteLocker writeLock { &_nodeMutex }; + _localIDMap.erase(killedNode->getLocalID()); + } handleNodeKill(killedNode); } } diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index a994b7bde0..b9c598500b 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -22,7 +22,7 @@ class NLPacket : public udt::Packet { Q_OBJECT public: // - // Current NLPacket format: + // NLPacket format: // // | BYTE | BYTE | BYTE | BYTE | // 0 1 2 3 @@ -35,28 +35,6 @@ public: // | (ONLY FOR VERIFIED PACKETS) | // | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - // Old NLPacket format: - // - // | BYTE | BYTE | BYTE | BYTE | - // - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | Packet Type | Version | | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | - // | | - // | Node UUID - 16 bytes | - // | (ONLY FOR SOURCED PACKETS) | - // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | | | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | - // | | - // | MD5 Verification - 16 bytes | - // | (ONLY FOR VERIFIED PACKETS) | - // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | | | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | // using LocalID = NetworkLocalID; diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 3d35424316..39a3800c4b 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -261,7 +261,9 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei SharedNodePointer matchingNode; - matchingNode = nodeList->nodeWithLocalID(receivedMessage->getSourceID()); + if (receivedMessage->getSourceID() != 0) { + matchingNode = nodeList->nodeWithLocalID(receivedMessage->getSourceID()); + } QMutexLocker packetListenerLocker(&_packetListenerLock); auto it = _messageListenerMap.find(receivedMessage->getType()); From efb1fdbc0d2597ff96e60292eff93cac454d9bf6 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 30 Mar 2018 18:29:26 -0700 Subject: [PATCH 035/174] Local IDs - add an explicit null value, use it for replicated packets --- assignment-client/src/audio/AudioMixer.cpp | 2 +- assignment-client/src/avatars/AvatarMixer.cpp | 2 +- domain-server/src/DomainGatekeeper.cpp | 2 +- libraries/networking/src/NLPacket.h | 2 ++ libraries/networking/src/NetworkPeer.h | 2 ++ libraries/networking/src/ReceivedMessage.h | 4 ++-- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index a18df68f90..d47172f62e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -137,7 +137,7 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer mess auto replicatedMessage = QSharedPointer::create(audioData, rewrittenType, versionForPacketType(rewrittenType), - message->getSenderSockAddr(), message->getSourceID()); + message->getSenderSockAddr(), Node::NULL_LOCAL_ID); getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode); } diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index f9f41822a5..25bbc4cd0a 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -127,7 +127,7 @@ void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer::create(avatarByteArray, PacketType::AvatarData, versionForPacketType(PacketType::AvatarData), - message->getSenderSockAddr(), message->getSourceID()); + message->getSenderSockAddr(), Node::NULL_LOCAL_ID); // queue up the replicated avatar data with the client data for the replicated node auto start = usecTimestampNow(); diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index b4ce467e0a..25317bf44b 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -1039,7 +1039,7 @@ Node::LocalID DomainGatekeeper::findOrCreateLocalID(const QUuid& uuid) { do { newLocalID = _currentLocalID; _currentLocalID += _idIncrement; - } while (newLocalID == 0 || _localIDs.find(newLocalID) != _localIDs.end()); + } while (newLocalID == Node::NULL_LOCAL_ID || _localIDs.find(newLocalID) != _localIDs.end()); _uuidToLocalID.emplace(uuid, newLocalID); _localIDs.insert(newLocalID); diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index b9c598500b..edd03627c3 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -38,6 +38,8 @@ public: // using LocalID = NetworkLocalID; + static const LocalID NULL_LOCAL_ID = 0; + static const int NUM_BYTES_LOCALID = sizeof(LocalID); // this is used by the Octree classes - must be known at compile time static const int MAX_PACKET_HEADER_SIZE = diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index 972d2cbdd7..462daa1ed2 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -41,6 +41,8 @@ public: void setUUID(const QUuid& uuid) { _uuid = uuid; } using LocalID = NetworkLocalID; + static const LocalID NULL_LOCAL_ID = 0; + LocalID getLocalID() const { return _localID; } void setLocalID(LocalID localID) { _localID = localID; } diff --git a/libraries/networking/src/ReceivedMessage.h b/libraries/networking/src/ReceivedMessage.h index f94985b7d3..af87ef75af 100644 --- a/libraries/networking/src/ReceivedMessage.h +++ b/libraries/networking/src/ReceivedMessage.h @@ -25,7 +25,7 @@ public: ReceivedMessage(const NLPacketList& packetList); ReceivedMessage(NLPacket& packet); ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, - const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID = 0); + const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID = NLPacket::NULL_LOCAL_ID); QByteArray getMessage() const { return _data; } const char* getRawMessage() const { return _data.constData(); } @@ -93,7 +93,7 @@ private: std::atomic _position { 0 }; std::atomic _numPackets { 0 }; - NLPacket::LocalID _sourceID; + NLPacket::LocalID _sourceID { NLPacket::NULL_LOCAL_ID }; PacketType _packetType; PacketVersion _packetVersion; HifiSockAddr _senderSockAddr; From f4bd1f5ed7130d3272a45f5f6dfbc8253ae542be Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 2 Apr 2018 09:45:46 -0700 Subject: [PATCH 036/174] Add definition for NetworkPeer::NULL_LOCAL_ID to (hopefully) satisfy MacOS --- libraries/networking/src/NetworkPeer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index b52c54c468..6d384ba558 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -23,6 +23,7 @@ #include #include "NodeType.h" +const NetworkPeer::LocalID NetworkPeer::NULL_LOCAL_ID; NetworkPeer::NetworkPeer(QObject* parent) : QObject(parent), From 2ba64e111509e2d3c77c2b860120856806f7648e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 2 Apr 2018 10:46:38 -0700 Subject: [PATCH 037/174] LocalID - Use tbb hash map instead of std one for better concurrency --- libraries/networking/src/LimitedNodeList.cpp | 7 ++----- libraries/networking/src/LimitedNodeList.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c30952c344..ec2e107567 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -696,7 +696,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t auto oldSoloNode = previousSoloIt->second; - _localIDMap.erase(oldSoloNode->getLocalID()); + _localIDMap.unsafe_erase(oldSoloNode->getLocalID()); _nodeHash.unsafe_erase(previousSoloIt); handleNodeKill(oldSoloNode); @@ -840,6 +840,7 @@ void LimitedNodeList::removeSilentNodes() { if (!node->isForcedNeverSilent() && (usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * USECS_PER_MSEC)) { // call the NodeHash erase to get rid of this node + _localIDMap.unsafe_erase(node->getLocalID()); it = _nodeHash.unsafe_erase(it); killedNodes.insert(node); @@ -852,10 +853,6 @@ void LimitedNodeList::removeSilentNodes() { }); foreach(const SharedNodePointer& killedNode, killedNodes) { - { - QWriteLocker writeLock { &_nodeMutex }; - _localIDMap.erase(killedNode->getLocalID()); - } handleNodeKill(killedNode); } } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 95d0e8b559..6c61fbc43c 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -431,7 +431,7 @@ private slots: private: mutable QReadWriteLock _sessionUUIDLock; QUuid _sessionUUID; - using LocalIDMapping = std::unordered_map; + using LocalIDMapping = tbb::concurrent_unordered_map; LocalIDMapping _localIDMap; Node::LocalID _sessionLocalID { 0 }; }; From 6d078f41e783007a1c51f16a34a9746e569621d7 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 2 Apr 2018 17:32:18 -0700 Subject: [PATCH 038/174] Use unique IDs for log strings that should have repeats supressed --- libraries/networking/src/LimitedNodeList.cpp | 15 ++++--- libraries/shared/src/LogHandler.cpp | 41 +++++++++++++++++++- libraries/shared/src/LogHandler.h | 5 +++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0803e380f2..d73ea8ca9c 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -345,12 +345,17 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; } else { - static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with UUID"; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); + //static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with UUID"; + //static QString repeatedMessage + // = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); + //qCDebug(networking) << "Packet of type" << headerType + // << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); - qCDebug(networking) << "Packet of type" << headerType - << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); + static const int repeatedIDUnknownNode = LogHandler::getInstance().newRepeatedMessageID(); + QString logString; + QDebug debugString(&logString); + debugString << "Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); + LogHandler::getInstance().printRepeatedMessage(repeatedIDUnknownNode, LogDebug, QMessageLogContext(), logString); } } diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 49927a325b..6b89307ddf 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -25,7 +25,7 @@ #include #include -QMutex LogHandler::_mutex; +QMutex LogHandler::_mutex(QMutex::Recursive); LogHandler& LogHandler::getInstance() { static LogHandler staticInstance; @@ -107,13 +107,25 @@ void LogHandler::flushRepeatedMessages() { message.messageCount = 0; } + + // New repeat-supress scheme: + for (int m = 0; m < (int)_repeatCounts.size(); ++m) { + int repeatCount = _repeatCounts[m]; + if (m > 1) { + QString repeatLogMessage = QString(m) + " repeated log entries - Last entry: \"" + _repeatedMessageStrings[m] + + "\""; + printMessage(LogSuppressed, QMessageLogContext(), repeatLogMessage); + _repeatCounts[m] = 0; + _repeatedMessageStrings[m] = QString(); + } + } } QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& context, const QString& message) { - QMutexLocker lock(&_mutex); if (message.isEmpty()) { return QString(); } + QMutexLocker lock(&_mutex); if (type == LogDebug) { // for debug messages, check if this matches any of our regexes for repeated log messages @@ -217,3 +229,28 @@ const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) { _onetimeMessages.push_back(onetimeMessage); return regexString; } + +int LogHandler::newRepeatedMessageID() { + QMutexLocker lock(&_mutex); + int newMessageId = _currentMessageID; + ++_currentMessageID; + _repeatCounts.push_back(0); + _repeatedMessageStrings.resize(_currentMessageID); + return newMessageId; +} + +void LogHandler::printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext & context, + const QString & message) { + QMutexLocker lock(&_mutex); + if (messageID >= _currentMessageID) { + return; + } + + if (_repeatCounts[messageID] == 0) { + printMessage(type, context, message); + } else { + _repeatedMessageStrings[messageID] = message; + } + + ++_repeatCounts[messageID]; +} diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 2e64f16c1e..7b459538ad 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -53,6 +53,8 @@ public: const QString& addRepeatedMessageRegex(const QString& regexString); const QString& addOnlyOnceMessageRegex(const QString& regexString); + int newRepeatedMessageID(); + void printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext& context, const QString &message); private slots: void setupRepeatedMessageFlusher(); @@ -81,6 +83,9 @@ private: }; std::vector _onetimeMessages; + int _currentMessageID { 0 }; + std::vector _repeatCounts; + std::vector _repeatedMessageStrings; static QMutex _mutex; }; From d1cb4aab89a0220e82a76f301d16ebc8b555e6d5 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 2 Apr 2018 17:55:23 -0700 Subject: [PATCH 039/174] Make BakedAssetType a scoped enum --- assignment-client/src/assets/AssetServer.cpp | 26 ++++++++++---------- assignment-client/src/assets/AssetServer.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 1eb43a45a5..b2fb74f77d 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -61,13 +61,13 @@ static const ScriptBakeVersion CURRENT_SCRIPT_BAKE_VERSION = (ScriptBakeVersion) BakedAssetType assetTypeForExtension(const QString& extension) { auto extensionLower = extension.toLower(); if (BAKEABLE_MODEL_EXTENSIONS.contains(extensionLower)) { - return Model; + return BakedAssetType::Model; } else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extensionLower.toLocal8Bit())) { - return Texture; + return BakedAssetType::Texture; } else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extensionLower)) { - return Script; + return BakedAssetType::Script; } - return Undefined; + return BakedAssetType::Undefined; } BakedAssetType assetTypeForFilename(const QString& filename) { @@ -82,11 +82,11 @@ BakedAssetType assetTypeForFilename(const QString& filename) { QString bakedFilenameForAssetType(BakedAssetType type) { switch (type) { - case Model: + case BakedAssetType::Model: return BAKED_MODEL_SIMPLE_NAME; - case Texture: + case BakedAssetType::Texture: return BAKED_TEXTURE_SIMPLE_NAME; - case Script: + case BakedAssetType::Script: return BAKED_SCRIPT_SIMPLE_NAME; default: return ""; @@ -95,11 +95,11 @@ QString bakedFilenameForAssetType(BakedAssetType type) { BakeVersion currentBakeVersionForAssetType(BakedAssetType type) { switch (type) { - case Model: + case BakedAssetType::Model: return (BakeVersion)CURRENT_MODEL_BAKE_VERSION; - case Texture: + case BakedAssetType::Texture: return (BakeVersion)CURRENT_TEXTURE_BAKE_VERSION; - case Script: + case BakedAssetType::Script: return (BakeVersion)CURRENT_SCRIPT_BAKE_VERSION; default: return 0; @@ -222,7 +222,7 @@ bool AssetServer::needsToBeBaked(const AssetUtils::AssetPath& path, const AssetU BakedAssetType type = assetTypeForFilename(path); - if (type == Undefined) { + if (type == BakedAssetType::Undefined) { return false; } @@ -241,7 +241,7 @@ bool AssetServer::needsToBeBaked(const AssetUtils::AssetPath& path, const AssetU AssetMeta meta; std::tie(loaded, meta) = readMetaFile(assetHash); - if (type == Texture && !loaded) { + if (type == BakedAssetType::Texture && !loaded) { return false; } @@ -1546,7 +1546,7 @@ bool AssetServer::setBakingEnabled(const AssetUtils::AssetPathList& paths, bool auto it = _fileMappings.find(path); if (it != _fileMappings.end()) { auto type = assetTypeForFilename(path); - if (type == Undefined) { + if (type == BakedAssetType::Undefined) { continue; } QString bakedFilename = bakedFilenameForAssetType(type); diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index a55a15e6fc..fb88df0171 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -27,7 +27,7 @@ using BakeVersion = int; static const BakeVersion INITIAL_BAKE_VERSION = 0; static const BakeVersion NEEDS_BAKING_BAKE_VERSION = -1; -enum BakedAssetType : int { +enum class BakedAssetType : int { Model = 0, Texture, Script, From a7fc6a299176109a669329beff643b54199798f5 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 3 Apr 2018 10:44:53 -0700 Subject: [PATCH 040/174] Repeated logs - use #define to replace qCDebug --- libraries/networking/src/LimitedNodeList.cpp | 7 ++----- libraries/networking/src/NetworkLogging.h | 11 +++++++++++ libraries/shared/src/LogHandler.cpp | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index d73ea8ca9c..c6451fa955 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -351,11 +351,8 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe //qCDebug(networking) << "Packet of type" << headerType // << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); - static const int repeatedIDUnknownNode = LogHandler::getInstance().newRepeatedMessageID(); - QString logString; - QDebug debugString(&logString); - debugString << "Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); - LogHandler::getInstance().printRepeatedMessage(repeatedIDUnknownNode, LogDebug, QMessageLogContext(), logString); + HIFI_FDEBUG(networking, + "Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); } } diff --git a/libraries/networking/src/NetworkLogging.h b/libraries/networking/src/NetworkLogging.h index 518c600efe..6b54dd2640 100644 --- a/libraries/networking/src/NetworkLogging.h +++ b/libraries/networking/src/NetworkLogging.h @@ -20,4 +20,15 @@ Q_DECLARE_LOGGING_CATEGORY(asset_client) Q_DECLARE_LOGGING_CATEGORY(entity_script_client) Q_DECLARE_LOGGING_CATEGORY(messages_client) +#define HIFI_FDEBUG(category, msg) \ + do { \ + if (category().isDebugEnabled()) { \ + static int repeatedMessageID_ = LogHandler::getInstance().newRepeatedMessageID(); \ + QString logString_; \ + QDebug debugString_(&logString_); \ + debugString_ << msg; \ + LogHandler::getInstance().printRepeatedMessage(repeatedMessageID_, LogDebug, QMessageLogContext(), logString_); \ + } \ + } while (false) + #endif // hifi_NetworkLogging_h diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 6b89307ddf..2494711613 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -111,8 +111,8 @@ void LogHandler::flushRepeatedMessages() { // New repeat-supress scheme: for (int m = 0; m < (int)_repeatCounts.size(); ++m) { int repeatCount = _repeatCounts[m]; - if (m > 1) { - QString repeatLogMessage = QString(m) + " repeated log entries - Last entry: \"" + _repeatedMessageStrings[m] + if (repeatCount > 1) { + QString repeatLogMessage = QString(repeatCount) + " repeated log entries - Last entry: \"" + _repeatedMessageStrings[m] + "\""; printMessage(LogSuppressed, QMessageLogContext(), repeatLogMessage); _repeatCounts[m] = 0; From 5b0bcd76e3de36379d2c08a9dd871992429861d0 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 3 Apr 2018 12:23:21 -0700 Subject: [PATCH 041/174] Repeated logging - Fixes and clean-up --- libraries/networking/src/NetworkLogging.h | 3 ++- libraries/shared/src/LogHandler.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/NetworkLogging.h b/libraries/networking/src/NetworkLogging.h index 6b54dd2640..fa2b24462a 100644 --- a/libraries/networking/src/NetworkLogging.h +++ b/libraries/networking/src/NetworkLogging.h @@ -27,7 +27,8 @@ Q_DECLARE_LOGGING_CATEGORY(messages_client) QString logString_; \ QDebug debugString_(&logString_); \ debugString_ << msg; \ - LogHandler::getInstance().printRepeatedMessage(repeatedMessageID_, LogDebug, QMessageLogContext(), logString_); \ + LogHandler::getInstance().printRepeatedMessage(repeatedMessageID_, LogDebug, QMessageLogContext(__FILE__, \ + __LINE__, __func__, category().categoryName()), logString_); \ } \ } while (false) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 2494711613..b5a0f069e9 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -112,8 +112,8 @@ void LogHandler::flushRepeatedMessages() { for (int m = 0; m < (int)_repeatCounts.size(); ++m) { int repeatCount = _repeatCounts[m]; if (repeatCount > 1) { - QString repeatLogMessage = QString(repeatCount) + " repeated log entries - Last entry: \"" + _repeatedMessageStrings[m] - + "\""; + QString repeatLogMessage = QString().setNum(repeatCount) + " repeated log entries - Last entry: \"" + + _repeatedMessageStrings[m] + "\""; printMessage(LogSuppressed, QMessageLogContext(), repeatLogMessage); _repeatCounts[m] = 0; _repeatedMessageStrings[m] = QString(); @@ -239,8 +239,8 @@ int LogHandler::newRepeatedMessageID() { return newMessageId; } -void LogHandler::printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext & context, - const QString & message) { +void LogHandler::printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext& context, + const QString& message) { QMutexLocker lock(&_mutex); if (messageID >= _currentMessageID) { return; From d4ab06b1d4b95df3ede52eac8c8ecd9190f17dc1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 3 Apr 2018 15:53:12 -0700 Subject: [PATCH 042/174] Move HIFI_FDEBUG macro to LogHandler.h Not all uses of repeated log messages include NetworkLogging.h, but if they use addRepeatedMessageRegex() they must include LogHandler.h. Also add second macro for client-supplied message ID. --- libraries/networking/src/NetworkLogging.h | 12 ------------ libraries/shared/src/LogHandler.h | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/NetworkLogging.h b/libraries/networking/src/NetworkLogging.h index fa2b24462a..518c600efe 100644 --- a/libraries/networking/src/NetworkLogging.h +++ b/libraries/networking/src/NetworkLogging.h @@ -20,16 +20,4 @@ Q_DECLARE_LOGGING_CATEGORY(asset_client) Q_DECLARE_LOGGING_CATEGORY(entity_script_client) Q_DECLARE_LOGGING_CATEGORY(messages_client) -#define HIFI_FDEBUG(category, msg) \ - do { \ - if (category().isDebugEnabled()) { \ - static int repeatedMessageID_ = LogHandler::getInstance().newRepeatedMessageID(); \ - QString logString_; \ - QDebug debugString_(&logString_); \ - debugString_ << msg; \ - LogHandler::getInstance().printRepeatedMessage(repeatedMessageID_, LogDebug, QMessageLogContext(__FILE__, \ - __LINE__, __func__, category().categoryName()), logString_); \ - } \ - } while (false) - #endif // hifi_NetworkLogging_h diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 7b459538ad..8ca8158ec0 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -89,4 +89,27 @@ private: static QMutex _mutex; }; +#define HIFI_FDEBUG(category, message) \ + do { \ + if (category().isDebugEnabled()) { \ + static int repeatedMessageID_ = LogHandler::getInstance().newRepeatedMessageID(); \ + QString logString_; \ + QDebug debugStringReceiver_(&logString_); \ + debugStringReceiver_ << message; \ + LogHandler::getInstance().printRepeatedMessage(repeatedMessageID_, LogDebug, QMessageLogContext(__FILE__, \ + __LINE__, __func__, category().categoryName()), logString_); \ + } \ + } while (false) + +#define HIFI_FDEBUG_ID(category, messageID, message) \ + do { \ + if (category().isDebugEnabled()) { \ + QString logString_; \ + QDebug debugStringReceiver_(&logString_); \ + debugStringReceiver_ << message; \ + LogHandler::getInstance().printRepeatedMessage(messageID, LogDebug, QMessageLogContext(__FILE__, \ + __LINE__, __func__, category().categoryName()), logString_); \ + } \ + } while (false) + #endif // hifi_LogHandler_h From 765688d4dafb3724df35b501f87b54a480ba6251 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 3 Apr 2018 17:40:07 -0700 Subject: [PATCH 043/174] add JSDoc package lock json to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index df91e0ca7b..8d92fe770b 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,6 @@ interface/compiledResources # GPUCache interface/resources/GPUCache/* + +# package lock file for JSDoc tool +tools/jsdoc/package-lock.json From 22ac40040200f255ff647bd972df6fb4de9af603 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 3 Apr 2018 17:48:17 -0700 Subject: [PATCH 044/174] update electron version to 1.8.4 --- server-console/package-lock.json | 454 ++++++++++++++++--------------- server-console/package.json | 8 +- server-console/src/main.js | 6 +- 3 files changed, 243 insertions(+), 225 deletions(-) diff --git a/server-console/package-lock.json b/server-console/package-lock.json index e25fd3cded..4311fde51a 100644 --- a/server-console/package-lock.json +++ b/server-console/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.2.tgz", + "integrity": "sha512-A6Uv1anbsCvrRDtaUXS2xZ5tlzD+Kg7yMRlSLFDy3z0r7KlGXDzL14vELXIAgpk2aJbU3XeZZQRcEkLkowT92g==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -40,12 +46,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, "array-find-index": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz", @@ -148,12 +148,6 @@ "lru-cache": "4.0.1" } }, - "balanced-match": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz", - "integrity": "sha1-qRzdHr7xqGZZ5w/03vAWJfwtZ1Y=", - "dev": true - }, "base64-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", @@ -217,16 +211,6 @@ "hoek": "2.16.3" } }, - "brace-expansion": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz", - "integrity": "sha1-Rr/1ARXUf8mriYVKu4fZgHihCZE=", - "dev": true, - "requires": { - "balanced-match": "0.3.0", - "concat-map": "0.0.1" - } - }, "buffers": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", @@ -515,29 +499,70 @@ "jsbn": "0.1.0" } }, - "electron-download": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-2.1.1.tgz", - "integrity": "sha1-AH07HyrTco0nzP5PhJayY/kTijE=", + "electron": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-1.8.4.tgz", + "integrity": "sha512-2f1cx0G3riMFODXFftF5AHXy+oHfhpntZHTDN66Hxtl09gmEr42B3piNEod9MEmw72f75LX2JfeYceqq1PF8cA==", "dev": true, "requires": { - "debug": "2.2.0", - "home-path": "1.0.3", + "@types/node": "8.10.2", + "electron-download": "3.3.0", + "extract-zip": "1.5.0" + } + }, + "electron-download": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz", + "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=", + "dev": true, + "requires": { + "debug": "2.6.9", + "fs-extra": "0.30.0", + "home-path": "1.0.5", "minimist": "1.2.0", - "mkdirp": "0.5.1", - "mv": "2.1.1", - "nugget": "1.6.2", - "path-exists": "1.0.0", - "rc": "1.1.6" + "nugget": "2.0.1", + "path-exists": "2.1.0", + "rc": "1.1.6", + "semver": "5.5.0", + "sumchecker": "1.3.1" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" + } + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "4.1.3", + "jsonfile": "2.2.3", + "klaw": "1.3.1", + "path-is-absolute": "1.0.0", + "rimraf": "2.6.2" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "sumchecker": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz", + "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=", + "dev": true, + "requires": { + "debug": "2.6.9", + "es6-promise": "4.2.4" } } } @@ -579,9 +604,9 @@ } }, "electron-packager": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-11.0.0.tgz", - "integrity": "sha512-ufyYMe3Gt6IEZm9RuG+KK3Nh+V2jZHWg9gihp8wylUNtleQihECIXtQdpPJxH9740XFERVPraNEaa7cZvDzpyw==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-12.0.0.tgz", + "integrity": "sha1-uC0k14ovIUA7v9FmpbFWmJTVzQw=", "dev": true, "requires": { "asar": "0.14.2", @@ -590,20 +615,25 @@ "electron-osx-sign": "0.4.8", "extract-zip": "1.5.0", "fs-extra": "5.0.0", + "galactus": "0.2.0", "get-package-info": "1.0.0", - "mz": "2.7.0", "nodeify": "1.0.1", "parse-author": "2.0.0", "pify": "3.0.0", "plist": "2.1.0", - "pruner": "0.0.7", - "rcedit": "0.9.0", + "rcedit": "1.0.0", "resolve": "1.5.0", "sanitize-filename": "1.6.1", "semver": "5.5.0", - "yargs-parser": "8.1.0" + "yargs-parser": "9.0.2" }, "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -726,6 +756,12 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "rcedit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-1.0.0.tgz", + "integrity": "sha512-W7DNa34x/3OgWyDHsI172AG/Lr/lZ+PkavFkHj0QhhkBRcV9QTmRJE1tDKrWkx8XHPSBsmZkNv9OKue6pncLFQ==", + "dev": true + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -746,19 +782,18 @@ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", "dev": true + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } } } }, - "electron-prebuilt": { - "version": "0.37.5", - "resolved": "https://registry.npmjs.org/electron-prebuilt/-/electron-prebuilt-0.37.5.tgz", - "integrity": "sha1-OkGJgod4FdOnrB+bLi9KcPQg/3A=", - "dev": true, - "requires": { - "electron-download": "2.1.1", - "extract-zip": "1.5.0" - } - }, "end-of-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", @@ -787,6 +822,12 @@ "is-arrayish": "0.2.1" } }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -873,6 +914,62 @@ } } }, + "flora-colossus": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-0.0.2.tgz", + "integrity": "sha1-fRvimh8X+k8isb1hSC+Gw04HuQE=", + "dev": true, + "requires": { + "debug": "3.1.0", + "fs-extra": "4.0.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "4.1.3", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -904,6 +1001,63 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "galactus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.0.tgz", + "integrity": "sha1-w9Y7pVAkZv5A6mfMaJCFs90kqPw=", + "dev": true, + "requires": { + "debug": "3.1.0", + "flora-colossus": "0.0.2", + "fs-extra": "4.0.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "4.1.3", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "generate-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", @@ -1107,9 +1261,9 @@ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, "home-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.3.tgz", - "integrity": "sha1-ns5Z/sPwMubRC1Q0/uJk30wt4y8=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.5.tgz", + "integrity": "sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=", "dev": true }, "hosted-git-info": { @@ -1461,15 +1615,6 @@ "mime-db": "1.22.0" } }, - "minimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", - "integrity": "sha1-UjYVelHk8ATBd/s8Un/33Xjw74M=", - "dev": true, - "requires": { - "brace-expansion": "1.1.3" - } - }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", @@ -1723,61 +1868,9 @@ } }, "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "0.5.1", - "ncp": "2.0.0", - "rimraf": "2.4.5" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "1.0.4", - "inherits": "2.0.1", - "minimatch": "3.0.0", - "once": "1.3.3", - "path-is-absolute": "1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "6.0.4" - } - } - } - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "1.3.0", - "object-assign": "4.0.1", - "thenify-all": "1.6.0" - } - }, - "ncp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node-notifier": { @@ -1843,27 +1936,27 @@ } }, "nugget": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz", - "integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", + "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", "dev": true, "requires": { - "debug": "2.2.0", + "debug": "2.6.9", "minimist": "1.2.0", "pretty-bytes": "1.0.4", "progress-stream": "1.2.0", "request": "2.71.0", - "single-line-log": "0.4.1", + "single-line-log": "1.1.2", "throttleit": "0.0.2" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, "throttleit": { @@ -1966,10 +2059,13 @@ } }, "path-exists": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", - "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } }, "path-is-absolute": { "version": "1.0.0", @@ -2070,46 +2166,6 @@ "is-promise": "1.0.1" } }, - "pruner": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/pruner/-/pruner-0.0.7.tgz", - "integrity": "sha1-NF+8s+gHARY6HXrfVrrCKaWh5ME=", - "dev": true, - "requires": { - "fs-extra": "4.0.3" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "4.1.3", - "jsonfile": "4.0.0", - "universalify": "0.1.1" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true, - "optional": true - } - } - } - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -2153,12 +2209,6 @@ "strip-json-comments": "1.0.4" } }, - "rcedit": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-0.9.0.tgz", - "integrity": "sha1-ORDfVzRTmeKwMl9KUZAH+J5V7xw=", - "dev": true - }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -2288,10 +2338,13 @@ "dev": true }, "single-line-log": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-0.4.1.tgz", - "integrity": "sha1-h6VWSfdJ14PsDc2AToFA2Yc8fO4=", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", + "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", + "dev": true, + "requires": { + "string-width": "1.0.1" + } }, "sntp": { "version": "1.0.9", @@ -2476,24 +2529,6 @@ } } }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "dev": true, - "requires": { - "any-promise": "1.3.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dev": true, - "requires": { - "thenify": "3.3.0" - } - }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -2694,23 +2729,6 @@ "y18n": "3.2.1" } }, - "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", - "dev": true, - "requires": { - "camelcase": "4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - }, "yauzl": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", diff --git a/server-console/package.json b/server-console/package.json index 0b13eeb2a8..2428d2574e 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -8,8 +8,8 @@ "" ], "devDependencies": { - "electron-packager": "^11.0.0", - "electron-prebuilt": "0.37.5" + "electron-packager": "^12.0.0", + "electron": "1.8.4" }, "repository": { "type": "git", @@ -25,6 +25,7 @@ "dependencies": { "always-tail": "0.2.0", "cheerio": "^0.19.0", + "electron-log": "1.1.1", "extend": "^3.0.0", "fs-extra": "^1.0.0", "node-notifier": "^5.2.1", @@ -32,7 +33,6 @@ "request": "^2.67.0", "request-progress": "1.0.2", "tar-fs": "^1.12.0", - "yargs": "^3.30.0", - "electron-log": "1.1.1" + "yargs": "^3.30.0" } } diff --git a/server-console/src/main.js b/server-console/src/main.js index efa04a8512..b08db6222f 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -8,9 +8,9 @@ const nativeImage = electron.nativeImage; const notifier = require('node-notifier'); const util = require('util'); const dialog = electron.dialog; -const Menu = require('menu'); -const Tray = require('tray'); -const shell = require('shell'); +const Menu = electron.Menu; +const Tray = electron.Tray; +const shell = electron.shell; const os = require('os'); const childProcess = require('child_process'); const path = require('path'); From 7d16ca9c1c66f3215441624c60aaf91dd55a626e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 3 Apr 2018 17:54:01 -0700 Subject: [PATCH 045/174] Remove uses of addRepeatedMessageRegex() and its implementation Change to new log-message ID scheme. --- domain-server/src/DomainServer.cpp | 22 +++------- interface/src/Application.cpp | 4 +- interface/src/InterfaceDynamicFactory.cpp | 6 +-- libraries/audio/src/AudioRingBuffer.cpp | 12 +++--- libraries/audio/src/PositionalAudioStream.cpp | 6 +-- libraries/entities/src/EntityItem.cpp | 6 +-- libraries/entities/src/EntityTree.cpp | 6 +-- libraries/fbx/src/FBXReader_Mesh.cpp | 6 +-- libraries/networking/src/LimitedNodeList.cpp | 17 ++------ .../networking/src/SequenceNumberStats.cpp | 10 +---- libraries/networking/src/udt/Packet.cpp | 3 +- libraries/networking/src/udt/SendQueue.cpp | 3 +- libraries/networking/src/udt/Socket.cpp | 12 +----- libraries/octree/src/Octree.cpp | 41 ++++--------------- libraries/octree/src/OctreeElement.cpp | 6 +-- libraries/octree/src/OctreeSceneStats.cpp | 8 +--- .../src/ObjectConstraintBallSocket.cpp | 7 +--- .../physics/src/ObjectConstraintConeTwist.cpp | 7 +--- .../physics/src/ObjectConstraintHinge.cpp | 7 +--- .../physics/src/ObjectConstraintSlider.cpp | 7 +--- .../render-utils/src/BackgroundStage.cpp | 3 -- libraries/render/src/render/DrawTask.cpp | 8 +--- libraries/shared/src/LogHandler.cpp | 41 ------------------- libraries/shared/src/LogHandler.h | 10 +---- 24 files changed, 52 insertions(+), 206 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 197ac7eac2..0965ef7bca 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -611,22 +611,14 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) { // let the NodeList do its checks now (but pass it the sourceNode so it doesn't need to look it up again) return nodeList->isPacketVerifiedWithSource(packet, sourceNode.data()); } else { - static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unmatched IP for UUID"; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); - - qDebug() << "Packet of type" << headerType - << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceID); + HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "Packet of type" << headerType + << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceID)); return false; } } else { - static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with UUID"; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); - - qDebug() << "Packet of type" << headerType - << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); + HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "Packet of type" << headerType + << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); return false; } @@ -1276,10 +1268,8 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointershouldBePhysical() && !entity->isReadyToComputeShape()) { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); - qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); + HIFI_FDEBUG(interfaceapp(), "Physics disabled until entity loads: " << entity->getID() << entity->getName()); // don't break here because we want all the relevant entities to start their downloads result = false; } diff --git a/interface/src/InterfaceDynamicFactory.cpp b/interface/src/InterfaceDynamicFactory.cpp index e51f63d01b..dc8a789d32 100644 --- a/interface/src/InterfaceDynamicFactory.cpp +++ b/interface/src/InterfaceDynamicFactory.cpp @@ -87,10 +87,8 @@ EntityDynamicPointer InterfaceDynamicFactory::factoryBA(EntityItemPointer ownerE if (dynamic) { dynamic->deserialize(data); if (dynamic->lifetimeIsOver()) { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex(".*factoryBA lifetimeIsOver during dynamic creation.*"); - qDebug() << "InterfaceDynamicFactory::factoryBA lifetimeIsOver during dynamic creation --" - << dynamic->getExpires() << "<" << usecTimestampNow(); + HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "InterfaceDynamicFactory::factoryBA lifetimeIsOver during dynamic creation --" + << dynamic->getExpires() << "<" << usecTimestampNow()); return nullptr; } } diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 59b3e874d7..ded390a4db 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -39,9 +39,6 @@ AudioRingBufferTemplate::AudioRingBufferTemplate(int numFrameSamples, int num _nextOutput = _buffer; _endOfLastWrite = _buffer; } - - static QString repeatedOverflowMessage = LogHandler::getInstance().addRepeatedMessageRegex(RING_BUFFER_OVERFLOW_DEBUG); - static QString repeatedDroppedMessage = LogHandler::getInstance().addRepeatedMessageRegex(DROPPED_SILENT_DEBUG); } template @@ -167,7 +164,8 @@ int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - qCDebug(audio) << qPrintable(RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + qPrintable(RING_BUFFER_OVERFLOW_DEBUG); } if (_endOfLastWrite + numWriteSamples > _buffer + _bufferLength) { @@ -224,7 +222,7 @@ int AudioRingBufferTemplate::addSilentSamples(int silentSamples) { if (numWriteSamples > samplesRoomFor) { numWriteSamples = samplesRoomFor; - qCDebug(audio) << qPrintable(DROPPED_SILENT_DEBUG); + HIFI_FDEBUG(audio(), DROPPED_SILENT_DEBUG); } if (_endOfLastWrite + numWriteSamples > _buffer + _bufferLength) { @@ -275,7 +273,7 @@ int AudioRingBufferTemplate::writeSamples(ConstIterator source, int maxSample int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - qCDebug(audio) << qPrintable(RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; @@ -297,7 +295,7 @@ int AudioRingBufferTemplate::writeSamplesWithFade(ConstIterator source, int m int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - qCDebug(audio) << qPrintable(RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; diff --git a/libraries/audio/src/PositionalAudioStream.cpp b/libraries/audio/src/PositionalAudioStream.cpp index 49b34a894e..f006f370c8 100644 --- a/libraries/audio/src/PositionalAudioStream.cpp +++ b/libraries/audio/src/PositionalAudioStream.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -80,10 +81,7 @@ int PositionalAudioStream::parsePositionalData(const QByteArray& positionalByteA // if the client sends us a bad position, flag it so that we don't consider this stream for mixing if (glm::isnan(_position.x) || glm::isnan(_position.y) || glm::isnan(_position.z)) { - static const QString INVALID_POSITION_REGEX = "PositionalAudioStream unpacked invalid position for node"; - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(INVALID_POSITION_REGEX); - - qDebug() << "PositionalAudioStream unpacked invalid position for node" << uuidStringWithoutCurlyBraces(getNodeID()); + HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "PositionalAudioStream unpacked invalid position for node" << uuidStringWithoutCurlyBraces(getNodeID()) ); _hasValidPosition = false; } else { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5d056e17d8..22341298c8 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2197,10 +2197,8 @@ void EntityItem::deserializeActionsInternal() { entity->addActionInternal(simulation, action); updated << actionID; } else { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex(".*action creation failed for.*"); - qCDebug(entities) << "EntityItem::deserializeActionsInternal -- action creation failed for" - << getID() << _name; // getName(); + HIFI_FDEBUG(entities(), "EntityItem::deserializeActionsInternal -- action creation failed for" + << getID() << _name); // getName(); removeActionInternal(actionID, nullptr); } } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 75f024d0b9..a8be7e89e9 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1630,11 +1630,9 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } } else { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex("^Edit failed.*"); - qCDebug(entities) << "Edit failed. [" << message.getType() <<"] " << + HIFI_FDEBUG(entities(), "Edit failed. [" << message.getType() <<"] " << "entity id:" << entityItemID << - "existingEntity pointer:" << existingEntity.get(); + "existingEntity pointer:" << existingEntity.get()); } } diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index b0e2faa600..a71f467b94 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -566,20 +566,18 @@ glm::vec3 FBXReader::normalizeDirForPacking(const glm::vec3& dir) { } void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); - unsigned int totalSourceIndices = 0; foreach(const FBXMeshPart& part, extractedMesh.parts) { totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); } if (!totalSourceIndices) { - qCDebug(modelformat) << "buildModelMesh failed -- no indices, url = " << url; + HIFI_FDEBUG(modelformat(), "buildModelMesh failed -- no indices, url = " << url); return; } if (extractedMesh.vertices.size() == 0) { - qCDebug(modelformat) << "buildModelMesh failed -- no vertices, url = " << url; + HIFI_FDEBUG(modelformat(), "buildModelMesh failed -- no vertices, url = " << url); return; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c6451fa955..685e775688 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -277,13 +277,8 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe emit dataReceived(sendingNodeType, packet.getPayloadSize()); return true; } else { - static const QString UNSOLICITED_REPLICATED_REGEX = - "Replicated packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown upstream"; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(UNSOLICITED_REPLICATED_REGEX); - - qCDebug(networking) << "Replicated packet of type" << headerType - << "received from unknown upstream" << packet.getSenderSockAddr(); + HIFI_FDEBUG(networking(), "Replicated packet of type" << headerType + << "received from unknown upstream" << packet.getSenderSockAddr()); return false; } @@ -345,13 +340,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; } else { - //static const QString UNKNOWN_REGEX = "Packet of type \\d+ \\([\\sa-zA-Z:]+\\) received from unknown node with UUID"; - //static QString repeatedMessage - // = LogHandler::getInstance().addRepeatedMessageRegex(UNKNOWN_REGEX); - //qCDebug(networking) << "Packet of type" << headerType - // << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID); - - HIFI_FDEBUG(networking, + HIFI_FDEBUG(networking(), "Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); } } diff --git a/libraries/networking/src/SequenceNumberStats.cpp b/libraries/networking/src/SequenceNumberStats.cpp index 6d7b271606..49d555f2eb 100644 --- a/libraries/networking/src/SequenceNumberStats.cpp +++ b/libraries/networking/src/SequenceNumberStats.cpp @@ -89,10 +89,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui } else if (absGap > MAX_REASONABLE_SEQUENCE_GAP) { arrivalInfo._status = Unreasonable; - static const QString UNREASONABLE_SEQUENCE_REGEX { "unreasonable sequence number: \\d+ previous: \\d+" }; - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(UNREASONABLE_SEQUENCE_REGEX); - - qCDebug(networking) << "unreasonable sequence number:" << incoming << "previous:" << _lastReceivedSequence; + HIFI_FDEBUG(networking(), "unreasonable sequence number:" << incoming << "previous:" << _lastReceivedSequence); _stats._unreasonable++; @@ -154,10 +151,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui arrivalInfo._status = Unreasonable; - static const QString UNREASONABLE_SEQUENCE_REGEX { "unreasonable sequence number: \\d+ \\(possible duplicate\\)" }; - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(UNREASONABLE_SEQUENCE_REGEX); - - qCDebug(networking) << "unreasonable sequence number:" << incoming << "(possible duplicate)"; + HIFI_FDEBUG(networking(), "unreasonable sequence number:" << incoming << "(possible duplicate)"); _stats._unreasonable++; diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index f07ea63994..942c676fe3 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -107,8 +107,7 @@ Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& se QString::number(getMessagePartNumber())); } - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("^Unobfuscating packet .*"); - qCDebug(networking) << qPrintable(debugString); + HIFI_FDEBUG(networking(), debugString); #endif obfuscate(NoObfuscation); // Undo obfuscation diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index b62624aab9..e437104495 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -479,8 +479,7 @@ bool SendQueue::maybeResendPacket() { debugString = debugString.arg(QString::number(resendPacket.getMessageNumber()), QString::number(resendPacket.getMessagePartNumber())); } - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("^Obfuscating packet .*"); - qCritical() << qPrintable(debugString); + HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), debugString); #endif // Create copy of the packet diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 4189cb613c..e29aab0a64 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -229,11 +229,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc if (bytesWritten < 0) { // when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug - static const QString WRITE_ERROR_REGEX = "Socket::writeDatagram QAbstractSocket::NetworkError - Unable to send a message"; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(WRITE_ERROR_REGEX); - - qCDebug(networking) << "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()); + HIFI_FDEBUG(networking(), "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()) ); } return bytesWritten; @@ -517,11 +513,7 @@ std::vector Socket::getConnectionSockAddrs() { } void Socket::handleSocketError(QAbstractSocket::SocketError socketError) { - static const QString SOCKET_REGEX = "udt::Socket error - "; - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex(SOCKET_REGEX); - - qCDebug(networking) << "udt::Socket error - " << socketError << _udpSocket.errorString(); + HIFI_FDEBUG(networking(), "udt::Socket error - " << socketError << _udpSocket.errorString()); } void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index dafdfd5bf4..f2fb984da1 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -121,11 +121,7 @@ void Octree::recurseTreeWithPostOperation(const RecurseOctreeOperation& operatio void Octree::recurseElementWithOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "Octree::recurseElementWithOperation\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -143,11 +139,7 @@ void Octree::recurseElementWithOperation(const OctreeElementPointer& element, co void Octree::recurseElementWithPostOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "Octree::recurseElementWithPostOperation\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -173,11 +165,7 @@ void Octree::recurseElementWithOperationDistanceSorted(const OctreeElementPointe const glm::vec3& point, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "Octree::recurseElementWithOperationDistanceSorted\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -215,11 +203,7 @@ void Octree::recurseTreeWithOperator(RecurseOctreeOperator* operatorObject) { bool Octree::recurseElementWithOperator(const OctreeElementPointer& element, RecurseOctreeOperator* operatorObject, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "Octree::recurseElementWithOperator\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return false; } @@ -285,11 +269,7 @@ OctreeElementPointer Octree::createMissingElement(const OctreeElementPointer& la const unsigned char* codeToReach, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "Octree::createMissingElement\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "Octree::createMissingElement() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "Octree::createMissingElement() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return lastParentElement; } int indexOfNewChild = branchIndexWithDescendant(lastParentElement->getOctalCode(), codeToReach); @@ -446,16 +426,9 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, uint64_t buffe (unsigned char *)bitstreamAt, NULL); int numberOfThreeBitSectionsInStream = numberOfThreeBitSectionsInCode(bitstreamAt, bufferSizeBytes); if (numberOfThreeBitSectionsInStream > UNREASONABLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... " - "numberOfThreeBitSectionsInStream: \\d+ This buffer is corrupt. Returning." - ); - - - qCDebug(octree) << "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... " + HIFI_FDEBUG(octree(), "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... " "numberOfThreeBitSectionsInStream:" << numberOfThreeBitSectionsInStream << - "This buffer is corrupt. Returning."; + "This buffer is corrupt. Returning."); return; } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index 989951b661..18226f0ffb 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -401,11 +401,7 @@ OctreeElementPointer OctreeElement::addChildAtIndex(int childIndex) { bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) { bool deleteApproved = false; if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "OctreeElement::safeDeepDeleteChildAtIndex\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - - qCDebug(octree) << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + HIFI_FDEBUG(octree(), "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return deleteApproved; } OctreeElementPointer childToDelete = getChildAtIndex(childIndex); diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 054603440d..3253a4dc07 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -636,12 +636,8 @@ void OctreeSceneStats::trackIncomingOctreePacket(ReceivedMessage& message, bool const qint64 MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive const qint64 MIN_RESONABLE_FLIGHT_TIME = -1 * (qint64)USECS_PER_SECOND; // more than 1 second of "reverse flight time" would be unreasonable if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) { - static QString repeatedMessage - = LogHandler::getInstance().addRepeatedMessageRegex( - "ignoring unreasonable packet... flightTime: -?\\d+ nodeClockSkewUsec: -?\\d+ usecs"); - - qCDebug(octree) << "ignoring unreasonable packet... flightTime:" << flightTime - << "nodeClockSkewUsec:" << nodeClockSkewUsec << "usecs";; + HIFI_FDEBUG(octree(), "ignoring unreasonable packet... flightTime:" << flightTime + << "nodeClockSkewUsec:" << nodeClockSkewUsec << "usecs"); return; // ignore any packets that are unreasonable } diff --git a/libraries/physics/src/ObjectConstraintBallSocket.cpp b/libraries/physics/src/ObjectConstraintBallSocket.cpp index 70613d46ae..4a9ef0f1ac 100644 --- a/libraries/physics/src/ObjectConstraintBallSocket.cpp +++ b/libraries/physics/src/ObjectConstraintBallSocket.cpp @@ -85,12 +85,9 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { return constraint; } - static QString repeatedBallSocketNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( - "ObjectConstraintBallSocket::getConstraint -- no rigidBody.*"); - btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"; + HIFI_FDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"); return nullptr; } @@ -99,7 +96,7 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"; + HIFI_FDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintConeTwist.cpp b/libraries/physics/src/ObjectConstraintConeTwist.cpp index 86f1f21c63..01972805d3 100644 --- a/libraries/physics/src/ObjectConstraintConeTwist.cpp +++ b/libraries/physics/src/ObjectConstraintConeTwist.cpp @@ -96,12 +96,9 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { return constraint; } - static QString repeatedConeTwistNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( - "ObjectConstraintConeTwist::getConstraint -- no rigidBody.*"); - btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - qCDebug(physics) << "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"; + HIFI_FDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"); return nullptr; } @@ -130,7 +127,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - qCDebug(physics) << "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"; + HIFI_FDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintHinge.cpp b/libraries/physics/src/ObjectConstraintHinge.cpp index 99ddd45abd..8fb1ca19a8 100644 --- a/libraries/physics/src/ObjectConstraintHinge.cpp +++ b/libraries/physics/src/ObjectConstraintHinge.cpp @@ -95,12 +95,9 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { return constraint; } - static QString repeatedHingeNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( - "ObjectConstraintHinge::getConstraint -- no rigidBody.*"); - btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - qCDebug(physics) << "ObjectConstraintHinge::getConstraint -- no rigidBodyA"; + HIFI_FDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyA"); return nullptr; } @@ -115,7 +112,7 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { // This hinge is between two entities... find the other rigid body. btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - qCDebug(physics) << "ObjectConstraintHinge::getConstraint -- no rigidBodyB"; + HIFI_FDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintSlider.cpp b/libraries/physics/src/ObjectConstraintSlider.cpp index c236afc10d..73ec59eb7c 100644 --- a/libraries/physics/src/ObjectConstraintSlider.cpp +++ b/libraries/physics/src/ObjectConstraintSlider.cpp @@ -87,12 +87,9 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { return constraint; } - static QString repeatedSliderNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex( - "ObjectConstraintSlider::getConstraint -- no rigidBody.*"); - btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - qCDebug(physics) << "ObjectConstraintSlider::getConstraint -- no rigidBodyA"; + HIFI_FDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); return nullptr; } @@ -121,7 +118,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - qCDebug(physics) << "ObjectConstraintSlider::getConstraint -- no rigidBodyB"; + HIFI_FDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index 886795ec79..d9115c7943 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -126,9 +126,6 @@ void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, if (defaultSkyboxAmbientTexture) { sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); - } else { - static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( - "Failed to get a valid Default Skybox Ambient Texture ? probably because it couldn't be find during initialization step"); } // fall through: render defaults skybox } else { diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index bdff97c1c1..1d6c0edab5 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -55,9 +55,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons } else if (key.hasOwnPipeline()) { item.render(args); } else { - qCDebug(renderlogging) << "Item could not be rendered with invalid key" << key; - static QString repeatedCouldNotBeRendered = LogHandler::getInstance().addRepeatedMessageRegex( - "Item could not be rendered with invalid key.*"); + HIFI_FDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; } @@ -108,9 +106,7 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { - static QString repeatedCouldNotBeRendered = LogHandler::getInstance().addRepeatedMessageRegex( - "Item could not be rendered with invalid key.*"); - qCDebug(renderlogging) << "Item could not be rendered with invalid key" << key; + HIFI_FDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); } } } diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index b5a0f069e9..06287e4d81 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -91,22 +91,6 @@ void LogHandler::setShouldDisplayMilliseconds(bool shouldDisplayMilliseconds) { void LogHandler::flushRepeatedMessages() { QMutexLocker lock(&_mutex); - for(auto& message: _repeatedMessages) { - - if (message.messageCount > 1) { - QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") - .arg(message.messageCount - 1) - .arg(message.regexp.pattern()) - .arg(message.lastMessage); - - QMessageLogContext emptyContext; - lock.unlock(); - printMessage(LogSuppressed, emptyContext, repeatMessage); - lock.relock(); - } - - message.messageCount = 0; - } // New repeat-supress scheme: for (int m = 0; m < (int)_repeatCounts.size(); ++m) { @@ -127,20 +111,6 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont } QMutexLocker lock(&_mutex); - if (type == LogDebug) { - // for debug messages, check if this matches any of our regexes for repeated log messages - for (auto& repeatRegex : _repeatedMessages) { - if (repeatRegex.regexp.indexIn(message) != -1) { - // If we've printed the first one then return out. - if (repeatRegex.messageCount++ == 0) { - break; - } - repeatRegex.lastMessage = message; - return QString(); - } - } - } - if (type == LogDebug) { // see if this message is one we should only print once for (auto& onceOnly : _onetimeMessages) { @@ -211,17 +181,6 @@ void LogHandler::setupRepeatedMessageFlusher() { }); } -const QString& LogHandler::addRepeatedMessageRegex(const QString& regexString) { - // make sure we setup the repeated message flusher, but do it on the LogHandler thread - QMetaObject::invokeMethod(this, "setupRepeatedMessageFlusher"); - - QMutexLocker lock(&_mutex); - RepeatedMessage repeatRecord; - repeatRecord.regexp = QRegExp(regexString); - _repeatedMessages.push_back(repeatRecord); - return regexString; -} - const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) { QMutexLocker lock(&_mutex); OnceOnlyMessage onetimeMessage; diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 8ca8158ec0..a84ce96df9 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -51,7 +51,6 @@ public: /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); - const QString& addRepeatedMessageRegex(const QString& regexString); const QString& addOnlyOnceMessageRegex(const QString& regexString); int newRepeatedMessageID(); void printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext& context, const QString &message); @@ -70,13 +69,6 @@ private: bool _shouldOutputThreadID { false }; bool _shouldDisplayMilliseconds { false }; - struct RepeatedMessage { - QRegExp regexp; - int messageCount { 0 }; - QString lastMessage; - }; - std::vector _repeatedMessages; - struct OnceOnlyMessage { QRegExp regexp; int messageCount { 0 }; @@ -91,7 +83,7 @@ private: #define HIFI_FDEBUG(category, message) \ do { \ - if (category().isDebugEnabled()) { \ + if (category.isDebugEnabled()) { \ static int repeatedMessageID_ = LogHandler::getInstance().newRepeatedMessageID(); \ QString logString_; \ QDebug debugStringReceiver_(&logString_); \ From c23d4df93237ba53373df2a7024849518ee93475 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 3 Apr 2018 17:54:26 -0700 Subject: [PATCH 046/174] use SIGTERM as default kill signal for child process bug --- server-console/src/modules/hf-process.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/src/modules/hf-process.js b/server-console/src/modules/hf-process.js index 767befec7b..797ee38a0d 100644 --- a/server-console/src/modules/hf-process.js +++ b/server-console/src/modules/hf-process.js @@ -226,7 +226,7 @@ Process.prototype = extend(Process.prototype, { } }); } else { - var signal = force ? 'SIGKILL' : null; + var signal = force ? 'SIGKILL' : 'SIGTERM'; this.child.kill(signal); } From 7638dceee39e8c3134f8cfdb92d32d2ea8fca934 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 3 Apr 2018 18:06:18 -0700 Subject: [PATCH 047/174] fix remote require from downloader page --- server-console/src/downloader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/src/downloader.js b/server-console/src/downloader.js index f7e67f03ce..7dc9223802 100644 --- a/server-console/src/downloader.js +++ b/server-console/src/downloader.js @@ -2,7 +2,7 @@ function ready() { console.log("Ready"); const electron = require('electron'); - const remote = require('remote'); + const remote = electron.remote; window.$ = require('./vendor/jquery/jquery-2.1.4.min.js'); $(".state").hide(); From c9c3d8f3327711ecb15b5500fcf0b1f523544d0a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 4 Apr 2018 08:07:35 -0700 Subject: [PATCH 048/174] adding entity selection for far grabbing --- .../controllers/controllerDispatcher.js | 9 +- .../controllerModules/farActionGrabEntity.js | 83 ++++++++++++------- .../libraries/controllerDispatcherUtils.js | 18 +++- 3 files changed, 78 insertions(+), 32 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 4f041d3067..86b7a98b2d 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -7,11 +7,12 @@ /* jslint bitwise: true */ -/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation, +/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation, controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true, LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES, getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, COLORS_GRAB_SEARCHING_HALF_SQUEEZE - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager + COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager, print + Selection, DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE */ controllerDispatcherPlugins = {}; @@ -123,6 +124,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); return getControllerWorldLocation(Controller.Standard.RightHand, true); }; + Selection.enableListHighlight(DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE); + this.updateTimings = function () { _this.intervalCount++; var thisInterval = Date.now(); @@ -157,7 +160,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.update = function () { try { _this.updateInternal(); - } catch (e) { + } catch (e) { print(e); } Script.setTimeout(_this.update, BASIC_TIMER_INTERVAL_MS); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 53272c324d..9dd82e0363 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -14,7 +14,7 @@ PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI - Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection + Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -103,6 +103,7 @@ Script.include("/~/system/libraries/Xform.js"); this.contextOverlayTimer = false; this.previousCollisionStatus = false; this.locked = false; + this.highlightedEntity = null; this.reticleMinX = MARGIN; this.reticleMaxX; this.reticleMinY = MARGIN; @@ -449,7 +450,9 @@ Script.include("/~/system/libraries/Xform.js"); if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; - + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", + this.highlightedEntity); + this.highlightedEntity = null; var targetProps = Entities.getEntityProperties(entityID, [ "dynamic", "shapeType", "position", "rotation", "dimensions", "density", @@ -497,38 +500,62 @@ Script.include("/~/system/libraries/Xform.js"); this.startFarGrabAction(controllerData, targetProps); } } - } else if (!this.entityWithContextOverlay) { - var _this = this; + } else { + var targetEntityID = rayPickInfo.objectID; + if (this.highlightedEntity !== targetEntityID) { + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", + this.highlightedEntity); + var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [ + "dynamic", "shapeType", "position", + "rotation", "dimensions", "density", + "userData", "locked", "type", "href" + ]); - if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) { - if (_this.contextOverlayTimer) { - Script.clearTimeout(_this.contextOverlayTimer); + var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps); + selectionTargetObject.parentProps = getEntityParents(selectionTargetProps); + var selectionTargetEntity = selectionTargetObject.getTargetEntity(); + + if (entityIsGrabbable(selectionTargetEntity.props) || + entityIsGrabbable(selectionTargetObject.entityProps)) { + + Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", rayPickInfo.objectID); } - _this.contextOverlayTimer = false; - _this.potentialEntityWithContextOverlay = rayPickInfo.objectID; + this.highlightedEntity = rayPickInfo.objectID; } - if (!_this.contextOverlayTimer) { - _this.contextOverlayTimer = Script.setTimeout(function () { - if (!_this.entityWithContextOverlay && - _this.contextOverlayTimer && - _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { - var props = Entities.getEntityProperties(rayPickInfo.objectID); - var pointerEvent = { - type: "Move", - id: _this.hand + 1, // 0 is reserved for hardware mouse - pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props), - pos3D: rayPickInfo.intersection, - normal: rayPickInfo.surfaceNormal, - direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), - button: "Secondary" - }; - if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) { - _this.entityWithContextOverlay = rayPickInfo.objectID; - } + if (!this.entityWithContextOverlay) { + var _this = this; + + if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) { + if (_this.contextOverlayTimer) { + Script.clearTimeout(_this.contextOverlayTimer); } _this.contextOverlayTimer = false; - }, 500); + _this.potentialEntityWithContextOverlay = rayPickInfo.objectID; + } + + if (!_this.contextOverlayTimer) { + _this.contextOverlayTimer = Script.setTimeout(function () { + if (!_this.entityWithContextOverlay && + _this.contextOverlayTimer && + _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { + var props = Entities.getEntityProperties(rayPickInfo.objectID); + var pointerEvent = { + type: "Move", + id: _this.hand + 1, // 0 is reserved for hardware mouse + pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props), + pos3D: rayPickInfo.intersection, + normal: rayPickInfo.surfaceNormal, + direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), + button: "Secondary" + }; + if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) { + _this.entityWithContextOverlay = rayPickInfo.objectID; + } + } + _this.contextOverlayTimer = false; + }, 500); + } } } } else if (this.distanceRotating) { diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index 75e1d6668b..05f6aa9fbf 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -22,6 +22,8 @@ DISPATCHER_PROPERTIES:true, HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, + DISPATCHER_HOVERING_LIST:true, + DISPATCHER_HOVERING_STYLE:true, Entities, makeDispatcherModuleParameters:true, makeRunningValues:true, @@ -88,6 +90,19 @@ NEAR_GRAB_RADIUS = 1.0; TEAR_AWAY_DISTANCE = 0.1; // ungrab an entity if its bounding-box moves this far from the hand TEAR_AWAY_COUNT = 2; // multiply by TEAR_AWAY_CHECK_TIME to know how long the item must be away TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks +DISPATCHER_HOVERING_LIST = "dispactherHoveringList"; +DISPATCHER_HOVERING_STYLE = { + isOutlineSmooth: true, + outlineWidth: 5, + outlineUnoccludedColor: {red: 255, green: 128, blue: 128}, + outlineUnoccludedAlpha: 0.88, + outlineOccludedColor: {red: 255, green: 128, blue: 128}, + outlineOccludedAlpha:0.5, + fillUnoccludedColor: {red: 26, green: 0, blue: 0}, + fillUnoccludedAlpha: 0.0, + fillOccludedColor: {red: 26, green: 0, blue: 0}, + fillOccludedAlpha: 0.0 +}; DISPATCHER_PROPERTIES = [ "position", @@ -400,6 +415,7 @@ if (typeof module !== 'undefined') { projectOntoOverlayXYPlane: projectOntoOverlayXYPlane, projectOntoEntityXYPlane: projectOntoEntityXYPlane, TRIGGER_OFF_VALUE: TRIGGER_OFF_VALUE, - TRIGGER_ON_VALUE: TRIGGER_ON_VALUE + TRIGGER_ON_VALUE: TRIGGER_ON_VALUE, + DISPATCHER_HOVERING_LIST: DISPATCHER_HOVERING_LIST }; } From 692ccfc09b9051abbac8ff4f72d98a05fc7e18d0 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 09:49:15 -0700 Subject: [PATCH 049/174] Create HIFI_FCDEBUG(_ID) variants that require a category Original macros use default settings. --- domain-server/src/DomainServer.cpp | 6 +++--- interface/src/Application.cpp | 2 +- interface/src/InterfaceDynamicFactory.cpp | 2 +- libraries/audio/src/AudioRingBuffer.cpp | 8 ++++---- libraries/audio/src/PositionalAudioStream.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 2 +- libraries/fbx/src/FBXReader_Mesh.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.cpp | 4 ++-- libraries/networking/src/SequenceNumberStats.cpp | 4 ++-- libraries/networking/src/udt/Packet.cpp | 2 +- libraries/networking/src/udt/SendQueue.cpp | 2 +- libraries/networking/src/udt/Socket.cpp | 4 ++-- libraries/octree/src/Octree.cpp | 12 ++++++------ libraries/octree/src/OctreeElement.cpp | 2 +- libraries/octree/src/OctreeSceneStats.cpp | 2 +- libraries/physics/src/ObjectConstraintBallSocket.cpp | 4 ++-- libraries/physics/src/ObjectConstraintConeTwist.cpp | 4 ++-- libraries/physics/src/ObjectConstraintHinge.cpp | 4 ++-- libraries/physics/src/ObjectConstraintSlider.cpp | 4 ++-- libraries/render/src/render/DrawTask.cpp | 4 ++-- libraries/shared/src/LogHandler.h | 10 +++++++--- 22 files changed, 47 insertions(+), 43 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 0965ef7bca..b1f996c9b2 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -611,13 +611,13 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) { // let the NodeList do its checks now (but pass it the sourceNode so it doesn't need to look it up again) return nodeList->isPacketVerifiedWithSource(packet, sourceNode.data()); } else { - HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "Packet of type" << headerType + HIFI_FDEBUG("Packet of type" << headerType << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceID)); return false; } } else { - HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "Packet of type" << headerType + HIFI_FDEBUG("Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); return false; @@ -1268,7 +1268,7 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointershouldBePhysical() && !entity->isReadyToComputeShape()) { - HIFI_FDEBUG(interfaceapp(), "Physics disabled until entity loads: " << entity->getID() << entity->getName()); + HIFI_FCDEBUG(interfaceapp(), "Physics disabled until entity loads: " << entity->getID() << entity->getName()); // don't break here because we want all the relevant entities to start their downloads result = false; } diff --git a/interface/src/InterfaceDynamicFactory.cpp b/interface/src/InterfaceDynamicFactory.cpp index dc8a789d32..b7861b56c8 100644 --- a/interface/src/InterfaceDynamicFactory.cpp +++ b/interface/src/InterfaceDynamicFactory.cpp @@ -87,7 +87,7 @@ EntityDynamicPointer InterfaceDynamicFactory::factoryBA(EntityItemPointer ownerE if (dynamic) { dynamic->deserialize(data); if (dynamic->lifetimeIsOver()) { - HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "InterfaceDynamicFactory::factoryBA lifetimeIsOver during dynamic creation --" + HIFI_FDEBUG("InterfaceDynamicFactory::factoryBA lifetimeIsOver during dynamic creation --" << dynamic->getExpires() << "<" << usecTimestampNow()); return nullptr; } diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index ded390a4db..7b1f24e519 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -164,7 +164,7 @@ int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); qPrintable(RING_BUFFER_OVERFLOW_DEBUG); } @@ -222,7 +222,7 @@ int AudioRingBufferTemplate::addSilentSamples(int silentSamples) { if (numWriteSamples > samplesRoomFor) { numWriteSamples = samplesRoomFor; - HIFI_FDEBUG(audio(), DROPPED_SILENT_DEBUG); + HIFI_FCDEBUG(audio(), DROPPED_SILENT_DEBUG); } if (_endOfLastWrite + numWriteSamples > _buffer + _bufferLength) { @@ -273,7 +273,7 @@ int AudioRingBufferTemplate::writeSamples(ConstIterator source, int maxSample int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; @@ -295,7 +295,7 @@ int AudioRingBufferTemplate::writeSamplesWithFade(ConstIterator source, int m int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; diff --git a/libraries/audio/src/PositionalAudioStream.cpp b/libraries/audio/src/PositionalAudioStream.cpp index f006f370c8..a6bbc71a65 100644 --- a/libraries/audio/src/PositionalAudioStream.cpp +++ b/libraries/audio/src/PositionalAudioStream.cpp @@ -81,7 +81,7 @@ int PositionalAudioStream::parsePositionalData(const QByteArray& positionalByteA // if the client sends us a bad position, flag it so that we don't consider this stream for mixing if (glm::isnan(_position.x) || glm::isnan(_position.y) || glm::isnan(_position.z)) { - HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), "PositionalAudioStream unpacked invalid position for node" << uuidStringWithoutCurlyBraces(getNodeID()) ); + HIFI_FDEBUG("PositionalAudioStream unpacked invalid position for node" << uuidStringWithoutCurlyBraces(getNodeID()) ); _hasValidPosition = false; } else { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 22341298c8..813be9dace 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2197,7 +2197,7 @@ void EntityItem::deserializeActionsInternal() { entity->addActionInternal(simulation, action); updated << actionID; } else { - HIFI_FDEBUG(entities(), "EntityItem::deserializeActionsInternal -- action creation failed for" + HIFI_FCDEBUG(entities(), "EntityItem::deserializeActionsInternal -- action creation failed for" << getID() << _name); // getName(); removeActionInternal(actionID, nullptr); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a8be7e89e9..8f158edecd 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1630,7 +1630,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c _recentlyDeletedEntityItemIDs.insert(usecTimestampNow(), entityItemID); } } else { - HIFI_FDEBUG(entities(), "Edit failed. [" << message.getType() <<"] " << + HIFI_FCDEBUG(entities(), "Edit failed. [" << message.getType() <<"] " << "entity id:" << entityItemID << "existingEntity pointer:" << existingEntity.get()); } diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index a71f467b94..2cb9d3ed9f 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -572,12 +572,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } if (!totalSourceIndices) { - HIFI_FDEBUG(modelformat(), "buildModelMesh failed -- no indices, url = " << url); + HIFI_FCDEBUG(modelformat(), "buildModelMesh failed -- no indices, url = " << url); return; } if (extractedMesh.vertices.size() == 0) { - HIFI_FDEBUG(modelformat(), "buildModelMesh failed -- no vertices, url = " << url); + HIFI_FCDEBUG(modelformat(), "buildModelMesh failed -- no vertices, url = " << url); return; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 685e775688..fa934b5539 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -277,7 +277,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe emit dataReceived(sendingNodeType, packet.getPayloadSize()); return true; } else { - HIFI_FDEBUG(networking(), "Replicated packet of type" << headerType + HIFI_FCDEBUG(networking(), "Replicated packet of type" << headerType << "received from unknown upstream" << packet.getSenderSockAddr()); return false; @@ -340,7 +340,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; } else { - HIFI_FDEBUG(networking(), + HIFI_FCDEBUG(networking(), "Packet of type" << headerType << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); } } diff --git a/libraries/networking/src/SequenceNumberStats.cpp b/libraries/networking/src/SequenceNumberStats.cpp index 49d555f2eb..7f1ee39554 100644 --- a/libraries/networking/src/SequenceNumberStats.cpp +++ b/libraries/networking/src/SequenceNumberStats.cpp @@ -89,7 +89,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui } else if (absGap > MAX_REASONABLE_SEQUENCE_GAP) { arrivalInfo._status = Unreasonable; - HIFI_FDEBUG(networking(), "unreasonable sequence number:" << incoming << "previous:" << _lastReceivedSequence); + HIFI_FCDEBUG(networking(), "unreasonable sequence number:" << incoming << "previous:" << _lastReceivedSequence); _stats._unreasonable++; @@ -151,7 +151,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui arrivalInfo._status = Unreasonable; - HIFI_FDEBUG(networking(), "unreasonable sequence number:" << incoming << "(possible duplicate)"); + HIFI_FCDEBUG(networking(), "unreasonable sequence number:" << incoming << "(possible duplicate)"); _stats._unreasonable++; diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 942c676fe3..0456fa1223 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -107,7 +107,7 @@ Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& se QString::number(getMessagePartNumber())); } - HIFI_FDEBUG(networking(), debugString); + HIFI_FCDEBUG(networking(), debugString); #endif obfuscate(NoObfuscation); // Undo obfuscation diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index e437104495..0df54d539d 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -479,7 +479,7 @@ bool SendQueue::maybeResendPacket() { debugString = debugString.arg(QString::number(resendPacket.getMessageNumber()), QString::number(resendPacket.getMessagePartNumber())); } - HIFI_FDEBUG((*QLoggingCategory::defaultCategory()), debugString); + HIFI_FDEBUG(debugString); #endif // Create copy of the packet diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index e29aab0a64..4d4303698b 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -229,7 +229,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc if (bytesWritten < 0) { // when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug - HIFI_FDEBUG(networking(), "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()) ); + HIFI_FCDEBUG(networking(), "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()) ); } return bytesWritten; @@ -513,7 +513,7 @@ std::vector Socket::getConnectionSockAddrs() { } void Socket::handleSocketError(QAbstractSocket::SocketError socketError) { - HIFI_FDEBUG(networking(), "udt::Socket error - " << socketError << _udpSocket.errorString()); + HIFI_FCDEBUG(networking(), "udt::Socket error - " << socketError << _udpSocket.errorString()); } void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index f2fb984da1..e34ba34c8f 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -121,7 +121,7 @@ void Octree::recurseTreeWithPostOperation(const RecurseOctreeOperation& operatio void Octree::recurseElementWithOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -139,7 +139,7 @@ void Octree::recurseElementWithOperation(const OctreeElementPointer& element, co void Octree::recurseElementWithPostOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -165,7 +165,7 @@ void Octree::recurseElementWithOperationDistanceSorted(const OctreeElementPointe const glm::vec3& point, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return; } @@ -203,7 +203,7 @@ void Octree::recurseTreeWithOperator(RecurseOctreeOperator* operatorObject) { bool Octree::recurseElementWithOperator(const OctreeElementPointer& element, RecurseOctreeOperator* operatorObject, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return false; } @@ -269,7 +269,7 @@ OctreeElementPointer Octree::createMissingElement(const OctreeElementPointer& la const unsigned char* codeToReach, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "Octree::createMissingElement() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "Octree::createMissingElement() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return lastParentElement; } int indexOfNewChild = branchIndexWithDescendant(lastParentElement->getOctalCode(), codeToReach); @@ -426,7 +426,7 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, uint64_t buffe (unsigned char *)bitstreamAt, NULL); int numberOfThreeBitSectionsInStream = numberOfThreeBitSectionsInCode(bitstreamAt, bufferSizeBytes); if (numberOfThreeBitSectionsInStream > UNREASONABLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... " + HIFI_FCDEBUG(octree(), "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... " "numberOfThreeBitSectionsInStream:" << numberOfThreeBitSectionsInStream << "This buffer is corrupt. Returning."); return; diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index 18226f0ffb..ef45e8b7ba 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -401,7 +401,7 @@ OctreeElementPointer OctreeElement::addChildAtIndex(int childIndex) { bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) { bool deleteApproved = false; if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FDEBUG(octree(), "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + HIFI_FCDEBUG(octree(), "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); return deleteApproved; } OctreeElementPointer childToDelete = getChildAtIndex(childIndex); diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 3253a4dc07..117f3e0385 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -636,7 +636,7 @@ void OctreeSceneStats::trackIncomingOctreePacket(ReceivedMessage& message, bool const qint64 MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive const qint64 MIN_RESONABLE_FLIGHT_TIME = -1 * (qint64)USECS_PER_SECOND; // more than 1 second of "reverse flight time" would be unreasonable if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) { - HIFI_FDEBUG(octree(), "ignoring unreasonable packet... flightTime:" << flightTime + HIFI_FCDEBUG(octree(), "ignoring unreasonable packet... flightTime:" << flightTime << "nodeClockSkewUsec:" << nodeClockSkewUsec << "usecs"); return; // ignore any packets that are unreasonable } diff --git a/libraries/physics/src/ObjectConstraintBallSocket.cpp b/libraries/physics/src/ObjectConstraintBallSocket.cpp index 4a9ef0f1ac..1f1cb2487d 100644 --- a/libraries/physics/src/ObjectConstraintBallSocket.cpp +++ b/libraries/physics/src/ObjectConstraintBallSocket.cpp @@ -87,7 +87,7 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"); return nullptr; } @@ -96,7 +96,7 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintConeTwist.cpp b/libraries/physics/src/ObjectConstraintConeTwist.cpp index 01972805d3..714fd662e1 100644 --- a/libraries/physics/src/ObjectConstraintConeTwist.cpp +++ b/libraries/physics/src/ObjectConstraintConeTwist.cpp @@ -98,7 +98,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"); return nullptr; } @@ -127,7 +127,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintHinge.cpp b/libraries/physics/src/ObjectConstraintHinge.cpp index 8fb1ca19a8..18014cddca 100644 --- a/libraries/physics/src/ObjectConstraintHinge.cpp +++ b/libraries/physics/src/ObjectConstraintHinge.cpp @@ -97,7 +97,7 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyA"); return nullptr; } @@ -112,7 +112,7 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { // This hinge is between two entities... find the other rigid body. btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintSlider.cpp b/libraries/physics/src/ObjectConstraintSlider.cpp index 73ec59eb7c..9ae34e1124 100644 --- a/libraries/physics/src/ObjectConstraintSlider.cpp +++ b/libraries/physics/src/ObjectConstraintSlider.cpp @@ -89,7 +89,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); return nullptr; } @@ -118,7 +118,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 1d6c0edab5..18335a1296 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -55,7 +55,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons } else if (key.hasOwnPipeline()) { item.render(args); } else { - HIFI_FDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); + HIFI_FCDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; } @@ -106,7 +106,7 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { - HIFI_FDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); + HIFI_FCDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); } } } diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index a84ce96df9..dfdfee6c3d 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -81,7 +81,7 @@ private: static QMutex _mutex; }; -#define HIFI_FDEBUG(category, message) \ +#define HIFI_FCDEBUG(category, message) \ do { \ if (category.isDebugEnabled()) { \ static int repeatedMessageID_ = LogHandler::getInstance().newRepeatedMessageID(); \ @@ -93,9 +93,11 @@ private: } \ } while (false) -#define HIFI_FDEBUG_ID(category, messageID, message) \ +#define HIFI_FDEBUG(message) HIFI_FCDEBUG((*QLoggingCategory::defaultCategory()), message) + +#define HIFI_FCDEBUG_ID(category, messageID, message) \ do { \ - if (category().isDebugEnabled()) { \ + if (category.isDebugEnabled()) { \ QString logString_; \ QDebug debugStringReceiver_(&logString_); \ debugStringReceiver_ << message; \ @@ -104,4 +106,6 @@ private: } \ } while (false) +#define HIFI_FDEBUG_ID(message) HIFI_FCDEBUG_ID((*QLoggingCategory::defaultCategory()), message) + #endif // hifi_LogHandler_h From 3a8c9de4fb9feca5f6a0a713230d1f397074a10e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 4 Apr 2018 10:38:32 -0700 Subject: [PATCH 050/174] fix some xcode warnings for unnecessary captured this --- assignment-client/src/Agent.cpp | 2 +- domain-server/src/DomainServer.cpp | 2 +- libraries/entities-renderer/src/RenderableWebEntityItem.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 10b8d44545..1df901dd98 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -380,7 +380,7 @@ void Agent::executeScript() { using namespace recording; static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME); - Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [this, scriptedAvatar](Frame::ConstPointer frame) { + Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [scriptedAvatar](Frame::ConstPointer frame) { auto recordingInterface = DependencyManager::get(); bool useFrameSkeleton = recordingInterface->getPlayerUseSkeletonModel(); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index dbf2907cc0..5f19bbe46e 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2926,7 +2926,7 @@ void DomainServer::updateReplicatedNodes() { } auto nodeList = DependencyManager::get(); - nodeList->eachMatchingNode([this](const SharedNodePointer& otherNode) -> bool { + nodeList->eachMatchingNode([](const SharedNodePointer& otherNode) -> bool { return otherNode->getType() == NodeType::Agent; }, [this](const SharedNodePointer& otherNode) { auto shouldReplicate = shouldReplicateNode(*otherNode); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index bd00ded12d..4f072d40e3 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -266,7 +266,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { // FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces // and the current rendering load) _webSurface->setMaxFps(DEFAULT_MAX_FPS); - QObject::connect(_webSurface.data(), &OffscreenQmlSurface::rootContextCreated, [this](QQmlContext* surfaceContext) { + QObject::connect(_webSurface.data(), &OffscreenQmlSurface::rootContextCreated, [](QQmlContext* surfaceContext) { // FIXME - Keyboard HMD only: Possibly add "HMDinfo" object to context for WebView.qml. surfaceContext->setContextProperty("desktop", QVariant()); // Let us interact with the keyboard From 2546ff91ca4427de972968794fdccb55924dc9d4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 28 Mar 2018 15:05:51 -0700 Subject: [PATCH 051/174] Fix nodelist connections not resetting on both ends This change adds a connection ID to ping packets. Each node keeps a connection id for each other node that it has connected to. When a node is removed the connection id is incremented. If a node sees another node with a higher connection id, it will reset its connection with the new connection id, ensuring that local state is reset on both ends when nodes lose contact. --- domain-server/src/DomainGatekeeper.cpp | 12 ++++++--- libraries/networking/src/LimitedNodeList.cpp | 27 +++++++++++++++----- libraries/networking/src/LimitedNodeList.h | 11 +++++--- libraries/networking/src/NodeList.cpp | 24 ++++++++++++++--- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 7d0b538f6e..9f24036e92 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -451,11 +451,12 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect return SharedNodePointer(); } - QUuid hintNodeID; + QUuid existingNodeID; // in case this is a node that's failing to connect // double check we don't have the same node whose sockets match exactly already in the list limitedNodeList->eachNodeBreakable([&](const SharedNodePointer& node){ + if (node->getPublicSocket() == nodeConnection.publicSockAddr && node->getLocalSocket() == nodeConnection.localSockAddr) { // we have a node that already has these exact sockets - this can occur if a node // is failing to connect to the domain @@ -465,15 +466,20 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect auto existingNodeData = static_cast(node->getLinkedData()); if (existingNodeData->getUsername() == username) { - hintNodeID = node->getUUID(); + qDebug() << "Deleting existing connection from same sockaddr: " << node->getUUID(); + existingNodeID = node->getUUID(); return false; } } return true; }); + if (!existingNodeID.isNull()) { + limitedNodeList->killNodeWithUUID(existingNodeID); + } + // add the connecting node (or re-use the matched one from eachNodeBreakable above) - SharedNodePointer newNode = addVerifiedNodeFromConnectRequest(nodeConnection, hintNodeID); + SharedNodePointer newNode = addVerifiedNodeFromConnectRequest(nodeConnection); // set the edit rights for this user newNode->setPermissions(userPerms); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0803e380f2..e27e2d6d08 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -578,9 +578,10 @@ void LimitedNodeList::reset() { // we need to make sure any socket connections are gone so wait on that here _nodeSocket.clearConnections(); + _connectionIDs.clear(); } -bool LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { +bool LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID, ConnectionID newConnectionID) { QReadLocker readLocker(&_nodeMutex); NodeHash::iterator it = _nodeHash.find(nodeUUID); @@ -594,7 +595,7 @@ bool LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { _nodeHash.unsafe_erase(it); } - handleNodeKill(matchingNode); + handleNodeKill(matchingNode, newConnectionID); return true; } @@ -609,7 +610,7 @@ void LimitedNodeList::processKillNode(ReceivedMessage& message) { killNodeWithUUID(nodeUUID); } -void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) { +void LimitedNodeList::handleNodeKill(const SharedNodePointer& node, ConnectionID nextConnectionID) { qCDebug(networking) << "Killed" << *node; node->stopPingTimer(); emit nodeKilled(node); @@ -617,6 +618,15 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) { if (auto activeSocket = node->getActiveSocket()) { _nodeSocket.cleanupConnection(*activeSocket); } + + auto it = _connectionIDs.find(node->getUUID()); + if (it != _connectionIDs.end()) { + if (nextConnectionID == NULL_CONNECTION_ID) { + it->second++; + } else { + it->second = nextConnectionID; + } + } } SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, @@ -638,6 +648,11 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t return matchingNode; } else { + auto it = _connectionIDs.find(uuid); + if (it == _connectionIDs.end()) { + _connectionIDs[uuid] = INITIAL_CONNECTION_ID; + } + // we didn't have this node, so add them Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); newNode->setIsReplicated(isReplicated); @@ -712,13 +727,13 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t } } -std::unique_ptr LimitedNodeList::constructPingPacket(PingType_t pingType) { - int packetSize = sizeof(PingType_t) + sizeof(quint64); +std::unique_ptr LimitedNodeList::constructPingPacket(const QUuid& nodeId, PingType_t pingType) { + int packetSize = sizeof(PingType_t) + sizeof(quint64) + sizeof(int64_t); auto pingPacket = NLPacket::create(PacketType::Ping, packetSize); - pingPacket->writePrimitive(pingType); pingPacket->writePrimitive(usecTimestampNow()); + pingPacket->writePrimitive(_connectionIDs[nodeId]); return pingPacket; } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 7165b3dd63..7ec3a41450 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -66,6 +66,10 @@ const QHostAddress DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME = QHostAddress::Lo const QString USERNAME_UUID_REPLACEMENT_STATS_KEY = "$username"; +using ConnectionID = int64_t; +const ConnectionID NULL_CONNECTION_ID { -1 }; +const ConnectionID INITIAL_CONNECTION_ID { 0 }; + typedef std::pair UUIDNodePair; typedef tbb::concurrent_unordered_map NodeHash; @@ -180,7 +184,7 @@ public: void getPacketStats(float& packetsInPerSecond, float& bytesInPerSecond, float& packetsOutPerSecond, float& bytesOutPerSecond); void resetPacketStats(); - std::unique_ptr constructPingPacket(PingType_t pingType = PingType::Agnostic); + std::unique_ptr constructPingPacket(const QUuid& nodeId, PingType_t pingType = PingType::Agnostic); std::unique_ptr constructPingReplyPacket(ReceivedMessage& message); static std::unique_ptr constructICEPingPacket(PingType_t pingType, const QUuid& iceID); @@ -319,7 +323,7 @@ public slots: void startSTUNPublicSocketUpdate(); virtual void sendSTUNRequest(); - bool killNodeWithUUID(const QUuid& nodeUUID); + bool killNodeWithUUID(const QUuid& nodeUUID, ConnectionID newConnectionID = NULL_CONNECTION_ID); signals: void dataSent(quint8 channelType, int bytes); @@ -371,7 +375,7 @@ protected: bool packetSourceAndHashMatchAndTrackBandwidth(const udt::Packet& packet, Node* sourceNode = nullptr); void processSTUNResponse(std::unique_ptr packet); - void handleNodeKill(const SharedNodePointer& node); + void handleNodeKill(const SharedNodePointer& node, ConnectionID newConnectionID = NULL_CONNECTION_ID); void stopInitialSTUNUpdate(bool success); @@ -418,6 +422,7 @@ protected: } } + std::unordered_map _connectionIDs; private slots: void flagTimeForConnectionStep(ConnectionStep connectionStep, quint64 timestamp); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cb0d2e4cd5..d33a81841a 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -214,6 +214,20 @@ void NodeList::processPingPacket(QSharedPointer message, Shared sendingNode->setSymmetricSocket(senderSockAddr); } } + + int64_t connectionId; + + message->readPrimitive(&connectionId); + + auto it = _connectionIDs.find(sendingNode->getUUID()); + if (it != _connectionIDs.end()) { + if (connectionId > it->second) { + qDebug() << "Received a ping packet with a larger connection id (" << connectionId << ">" << it->second << ") from " + << sendingNode->getUUID(); + killNodeWithUUID(sendingNode->getUUID(), connectionId); + } + } + } void NodeList::processPingReplyPacket(QSharedPointer message, SharedNodePointer sendingNode) { @@ -689,16 +703,18 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { if (node->getConnectionAttempts() > 0 && node->getConnectionAttempts() % NUM_DEBUG_CONNECTION_ATTEMPTS == 0) { qCDebug(networking) << "No response to UDP hole punch pings for node" << node->getUUID() << "in last second."; } + + auto nodeId = node->getUUID(); // send the ping packet to the local and public sockets for this node - auto localPingPacket = constructPingPacket(PingType::Local); + auto localPingPacket = constructPingPacket(nodeId, PingType::Local); sendPacket(std::move(localPingPacket), *node, node->getLocalSocket()); - auto publicPingPacket = constructPingPacket(PingType::Public); + auto publicPingPacket = constructPingPacket(nodeId, PingType::Public); sendPacket(std::move(publicPingPacket), *node, node->getPublicSocket()); if (!node->getSymmetricSocket().isNull()) { - auto symmetricPingPacket = constructPingPacket(PingType::Symmetric); + auto symmetricPingPacket = constructPingPacket(nodeId, PingType::Symmetric); sendPacket(std::move(symmetricPingPacket), *node, node->getSymmetricSocket()); } @@ -768,7 +784,7 @@ void NodeList::sendKeepAlivePings() { auto type = node->getType(); return !node->isUpstream() && _nodeTypesOfInterest.contains(type) && !NodeType::isDownstream(type); }, [&](const SharedNodePointer& node) { - sendPacket(constructPingPacket(), *node); + sendPacket(constructPingPacket(node->getUUID()), *node); }); } From 42149e295d2dc4a7ac606a8c3b397628a1f72a3d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 4 Apr 2018 12:55:28 -0700 Subject: [PATCH 052/174] editing seletion style --- .../controllerModules/farActionGrabEntity.js | 4 ++++ .../system/libraries/controllerDispatcherUtils.js | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 9dd82e0363..58f032de08 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -402,6 +402,8 @@ Script.include("/~/system/libraries/Xform.js"); if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData) || this.targetIsNull()) { this.endNearGrabAction(); + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", + this.highlightedEntity); return makeRunningValues(false, [], []); } this.intersectionDistance = controllerData.rayPicks[this.hand].distance; @@ -571,6 +573,8 @@ Script.include("/~/system/libraries/Xform.js"); if (disableModule) { if (disableModule.disableModules) { this.endNearGrabAction(); + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", + this.highlightedEntity); return makeRunningValues(false, [], []); } } diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index 05f6aa9fbf..f82de4b71d 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -93,14 +93,14 @@ TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks DISPATCHER_HOVERING_LIST = "dispactherHoveringList"; DISPATCHER_HOVERING_STYLE = { isOutlineSmooth: true, - outlineWidth: 5, + outlineWidth: 0, outlineUnoccludedColor: {red: 255, green: 128, blue: 128}, - outlineUnoccludedAlpha: 0.88, + outlineUnoccludedAlpha: 0, outlineOccludedColor: {red: 255, green: 128, blue: 128}, - outlineOccludedAlpha:0.5, - fillUnoccludedColor: {red: 26, green: 0, blue: 0}, - fillUnoccludedAlpha: 0.0, - fillOccludedColor: {red: 26, green: 0, blue: 0}, + outlineOccludedAlpha:0.0, + fillUnoccludedColor: {red: 255, green: 255, blue: 255}, + fillUnoccludedAlpha: 0.15, + fillOccludedColor: {red: 255, green: 255, blue: 255}, fillOccludedAlpha: 0.0 }; From ed3347a89b76003be9d58071b0b74a76e397104c Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 14:11:10 -0700 Subject: [PATCH 053/174] Repeated logging - reviewer fixes --- libraries/audio/src/AudioRingBuffer.cpp | 23 +++++++++++++++---- libraries/fbx/src/FBXReader_Mesh.cpp | 6 +++-- .../src/ObjectConstraintBallSocket.cpp | 6 +++-- .../physics/src/ObjectConstraintConeTwist.cpp | 6 +++-- .../physics/src/ObjectConstraintHinge.cpp | 6 +++-- .../physics/src/ObjectConstraintSlider.cpp | 6 +++-- libraries/render/src/render/DrawTask.cpp | 15 ++++++++++-- libraries/shared/src/LogHandler.cpp | 22 +++++++++--------- libraries/shared/src/LogHandler.h | 9 +++++--- 9 files changed, 69 insertions(+), 30 deletions(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 7b1f24e519..683211aac6 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -151,6 +151,11 @@ int AudioRingBufferTemplate::appendData(char *data, int maxSize) { return numReadSamples * SampleSize; } +namespace { + int repeatedOverflowMessageID = 0; + std::atomic messageIDInit = 0; +} + template int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { // only copy up to the number of samples we have capacity for @@ -164,8 +169,10 @@ int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); - qPrintable(RING_BUFFER_OVERFLOW_DEBUG); + if (++messageIDInit == 1) { + repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); + } + HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } if (_endOfLastWrite + numWriteSamples > _buffer + _bufferLength) { @@ -273,7 +280,11 @@ int AudioRingBufferTemplate::writeSamples(ConstIterator source, int maxSample int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + + if (++messageIDInit == 1) { + repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); + } + HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; @@ -295,7 +306,11 @@ int AudioRingBufferTemplate::writeSamplesWithFade(ConstIterator source, int m int samplesToDelete = samplesToCopy - samplesRoomFor; _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - HIFI_FCDEBUG(audio(), RING_BUFFER_OVERFLOW_DEBUG); + + if (++messageIDInit == 1) { + repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); + } + HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } Sample* bufferLast = _buffer + _bufferLength - 1; diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 2cb9d3ed9f..e8365e38b7 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -571,13 +571,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); } + static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); + if (!totalSourceIndices) { - HIFI_FCDEBUG(modelformat(), "buildModelMesh failed -- no indices, url = " << url); + HIFI_FCDEBUG_ID(modelformat(), repeatMessageID, "buildModelMesh failed -- no indices, url = " << url); return; } if (extractedMesh.vertices.size() == 0) { - HIFI_FCDEBUG(modelformat(), "buildModelMesh failed -- no vertices, url = " << url); + HIFI_FCDEBUG_ID(modelformat(), repeatMessageID, "buildModelMesh failed -- no vertices, url = " << url); return; } diff --git a/libraries/physics/src/ObjectConstraintBallSocket.cpp b/libraries/physics/src/ObjectConstraintBallSocket.cpp index 1f1cb2487d..4736f2c9e2 100644 --- a/libraries/physics/src/ObjectConstraintBallSocket.cpp +++ b/libraries/physics/src/ObjectConstraintBallSocket.cpp @@ -85,9 +85,11 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { return constraint; } + static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); + btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FCDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA"); return nullptr; } @@ -96,7 +98,7 @@ btTypedConstraint* ObjectConstraintBallSocket::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FCDEBUG(physics(), "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintConeTwist.cpp b/libraries/physics/src/ObjectConstraintConeTwist.cpp index 714fd662e1..47228c1c16 100644 --- a/libraries/physics/src/ObjectConstraintConeTwist.cpp +++ b/libraries/physics/src/ObjectConstraintConeTwist.cpp @@ -96,9 +96,11 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { return constraint; } + static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); + btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FCDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintConeTwist::getConstraint -- no rigidBodyA"); return nullptr; } @@ -127,7 +129,7 @@ btTypedConstraint* ObjectConstraintConeTwist::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FCDEBUG(physics(), "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintConeTwist::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintHinge.cpp b/libraries/physics/src/ObjectConstraintHinge.cpp index 18014cddca..4793741391 100644 --- a/libraries/physics/src/ObjectConstraintHinge.cpp +++ b/libraries/physics/src/ObjectConstraintHinge.cpp @@ -94,10 +94,12 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { if (constraint) { return constraint; } + + static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FCDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintHinge::getConstraint -- no rigidBodyA"); return nullptr; } @@ -112,7 +114,7 @@ btTypedConstraint* ObjectConstraintHinge::getConstraint() { // This hinge is between two entities... find the other rigid body. btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FCDEBUG(physics(), "ObjectConstraintHinge::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintHinge::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/physics/src/ObjectConstraintSlider.cpp b/libraries/physics/src/ObjectConstraintSlider.cpp index 9ae34e1124..da5bba7f4d 100644 --- a/libraries/physics/src/ObjectConstraintSlider.cpp +++ b/libraries/physics/src/ObjectConstraintSlider.cpp @@ -87,9 +87,11 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { return constraint; } + static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID(); + btRigidBody* rigidBodyA = getRigidBody(); if (!rigidBodyA) { - HIFI_FCDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyA"); return nullptr; } @@ -118,7 +120,7 @@ btTypedConstraint* ObjectConstraintSlider::getConstraint() { btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID); if (!rigidBodyB) { - HIFI_FCDEBUG(physics(), "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); + HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyB"); return nullptr; } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 18335a1296..86a6dee145 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -41,6 +41,11 @@ void render::renderItems(const RenderContextPointer& renderContext, const ItemBo } } +namespace { + int repeatedInvalidKeyMessageID = 0; + std::atomic messageIDInit = 0; +} + void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item, const ShapeKey& globalKey) { assert(item.getKey().isShape()); auto key = item.getShapeKey() | globalKey; @@ -55,7 +60,10 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons } else if (key.hasOwnPipeline()) { item.render(args); } else { - HIFI_FCDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); + if (++messageIDInit == 1) { + repeatedInvalidKeyMessageID = LogHandler::getInstance().newRepeatedMessageID(); + } + HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; } @@ -106,7 +114,10 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { - HIFI_FCDEBUG(renderlogging(), "Item could not be rendered with invalid key" << key); + if (++messageIDInit == 1) { + repeatedInvalidKeyMessageID = LogHandler::getInstance().newRepeatedMessageID(); + } + HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } } } diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 06287e4d81..70e41b8304 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -92,15 +92,15 @@ void LogHandler::setShouldDisplayMilliseconds(bool shouldDisplayMilliseconds) { void LogHandler::flushRepeatedMessages() { QMutexLocker lock(&_mutex); - // New repeat-supress scheme: - for (int m = 0; m < (int)_repeatCounts.size(); ++m) { - int repeatCount = _repeatCounts[m]; + // New repeat-suppress scheme: + for (int m = 0; m < (int)_repeatedMessageRecords.size(); ++m) { + int repeatCount = _repeatedMessageRecords[m].repeatCount; if (repeatCount > 1) { QString repeatLogMessage = QString().setNum(repeatCount) + " repeated log entries - Last entry: \"" - + _repeatedMessageStrings[m] + "\""; + + _repeatedMessageRecords[m].repeatString + "\""; printMessage(LogSuppressed, QMessageLogContext(), repeatLogMessage); - _repeatCounts[m] = 0; - _repeatedMessageStrings[m] = QString(); + _repeatedMessageRecords[m].repeatCount = 0; + _repeatedMessageRecords[m].repeatString = QString(); } } } @@ -193,8 +193,8 @@ int LogHandler::newRepeatedMessageID() { QMutexLocker lock(&_mutex); int newMessageId = _currentMessageID; ++_currentMessageID; - _repeatCounts.push_back(0); - _repeatedMessageStrings.resize(_currentMessageID); + RepeatedMessageRecord newRecord { 0 }; + _repeatedMessageRecords.push_back(newRecord); return newMessageId; } @@ -205,11 +205,11 @@ void LogHandler::printRepeatedMessage(int messageID, LogMsgType type, const QMes return; } - if (_repeatCounts[messageID] == 0) { + if (_repeatedMessageRecords[messageID].repeatCount == 0) { printMessage(type, context, message); } else { - _repeatedMessageStrings[messageID] = message; + _repeatedMessageRecords[messageID].repeatString = message; } - ++_repeatCounts[messageID]; + ++_repeatedMessageRecords[messageID].repeatCount; } diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index dfdfee6c3d..2b1f9c47aa 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -76,8 +76,11 @@ private: std::vector _onetimeMessages; int _currentMessageID { 0 }; - std::vector _repeatCounts; - std::vector _repeatedMessageStrings; + struct RepeatedMessageRecord { + int repeatCount; + QString repeatString; + }; + std::vector _repeatedMessageRecords; static QMutex _mutex; }; @@ -106,6 +109,6 @@ private: } \ } while (false) -#define HIFI_FDEBUG_ID(message) HIFI_FCDEBUG_ID((*QLoggingCategory::defaultCategory()), message) +#define HIFI_FDEBUG_ID(messageID, message) HIFI_FCDEBUG_ID((*QLoggingCategory::defaultCategory()), messageID, message) #endif // hifi_LogHandler_h From ce5f6da6ca897c92ec94bba981dc73f5a753be11 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 14:43:26 -0700 Subject: [PATCH 054/174] Restore setup of flush timer that was inadvertently lost --- libraries/shared/src/LogHandler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 70e41b8304..a5c8cfd420 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -36,6 +36,9 @@ LogHandler::LogHandler() { // when the log handler is first setup we should print our timezone QString timezoneString = "Time zone: " + QDateTime::currentDateTime().toString("t"); printMessage(LogMsgType::LogInfo, QMessageLogContext(), timezoneString); + + // make sure we setup the repeated message flusher, but do it on the LogHandler thread + QMetaObject::invokeMethod(this, "setupRepeatedMessageFlusher"); } LogHandler::~LogHandler() { From d05f0600d474e48f00ef1e1066c513085d9a3b37 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 15:44:47 -0700 Subject: [PATCH 055/174] Handle one-time messages outside LogHandler class Also change to std::call_once for the file-scope message IDs. --- domain-server/src/DomainServer.cpp | 26 +++++++++++++----------- libraries/render/src/render/DrawTask.cpp | 12 +++++------ libraries/shared/src/LogHandler.cpp | 23 --------------------- libraries/shared/src/LogHandler.h | 7 ------- 4 files changed, 19 insertions(+), 49 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b1f996c9b2..f48ef80048 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1284,10 +1284,10 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer NOISY_MESSAGE_INTERVAL_MSECS) { - static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex - ("Received a request for assignment type [^ ]+ from [^ ]+"); + static bool printedAssignmentTypeMessage = false; + if (!printedAssignmentTypeMessage && (requestAssignment.getType() != Assignment::AgentType + || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS)) { + printedAssignmentTypeMessage = true; qDebug() << "Received a request for assignment type" << requestAssignment.getType() << "from" << message->getSenderSockAddr(); noisyMessageTimer.restart(); @@ -1324,10 +1324,10 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointergetUUID(), requestAssignment.getWalletUUID(), requestAssignment.getNodeVersion()); } else { - if (requestAssignment.getType() != Assignment::AgentType - || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS) { - static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex - ("Unable to fulfill assignment request of type [^ ]+ from [^ ]+"); + static bool printedAssignmentRequestMessage = false; + if (!printedAssignmentRequestMessage && (requestAssignment.getType() != Assignment::AgentType + || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS)) { + printedAssignmentRequestMessage = true; qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << message->getSenderSockAddr(); noisyMessageTimer.restart(); @@ -1576,10 +1576,12 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() { callbackParameters.jsonCallbackReceiver = this; callbackParameters.jsonCallbackMethod = "handleSuccessfulICEServerAddressUpdate"; - static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex - ("Updating ice-server address in High Fidelity Metaverse API to [^ \n]+"); - qDebug() << "Updating ice-server address in High Fidelity Metaverse API to" - << (_iceServerSocket.isNull() ? "" : _iceServerSocket.getAddress().toString()); + static bool printedIceServerMessage = false; + if (!printedIceServerMessage) { + printedIceServerMessage = true; + qDebug() << "Updating ice-server address in High Fidelity Metaverse API to" + << (_iceServerSocket.isNull() ? "" : _iceServerSocket.getAddress().toString()); + } static const QString DOMAIN_ICE_ADDRESS_UPDATE = "/api/v1/domains/%1/ice_server_address"; diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 86a6dee145..ac0adb54ff 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -43,7 +43,7 @@ void render::renderItems(const RenderContextPointer& renderContext, const ItemBo namespace { int repeatedInvalidKeyMessageID = 0; - std::atomic messageIDInit = 0; + std::once_flag messageIDFlag; } void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item, const ShapeKey& globalKey) { @@ -60,9 +60,8 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons } else if (key.hasOwnPipeline()) { item.render(args); } else { - if (++messageIDInit == 1) { - repeatedInvalidKeyMessageID = LogHandler::getInstance().newRepeatedMessageID(); - } + std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, + repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; @@ -114,9 +113,8 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { - if (++messageIDInit == 1) { - repeatedInvalidKeyMessageID = LogHandler::getInstance().newRepeatedMessageID(); - } + std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, + repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } } diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index a5c8cfd420..8cd43e8c0a 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -114,21 +114,6 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont } QMutexLocker lock(&_mutex); - if (type == LogDebug) { - // see if this message is one we should only print once - for (auto& onceOnly : _onetimeMessages) { - if (onceOnly.regexp.indexIn(message) != -1) { - if (onceOnly.messageCount++ == 0) { - // we have a match and haven't yet printed this message. - break; - } else { - // We've already printed this message, don't print it again. - return QString(); - } - } - } - } - // log prefix is in the following format // [TIMESTAMP] [DEBUG] [PID] [TID] [TARGET] logged string @@ -184,14 +169,6 @@ void LogHandler::setupRepeatedMessageFlusher() { }); } -const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) { - QMutexLocker lock(&_mutex); - OnceOnlyMessage onetimeMessage; - onetimeMessage.regexp = QRegExp(regexString); - _onetimeMessages.push_back(onetimeMessage); - return regexString; -} - int LogHandler::newRepeatedMessageID() { QMutexLocker lock(&_mutex); int newMessageId = _currentMessageID; diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 2b1f9c47aa..56450768ff 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -51,7 +51,6 @@ public: /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); - const QString& addOnlyOnceMessageRegex(const QString& regexString); int newRepeatedMessageID(); void printRepeatedMessage(int messageID, LogMsgType type, const QMessageLogContext& context, const QString &message); @@ -69,12 +68,6 @@ private: bool _shouldOutputThreadID { false }; bool _shouldDisplayMilliseconds { false }; - struct OnceOnlyMessage { - QRegExp regexp; - int messageCount { 0 }; - }; - std::vector _onetimeMessages; - int _currentMessageID { 0 }; struct RepeatedMessageRecord { int repeatCount; From 104788de508e9b0ce134beed50b069142fcb2667 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 16:03:56 -0700 Subject: [PATCH 056/174] Take out useless noisy message timer --- domain-server/src/DomainServer.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index f48ef80048..432a9a83a9 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1273,24 +1273,11 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer NOISY_MESSAGE_INTERVAL_MSECS)) { + if (!printedAssignmentTypeMessage && requestAssignment.getType() != Assignment::AgentType) { printedAssignmentTypeMessage = true; qDebug() << "Received a request for assignment type" << requestAssignment.getType() << "from" << message->getSenderSockAddr(); - noisyMessageTimer.restart(); } SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); @@ -1325,12 +1312,10 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer NOISY_MESSAGE_INTERVAL_MSECS)) { + if (!printedAssignmentRequestMessage && requestAssignment.getType() != Assignment::AgentType) { printedAssignmentRequestMessage = true; qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << message->getSenderSockAddr(); - noisyMessageTimer.restart(); } } } From a370d287c3db5fad8c5e2d9fd2af56d312d19bc1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 16:42:10 -0700 Subject: [PATCH 057/174] Change AudioRingBuffer.cpp to use std::call_once --- libraries/audio/src/AudioRingBuffer.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 683211aac6..8f41ca8947 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -153,7 +153,7 @@ int AudioRingBufferTemplate::appendData(char *data, int maxSize) { namespace { int repeatedOverflowMessageID = 0; - std::atomic messageIDInit = 0; + std::once_flag messageIDFlag; } template @@ -169,9 +169,8 @@ int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - if (++messageIDInit == 1) { - repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); - } + std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, + repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } @@ -281,9 +280,8 @@ int AudioRingBufferTemplate::writeSamples(ConstIterator source, int maxSample _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - if (++messageIDInit == 1) { - repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); - } + std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, + repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } @@ -307,9 +305,8 @@ int AudioRingBufferTemplate::writeSamplesWithFade(ConstIterator source, int m _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - if (++messageIDInit == 1) { - repeatedOverflowMessageID = LogHandler::getInstance().newRepeatedMessageID(); - } + std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, + repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } From 93bcd1df2008f8b9ab4689878467d3b0f0206f3f Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 17:55:45 -0700 Subject: [PATCH 058/174] Fix Linux build for std::call_once with lambda MacOS & Ubuntu don't like the combination of std::call_once and lambda w/ reference param, for some reason. Change to pointer param. --- libraries/audio/src/AudioRingBuffer.cpp | 12 ++++++------ libraries/render/src/render/DrawTask.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 8f41ca8947..518fdd3c17 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -169,8 +169,8 @@ int AudioRingBufferTemplate::writeData(const char* data, int maxSize) { _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, - repeatedOverflowMessageID); + std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, + &repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } @@ -280,8 +280,8 @@ int AudioRingBufferTemplate::writeSamples(ConstIterator source, int maxSample _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, - repeatedOverflowMessageID); + std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, + &repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } @@ -305,8 +305,8 @@ int AudioRingBufferTemplate::writeSamplesWithFade(ConstIterator source, int m _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete); _overflowCount++; - std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, - repeatedOverflowMessageID); + std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, + &repeatedOverflowMessageID); HIFI_FCDEBUG_ID(audio(), repeatedOverflowMessageID, RING_BUFFER_OVERFLOW_DEBUG); } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index ac0adb54ff..8aabffea46 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -60,8 +60,8 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons } else if (key.hasOwnPipeline()) { item.render(args); } else { - std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, - repeatedInvalidKeyMessageID); + std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, + &repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } args->_itemShapeKey = 0; @@ -113,8 +113,8 @@ void render::renderStateSortShapes(const RenderContextPointer& renderContext, } else if (key.hasOwnPipeline()) { ownPipelineBucket.push_back( std::make_tuple(item, key) ); } else { - std::call_once(messageIDFlag, [](int& id) { id = LogHandler::getInstance().newRepeatedMessageID(); }, - repeatedInvalidKeyMessageID); + std::call_once(messageIDFlag, [](int* id) { *id = LogHandler::getInstance().newRepeatedMessageID(); }, + &repeatedInvalidKeyMessageID); HIFI_FCDEBUG_ID(renderlogging(), repeatedInvalidKeyMessageID, "Item could not be rendered with invalid key" << key); } } From f10bbce5575cda902ced8bdca784e316b590b8ef Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 4 Apr 2018 18:32:40 -0700 Subject: [PATCH 059/174] Squelch initialization warning --- libraries/shared/src/LogHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 8cd43e8c0a..45cf01510d 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -173,7 +173,7 @@ int LogHandler::newRepeatedMessageID() { QMutexLocker lock(&_mutex); int newMessageId = _currentMessageID; ++_currentMessageID; - RepeatedMessageRecord newRecord { 0 }; + RepeatedMessageRecord newRecord { 0, QString() }; _repeatedMessageRecords.push_back(newRecord); return newMessageId; } From cc341e8ad7c14b7b74b6819da3bb17dcd742c458 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 5 Apr 2018 15:38:56 -0700 Subject: [PATCH 060/174] highlight nearby entities --- .../controllerModules/farActionGrabEntity.js | 2 + .../highlightNearbyEntities.js | 88 +++++++++++++++++++ .../controllerModules/nearActionGrabEntity.js | 3 +- .../controllerModules/nearParentGrabEntity.js | 11 ++- .../controllerModules/nearTrigger.js | 3 +- .../system/controllers/controllerScripts.js | 1 + .../libraries/controllerDispatcherUtils.js | 24 ++++- 7 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 scripts/system/controllers/controllerModules/highlightNearbyEntities.js diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 58f032de08..b7fdacfe38 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -404,6 +404,7 @@ Script.include("/~/system/libraries/Xform.js"); this.endNearGrabAction(); Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); + this.highlightedEntity = null; return makeRunningValues(false, [], []); } this.intersectionDistance = controllerData.rayPicks[this.hand].distance; @@ -575,6 +576,7 @@ Script.include("/~/system/libraries/Xform.js"); this.endNearGrabAction(); Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); + this.highlightedEntity = null; return makeRunningValues(false, [], []); } } diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js new file mode 100644 index 0000000000..de58c5a388 --- /dev/null +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -0,0 +1,88 @@ +"use strict"; + +// highlightNearbyEntities.js +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + + +/* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, + makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, + PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, + DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams +*/ + +(function () { + Script.include("/~/system/libraries/controllerDispatcherUtils.js"); + Script.include("/~/system/libraries/controllers.js"); + var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); + function HighlightNearbyEntities(hand) { + this.hand = hand; + this.highlightedEntities = []; + + this.parameters = dispatcherUtils.makeDispatcherModuleParameters( + 480, + this.hand === dispatcherUtils.RIGHT_HAND ? ["rightHand"] : ["leftHand"], + [], + 100); + + + this.isGrabable = function(controllerData, props) { + if (dispatcherUtils.entityIsGrabbable(props) || dispatcherUtils.entityIsCloneable(props)) { + // if we've attempted to grab a child, roll up to the root of the tree + var groupRootProps = dispatcherUtils.findGroupParent(controllerData, props); + if (dispatcherUtils.entityIsGrabbable(groupRootProps)) { + return true; + } + return true; + } + return false; + }; + + this.hasHyperLink = function(props) { + return (props.href !== "" && props.href !== undefined); + }; + + this.highlightEntities = function(controllerData) { + if (this.highlightedEntities.length > 0) { + dispatcherUtils.clearHighlightedEntities(); + this.highlightedEntities = []; + } + + var nearbyEntitiesProperties = controllerData.nearbyEntityProperties[this.hand]; + var sensorScaleFactor = MyAvatar.sensorToWorldScale; + for (var i = 0; i < nearbyEntitiesProperties.length; i++) { + var props = nearbyEntitiesProperties[i]; + if (props.distance > dispatcherUtils.NEAR_GRAB_RADIUS * sensorScaleFactor) { + continue; + } + if (this.isGrabable(controllerData, props) || this.hasHyperLink(props)) { + dispatcherUtils.highlightTargetEntity(props.id); + this.highlightedEntities.push(props.id); + } + } + }; + + this.isReady = function(controllerData) { + this.highlightEntities(controllerData); + return dispatcherUtils.makeRunningValues(false, [], []); + }; + + this.run = function(controllerData) { + return this.isReady(controllerData); + }; + } + + var leftHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.LEFT_HAND); + var rightHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.RIGHT_HAND); + + dispatcherUtils.enableDispatcherModule("LeftHighlightNearbyEntities", leftHighlightNearbyEntities); + dispatcherUtils.enableDispatcherModule("RightHighlightNearbyEntities", rightHighlightNearbyEntities); + + function cleanup() { + dispatcherUtils.disableDispatcherModule("LeftHighlightNearbyEntities"); + dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities"); + } + + Script.scriptEnding.connect(cleanup); +}()); diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index 147d6b807f..da9cafbe07 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -10,7 +10,7 @@ propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity, - HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE + HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -114,6 +114,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "startNearGrab", args); + unhighlightTargetEntity(this.targetEntityID); }; // this is for when the action is going to time-out diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 01c8424e0c..945c091f7e 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -11,7 +11,8 @@ TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, - TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox + TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Selection, DISPATCHER_HOVERING_LIST, Uuid, + highlightTargetEntity, unhighlightTargetEntity */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -34,6 +35,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.autoUnequipCounter = 0; this.lastUnexpectedChildrenCheckTime = 0; this.robbed = false; + this.highlightedEntity = null; this.parameters = makeDispatcherModuleParameters( 500, @@ -87,7 +89,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.startNearParentingGrabEntity = function (controllerData, targetProps) { Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - + unhighlightTargetEntity(this.targetEntityID); var handJointIndex; // if (this.ignoreIK) { // handJointIndex = this.controllerJointIndex; @@ -158,6 +160,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); grabbedEntity: this.targetEntityID, joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" })); + unhighlightTargetEntity(this.targetEntityID); this.grabbing = false; this.targetEntityID = null; this.robbed = false; @@ -280,6 +283,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it } else { this.targetEntityID = targetProps.id; + this.highlightedEntity = this.targetEntityID; + highlightTargetEntity(this.targetEntityID); return makeRunningValues(true, [this.targetEntityID], []); } } else { @@ -300,6 +305,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; if (!props) { // entity was deleted + unhighlightTargetEntity(this.targetEntityID); this.grabbing = false; this.targetEntityID = null; this.hapticTargetID = null; @@ -321,6 +327,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var readiness = this.isReady(controllerData); if (!readiness.active) { this.robbed = false; + unhighlightTargetEntity(this.highlightedEntity); return readiness; } if (controllerData.triggerClicks[this.hand] || controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE) { diff --git a/scripts/system/controllers/controllerModules/nearTrigger.js b/scripts/system/controllers/controllerModules/nearTrigger.js index 42db3d6f61..6a9cd9fbcd 100644 --- a/scripts/system/controllers/controllerModules/nearTrigger.js +++ b/scripts/system/controllers/controllerModules/nearTrigger.js @@ -7,7 +7,7 @@ /* global Script, Entities, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, getGrabbableData, - Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS + Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS, unhighlightTargetEntity */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -55,6 +55,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.startNearTrigger = function (controllerData) { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "startNearTrigger", args); + unhighlightTargetEntity(this.targetEntityID); }; this.continueNearTrigger = function (controllerData) { diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index 8db8e29f37..058c99349d 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -32,6 +32,7 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/hudOverlayPointer.js", "controllerModules/mouseHMD.js", "controllerModules/scaleEntity.js", + "controllerModules/highlightNearbyEntities.js", "controllerModules/nearGrabHyperLinkEntity.js" ]; diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index f82de4b71d..827b29e78a 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -7,6 +7,7 @@ /* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform, + Selection, MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true, HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true, DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true, @@ -51,7 +52,10 @@ TEAR_AWAY_DISTANCE:true, TEAR_AWAY_COUNT:true, TEAR_AWAY_CHECK_TIME:true, - distanceBetweenPointAndEntityBoundingBox:true + distanceBetweenPointAndEntityBoundingBox:true, + highlightTargetEntity:true, + clearHighlightedEntities:true, + unhighlightTargetEntity:true */ MSECS_PER_SEC = 1000.0; @@ -95,7 +99,7 @@ DISPATCHER_HOVERING_STYLE = { isOutlineSmooth: true, outlineWidth: 0, outlineUnoccludedColor: {red: 255, green: 128, blue: 128}, - outlineUnoccludedAlpha: 0, + outlineUnoccludedAlpha: 0.0, outlineOccludedColor: {red: 255, green: 128, blue: 128}, outlineOccludedAlpha:0.0, fillUnoccludedColor: {red: 255, green: 255, blue: 255}, @@ -235,6 +239,18 @@ entityIsGrabbable = function (props) { return true; }; +clearHighlightedEntities = function() { + Selection.clearSelectedItemsList(DISPATCHER_HOVERING_LIST); +}; + +highlightTargetEntity = function(entityID) { + Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", entityID); +}; + +unhighlightTargetEntity = function(entityID) { + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", entityID); +}; + entityIsDistanceGrabbable = function(props) { if (!entityIsGrabbable(props)) { return false; @@ -404,7 +420,11 @@ if (typeof module !== 'undefined') { makeDispatcherModuleParameters: makeDispatcherModuleParameters, enableDispatcherModule: enableDispatcherModule, disableDispatcherModule: disableDispatcherModule, + highlightTargetEntity: highlightTargetEntity, + unhighlightTargetEntity: unhighlightTargetEntity, + clearHighlightedEntities: clearHighlightedEntities, makeRunningValues: makeRunningValues, + findGroupParent: findGroupParent, LEFT_HAND: LEFT_HAND, RIGHT_HAND: RIGHT_HAND, BUMPER_ON_VALUE: BUMPER_ON_VALUE, From 07b1a6be01365304f44cfdc5f7ba735175e715a3 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 6 Apr 2018 11:01:40 -0700 Subject: [PATCH 061/174] saving work --- .../controllers/controllerDispatcher.js | 2 +- .../controllerModules/equipEntity.js | 50 ++++++++++++++++++- .../highlightNearbyEntities.js | 3 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 86b7a98b2d..f4fd933ce4 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -30,7 +30,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ; var PROFILE = false; - var DEBUG = false; + var DEBUG = true; if (typeof Test !== "undefined") { PROFILE = true; diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 252f6efa9e..c5ec76ccfd 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -23,6 +23,27 @@ var DEFAULT_SPHERE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eq var EQUIP_SPHERE_SCALE_FACTOR = 0.65; +var EQUIPPING_OUTER_COLOR = { red: 0, green: 100, blue: 0 }; +var EQUIPPING_INNER_COLOR = { red: 0, green: 150, blue: 0 }; +var UNEQUIPPING_OUTER_COLOR = { red: 100, green: 0, blue: 0 }; +var UNEQUIPPING_INNER_COLOR = { red: 150, green: 0, blue: 0 }; + +var CIRCLE_3D_PROPERTIES = { + solid: true, + innerRadius: 0.0, + outerRadius: 1.0, + startAt: 0, + endAt: 180, + outerColor: EQUIPPING_OUTER_COLOR, + innerColor: EQUIPPING_INNER_COLOR, + alpha: 1.0, + innerAlpha: 0.9, + Alpha: 1.0 +}; + +var EQUIP_TIME = 3000; +var UNEQUIP_TIME = 4000; + // Each overlayInfoSet describes a single equip hotspot. // It is an object with the following keys: // timestamp - last time this object was updated, used to delete stale hotspot overlays. @@ -158,6 +179,29 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } }; + +function EquipTimer(hand) { + this.hand = hand; + this.controllerTriggerPressed = false; + this.equipTime = EQUIP_TIME; + this.currentTimeLapse = 0; + this.equip = true; + this.finished = false; + this.circle3dProperties = CIRCLE_3D_PROPERTIES; + this.circle3dOverlay = Overlays.addOverlay("circle3d", this.circle3dProperties); +} + +EquipTimer.prototype.update = function(deltaTime, timestamp, controllerData) { +}; + +EquipTimer.prototype.finished = function() { + return this.finished; +}; + +EquipTimer.prototype.cleanup = function() { + Overlays.deleteOverlay(this.circle3dOverlay); +}; + (function() { var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints"; @@ -279,6 +323,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var equipHotspotBuddy = new EquipHotspotBuddy(); + this.equipTimer = new EquipTimer(this.hand); + this.setMessageGrabData = function(entityProperties) { if (entityProperties) { this.messageGrabEntity = true; @@ -621,8 +667,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa // if the potentialHotspot os not cloneable and locked return null if (potentialEquipHotspot && - (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) || - this.messageGrabEntity)) { + (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease && + this.equipTimer.finished()) || this.messageGrabEntity)) { this.grabbedHotspot = potentialEquipHotspot; this.targetEntityID = this.grabbedHotspot.entityID; this.startEquipEntity(controllerData); diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index de58c5a388..d204499c05 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -45,7 +45,8 @@ this.highlightEntities = function(controllerData) { if (this.highlightedEntities.length > 0) { - dispatcherUtils.clearHighlightedEntities(); + //print("-----> clearing + //dispatcherUtils.clearHighlightedEntities(); this.highlightedEntities = []; } From fd478328579c3d6a95188c3103943e88cf22a7af Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 6 Apr 2018 11:47:09 -0700 Subject: [PATCH 062/174] saving changes --- scripts/system/controllers/controllerDispatcher.js | 1 + .../controllers/controllerModules/equipEntity.js | 14 ++++++++++++-- .../controllerModules/highlightNearbyEntities.js | 3 +-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index f4fd933ce4..12f9fdbba0 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -125,6 +125,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); }; Selection.enableListHighlight(DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE); + Selection.enableListToScene(DISPATCHER_HOVERING_LIST); this.updateTimings = function () { _this.intervalCount++; diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index c5ec76ccfd..60a36ea06d 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -30,6 +30,7 @@ var UNEQUIPPING_INNER_COLOR = { red: 150, green: 0, blue: 0 }; var CIRCLE_3D_PROPERTIES = { solid: true, + visible: false, innerRadius: 0.0, outerRadius: 1.0, startAt: 0, @@ -182,7 +183,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa function EquipTimer(hand) { this.hand = hand; - this.controllerTriggerPressed = false; + this.primaryTriggerPressed = false; + this.secondaryTriggerPressed = false; this.equipTime = EQUIP_TIME; this.currentTimeLapse = 0; this.equip = true; @@ -192,6 +194,14 @@ function EquipTimer(hand) { } EquipTimer.prototype.update = function(deltaTime, timestamp, controllerData) { + /*var TRIGGER_ON_VALUE = 0.105; + var BUMPER_ON_VALUE = 0.5; + var primaryTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE; + var secondaryTriggerPressed = controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE; + + if (primaryTriggerPressed || secondaryTriggerPressed) { + if (primaryTriggerPressed === this.primaryTriggerPressed && + */ }; EquipTimer.prototype.finished = function() { @@ -662,7 +672,7 @@ EquipTimer.prototype.cleanup = function() { } equipHotspotBuddy.update(deltaTime, timestamp, controllerData); - + this.equiptTimer.update(deltaTime, timestamp, controllerData); // if the potentialHotspot is cloneable, clone it and return it // if the potentialHotspot os not cloneable and locked return null diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index d204499c05..de58c5a388 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -45,8 +45,7 @@ this.highlightEntities = function(controllerData) { if (this.highlightedEntities.length > 0) { - //print("-----> clearing - //dispatcherUtils.clearHighlightedEntities(); + dispatcherUtils.clearHighlightedEntities(); this.highlightedEntities = []; } From 2c20593b6defe3a4bf1a421518a2e6a46976edbd Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 6 Apr 2018 16:30:45 -0700 Subject: [PATCH 063/174] editing equip code --- .../controllers/controllerDispatcher.js | 2 +- .../controllerModules/equipEntity.js | 74 +++++++++++++++---- .../highlightNearbyEntities.js | 5 +- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 12f9fdbba0..04f9b3e43a 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -30,7 +30,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ; var PROFILE = false; - var DEBUG = true; + var DEBUG = false; if (typeof Test !== "undefined") { PROFILE = true; diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 60a36ea06d..2d74bbe9ae 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -183,31 +183,62 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa function EquipTimer(hand) { this.hand = hand; + this.timelapsed = 0; this.primaryTriggerPressed = false; this.secondaryTriggerPressed = false; - this.equipTime = EQUIP_TIME; - this.currentTimeLapse = 0; - this.equip = true; + this.targetTime = EQUIP_TIME; this.finished = false; this.circle3dProperties = CIRCLE_3D_PROPERTIES; this.circle3dOverlay = Overlays.addOverlay("circle3d", this.circle3dProperties); } -EquipTimer.prototype.update = function(deltaTime, timestamp, controllerData) { - /*var TRIGGER_ON_VALUE = 0.105; +EquipTimer.prototype.update = function(deltaTime, targetEntityID, controllerData) { + var TRIGGER_ON_VALUE = 0.105; var BUMPER_ON_VALUE = 0.5; var primaryTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE; var secondaryTriggerPressed = controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE; if (primaryTriggerPressed || secondaryTriggerPressed) { - if (primaryTriggerPressed === this.primaryTriggerPressed && - */ + if ((primaryTriggerPressed === this.primaryTriggerPressed) && + (secondaryTriggerPressed === this.secondaryTriggerPressed)) { + this.timelapsed += deltaTime * 1000; // convert to ms + // update overlay + + var entityProperties = Entities.getEntityProperties(targetEntityID, ["position", "rotation"]); + if (entityProperties) { + var PI = 3.14159; + var TWO_PI = PI * 2; + var FORWARD_OFFSET = 0.1 * MyAvatar.sensorToWorldScale; + var direction = Vec3.subtract(entityProperties.position - HMD.position); + var overlayPosition = Vec3.sum(entityProperties.position, Vec3.multiply(FORWARD_OFFSET, direction)); + } + if (this.timelapsed >= this.targetTime) { + print("finished"); + this.finished = true; + } + + return; + } + + this.reset(); + this.primaryTriggerPressed = primaryTriggerPressed; + this.secondaryTriggerPressed = secondaryTriggerPressed; + } else { + this.reset(); + } }; -EquipTimer.prototype.finished = function() { +EquipTimer.prototype.done = function() { return this.finished; }; +EquipTimer.prototype.reset = function() { + this.finished = false; + this.timelapsed = 0; + this.primaryTriggerPressed = false; + this.secondaryTriggerPressed = false; +}; + EquipTimer.prototype.cleanup = function() { Overlays.deleteOverlay(this.circle3dOverlay); }; @@ -324,6 +355,7 @@ EquipTimer.prototype.cleanup = function() { this.shouldSendStart = false; this.equipedWithSecondary = false; this.handHasBeenRightsideUp = false; + this.equipAtRun = false; this.parameters = makeDispatcherModuleParameters( 300, @@ -672,20 +704,23 @@ EquipTimer.prototype.cleanup = function() { } equipHotspotBuddy.update(deltaTime, timestamp, controllerData); - this.equiptTimer.update(deltaTime, timestamp, controllerData); // if the potentialHotspot is cloneable, clone it and return it // if the potentialHotspot os not cloneable and locked return null if (potentialEquipHotspot && - (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease && - this.equipTimer.finished()) || this.messageGrabEntity)) { + (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) || this.messageGrabEntity)) { this.grabbedHotspot = potentialEquipHotspot; this.targetEntityID = this.grabbedHotspot.entityID; - this.startEquipEntity(controllerData); + this.equipAtRun = true; this.messageGrabEntity = false; - this.equipedWithSecondary = this.secondarySmoothedSqueezed(); + if (this.messageGrabEntity) { + this.startEquipEntity(controllerData); + this.equipedWithSecondary = this.secondarySmoothedSqueezed(); + this.equipAtRun = false; + } return makeRunningValues(true, [potentialEquipHotspot.entityID], []); } else { + this.equipAtRun = false; return makeRunningValues(false, [], []); } }; @@ -706,6 +741,19 @@ EquipTimer.prototype.cleanup = function() { var timestamp = Date.now(); this.updateInputs(controllerData); + if (this.equipAtRun) { + if ((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) { + this.equipTimer.update(deltaTime, this.targetEntityID, controllerData); + if (this.equipTimer.done()) { + this.equipAtRun = false; + this.startEquipEntity(controllerData); + this.equipedWithSecondary = this.secondarySmoothedSqueezed(); + this.equipTimer.reset(); + } + return makeRunningValues(true, [], []); + } + } + if (!this.isTargetIDValid(controllerData)) { this.endEquipEntity(); return makeRunningValues(false, [], []); diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index de58c5a388..2b9b79578f 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -9,12 +9,13 @@ /* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams + DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable */ (function () { Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); + Script.include("/~/system/libraries/cloneEntityUtils.js"); var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); function HighlightNearbyEntities(hand) { this.hand = hand; @@ -28,7 +29,7 @@ this.isGrabable = function(controllerData, props) { - if (dispatcherUtils.entityIsGrabbable(props) || dispatcherUtils.entityIsCloneable(props)) { + if (dispatcherUtils.entityIsGrabbable(props) || entityIsCloneable(props)) { // if we've attempted to grab a child, roll up to the root of the tree var groupRootProps = dispatcherUtils.findGroupParent(controllerData, props); if (dispatcherUtils.entityIsGrabbable(groupRootProps)) { From 1113202a906783a492dccf9c3581a7f9d0ea038e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 9 Apr 2018 16:51:20 -0700 Subject: [PATCH 064/174] reverting file --- .../controllerModules/equipEntity.js | 114 +----------------- 1 file changed, 5 insertions(+), 109 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 2d74bbe9ae..252f6efa9e 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -23,28 +23,6 @@ var DEFAULT_SPHERE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eq var EQUIP_SPHERE_SCALE_FACTOR = 0.65; -var EQUIPPING_OUTER_COLOR = { red: 0, green: 100, blue: 0 }; -var EQUIPPING_INNER_COLOR = { red: 0, green: 150, blue: 0 }; -var UNEQUIPPING_OUTER_COLOR = { red: 100, green: 0, blue: 0 }; -var UNEQUIPPING_INNER_COLOR = { red: 150, green: 0, blue: 0 }; - -var CIRCLE_3D_PROPERTIES = { - solid: true, - visible: false, - innerRadius: 0.0, - outerRadius: 1.0, - startAt: 0, - endAt: 180, - outerColor: EQUIPPING_OUTER_COLOR, - innerColor: EQUIPPING_INNER_COLOR, - alpha: 1.0, - innerAlpha: 0.9, - Alpha: 1.0 -}; - -var EQUIP_TIME = 3000; -var UNEQUIP_TIME = 4000; - // Each overlayInfoSet describes a single equip hotspot. // It is an object with the following keys: // timestamp - last time this object was updated, used to delete stale hotspot overlays. @@ -180,69 +158,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } }; - -function EquipTimer(hand) { - this.hand = hand; - this.timelapsed = 0; - this.primaryTriggerPressed = false; - this.secondaryTriggerPressed = false; - this.targetTime = EQUIP_TIME; - this.finished = false; - this.circle3dProperties = CIRCLE_3D_PROPERTIES; - this.circle3dOverlay = Overlays.addOverlay("circle3d", this.circle3dProperties); -} - -EquipTimer.prototype.update = function(deltaTime, targetEntityID, controllerData) { - var TRIGGER_ON_VALUE = 0.105; - var BUMPER_ON_VALUE = 0.5; - var primaryTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE; - var secondaryTriggerPressed = controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE; - - if (primaryTriggerPressed || secondaryTriggerPressed) { - if ((primaryTriggerPressed === this.primaryTriggerPressed) && - (secondaryTriggerPressed === this.secondaryTriggerPressed)) { - this.timelapsed += deltaTime * 1000; // convert to ms - // update overlay - - var entityProperties = Entities.getEntityProperties(targetEntityID, ["position", "rotation"]); - if (entityProperties) { - var PI = 3.14159; - var TWO_PI = PI * 2; - var FORWARD_OFFSET = 0.1 * MyAvatar.sensorToWorldScale; - var direction = Vec3.subtract(entityProperties.position - HMD.position); - var overlayPosition = Vec3.sum(entityProperties.position, Vec3.multiply(FORWARD_OFFSET, direction)); - } - if (this.timelapsed >= this.targetTime) { - print("finished"); - this.finished = true; - } - - return; - } - - this.reset(); - this.primaryTriggerPressed = primaryTriggerPressed; - this.secondaryTriggerPressed = secondaryTriggerPressed; - } else { - this.reset(); - } -}; - -EquipTimer.prototype.done = function() { - return this.finished; -}; - -EquipTimer.prototype.reset = function() { - this.finished = false; - this.timelapsed = 0; - this.primaryTriggerPressed = false; - this.secondaryTriggerPressed = false; -}; - -EquipTimer.prototype.cleanup = function() { - Overlays.deleteOverlay(this.circle3dOverlay); -}; - (function() { var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints"; @@ -355,7 +270,6 @@ EquipTimer.prototype.cleanup = function() { this.shouldSendStart = false; this.equipedWithSecondary = false; this.handHasBeenRightsideUp = false; - this.equipAtRun = false; this.parameters = makeDispatcherModuleParameters( 300, @@ -365,8 +279,6 @@ EquipTimer.prototype.cleanup = function() { var equipHotspotBuddy = new EquipHotspotBuddy(); - this.equipTimer = new EquipTimer(this.hand); - this.setMessageGrabData = function(entityProperties) { if (entityProperties) { this.messageGrabEntity = true; @@ -704,23 +616,20 @@ EquipTimer.prototype.cleanup = function() { } equipHotspotBuddy.update(deltaTime, timestamp, controllerData); + // if the potentialHotspot is cloneable, clone it and return it // if the potentialHotspot os not cloneable and locked return null if (potentialEquipHotspot && - (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) || this.messageGrabEntity)) { + (((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) || + this.messageGrabEntity)) { this.grabbedHotspot = potentialEquipHotspot; this.targetEntityID = this.grabbedHotspot.entityID; - this.equipAtRun = true; + this.startEquipEntity(controllerData); this.messageGrabEntity = false; - if (this.messageGrabEntity) { - this.startEquipEntity(controllerData); - this.equipedWithSecondary = this.secondarySmoothedSqueezed(); - this.equipAtRun = false; - } + this.equipedWithSecondary = this.secondarySmoothedSqueezed(); return makeRunningValues(true, [potentialEquipHotspot.entityID], []); } else { - this.equipAtRun = false; return makeRunningValues(false, [], []); } }; @@ -741,19 +650,6 @@ EquipTimer.prototype.cleanup = function() { var timestamp = Date.now(); this.updateInputs(controllerData); - if (this.equipAtRun) { - if ((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) { - this.equipTimer.update(deltaTime, this.targetEntityID, controllerData); - if (this.equipTimer.done()) { - this.equipAtRun = false; - this.startEquipEntity(controllerData); - this.equipedWithSecondary = this.secondarySmoothedSqueezed(); - this.equipTimer.reset(); - } - return makeRunningValues(true, [], []); - } - } - if (!this.isTargetIDValid(controllerData)) { this.endEquipEntity(); return makeRunningValues(false, [], []); From 2e1ebac03ffcfb7b7180330c1d51b9ecd6b226e9 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 9 Apr 2018 18:07:03 -0700 Subject: [PATCH 065/174] clean up functionality --- .../controllerModules/equipEntity.js | 4 +- .../highlightNearbyEntities.js | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 252f6efa9e..8ad5c80cb8 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -10,7 +10,7 @@ getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable, - cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid + cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid, unhighlightTargetEntity */ Script.include("/~/system/libraries/Xform.js"); @@ -483,7 +483,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.dropGestureReset(); this.clearEquipHaptics(); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - + unhighlightTargetEntity(this.targetEntityID); var grabbedProperties = Entities.getEntityProperties(this.targetEntityID); // if an object is "equipped" and has a predefined offset, use it. diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index 2b9b79578f..44d48138d2 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -17,8 +17,21 @@ Script.include("/~/system/libraries/controllers.js"); Script.include("/~/system/libraries/cloneEntityUtils.js"); var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); + + function differenceInArrays(firstArray, secondArray) { + print("first " + firstArray); + print("second " + secondArray); + var differenceArray = firstArray.filter(function(element) { + return secondArray.indexOf(element) < 0; + }); + + return differenceArray; + } + function HighlightNearbyEntities(hand) { this.hand = hand; + this.otherHand = hand === dispatcherUtils.RIGHT_HAND ? dispatcherUtils.LEFT_HAND : + dispatcherUtils.RIGHT_HAND; this.highlightedEntities = []; this.parameters = dispatcherUtils.makeDispatcherModuleParameters( @@ -44,13 +57,20 @@ return (props.href !== "" && props.href !== undefined); }; - this.highlightEntities = function(controllerData) { - if (this.highlightedEntities.length > 0) { - dispatcherUtils.clearHighlightedEntities(); - this.highlightedEntities = []; - } + this.getOtherModule = function() { + var otherModule = this.hand === dispatcherUtils.RIGHT_HAND ? leftHighlightNearbyEntities : + rightHighlightNearbyEntities; + return otherModule; + }; + this.getOtherHandHighlightedEntities = function() { + return this.getOtherModule().highlightedEntities; + }; + + this.highlightEntities = function(controllerData) { var nearbyEntitiesProperties = controllerData.nearbyEntityProperties[this.hand]; + var otherHandHighlightedEntities = this.getOtherHandHighlightedEntities(); + var newHighlightedEntities = []; var sensorScaleFactor = MyAvatar.sensorToWorldScale; for (var i = 0; i < nearbyEntitiesProperties.length; i++) { var props = nearbyEntitiesProperties[i]; @@ -59,9 +79,18 @@ } if (this.isGrabable(controllerData, props) || this.hasHyperLink(props)) { dispatcherUtils.highlightTargetEntity(props.id); - this.highlightedEntities.push(props.id); + newHighlightedEntities.push(props.id); } } + + var unhighlightEntities = differenceInArrays(this.highlightedEntities, newHighlightedEntities); + + unhighlightEntities.forEach(function(entityID) { + if (otherHandHighlightedEntities.indexOf(entityID) < 0 ) { + dispatcherUtils.unhighlightTargetEntity(entityID); + } + }); + this.highlightedEntities = newHighlightedEntities; }; this.isReady = function(controllerData) { From 447163bd07e40b62bd832ac7271bd71a5e1b8285 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 10 Apr 2018 09:23:40 -0700 Subject: [PATCH 066/174] clean up scripts --- .../controllerModules/equipEntity.js | 6 ++++ .../highlightNearbyEntities.js | 33 ++++++++++++++++--- .../controllerModules/nearActionGrabEntity.js | 6 ++++ .../controllerModules/nearParentGrabEntity.js | 6 ++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 8ad5c80cb8..09d64b5d05 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -484,6 +484,12 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.clearEquipHaptics(); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); unhighlightTargetEntity(this.targetEntityID); + var message = { + hand: this.hand, + entityID: this.targetEntityID + }; + + Messages.sendMessage('Hifi-unhighlight-entity', JSON.stringify(message)); var grabbedProperties = Entities.getEntityProperties(this.targetEntityID); // if an object is "equipped" and has a predefined offset, use it. diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index 44d48138d2..a102a5d735 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -9,7 +9,7 @@ /* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable + DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable, Messages, print */ (function () { @@ -19,8 +19,6 @@ var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); function differenceInArrays(firstArray, secondArray) { - print("first " + firstArray); - print("second " + secondArray); var differenceArray = firstArray.filter(function(element) { return secondArray.indexOf(element) < 0; }); @@ -57,6 +55,13 @@ return (props.href !== "" && props.href !== undefined); }; + this.removeEntityFromHighlightList = function(entityID) { + var index = this.highlightedEntities.indexOf(entityID); + if (index > -1) { + this.highlightedEntities.splice(index, 1); + } + }; + this.getOtherModule = function() { var otherModule = this.hand === dispatcherUtils.RIGHT_HAND ? leftHighlightNearbyEntities : rightHighlightNearbyEntities; @@ -103,6 +108,25 @@ }; } + var handleMessage = function(channel, message, sender) { + var data; + if (sender === MyAvatar.sessionUUID) { + if (channel === 'Hifi-unhighlight-entity') { + try { + data = JSON.parse(message); + + var hand = data.hand; + if (hand === dispatcherUtils.LEFT_HAND) { + leftHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); + } else if (hand === dispatcherUtils.RIGHT_HAND) { + rightHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); + } + } catch (e) { + print("Failed to parse message"); + } + } + } + }; var leftHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.LEFT_HAND); var rightHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.RIGHT_HAND); @@ -113,6 +137,7 @@ dispatcherUtils.disableDispatcherModule("LeftHighlightNearbyEntities"); dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities"); } - + Messages.subscribe('Hifi-unhighlight-entity'); + Messages.messageReceived.connect(handleMessage); Script.scriptEnding.connect(cleanup); }()); diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index da9cafbe07..a1e4cff40d 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -115,6 +115,12 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.targetEntityID, "startNearGrab", args); unhighlightTargetEntity(this.targetEntityID); + var message = { + hand: this.hand, + entityID: this.targetEntityID + }; + + Messages.sendMessage('Hifi-unhighlight-entity', JSON.stringify(message)); }; // this is for when the action is going to time-out diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 945c091f7e..55dde21f46 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -90,6 +90,12 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.startNearParentingGrabEntity = function (controllerData, targetProps) { Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); unhighlightTargetEntity(this.targetEntityID); + var message = { + hand: this.hand, + entityID: this.targetEntityID + }; + + Messages.sendMessage('Hifi-unhighlight-entity', JSON.stringify(message)); var handJointIndex; // if (this.ignoreIK) { // handJointIndex = this.controllerJointIndex; From f81836c8300ee89146f07b4757d392f3f79bcc3a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 9 Apr 2018 18:28:59 -0700 Subject: [PATCH 067/174] support specification of named landing-points in serverless-domain json files --- interface/src/Application.cpp | 3 +++ libraries/entities/src/EntityTree.cpp | 12 ++++++++++++ libraries/entities/src/EntityTree.h | 4 ++++ libraries/networking/src/AddressManager.cpp | 12 ++++++++++-- libraries/networking/src/DomainHandler.cpp | 15 +++++++++++---- libraries/networking/src/DomainHandler.h | 6 +++++- libraries/networking/src/NodeList.cpp | 20 ++++++++++++++++---- 7 files changed, 61 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 18ba881573..9a97e9a42f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3146,6 +3146,9 @@ void Application::loadServerlessDomain(QUrl domainURL) { tmpTree->sendEntities(&_entityEditSender, getEntities()->getTree(), 0, 0, 0); } + std::map namedPaths = tmpTree->getNamedPaths(); + nodeList->getDomainHandler().setIsConnected(true, namedPaths); + _fullSceneReceivedCounter++; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 2cf66911a4..d5c7b9c2d6 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2303,6 +2303,18 @@ bool EntityTree::readFromMap(QVariantMap& map) { _persistDataVersion = map["DataVersion"].toInt(); } + _namedPaths.clear(); + if (map.contains("Paths")) { + QVariantMap namedPathsMap = map["Paths"].toMap(); + for(QVariantMap::const_iterator iter = namedPathsMap.begin(); iter != namedPathsMap.end(); ++iter) { + QString namedPathName = iter.key(); + QString namedPathViewPoint = iter.value().toString(); + _namedPaths[namedPathName] = namedPathViewPoint; + } + } else { + _namedPaths["/"] = "/"; + } + // map will have a top-level list keyed as "Entities". This will be extracted // and iterated over. Each member of this list is converted to a QVariantMap, then // to a QScriptValue, and then to EntityItemProperties. These properties are used diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 5f69714432..791c030fc8 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -301,6 +301,8 @@ public: static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName); static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName); + std::map getNamedPaths() const { return _namedPaths; } + signals: void deletingEntity(const EntityItemID& entityID); void deletingEntityPointer(EntityItem* entityID); @@ -417,6 +419,8 @@ private: static std::function _removeMaterialFromOverlayOperator; bool _serverlessDomain { false }; + + std::map _namedPaths; }; #endif // hifi_EntityTree_h diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 3c24cc796c..56b148a43c 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -29,7 +29,7 @@ #include "UserActivityLogger.h" #include "udt/PacketHeaders.h" -const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json"; +const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json?location=/"; const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; @@ -312,7 +312,15 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { _shareablePlaceName.clear(); setDomainInfo(lookupUrl, trigger); emit lookupResultsFinished(); - handlePath(DOMAIN_SPAWNING_POINT, LookupTrigger::Internal, false); + + QString path = DOMAIN_SPAWNING_POINT; + QUrlQuery queryArgs(lookupUrl); + const QString LOCATION_QUERY_KEY = "location"; + if (queryArgs.hasQueryItem(LOCATION_QUERY_KEY)) { + path = queryArgs.queryItemValue(LOCATION_QUERY_KEY); + } + + handlePath(path, LookupTrigger::Internal, false); return true; } diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index c20d6d73be..fe3b0abcb7 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -173,9 +173,7 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { QString previousHost = _domainURL.host(); _domainURL = domainURL; - if (domainURL.scheme() != URL_SCHEME_HIFI) { - setIsConnected(true); - } else if (previousHost != domainURL.host()) { + if (previousHost != domainURL.host()) { qCDebug(networking) << "Updated domain hostname to" << domainURL.host(); if (!domainURL.host().isEmpty()) { @@ -250,6 +248,14 @@ void DomainHandler::activateICEPublicSocket() { emit completedSocketDiscovery(); } +QString DomainHandler::getViewPointFromNamedPath(QString namedPath) { + auto lookup = _namedPaths.find(namedPath); + if (lookup != _namedPaths.end()) { + return lookup->second; + } + return DOMAIN_SPAWNING_POINT; +} + void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { for (int i = 0; i < hostInfo.addresses().size(); i++) { if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { @@ -279,7 +285,8 @@ void DomainHandler::completedIceServerHostnameLookup() { emit iceSocketAndIDReceived(); } -void DomainHandler::setIsConnected(bool isConnected) { +void DomainHandler::setIsConnected(bool isConnected, std::map namedPaths) { + _namedPaths = namedPaths; if (_isConnected != isConnected) { _isConnected = isConnected; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index fbc60e2492..760b2f8235 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -73,9 +73,11 @@ public: void activateICEPublicSocket(); bool isConnected() const { return _isConnected; } - void setIsConnected(bool isConnected); + void setIsConnected(bool isConnected, std::map namedPaths = std::map()); bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_HIFI; } + QString getViewPointFromNamedPath(QString namedPath); + bool hasSettings() const { return !_settingsObject.isEmpty(); } void requestDomainSettings(); const QJsonObject& getSettingsObject() const { return _settingsObject; } @@ -200,6 +202,8 @@ private: int _checkInPacketsSinceLastReply { 0 }; QTimer _apiRefreshTimer; + + std::map _namedPaths; }; const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" }; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cb0d2e4cd5..3c2b4cd336 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -413,7 +413,14 @@ void NodeList::sendDomainServerCheckIn() { } void NodeList::handleDSPathQuery(const QString& newPath) { - if (_domainHandler.isSocketKnown()) { + if (_domainHandler.isServerless()) { + if (_domainHandler.isConnected()) { + auto viewpoint = _domainHandler.getViewPointFromNamedPath(newPath); + DependencyManager::get()->goToViewpointForPath(viewpoint, newPath); + } else { + _domainHandler.setPendingPath(newPath); + } + } else if (_domainHandler.isSocketKnown()) { // if we have a DS socket we assume it will get this packet and send if off right away sendDSPathQuery(newPath); } else { @@ -427,10 +434,15 @@ void NodeList::sendPendingDSPathQuery() { QString pendingPath = _domainHandler.getPendingPath(); if (!pendingPath.isEmpty()) { - qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; - // this is a slot triggered if we just established a network link with a DS and want to send a path query - sendDSPathQuery(_domainHandler.getPendingPath()); + if (_domainHandler.isServerless()) { + auto viewpoint = _domainHandler.getViewPointFromNamedPath(pendingPath); + DependencyManager::get()->goToViewpointForPath(viewpoint, pendingPath); + } else { + qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; + // this is a slot triggered if we just established a network link with a DS and want to send a path query + sendDSPathQuery(_domainHandler.getPendingPath()); + } // clear whatever the pending path was _domainHandler.clearPendingPath(); From ee3e8093e18bd06f1564e594bd6b882aeea228d4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 10 Apr 2018 10:19:35 -0700 Subject: [PATCH 068/174] update tutorial content to include default landing-point --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index 4d0773f5f5..6235205aad 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v2.zip - URL_MD5 d76bdb3e2bf7ae5d20115bd97b0c44a8 + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67.zip + URL_MD5 3fc4b7332be771d71b43b6d688de9aa7 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From a9b9a1cb105016be5160f7b634c7dfd9f0a75901 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Apr 2018 15:54:19 -0700 Subject: [PATCH 069/174] Commerce: Gifts --- .../fonts/hifi-glyphs.eot | Bin 31678 -> 33642 bytes .../fonts/hifi-glyphs.svg | 11 +- .../fonts/hifi-glyphs.ttf | Bin 31500 -> 33464 bytes .../hifi-glyphs-1.31/fonts/hifi-glyphs.woff | Bin 0 -> 21496 bytes .../icons-reference.html | 90 +- .../styles.css | 33 +- interface/resources/fonts/hifi-glyphs.ttf | Bin 32544 -> 33464 bytes .../fonts/hifi-glyphs/fonts/hifi-glyphs.woff | Bin 20032 -> 0 bytes .../qml/hifi/commerce/checkout/Checkout.qml | 57 +- .../hifi/commerce/common/CommerceLightbox.qml | 28 +- .../sendAsset}/ConnectionItem.qml | 6 +- .../sendAsset}/RecipientDisplay.qml | 4 +- .../sendAsset/SendAsset.qml} | 519 ++++++----- .../sendAsset}/images/connection.svg | 0 .../sendAsset}/images/nearby.svg | 0 .../sendAsset}/images/p2p-nearby-selected.svg | 0 .../images/p2p-nearby-unselected.svg | 0 .../images/send-money-effect-sm.jpg | Bin .../hifi/commerce/purchases/PurchasedItem.qml | 781 ++++++++-------- .../qml/hifi/commerce/purchases/Purchases.qml | 204 +++-- .../hifi/commerce/wallet/PassphraseModal.qml | 4 +- .../qml/hifi/commerce/wallet/Wallet.qml | 12 +- .../qml/hifi/commerce/wallet/WalletChoice.qml | 17 +- .../qml/hifi/commerce/wallet/WalletSetup.qml | 4 +- .../qml/styles-uit/HifiConstants.qml | 5 + interface/src/Application.cpp | 2 +- interface/src/commerce/Ledger.cpp | 26 +- interface/src/commerce/Ledger.h | 16 +- interface/src/commerce/QmlCommerce.cpp | 16 +- interface/src/commerce/QmlCommerce.h | 8 +- .../entities/src/EntityScriptingInterface.cpp | 2 +- scripts/system/commerce/wallet.js | 196 ++-- scripts/system/libraries/connectionUtils.js | 94 ++ scripts/system/marketplaces/marketplaces.js | 836 +++++++++++++++--- 34 files changed, 1995 insertions(+), 976 deletions(-) rename interface/resources/fonts/{hifi-glyphs => hifi-glyphs-1.31}/fonts/hifi-glyphs.eot (82%) rename interface/resources/fonts/{hifi-glyphs => hifi-glyphs-1.31}/fonts/hifi-glyphs.svg (92%) rename interface/resources/fonts/{hifi-glyphs => hifi-glyphs-1.31}/fonts/hifi-glyphs.ttf (82%) create mode 100644 interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.woff rename interface/resources/fonts/{hifi-glyphs => hifi-glyphs-1.31}/icons-reference.html (93%) rename interface/resources/fonts/{hifi-glyphs => hifi-glyphs-1.31}/styles.css (94%) delete mode 100644 interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.woff rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/ConnectionItem.qml (97%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/RecipientDisplay.qml (97%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney/SendMoney.qml => common/sendAsset/SendAsset.qml} (77%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/images/connection.svg (100%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/images/nearby.svg (100%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/images/p2p-nearby-selected.svg (100%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/images/p2p-nearby-unselected.svg (100%) rename interface/resources/qml/hifi/commerce/{wallet/sendMoney => common/sendAsset}/images/send-money-effect-sm.jpg (100%) create mode 100644 scripts/system/libraries/connectionUtils.js diff --git a/interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.eot b/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.eot similarity index 82% rename from interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.eot rename to interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.eot index d3591e6499c6afaf63e4a2c0f144f4722c2f8d9f..1be5435ced839789c55bbeb6584a2ae2d04400fd 100644 GIT binary patch delta 3467 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 QIOC1+r~f&WfB6IQ2jFE`i~s-t delta 1504 zcmYjRYfO`86n@_Kd%sJ+ek}#suca*o3barzr56eaPDBLc?hO$U?c^p>ZIn6W*3CKG zyd-K(w(JKn%R-jS7$cJyV+=9=Fw2se#Vw1vgqZyxY8*dYwq#3K+OTBrc~8!B&Uv4c z^Zt2W&eHpT65;+NpiEvCLTsh$f$ehb>DZ}=`VTO%3c%i2zqJ8(ApjGP0c3aV^!hvQ zwMGHb4WR2#BpiLO@Fy=op8#}lD10KiwgwKEcmzNi8a*|5XHSO+2;IQwo#BCSzrO8u zA%N!qLc_xYVOB<#0b&G@Hyjy@jc2{F7yxn;AkNWahr*pzkzs(Z0f;>k9*^P`=>te* zVxgnq$iS-&i(SBp1ZN?7?8I3AmfLn<>>(f!5Fp{U2VE-%QfmHymLhR}{_L*$UtD_z z(EMaw0*x;bFS!_BCHqNHyqz`@Yy2wxJ(hUPt-C!r733heB(j5%`own={N(tV<)XE< zB+6OFI!f*V0ZRZjpc*yUh)tM8EgDgWE!cquG+`T>QHBl_p#`lN#1OV(Gv4V$1u7B3 zF0`Q?yJ1Hrve1ugai15aK!sr zzRv^|W>}B`D{Sb(K6GO*_MjL0(T4*#h%ny8Aq-#`hj9d>@p~*IcLGzG#tdTk03YHs zKEfG%jB}X9S$u*|aRKM!67TNYP+hZe(`0R9-Ig5>kfKRah6;>^vAL#7aUca--!7*MCC5^0AbovxSYFfI{q?#=m zR$JG;?!EEL{A~OhFT~A4UaVJhPfnBj`N{Gt`X! zjO!V1tvijETeof2cEvVldt_U+JM5$OCHrcoGxK=N5pw*NRhRWTyEEr#&a!hN zw>Ix)eoy{Wm*nbl>)oa9dG{^%efP@(N5NvjUxm$u-+B~J)bqCJTJcEn=f#gp3QE2% zZ77{6oiBai9rby9i@t}xAN^(iUjL1N9HIz=HttfqVlDIy*stR5LNb;i$+o1_L>46=;Q8?V&^#7?UVRDXY_oQp}*}QZ?eVUX&zJucS&MIZinp z157WAae#OMdX>v36v4aM5>WQN(f<+hNq;xmk}Z` zC0kT@N%=~Y6rI6fkt9LZ>Le*uk!3L<3_+AHoU#19cR@R;C1LQ{uFRYjgh=@Kk%5IPGnK3{DH|YbYoJMW(F3p~ bi;0}W1rRV`U1<{fhVM6i`9mW9U)BBv{ diff --git a/interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.svg b/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.svg similarity index 92% rename from interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.svg rename to interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.svg index 43c4932879..c68cb63a0d 100644 --- a/interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.svg +++ b/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.svg @@ -25,7 +25,6 @@ - @@ -145,4 +144,14 @@ + + + + + + + + + + diff --git a/interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.ttf b/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.ttf similarity index 82% rename from interface/resources/fonts/hifi-glyphs/fonts/hifi-glyphs.ttf rename to interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.ttf index 8907cf7858dd304cdad024bfa1ff4ca5cd94caf9..edc447c13245b74845bcce8687c7432f37872c39 100644 GIT binary patch delta 3470 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 Fe*ppxP9FdO delta 1526 zcmYLJdrXs86#w1(-S5$_{YruMYiUb?0xc9M^g#i^7a|~npdtby+R00x+5swptZwtM z`ACdivS)}{7P4f<7@5Qnvl!zaW?3?0wqXXjN&=z1xRJ$LWjbU z{^x5JI)L#+&3yFm_(b2Pn|5I09w3n9a0Ia3?RdH`rRGm)DH8J2hl}cKOBdD4WG%TE zUq|+mqWEW|fmq{D$RDvpnp@rWWFL_I;F6vljMOCtgoM`(-&!hKSxL6eS;DG^BaL4ffgJZlPN*Y38UVP8mqKVQ4m7OPfr4k=~uYnEuiz8IKwlOkUHlX--wusCw7j zZvMm)vdmf@WT+W^8CNr2S(~gA)~nVRwocm_+hyCV?Y?c5BSZh*+IT@LMb5}Av`4<;TYoy<5`*_nyR+uQ-$%2BfO4M z#xcg^o;!@EgiyjsqRffBrkaU~8jgxgV=$0|R)JQi)gDS@fia14l(Jeylwt;*lByAB z^r9q*dR?j{k}=9Dlou$caMZ|i3MU$rRKiG#MwSWX6qz#?$eck+5qYL^0%e3Uk!mE7 z5<-}y;VIeH!w3HMmWToP zPy%0kWZJ_5z7k*j^Y0V(f3{mx{{zrIB&PrX diff --git a/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.woff b/interface/resources/fonts/hifi-glyphs-1.31/fonts/hifi-glyphs.woff new file mode 100644 index 0000000000000000000000000000000000000000..f26000caf42cd88ba2e2ba3ac079299b43515ce3 GIT binary patch literal 21496 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

HiFi Glyphs

-

This font was created for use inHigh Fidelity

+

This font was created for use in High Fidelity

CSS mapping

  • @@ -87,10 +87,6 @@
  • -
  • -
    - -
  • @@ -567,6 +563,46 @@
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +

Character mapping

    @@ -642,10 +678,6 @@
    -
  • -
    - -
  • @@ -1122,6 +1154,46 @@
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +