From b1c09d71f740a8210cb12a38c5c1deb5efa1f3b7 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:02:34 -0700 Subject: [PATCH 001/146] Add packet listeners to DatagramProcessor --- interface/src/DatagramProcessor.cpp | 26 ++++++++++++++++++++++++-- interface/src/DatagramProcessor.h | 4 ++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 14e286c80e..354b7c72f1 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -23,11 +23,20 @@ #include "DatagramProcessor.h" DatagramProcessor::DatagramProcessor(QObject* parent) : - QObject(parent) + QObject(parent), + _packetListenerMap() { } +void DatagramProcessor::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { + if (packetListenerMap.contains(type)) { + qDebug() << "Warning: Registering a packet listener for packet type " << type + << " that will remove a previously registered listener"; + } + packetListenerMap[type] = QPair(object, methodName); +} + void DatagramProcessor::processDatagrams() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "DatagramProcessor::processDatagrams()"); @@ -160,7 +169,20 @@ void DatagramProcessor::processDatagrams() { } break; default: - nodeList->processNodeData(senderSockAddr, incomingPacket); + //nodeList->processNodeData(senderSockAddr, incomingPacket); + if (packetListenerMap.contains(incomingType)) { + auto& listener = packetListenerMap[incomingType]; + NLPacket packet; + bool success = QMetaObject::invokeMethod(listener.first, listener.second, + Q_ARG(std::unique_ptr, packet), + Q_ARG(HifiSockAddr, senderSockAddr)); + if (!success) { + qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first.name() << "::" << listener.second; + } + } else { + QDebug() << "No listener found for packet type: " << incomingType; + } + break; } } diff --git a/interface/src/DatagramProcessor.h b/interface/src/DatagramProcessor.h index 7fc192ee2d..b24752d0cf 100644 --- a/interface/src/DatagramProcessor.h +++ b/interface/src/DatagramProcessor.h @@ -27,10 +27,14 @@ public: void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; } void shutdown() { _isShuttingDown = true; } + + void registerPacketListener(Packet::Type type, QObject* object, QString methodName); + public slots: void processDatagrams(); private: + QMap> packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; int _inByteCount = 0; From e89dbe8541fc29e05af0112ff2212a4e26e776ff Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:02:56 -0700 Subject: [PATCH 002/146] Update PacketType in DatagramProcessor --- interface/src/DatagramProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 354b7c72f1..6730a1716e 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -122,7 +122,7 @@ void DatagramProcessor::processDatagrams() { break; } case PacketType::DomainConnectionDenied: { - int headerSize = numBytesForPacketHeaderGivenPacketType::(PacketTypeDomainConnectionDenied); + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); QDataStream packetStream(QByteArray(incomingPacket.constData() + headerSize, incomingPacket.size() - headerSize)); QString reason; @@ -144,7 +144,7 @@ void DatagramProcessor::processDatagrams() { glm::vec3 position; float radius; - int headerSize = numBytesForPacketHeaderGivenPacketType::(PacketTypeMuteEnvironment); + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), From 9d25612ff8ce4303940071d3816258b20ffa530e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:04:56 -0700 Subject: [PATCH 003/146] Move DatagramProcessor to PacketProcessor --- .../networking/src/PacketProcessor.cpp | 3 ++- .../networking/src/PacketProcessor.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) rename interface/src/DatagramProcessor.cpp => libraries/networking/src/PacketProcessor.cpp (99%) rename interface/src/DatagramProcessor.h => libraries/networking/src/PacketProcessor.h (95%) diff --git a/interface/src/DatagramProcessor.cpp b/libraries/networking/src/PacketProcessor.cpp similarity index 99% rename from interface/src/DatagramProcessor.cpp rename to libraries/networking/src/PacketProcessor.cpp index 6730a1716e..7e0cfdd668 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/libraries/networking/src/PacketProcessor.cpp @@ -1,8 +1,9 @@ // -// DatagramProcessor.cpp +// PacketProcessor.cpp // interface/src // // Created by Stephen Birarda on 1/23/2014. +// Update by Ryan Huffman on 7/8/2015. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. diff --git a/interface/src/DatagramProcessor.h b/libraries/networking/src/PacketProcessor.h similarity index 95% rename from interface/src/DatagramProcessor.h rename to libraries/networking/src/PacketProcessor.h index b24752d0cf..b400c7b09c 100644 --- a/interface/src/DatagramProcessor.h +++ b/libraries/networking/src/PacketProcessor.h @@ -1,8 +1,9 @@ // -// DatagramProcessor.h +// PacketProcessor.h // interface/src // // Created by Stephen Birarda on 1/23/2014. +// Update by Ryan Huffman on 7/8/2015. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. From 92462db4e1ea5b7e9258500d86158cd73e2c45df Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:49:00 -0700 Subject: [PATCH 004/146] Rename DatagramProcessor and add packet listener mutex --- libraries/networking/src/PacketProcessor.cpp | 17 ++++++++++++----- libraries/networking/src/PacketProcessor.h | 11 ++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libraries/networking/src/PacketProcessor.cpp b/libraries/networking/src/PacketProcessor.cpp index 7e0cfdd668..27261d36f5 100644 --- a/libraries/networking/src/PacketProcessor.cpp +++ b/libraries/networking/src/PacketProcessor.cpp @@ -21,26 +21,28 @@ #include "Menu.h" #include "InterfaceLogging.h" -#include "DatagramProcessor.h" +#include "PacketProcessor.h" -DatagramProcessor::DatagramProcessor(QObject* parent) : +PacketProcessor::PacketProcessor(QObject* parent) : QObject(parent), _packetListenerMap() { } -void DatagramProcessor::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { +void PacketProcessor::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { + packetListenerLock.lock(); if (packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type << " that will remove a previously registered listener"; } packetListenerMap[type] = QPair(object, methodName); + packetListenerLock.unlock(); } -void DatagramProcessor::processDatagrams() { +void PacketProcessor::processDatagrams() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "DatagramProcessor::processDatagrams()"); + "PacketProcessor::processDatagrams()"); if (_isShuttingDown) { return; // bail early... we're shutting down. @@ -171,6 +173,11 @@ void DatagramProcessor::processDatagrams() { break; default: //nodeList->processNodeData(senderSockAddr, incomingPacket); + + packetListenerLock.lock(); + auto& listener = packetListenerMap[incomingType]; + packetListenerLock.unlock(); + if (packetListenerMap.contains(incomingType)) { auto& listener = packetListenerMap[incomingType]; NLPacket packet; diff --git a/libraries/networking/src/PacketProcessor.h b/libraries/networking/src/PacketProcessor.h index b400c7b09c..08d5e1c2a0 100644 --- a/libraries/networking/src/PacketProcessor.h +++ b/libraries/networking/src/PacketProcessor.h @@ -10,15 +10,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_DatagramProcessor_h -#define hifi_DatagramProcessor_h +#ifndef hifi_PacketProcessor_h +#define hifi_PacketProcessor_h #include -class DatagramProcessor : public QObject { +class PacketProcessor : public QObject { Q_OBJECT public: - DatagramProcessor(QObject* parent = 0); + PacketProcessor(QObject* parent = 0); int getInPacketCount() const { return _inPacketCount; } int getOutPacketCount() const { return _outPacketCount; } @@ -35,6 +35,7 @@ public slots: void processDatagrams(); private: + QMutex packetListenerLock; QMap> packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; @@ -43,4 +44,4 @@ private: bool _isShuttingDown = false; }; -#endif // hifi_DatagramProcessor_h +#endif // hifi_PacketProcessor_h From 44c34ac566a85929a85d15817b27384ad8f847e0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:49:30 -0700 Subject: [PATCH 005/146] Rename PacketProcessor to PacketReceiver --- libraries/networking/src/PacketProcessor.cpp | 12 ++++++------ libraries/networking/src/PacketProcessor.h | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/PacketProcessor.cpp b/libraries/networking/src/PacketProcessor.cpp index 27261d36f5..09d7c5488b 100644 --- a/libraries/networking/src/PacketProcessor.cpp +++ b/libraries/networking/src/PacketProcessor.cpp @@ -1,5 +1,5 @@ // -// PacketProcessor.cpp +// PacketReceiver.cpp // interface/src // // Created by Stephen Birarda on 1/23/2014. @@ -21,16 +21,16 @@ #include "Menu.h" #include "InterfaceLogging.h" -#include "PacketProcessor.h" +#include "PacketReceiver.h" -PacketProcessor::PacketProcessor(QObject* parent) : +PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent), _packetListenerMap() { } -void PacketProcessor::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { +void PacketReceiver::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { packetListenerLock.lock(); if (packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type @@ -40,9 +40,9 @@ void PacketProcessor::registerPacketListener(Packet::Type type, QObject* object, packetListenerLock.unlock(); } -void PacketProcessor::processDatagrams() { +void PacketReceiver::processDatagrams() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "PacketProcessor::processDatagrams()"); + "PacketReceiver::processDatagrams()"); if (_isShuttingDown) { return; // bail early... we're shutting down. diff --git a/libraries/networking/src/PacketProcessor.h b/libraries/networking/src/PacketProcessor.h index 08d5e1c2a0..58bd9b468b 100644 --- a/libraries/networking/src/PacketProcessor.h +++ b/libraries/networking/src/PacketProcessor.h @@ -1,5 +1,5 @@ // -// PacketProcessor.h +// PacketReceiver.h // interface/src // // Created by Stephen Birarda on 1/23/2014. @@ -10,15 +10,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_PacketProcessor_h -#define hifi_PacketProcessor_h +#ifndef hifi_PacketReceiver_h +#define hifi_PacketReceiver_h #include -class PacketProcessor : public QObject { +class PacketReceiver : public QObject { Q_OBJECT public: - PacketProcessor(QObject* parent = 0); + PacketReceiver(QObject* parent = 0); int getInPacketCount() const { return _inPacketCount; } int getOutPacketCount() const { return _outPacketCount; } @@ -44,4 +44,4 @@ private: bool _isShuttingDown = false; }; -#endif // hifi_PacketProcessor_h +#endif // hifi_PacketReceiver_h From 5940aee0e7972d99ad7bfc7504f5369ad71730a5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 10:50:26 -0700 Subject: [PATCH 006/146] Rename PacketProcessor files --- .../networking/src/{PacketProcessor.cpp => PacketReceiver.cpp} | 0 libraries/networking/src/{PacketProcessor.h => PacketReceiver.h} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename libraries/networking/src/{PacketProcessor.cpp => PacketReceiver.cpp} (100%) rename libraries/networking/src/{PacketProcessor.h => PacketReceiver.h} (100%) diff --git a/libraries/networking/src/PacketProcessor.cpp b/libraries/networking/src/PacketReceiver.cpp similarity index 100% rename from libraries/networking/src/PacketProcessor.cpp rename to libraries/networking/src/PacketReceiver.cpp diff --git a/libraries/networking/src/PacketProcessor.h b/libraries/networking/src/PacketReceiver.h similarity index 100% rename from libraries/networking/src/PacketProcessor.h rename to libraries/networking/src/PacketReceiver.h From 9d0bffaa19c6785b67ba602bc278e17e0e6ee501 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 11:14:43 -0700 Subject: [PATCH 007/146] Add PacketReceiver to LimitedNodeList --- libraries/networking/src/LimitedNodeList.cpp | 3 +++ libraries/networking/src/LimitedNodeList.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index aef732e5e1..2559c1b233 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -48,6 +48,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short _localSockAddr(), _publicSockAddr(), _stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT), + _packetReceiver(this), _numCollectedPackets(0), _numCollectedBytes(0), _packetStatTimer(), @@ -92,6 +93,8 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short // check the local socket right now updateLocalSockAddr(); + connect(_nodeSocket, &QUdpSocket::readyRead, _packetReceiver, &PacketReceiver::processDatagrams); + _packetStatTimer.start(); } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 7fc93b4f64..0df8f7232f 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -121,6 +121,8 @@ public: bool packetVersionAndHashMatch(const QByteArray& packet); + PacketReceiver& getPacketReceiver() { return _packetReceiver; } + // QByteArray byteArrayWithPopulatedHeader(PacketType::Value packetType) // { return byteArrayWithUUIDPopulatedHeader(packetType, _sessionUUID); } // int populatePacketHeader(QByteArray& packet, PacketType::Value packetType) @@ -305,6 +307,8 @@ protected: HifiSockAddr _publicSockAddr; HifiSockAddr _stunSockAddr; + PacketReceiver _packetReceiver; + // XXX can BandwidthRecorder be used for this? int _numCollectedPackets; int _numCollectedBytes; From 8a415b2adbe69b5faddde64cfc97c583f7e2e301 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 11:15:00 -0700 Subject: [PATCH 008/146] Register for packet types in NodeList --- libraries/networking/src/NodeList.cpp | 17 +++++++++++++++++ libraries/networking/src/NodeList.h | 1 + 2 files changed, 18 insertions(+) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 4c92ce07e7..66d7f1e25f 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -90,6 +90,18 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // we definitely want STUN to update our public socket, so call the LNL to kick that off startSTUNPublicSocketUpdate(); + + auto packetReceiver = getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::DomainList, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::Ping, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::PingReply, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processReceivedPacket"); } qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { @@ -152,6 +164,11 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& } } +// TODO: Break this out into individual packet types +void NodeList::processReceivedPacket(std::unique_ptr, HifiSockAddr senderSockAddr) { + qDebug() << "Got packet!"; +} + void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { PacketType::Value packetType = packetTypeForPacket(packet); switch (packetType) { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 43e35f8958..6ac08fcbd9 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -61,6 +61,7 @@ public: void addSetOfNodeTypesToNodeInterestSet(const NodeSet& setOfNodeTypes); void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); } + void processReceivedPacket(std::unique_ptr, HifiSockAddr senderSockAddr); void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } From b960d86f8095e87eefc042e940067de5a368256d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 11:54:06 -0700 Subject: [PATCH 009/146] Remove datagramProcessor from Application --- interface/src/Application.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dfa082719a..3b633580ee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -308,7 +308,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _window(new MainWindow(desktop())), _toolWindow(NULL), _friendsWindow(NULL), - _datagramProcessor(), _undoStack(), _undoStackScriptingInterface(&_undoStack), _frameCount(0), @@ -387,8 +386,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // make sure the node thread is given highest priority nodeThread->setPriority(QThread::TimeCriticalPriority); - _datagramProcessor = new DatagramProcessor(nodeList.data()); - // have the NodeList use deleteLater from DM customDeleter nodeList->setCustomDeleter([](Dependency* dependency) { static_cast(dependency)->deleteLater(); @@ -404,9 +401,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : ResourceCache* geometryCache = geometryCacheP.data(); connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); - // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); - // put the audio processing on a separate thread QThread* audioThread = new QThread(); audioThread->setObjectName("Audio Thread"); @@ -641,6 +635,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : auto applicationUpdater = DependencyManager::get(); connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); applicationUpdater->checkForUpdate(); + + auto& packetReceiver = nodeList->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); } void Application::aboutToQuit() { @@ -654,7 +651,7 @@ void Application::cleanupBeforeQuit() { _entities.clear(); // this will allow entity scripts to properly shutdown - _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit + //_datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts ScriptEngine::stopAllScripts(this); // stop all currently running global scripts @@ -1783,7 +1780,7 @@ void Application::checkFPS() { _fps = (float)_frameCount / diffTime; _frameCount = 0; - _datagramProcessor->resetCounters(); + //_datagramProcessor->resetCounters(); _timerStart.start(); // ask the node list to check in with the domain server From 0b0446e527e452647f54973b0db28cf5969dfa00 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 11:54:22 -0700 Subject: [PATCH 010/146] Add handleComainConnectionDeniedPacket to Application --- interface/src/Application.cpp | 15 +++++++++++++++ interface/src/Application.h | 3 +-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3b633580ee..fb01af2747 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3815,6 +3815,21 @@ void Application::domainConnectionDenied(const QString& reason) { } } +void handleDomainConnectionDeniedPacket(std::unique_ptr, HifiSockAddr senderSockAddr) { + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); + QDataStream packetStream(QByteArray(incomingPacket.constData() + headerSize, + incomingPacket.size() - headerSize)); + QString reason; + packetStream >> reason; + + // output to the log so the user knows they got a denied connection request + // and check and signal for an access token so that we can make sure they are logged in + qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; + qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; + domainConnectionDenied(reason); + AccountManager::getInstance().checkAndSignalForAccessToken(); +} + void Application::connectedToDomain(const QString& hostname) { AccountManager& accountManager = AccountManager::getInstance(); const QUuid& domainID = DependencyManager::get()->getDomainHandler().getUUID(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 0131fdb19a..8ae00cdd38 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -445,6 +445,7 @@ public slots: void notifyPacketVersionMismatch(); void domainConnectionDenied(const QString& reason); + void handleDomainConnectionDeniedPacket(std::unique_ptr, HifiSockAddr senderSockAddr); void cameraMenuChanged(); @@ -528,8 +529,6 @@ private: ToolWindow* _toolWindow; WebWindowClass* _friendsWindow; - DatagramProcessor* _datagramProcessor; - QUndoStack _undoStack; UndoStackScriptingInterface _undoStackScriptingInterface; From f1bf52602fdd16043b82c1f1463c8bb1d479ab50 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 11:54:50 -0700 Subject: [PATCH 011/146] Fix Packet::Type (PacketType::Value) --- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/networking/src/LimitedNodeList.h | 1 + libraries/networking/src/NodeList.cpp | 2 +- libraries/networking/src/PacketReceiver.cpp | 17 +---------------- libraries/networking/src/PacketReceiver.h | 4 ++-- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 2559c1b233..efd2373a82 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -93,7 +93,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short // check the local socket right now updateLocalSockAddr(); - connect(_nodeSocket, &QUdpSocket::readyRead, _packetReceiver, &PacketReceiver::processDatagrams); + connect(&_nodeSocket, &QUdpSocket::readyRead, &_packetReceiver, &PacketReceiver::processDatagrams); _packetStatTimer.start(); } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 0df8f7232f..84b40c70ff 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -39,6 +39,7 @@ #include "NLPacket.h" #include "PacketHeaders.h" #include "PacketList.h" +#include "PacketReceiver.h" #include "UUIDHasher.h" const int MAX_PACKET_SIZE = 1450; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 66d7f1e25f..94b6e2a0e7 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -91,7 +91,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // we definitely want STUN to update our public socket, so call the LNL to kick that off startSTUNPublicSocketUpdate(); - auto packetReceiver = getPacketReceiver(); + auto& packetReceiver = getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::DomainList, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, this, "processReceivedPacket"); diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 09d7c5488b..b3b839014b 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -30,7 +30,7 @@ PacketReceiver::PacketReceiver(QObject* parent) : } -void PacketReceiver::registerPacketListener(Packet::Type type, QObject* object, QString methodName) { +void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, QString methodName) { packetListenerLock.lock(); if (packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type @@ -124,21 +124,6 @@ void PacketReceiver::processDatagrams() { } break; } - case PacketType::DomainConnectionDenied: { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); - QDataStream packetStream(QByteArray(incomingPacket.constData() + headerSize, - incomingPacket.size() - headerSize)); - QString reason; - packetStream >> reason; - - // output to the log so the user knows they got a denied connection request - // and check and signal for an access token so that we can make sure they are logged in - qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; - qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; - application->domainConnectionDenied(reason); - AccountManager::getInstance().checkAndSignalForAccessToken(); - break; - } case PacketType::NoisyMute: case PacketType::MuteEnvironment: { bool mute = !DependencyManager::get()->isMuted(); diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 58bd9b468b..cc61bdb3cb 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -29,14 +29,14 @@ public: void shutdown() { _isShuttingDown = true; } - void registerPacketListener(Packet::Type type, QObject* object, QString methodName); + void registerPacketListener(PacketType::Value type, QObject* object, QString methodName); public slots: void processDatagrams(); private: QMutex packetListenerLock; - QMap> packetListenerMap; + QMap> packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; int _inByteCount = 0; From c365ea60ad3993e992d6a0c035ffb88fb0f0d268 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 13:13:21 -0700 Subject: [PATCH 012/146] Add packet listening to AvatarManager --- interface/src/avatar/AvatarManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index dbd46cbfbd..955394a465 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -66,6 +66,12 @@ AvatarManager::AvatarManager(QObject* parent) : // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType >("NodeWeakPointer"); _myAvatar = std::make_shared(); + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, ...); + packetReceiver.registerPacketListener(PacketType::KillAvatar, this, ...); + packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, ...); + packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, ...); } void AvatarManager::init() { From 1b5d526444540e6e0f5eb5427d55a2d891f71609 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 8 Jul 2015 15:06:50 -0700 Subject: [PATCH 013/146] Add new packet processing to AvatarManager --- interface/src/avatar/AvatarManager.cpp | 6 -- libraries/avatars/src/AvatarHashMap.cpp | 85 +++++++++++-------------- libraries/avatars/src/AvatarHashMap.h | 9 ++- libraries/networking/src/NLPacket.h | 2 + 4 files changed, 44 insertions(+), 58 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 955394a465..dbd46cbfbd 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -66,12 +66,6 @@ AvatarManager::AvatarManager(QObject* parent) : // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType >("NodeWeakPointer"); _myAvatar = std::make_shared(); - - auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, ...); - packetReceiver.registerPacketListener(PacketType::KillAvatar, this, ...); - packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, ...); - packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, ...); } void AvatarManager::init() { diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 60eb5c4499..85f85f68e6 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -18,25 +18,13 @@ AvatarHashMap::AvatarHashMap() { connect(DependencyManager::get().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); -} -void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer) { - switch (packetTypeForPacket(datagram)) { - case PacketType::BulkAvatarData: - processAvatarDataPacket(datagram, mixerWeakPointer); - break; - case PacketType::AvatarIdentity: - processAvatarIdentityPacket(datagram, mixerWeakPointer); - break; - case PacketType::AvatarBillboard: - processAvatarBillboardPacket(datagram, mixerWeakPointer); - break; - case PacketType::KillAvatar: - processKillAvatar(datagram); - break; - default: - break; - } + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); + packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "processKillAvatar"); + packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); + packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket"); } bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) { @@ -65,86 +53,89 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe return avatar; } -void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer &mixerWeakPointer) { - int bytesRead = numBytesForPacketHeader(datagram); - +void AvatarHashMap::processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size); + int bytesRead = 0; + + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); // enumerate over all of the avatars in this packet // only add them if mixerWeakPointer points to something (meaning that mixer is still around) - while (bytesRead < datagram.size() && mixerWeakPointer.data()) { - QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); + while (bytesRead < data.size() && avatarMixer.data()) { + QUuid sessionUUID = QUuid::fromRfc4122(data.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); bytesRead += NUM_BYTES_RFC4122_UUID; - + if (sessionUUID != _lastOwnerSessionUUID) { AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, mixerWeakPointer); + avatar = addAvatar(sessionUUID, avatarMixer); } - + // have the matching (or new) avatar parse the data from the packet - bytesRead += avatar->parseDataAtOffset(datagram, bytesRead); + bytesRead += avatar->parseDataAtOffset(data, bytesRead); } else { // create a dummy AvatarData class to throw this data on the ground AvatarData dummyData; - bytesRead += dummyData.parseDataAtOffset(datagram, bytesRead); + bytesRead += dummyData.parseDataAtOffset(data, bytesRead); } } } -void AvatarHashMap::processAvatarIdentityPacket(const QByteArray &packet, const QWeakPointer& mixerWeakPointer) { +void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { // setup a data stream to parse the packet - QDataStream identityStream(packet); - identityStream.skipRawData(numBytesForPacketHeader(packet)); - + QDataStream identityStream { packet.get() }; + QUuid sessionUUID; - + while (!identityStream.atEnd()) { - + QUrl faceMeshURL, skeletonURL; QVector attachmentData; QString displayName; identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> attachmentData >> displayName; - + // mesh URL for a UUID, find avatar in our list AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, mixerWeakPointer); + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + avatar = addAvatar(sessionUUID, avatarMixer); } if (avatar->getFaceModelURL() != faceMeshURL) { avatar->setFaceModelURL(faceMeshURL); } - + if (avatar->getSkeletonModelURL() != skeletonURL) { avatar->setSkeletonModelURL(skeletonURL); } - + if (avatar->getAttachmentData() != attachmentData) { avatar->setAttachmentData(attachmentData); } - + if (avatar->getDisplayName() != displayName) { avatar->setDisplayName(displayName); } } } -void AvatarHashMap::processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer) { - int headerSize = numBytesForPacketHeader(packet); - QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID)); - +void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size); + QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID)); + AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, mixerWeakPointer); + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + avatar = addAvatar(sessionUUID, avatarMixer); } - QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID); + QByteArray billboard = data.mid(NUM_BYTES_RFC4122_UUID); if (avatar->getBillboard() != billboard) { avatar->setBillboard(billboard); } } -void AvatarHashMap::processKillAvatar(const QByteArray& datagram) { +void AvatarHashMap::processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr) { // read the node id - QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID)); + QUuid sessionUUID = QUuid::fromRfc4122(QByteArray(packet->getPayload(), NUM_BYTES_RFC4122_UUID)); removeAvatar(sessionUUID); } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 45edbf8d5a..537f0ca685 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -38,6 +38,10 @@ public slots: private slots: void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); + void processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void processAvatarIdentityPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr); protected: AvatarHashMap(); @@ -49,11 +53,6 @@ protected: AvatarHash _avatarHash; private: - void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processKillAvatar(const QByteArray& datagram); - QUuid _lastOwnerSessionUUID; }; diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 9105418492..96b3e2a029 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -25,6 +25,8 @@ public: virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 localHeaderSize() const; // Current level's header size + + QUuid getSourceID() const { return QUuid(); } protected: NLPacket(PacketType::Value type, int64_t size); From 3b7ad982a419a4d059de9a6bce5912f0f7a9dc5c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:23:50 -0700 Subject: [PATCH 014/146] Update OctreePacketProcessor to use packet callbacks --- .../src/octree/OctreePacketProcessor.cpp | 54 ++++++++++++++++--- interface/src/octree/OctreePacketProcessor.h | 10 +++- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index c5b4d2a4a7..4e01b9dc37 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -16,10 +16,48 @@ #include "OctreePacketProcessor.h" #include "SceneScriptingInterface.h" +OctreePacketProcessor::OctreePacketProcessor() { + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleEntityDataPacket"); + packetReceiver.registerPacketListener(PacketType::EntityData, this, "handleEntityDataPacket"); + packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket"); + packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleOctreeStatsPacket"); + packetReceiver.registerPacketListener(PacketType::EnvironmentData, this, "handleEnvironmentDataPacket"); +} + +// TODO implement packet processing in PacketType-specific methods +void OctreePacketProcessor::handleEntityDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (sendingNode) { + processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + } +} + +void OctreePacketProcessor::handleEntityErasePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (sendingNode) { + processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + } +} + +void OctreePacketProcessor::handleOctreeStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (sendingNode) { + processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + } +} + +void OctreePacketProcessor::handleEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (sendingNode) { + processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + } +} + void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "OctreePacketProcessor::processPacket()"); - + QByteArray mutablePacket = packet; const int WAY_BEHIND = 300; @@ -34,7 +72,7 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, PacketType::Value voxelPacketType = packetTypeForPacket(mutablePacket); - + // note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // then process any remaining bytes as if it was another packet @@ -43,7 +81,7 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, wasStatsPacket = true; if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); - + // TODO: this does not look correct, the goal is to test the packet version for the piggyback, but // this is testing the version and hash of the original packet if (!DependencyManager::get()->packetVersionAndHashMatch(packet)) { @@ -54,28 +92,28 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, return; // bail since no piggyback data } } // fall through to piggyback message - + voxelPacketType = packetTypeForPacket(mutablePacket); PacketVersion packetVersion = mutablePacket[1]; PacketVersion expectedVersion = versionForPacketType(voxelPacketType); - + // check version of piggyback packet against expected version if (packetVersion != expectedVersion) { static QMultiMap versionDebugSuppressMap; - + QUuid senderUUID = uuidFromPacketHeader(packet); if (!versionDebugSuppressMap.contains(senderUUID, voxelPacketType)) { qDebug() << "Packet version mismatch on" << voxelPacketType << "- Sender" << senderUUID << "sent" << (int)packetVersion << "but" << (int)expectedVersion << "expected."; - + emit packetVersionMismatch(); versionDebugSuppressMap.insert(senderUUID, voxelPacketType); } return; // bail since piggyback version doesn't match } - + app->trackIncomingOctreePacket(mutablePacket, sendingNode, wasStatsPacket); if (sendingNode) { diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 5c52dec002..a0f2ed3e7b 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -16,13 +16,21 @@ /// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() -class OctreePacketProcessor : public ReceivedPacketProcessor { +class OctreePacketProcessor : public GenericThread { Q_OBJECT +public: + OctreePacketProcessor(); signals: void packetVersionMismatch(); protected: virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + +private slots: + void handleEntityDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleEntityErasePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleOctreeStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); }; #endif // hifi_OctreePacketProcessor_h From bb132e354bc24d9665524ab882b1674d589f766d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:24:07 -0700 Subject: [PATCH 015/146] Update AudioClient to use packet callbacks --- libraries/audio-client/src/AudioClient.cpp | 95 ++++++++++++++++++++++ libraries/audio-client/src/AudioClient.h | 12 ++- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a75b9124db..3856e32fca 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -140,6 +140,14 @@ AudioClient::AudioClient() : // create GVerb filter _gverb = createGverbFilter(); configureGverbFilter(_gverb); + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioStreamStatsPacket"); + packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFrame"); + packetReceiver.registerPacketListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); + packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } AudioClient::~AudioClient() { @@ -527,6 +535,93 @@ void AudioClient::stop() { } } +void AudioClient::handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + _stats.parseAudioStreamStatsPacket(packet->getData()); + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + const char* dataAt = packet->getPayload(); + + char bitset; + memcpy(&bitset, dataAt, sizeof(char)); + dataAt += sizeof(char); + + bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; + if (hasReverb) { + float reverbTime, wetLevel; + memcpy(&reverbTime, dataAt, sizeof(float)); + dataAt += sizeof(float); + memcpy(&wetLevel, dataAt, sizeof(float)); + dataAt += sizeof(float); + _receivedAudioStream.setReverb(reverbTime, wetLevel); + } else { + _receivedAudioStream.clearReverb(); + } + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); + nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); + + if (_audioOutput) { + + if (!_hasReceivedFirstPacket) { + _hasReceivedFirstPacket = true; + + // have the audio scripting interface emit a signal to say we just connected to mixer + emit receivedFirstPacket(); + } + + // Audio output must exist and be correctly set up if we're going to process received audio + _receivedAudioStream.parseData(packet->getData()); + } + + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + updateLastHeardFromAudioMixer(packet); +} + +void AudioClient::handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + if (!_muted) { + toggleMute(); + // TODO reimplement on interface side + //AudioScriptingInterface::getInstance().mutedByMixer(); + } +} + +void AudioClient::handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + glm::vec3 position; + float radius; + + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); + memcpy(&position, packet->getPayload(), sizeof(glm::vec3)); + memcpy(&radius, packet->getPayload() + sizeof(glm::vec3), sizeof(float)); + float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), + position); + bool shouldMute = !_muted && (distance < radius); + + if (shouldMute) { + toggleMute(); + // TODO reimplement on interface side + //AudioScriptingInterface::getInstance().environmentMuted(); + } +} + +void AudioClient::updateLastHeardFromAudioMixer(std::unique_ptr& packet) { + // update having heard from the audio-mixer and record the bytes received + SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); + if (audioMixer) { + audioMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + +} + QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) { QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode); return deviceInfo.deviceName(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 484e3a14e8..59b7fc48a9 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -133,10 +133,15 @@ public: public slots: void start(); void stop(); - void addReceivedAudioToStream(const QByteArray& audioByteArray); - void parseAudioEnvironmentData(const QByteArray& packet); + + void handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } - void parseAudioStreamStatsPacket(const QByteArray& packet) { _stats.parseAudioStreamStatsPacket(packet); } void handleAudioInput(); void reset(); void audioMixerKilled(); @@ -202,6 +207,7 @@ private slots: void audioStateChanged(QAudio::State state); private: + void updateLastHeardFromAudioMixer(std::unique_ptr& packet); void outputFormatChanged(); QByteArray firstInputFrame; From 32b232c87a6c005cf227d288f6870b99e776e401 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:24:28 -0700 Subject: [PATCH 016/146] Update AvatarHashMap to use packet callbacks --- libraries/avatars/src/AvatarHashMap.cpp | 22 +++++++++++++++++++--- libraries/avatars/src/AvatarHashMap.h | 12 ++++++------ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 85f85f68e6..fb20f91431 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -19,7 +19,6 @@ AvatarHashMap::AvatarHashMap() { connect(DependencyManager::get().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); - auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "processKillAvatar"); @@ -58,6 +57,10 @@ void AvatarHashMap::processAvatarDataPacket(std::unique_ptr packet, Hi int bytesRead = 0; SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (avatarMixer) { + avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + // enumerate over all of the avatars in this packet // only add them if mixerWeakPointer points to something (meaning that mixer is still around) while (bytesRead < data.size() && avatarMixer.data()) { @@ -86,6 +89,11 @@ void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet QUuid sessionUUID; + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (avatarMixer) { + avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + while (!identityStream.atEnd()) { QUrl faceMeshURL, skeletonURL; @@ -96,7 +104,6 @@ void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet // mesh URL for a UUID, find avatar in our list AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); avatar = addAvatar(sessionUUID, avatarMixer); } if (avatar->getFaceModelURL() != faceMeshURL) { @@ -121,9 +128,13 @@ void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packe const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size); QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID)); + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (avatarMixer) { + avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); avatar = addAvatar(sessionUUID, avatarMixer); } @@ -134,6 +145,11 @@ void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packe } void AvatarHashMap::processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); + if (avatarMixer) { + avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); + } + // read the node id QUuid sessionUUID = QUuid::fromRfc4122(QByteArray(packet->getPayload(), NUM_BYTES_RFC4122_UUID)); removeAvatar(sessionUUID); diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 537f0ca685..dbfd2dc88e 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -27,29 +27,29 @@ class AvatarHashMap : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY - + public: const AvatarHash& getAvatarHash() { return _avatarHash; } int size() { return _avatarHash.size(); } - + public slots: void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); bool isAvatarInRange(const glm::vec3 & position, const float range); - + private slots: void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); void processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); void processAvatarIdentityPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); void processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); void processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr); - + protected: AvatarHashMap(); - + virtual AvatarSharedPointer newSharedAvatar(); virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer); virtual void removeAvatar(const QUuid& sessionUUID); - + AvatarHash _avatarHash; private: From 0180bdc4fb1d5a6c8cc37be4ae8b5e1fa29eefb0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:24:50 -0700 Subject: [PATCH 017/146] Update EntityEditPacketSender to use packet callbacks --- .../entities/src/EntityEditPacketSender.cpp | 16 +++++++++++++--- libraries/entities/src/EntityEditPacketSender.h | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index f228467316..9ed1fa5904 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -17,16 +17,26 @@ #include "EntitiesLogging.h" #include "EntityItem.h" +EntityEditPacketSender::EntityEditPacketSender() { + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); +} -void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType::Value type, +void EntityEditPacketSender::processEntityEditNackPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { + if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { + processNackPacket(QByteArray::fromRawData(packet->getData())); + } +} + +void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType::Value type, unsigned char* editBuffer, size_t length, int clockSkew) { - + if (type == PacketType::EntityAdd || type == PacketType::EntityEdit) { EntityItem::adjustEditPacketForClockSkew(editBuffer, length, clockSkew); } } -void EntityEditPacketSender::queueEditEntityMessage(PacketType::Value type, EntityItemID modelID, +void EntityEditPacketSender::queueEditEntityMessage(PacketType::Value type, EntityItemID modelID, const EntityItemProperties& properties) { if (!_shouldSend) { return; // bail early diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index ce88f41b04..30076b1832 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -20,6 +20,8 @@ class EntityEditPacketSender : public OctreeEditPacketSender { Q_OBJECT public: + EntityEditPacketSender(); + /// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines /// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in /// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known. @@ -28,6 +30,8 @@ public: void queueEraseEntityMessage(const EntityItemID& entityItemID); + void processEntityEditNackPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + // My server type is the model server virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual void adjustEditPacketForClockSkew(PacketType::Value type, unsigned char* editBuffer, size_t length, int clockSkew); From 7f771122ee1d43015c8c46aa85b4ff0dc57365dc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 09:25:12 -0700 Subject: [PATCH 018/146] Remove old packet handling from PacketReceiver --- libraries/networking/src/PacketReceiver.cpp | 131 +++----------------- libraries/networking/src/PacketReceiver.h | 2 +- 2 files changed, 19 insertions(+), 114 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index b3b839014b..b94242f85e 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -1,6 +1,6 @@ // // PacketReceiver.cpp -// interface/src +// libraries/networking/src // // Created by Stephen Birarda on 1/23/2014. // Update by Ryan Huffman on 7/8/2015. @@ -48,136 +48,41 @@ void PacketReceiver::processDatagrams() { return; // bail early... we're shutting down. } - HifiSockAddr senderSockAddr; - static QByteArray incomingPacket; - Application* application = Application::getInstance(); auto nodeList = DependencyManager::get(); while (DependencyManager::get()->getNodeSocket().hasPendingDatagrams()) { incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); + HifiSockAddr senderSockAddr; nodeList->readDatagram(incomingPacket, senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); _inPacketCount++; _inByteCount += incomingPacket.size(); if (nodeList->packetVersionAndHashMatch(incomingPacket)) { - PacketType::Value incomingType = packetTypeForPacket(incomingPacket); - // only process this packet if we have a match on the packet version - switch (incomingType) { - case PacketType::AudioEnvironment: - case PacketType::AudioStreamStats: - case PacketType::MixedAudio: - case PacketType::SilentAudioFrame: { - if (incomingType == PacketType::AudioStreamStats) { - QMetaObject::invokeMethod(DependencyManager::get().data(), "parseAudioStreamStatsPacket", - Qt::QueuedConnection, - Q_ARG(QByteArray, incomingPacket)); - } else if (incomingType == PacketType::AudioEnvironment) { - QMetaObject::invokeMethod(DependencyManager::get().data(), "parseAudioEnvironmentData", - Qt::QueuedConnection, - Q_ARG(QByteArray, incomingPacket)); - } else { - QMetaObject::invokeMethod(DependencyManager::get().data(), "addReceivedAudioToStream", - Qt::QueuedConnection, - Q_ARG(QByteArray, incomingPacket)); - } - // update having heard from the audio-mixer and record the bytes received - SharedNodePointer audioMixer = nodeList->sendingNodeForPacket(incomingPacket); + // TODO What do we do about this? + //nodeList->processNodeData(senderSockAddr, incomingPacket); - if (audioMixer) { - audioMixer->setLastHeardMicrostamp(usecTimestampNow()); - } + packetListenerLock.lock(); + auto& listener = packetListenerMap[incomingType]; + packetListenerLock.unlock(); - break; + if (packetListenerMap.contains(incomingType)) { + auto& listener = packetListenerMap[incomingType]; + NLPacket packet; + bool success = QMetaObject::invokeMethod(listener.first, listener.second, + Q_ARG(std::unique_ptr, packet), + Q_ARG(HifiSockAddr, senderSockAddr)); + if (!success) { + qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first.name() << "::" << listener.second; } - case PacketType::EntityData: - case PacketType::EntityErase: - case PacketType::OctreeStats: - case PacketType::EnvironmentData: { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::networkReceive()... _octreeProcessor.queueReceivedPacket()"); - SharedNodePointer matchedNode = DependencyManager::get()->sendingNodeForPacket(incomingPacket); - - if (matchedNode) { - // add this packet to our list of octree packets and process them on the octree data processing - application->_octreeProcessor.queueReceivedPacket(matchedNode, incomingPacket); - } - break; - } - case PacketType::BulkAvatarData: - case PacketType::KillAvatar: - case PacketType::AvatarIdentity: - case PacketType::AvatarBillboard: { - // update having heard from the avatar-mixer and record the bytes received - SharedNodePointer avatarMixer = nodeList->sendingNodeForPacket(incomingPacket); - - if (avatarMixer) { - avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); - - QMetaObject::invokeMethod(DependencyManager::get().data(), "processAvatarMixerDatagram", - Q_ARG(const QByteArray&, incomingPacket), - Q_ARG(const QWeakPointer&, avatarMixer)); - } - break; - } - case PacketType::NoisyMute: - case PacketType::MuteEnvironment: { - bool mute = !DependencyManager::get()->isMuted(); - - if (incomingType == PacketType::MuteEnvironment) { - glm::vec3 position; - float radius; - - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); - memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); - memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); - float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), - position); - - mute = mute && (distance < radius); - } - - if (mute) { - DependencyManager::get()->toggleMute(); - if (incomingType == PacketType::MuteEnvironment) { - AudioScriptingInterface::getInstance().environmentMuted(); - } else { - AudioScriptingInterface::getInstance().mutedByMixer(); - } - } - break; - } - case PacketType::EntityEditNack: - if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { - application->_entityEditSender.processNackPacket(incomingPacket); - } - break; - default: - //nodeList->processNodeData(senderSockAddr, incomingPacket); - - packetListenerLock.lock(); - auto& listener = packetListenerMap[incomingType]; - packetListenerLock.unlock(); - - if (packetListenerMap.contains(incomingType)) { - auto& listener = packetListenerMap[incomingType]; - NLPacket packet; - bool success = QMetaObject::invokeMethod(listener.first, listener.second, - Q_ARG(std::unique_ptr, packet), - Q_ARG(HifiSockAddr, senderSockAddr)); - if (!success) { - qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first.name() << "::" << listener.second; - } - } else { - QDebug() << "No listener found for packet type: " << incomingType; - } - - break; + } else { + QDebug() << "No listener found for packet type: " << incomingType; } + } } } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index cc61bdb3cb..fd814c85ea 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -1,6 +1,6 @@ // // PacketReceiver.h -// interface/src +// libraries/networking/src // // Created by Stephen Birarda on 1/23/2014. // Update by Ryan Huffman on 7/8/2015. From 5e65f422fa1a81e885fb4c8cf504a5c952173fe1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:30:25 -0700 Subject: [PATCH 019/146] Move mute environment handling to Application --- interface/src/Application.cpp | 11 +++++ libraries/audio-client/src/AudioClient.cpp | 48 +--------------------- libraries/audio-client/src/AudioClient.h | 7 +++- 3 files changed, 19 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b7c926a7e8..20878205a9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -419,6 +419,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); connect(audioIO.data(), &AudioClient::disconnected, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected); + connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { + auto audioClient = DependencyManager::get(); + float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), + position); + bool shouldMute = !audioClient->isMuted() && (distance < radius); + + if (shouldMute) { + audioClient->toggleMute(); + AudioScriptingInterface::getInstance().environmentMuted(); + } + }); audioThread->start(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 983fa4c20e..2571f42786 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -602,19 +602,13 @@ void AudioClient::handleMuteEnvironmentPacket(std::unique_ptr packet, int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); memcpy(&position, packet->getPayload(), sizeof(glm::vec3)); memcpy(&radius, packet->getPayload() + sizeof(glm::vec3), sizeof(float)); - float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), - position); - bool shouldMute = !_muted && (distance < radius); - if (shouldMute) { - toggleMute(); - // TODO reimplement on interface side - //AudioScriptingInterface::getInstance().environmentMuted(); - } + emit muteEnvironmentRequested(position, radius); } void AudioClient::updateLastHeardFromAudioMixer(std::unique_ptr& packet) { // update having heard from the audio-mixer and record the bytes received + auto nodeList = DependencyManager::get(); SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); if (audioMixer) { audioMixer->setLastHeardMicrostamp(usecTimestampNow()); @@ -1023,44 +1017,6 @@ void AudioClient::sendMuteEnvironmentPacket() { } } -void AudioClient::addReceivedAudioToStream(const QByteArray& audioByteArray) { - DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); - - if (_audioOutput) { - - if (!_hasReceivedFirstPacket) { - _hasReceivedFirstPacket = true; - - // have the audio scripting interface emit a signal to say we just connected to mixer - emit receivedFirstPacket(); - } - - // Audio output must exist and be correctly set up if we're going to process received audio - _receivedAudioStream.parseData(audioByteArray); - } -} - -void AudioClient::parseAudioEnvironmentData(const QByteArray &packet) { - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const char* dataAt = packet.constData() + numBytesPacketHeader; - - char bitset; - memcpy(&bitset, dataAt, sizeof(char)); - dataAt += sizeof(char); - - bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; - if (hasReverb) { - float reverbTime, wetLevel; - memcpy(&reverbTime, dataAt, sizeof(float)); - dataAt += sizeof(float); - memcpy(&wetLevel, dataAt, sizeof(float)); - dataAt += sizeof(float); - _receivedAudioStream.setReverb(reverbTime, wetLevel); - } else { - _receivedAudioStream.clearReverb(); - } -} - void AudioClient::toggleMute() { _muted = !_muted; emit muteToggled(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 37e21e7277..cc04d60367 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -13,6 +13,7 @@ #define hifi_AudioClient_h #include +#include #include #include @@ -32,8 +33,10 @@ #include #include #include -#include +#include +#include +#include #include #include #include @@ -197,6 +200,8 @@ signals: void audioFinished(); + void muteEnvironmentRequested(glm::vec3 position, float radius); + protected: AudioClient(); ~AudioClient(); From 8da50d342ccc2f0845a97aaf9336326fa229fcac Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:31:01 -0700 Subject: [PATCH 020/146] Remove DatagramProcessor.h from Application --- interface/src/Application.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 8ae00cdd38..9653556da0 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -43,7 +43,6 @@ #include "AudioClient.h" #include "Bookmarks.h" #include "Camera.h" -#include "DatagramProcessor.h" #include "Environment.h" #include "FileLogger.h" #include "GLCanvas.h" From 6f9907a22d81d1e0d59406ce50fce81a1da7c5f2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:31:30 -0700 Subject: [PATCH 021/146] Stub in process() for OctreePacketProcessor --- interface/src/octree/OctreePacketProcessor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index a0f2ed3e7b..7e5d6e40e4 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -21,6 +21,8 @@ class OctreePacketProcessor : public GenericThread { public: OctreePacketProcessor(); + virtual bool process() override { }; + signals: void packetVersionMismatch(); From 5737b3b7707730af0d1db507a8e2c3e52f5696a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:32:19 -0700 Subject: [PATCH 022/146] Fix call to size() in AvatarHashMap --- libraries/avatars/src/AvatarHashMap.cpp | 4 ++-- libraries/avatars/src/AvatarHashMap.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index fb20f91431..eebd9aabdd 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -53,7 +53,7 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe } void AvatarHashMap::processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { - const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size); + const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); int bytesRead = 0; SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); @@ -125,7 +125,7 @@ void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet } void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { - const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size); + const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID)); SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index dbfd2dc88e..365241bc2c 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -19,6 +19,7 @@ #include #include +#include #include #include "AvatarData.h" From 672c5cc5b332b857e159c15d4129a4fff955a161 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:33:00 -0700 Subject: [PATCH 023/146] Properly create QByteArray in EntityEditPacketSender --- libraries/entities/src/EntityEditPacketSender.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index a00fea4948..48f5403063 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -24,7 +24,7 @@ EntityEditPacketSender::EntityEditPacketSender() { void EntityEditPacketSender::processEntityEditNackPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { - processNackPacket(QByteArray::fromRawData(packet->getData())); + processNackPacket(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } From b7fe91ccc69869f883555b7e5d848143d7ad8535 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:34:02 -0700 Subject: [PATCH 024/146] Fix errors PacketReceiver --- libraries/networking/src/PacketReceiver.cpp | 44 +++++++++------------ libraries/networking/src/PacketReceiver.h | 11 +++++- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index b94242f85e..a83b3b91a5 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -10,19 +10,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - -#include -#include - -#include "Application.h" -#include "avatar/AvatarManager.h" -#include "AudioClient.h" -#include "Menu.h" -#include "InterfaceLogging.h" - #include "PacketReceiver.h" +#include "DependencyManager.h" +#include "NLPacket.h" +#include "NodeList.h" + PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent), _packetListenerMap() @@ -31,18 +24,18 @@ PacketReceiver::PacketReceiver(QObject* parent) : } void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, QString methodName) { - packetListenerLock.lock(); - if (packetListenerMap.contains(type)) { + _packetListenerLock.lock(); + if (_packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type << " that will remove a previously registered listener"; } - packetListenerMap[type] = QPair(object, methodName); - packetListenerLock.unlock(); + _packetListenerMap[type] = QPair(object, methodName); + _packetListenerLock.unlock(); } void PacketReceiver::processDatagrams() { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "PacketReceiver::processDatagrams()"); + //PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + //"PacketReceiver::processDatagrams()"); if (_isShuttingDown) { return; // bail early... we're shutting down. @@ -66,21 +59,22 @@ void PacketReceiver::processDatagrams() { // TODO What do we do about this? //nodeList->processNodeData(senderSockAddr, incomingPacket); - packetListenerLock.lock(); - auto& listener = packetListenerMap[incomingType]; - packetListenerLock.unlock(); + _packetListenerLock.lock(); + auto& listener = _packetListenerMap[incomingType]; + _packetListenerLock.unlock(); - if (packetListenerMap.contains(incomingType)) { - auto& listener = packetListenerMap[incomingType]; - NLPacket packet; + if (_packetListenerMap.contains(incomingType)) { + auto& listener = _packetListenerMap[incomingType]; + //TODO Update packet + std::unique_ptr packet; bool success = QMetaObject::invokeMethod(listener.first, listener.second, Q_ARG(std::unique_ptr, packet), Q_ARG(HifiSockAddr, senderSockAddr)); if (!success) { - qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first.name() << "::" << listener.second; + qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first->objectName() << "::" << listener.second; } } else { - QDebug() << "No listener found for packet type: " << incomingType; + qDebug() << "No listener found for packet type: " << incomingType; } } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index fd814c85ea..609797cc26 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -13,7 +13,14 @@ #ifndef hifi_PacketReceiver_h #define hifi_PacketReceiver_h +#include +#include #include +#include + +#include + +#include "PacketHeaders.h" class PacketReceiver : public QObject { Q_OBJECT @@ -35,8 +42,8 @@ public slots: void processDatagrams(); private: - QMutex packetListenerLock; - QMap> packetListenerMap; + QMutex _packetListenerLock; + QMap> _packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; int _inByteCount = 0; From f8b4c8490357136674e3ba2a9d8e19f2f70b4d45 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 15:34:20 -0700 Subject: [PATCH 025/146] Add missing header in SentPacketHistory --- libraries/networking/src/SentPacketHistory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/SentPacketHistory.h b/libraries/networking/src/SentPacketHistory.h index 2971df12f5..1808e0020b 100644 --- a/libraries/networking/src/SentPacketHistory.h +++ b/libraries/networking/src/SentPacketHistory.h @@ -13,8 +13,9 @@ #include #include -#include "RingBufferHistory.h" +#include "NLPacket.h" +#include "RingBufferHistory.h" #include "SequenceNumberStats.h" class NLPacket; From 2380fb23c3ea7e31ec6d4d790f1dbdcbb75ff3d2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 16:05:52 -0700 Subject: [PATCH 026/146] Update OctreePacketProcessor to use NLPacket& --- interface/src/octree/OctreePacketProcessor.cpp | 8 ++++---- interface/src/octree/OctreePacketProcessor.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 5d26ac4536..5ba191e3c7 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -26,28 +26,28 @@ OctreePacketProcessor::OctreePacketProcessor() { } // TODO implement packet processing in PacketType-specific methods -void OctreePacketProcessor::handleEntityDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEntityDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleEntityErasePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEntityErasePacket(NLPacket& packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleOctreeStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleOctreeStatsPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEnvironmentDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 7e5d6e40e4..0aac9538bb 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -30,9 +30,9 @@ protected: virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); private slots: - void handleEntityDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleEntityErasePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleOctreeStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleEntityDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr); + void handleEntityErasePacket(NLPacket& packet, HifiSockAddr senderSockAddr); + void handleOctreeStatsPacket(NLPacket& packet, HifiSockAddr senderSockAddr); + void handleEnvironmentDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr); }; #endif // hifi_OctreePacketProcessor_h From 976d14736d4e8e229828fe680688a61a0a16d66e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 9 Jul 2015 16:06:21 -0700 Subject: [PATCH 027/146] Update PacketReceiver to pass NLPacket as NLPacket& --- libraries/networking/src/PacketReceiver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index a83b3b91a5..853a4baae4 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -68,7 +68,7 @@ void PacketReceiver::processDatagrams() { //TODO Update packet std::unique_ptr packet; bool success = QMetaObject::invokeMethod(listener.first, listener.second, - Q_ARG(std::unique_ptr, packet), + Q_ARG(NLPacket&, *packet), Q_ARG(HifiSockAddr, senderSockAddr)); if (!success) { qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first->objectName() << "::" << listener.second; From 78ff6477bdb6479da9d6dd328827b668f7928b29 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 08:45:21 -0700 Subject: [PATCH 028/146] Update OctreePacketProcessor to use QSharedPointer --- interface/src/octree/OctreePacketProcessor.cpp | 8 ++++---- interface/src/octree/OctreePacketProcessor.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 5ba191e3c7..4f3a4765ed 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -26,28 +26,28 @@ OctreePacketProcessor::OctreePacketProcessor() { } // TODO implement packet processing in PacketType-specific methods -void OctreePacketProcessor::handleEntityDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEntityDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleEntityErasePacket(NLPacket& packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEntityErasePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleOctreeStatsPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleOctreeStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } } -void OctreePacketProcessor::handleEnvironmentDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr) { +void OctreePacketProcessor::handleEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (sendingNode) { processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 0aac9538bb..73d9161a74 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -30,9 +30,9 @@ protected: virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); private slots: - void handleEntityDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr); - void handleEntityErasePacket(NLPacket& packet, HifiSockAddr senderSockAddr); - void handleOctreeStatsPacket(NLPacket& packet, HifiSockAddr senderSockAddr); - void handleEnvironmentDataPacket(NLPacket& packet, HifiSockAddr senderSockAddr); + void handleEntityDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleEntityErasePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleOctreeStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); }; #endif // hifi_OctreePacketProcessor_h From 28a1059232b710fc97f432e04fd1cb9d0189e6d3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 08:45:39 -0700 Subject: [PATCH 029/146] Update AudioClient to use QSharedPointer --- libraries/audio-client/src/AudioClient.cpp | 14 +++++++------- libraries/audio-client/src/AudioClient.h | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 2571f42786..c946586074 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -535,13 +535,13 @@ void AudioClient::stop() { } } -void AudioClient::handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { _stats.parseAudioStreamStatsPacket(packet->getData()); updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { const char* dataAt = packet->getPayload(); char bitset; @@ -563,7 +563,7 @@ void AudioClient::handleAudioEnvironmentDataPacket(std::unique_ptr pac updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); @@ -583,11 +583,11 @@ void AudioClient::handleAudioDataPacket(std::unique_ptr packet, HifiSo updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr) { updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { if (!_muted) { toggleMute(); // TODO reimplement on interface side @@ -595,7 +595,7 @@ void AudioClient::handleNoisyMutePacket(std::unique_ptr packet, HifiSo } } -void AudioClient::handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { glm::vec3 position; float radius; @@ -606,7 +606,7 @@ void AudioClient::handleMuteEnvironmentPacket(std::unique_ptr packet, emit muteEnvironmentRequested(position, radius); } -void AudioClient::updateLastHeardFromAudioMixer(std::unique_ptr& packet) { +void AudioClient::updateLastHeardFromAudioMixer(QSharedPointer& packet) { // update having heard from the audio-mixer and record the bytes received auto nodeList = DependencyManager::get(); SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index cc04d60367..8812473a79 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -139,12 +139,12 @@ public slots: void start(); void stop(); - void handleAudioStreamStatsPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleAudioEnvironmentDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleAudioDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleSilentAudioFrame(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleNoisyMutePacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void handleMuteEnvironmentPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } void handleAudioInput(); @@ -214,7 +214,7 @@ private slots: void audioStateChanged(QAudio::State state); private: - void updateLastHeardFromAudioMixer(std::unique_ptr& packet); + void updateLastHeardFromAudioMixer(QSharedPointer& packet); void outputFormatChanged(); QByteArray firstInputFrame; From 4db3b309b5e6be7110f2bda27f7bead55729df2e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 08:45:54 -0700 Subject: [PATCH 030/146] Update AvatarHashMap to use QSharedPointer --- libraries/avatars/src/AvatarHashMap.cpp | 8 ++++---- libraries/avatars/src/AvatarHashMap.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index eebd9aabdd..15d161aa84 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -52,7 +52,7 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe return avatar; } -void AvatarHashMap::processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AvatarHashMap::processAvatarDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); int bytesRead = 0; @@ -83,7 +83,7 @@ void AvatarHashMap::processAvatarDataPacket(std::unique_ptr packet, Hi } } -void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { // setup a data stream to parse the packet QDataStream identityStream { packet.get() }; @@ -124,7 +124,7 @@ void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr packet } } -void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID)); @@ -144,7 +144,7 @@ void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr packe } } -void AvatarHashMap::processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void AvatarHashMap::processKillAvatar(QSharedPointer packet, HifiSockAddr senderSockAddr) { SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); if (avatarMixer) { avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 365241bc2c..95f996dec3 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -39,10 +39,10 @@ public slots: private slots: void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); - void processAvatarDataPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void processAvatarIdentityPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void processAvatarBillboardPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); - void processKillAvatar(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void processAvatarDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void processAvatarIdentityPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void processAvatarBillboardPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void processKillAvatar(QSharedPointer packet, HifiSockAddr senderSockAddr); protected: AvatarHashMap(); From ec0fc81b86b0bb3c473c76360f9f3d96c0f8577a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 08:46:11 -0700 Subject: [PATCH 031/146] Update EntityEditPacketSender to use QSharedPointer --- libraries/entities/src/EntityEditPacketSender.cpp | 2 +- libraries/entities/src/EntityEditPacketSender.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 48f5403063..3b938b9f1d 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -22,7 +22,7 @@ EntityEditPacketSender::EntityEditPacketSender() { packetReceiver.registerPacketListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); } -void EntityEditPacketSender::processEntityEditNackPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr) { +void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { processNackPacket(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index f1cee09207..667040c1df 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -30,7 +30,7 @@ public: void queueEraseEntityMessage(const EntityItemID& entityItemID); - void processEntityEditNackPacket(std::unique_ptr packet, HifiSockAddr senderSockAddr); + void processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); // My server type is the model server virtual char getMyNodeType() const { return NodeType::EntityServer; } From d009bf826e017ff4fd00ce348e455431bf625216 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 08:46:21 -0700 Subject: [PATCH 032/146] Update PacketReceiver to use QSharedPointer --- libraries/networking/src/PacketReceiver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 853a4baae4..6b4628e62c 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -66,9 +66,9 @@ void PacketReceiver::processDatagrams() { if (_packetListenerMap.contains(incomingType)) { auto& listener = _packetListenerMap[incomingType]; //TODO Update packet - std::unique_ptr packet; + QSharedPointer packet; bool success = QMetaObject::invokeMethod(listener.first, listener.second, - Q_ARG(NLPacket&, *packet), + Q_ARG(QSharedPointer, packet), Q_ARG(HifiSockAddr, senderSockAddr)); if (!success) { qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first->objectName() << "::" << listener.second; From c841867044012d7f349182a1714462a216c06f06 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 09:37:24 -0700 Subject: [PATCH 033/146] Update AudioMixer to use PacketReceiver --- assignment-client/src/audio/AudioMixer.cpp | 70 ++++++++++++++-------- assignment-client/src/audio/AudioMixer.h | 8 +++ 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bb58bb0f78..0d0237b7e1 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -94,6 +94,15 @@ AudioMixer::AudioMixer(const QByteArray& packet) : { // constant defined in AudioMixer.h. However, we don't want to include this here // we will soon find a better common home for these audio-related constants + // SOON + + auto nodeList = DependencyManager::get(); + nodeList->registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); + nodeList->registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); + nodeList->registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); + nodeList->registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); + nodeList->registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); + nodeList->registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f; @@ -535,36 +544,45 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { } void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - auto nodeList = DependencyManager::get(); - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - // pull any new audio data from nodes off of the network stack - PacketType::Value mixerPacketType = packetTypeForPacket(receivedPacket); - if (mixerPacketType == PacketType::MicrophoneAudioNoEcho - || mixerPacketType == PacketType::MicrophoneAudioWithEcho - || mixerPacketType == PacketType::InjectAudio - || mixerPacketType == PacketType::SilentAudioFrame - || mixerPacketType == PacketType::AudioStreamStats) { + nodeList->processNodeData(senderSockAddr, receivedPacket); + } +} - nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); - } else if (mixerPacketType == PacketType::MuteEnvironment) { - SharedNodePointer sendingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (sendingNode->getCanAdjustLocks()) { - auto packet = NLPacket::create(PacketType::MuteEnvironment); - // Copy payload - packet->write(receivedPacket.mid(numBytesForPacketHeader(receivedPacket))); +void AudioMixer::handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); +} - nodeList->eachNode([&](const SharedNodePointer& node){ - if (node->getType() == NodeType::Agent && node->getActiveSocket() && - node->getLinkedData() && node != sendingNode) { - nodeList->sendPacket(std::move(packet), node); - } - }); +void AudioMixer::handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); +} + +void AudioMixer::handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); +} + +void AudioMixer::handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); +} + +void AudioMixer::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); +} + +void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); + SharedNodePointer sendingNode = nodeList->nodeWithUUID(packet->getSourceID()); + if (sendingNode->getCanAdjustLocks()) { + auto packet = NLPacket::create(PacketType::MuteEnvironment); + // Copy payload + packet->write(receivedPacket.mid(numBytesForPacketHeader(receivedPacket))); + + nodeList->eachNode([&](const SharedNodePointer& node){ + if (node->getType() == NodeType::Agent && node->getActiveSocket() && + node->getLinkedData() && node != sendingNode) { + nodeList->sendPacket(std::move(packet), node); } - } else { - // let processNodeData handle it. - nodeList->processNodeData(senderSockAddr, receivedPacket); - } + }); } } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 8eb64af74c..a800ffbe68 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -42,6 +42,14 @@ public slots: static const InboundAudioStream::Settings& getStreamSettings() { return _streamSettings; } +private slots: + void handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + private: /// adds one stream to the mix for a listening node int addStreamToMixForListeningNodeWithStream(AudioMixerClientData* listenerNodeData, From 83dedd0a1532b2371470619362d58f37200436ea Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 09:37:43 -0700 Subject: [PATCH 034/146] Add todo to move PacketReceiver to its own thread --- libraries/networking/src/LimitedNodeList.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 15ffeb2ebd..9532a1a389 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -93,6 +93,8 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short // check the local socket right now updateLocalSockAddr(); + // TODO: Create a new thread, and move PacketReceiver to it + connect(&_nodeSocket, &QUdpSocket::readyRead, &_packetReceiver, &PacketReceiver::processDatagrams); _packetStatTimer.start(); From 528fac6b84af02a80c465100d715244c904cb8a5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 12:22:25 -0700 Subject: [PATCH 035/146] rework of PacketReceiver registration API, HifiSockAddr packet getter --- libraries/networking/src/Packet.h | 5 +++ libraries/networking/src/PacketReceiver.cpp | 47 +++++++++++++++++++-- libraries/networking/src/PacketReceiver.h | 6 ++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/Packet.h b/libraries/networking/src/Packet.h index e9483ca1f1..c52fb88e49 100644 --- a/libraries/networking/src/Packet.h +++ b/libraries/networking/src/Packet.h @@ -48,6 +48,9 @@ public: qint64 getSizeUsed() const { return _sizeUsed; } void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; } + HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } + const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; } + // Header readers PacketType::Value readType() const; PacketVersion readVersion() const; @@ -87,6 +90,8 @@ protected: qint64 _capacity = 0; // Total capacity of the payload qint64 _sizeUsed = 0; // How much of the payload is actually used + + HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end) }; diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 6b4628e62c..a0a5e0ca6f 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -23,13 +23,54 @@ PacketReceiver::PacketReceiver(QObject* parent) : } -void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, QString methodName) { +void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, const char* slot) { + Q_ASSERT(object); + _packetListenerLock.lock(); + if (_packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type - << " that will remove a previously registered listener"; + << "that will remove a previously registered listener"; } - _packetListenerMap[type] = QPair(object, methodName); + + // convert the const char* slot to a QMetaMethod + int methodIndex = object->indexOfSlot(slot); + Q_ASSERT(methodIndex >= 0); + + QMetaMethod slotMethod = object->method(methodIndex); + Q_ASSERT(method.isValid()); + + // compare the parameters we expect and the parameters the QMetaMethod has + bool parametersMatch = false; + + if (NON_SOURCED_PACKETS.contains(type)) { + const QList NON_SOURCED_PACKET_LISTENER_PARAMETERS = QList() + << QString("QSharedPointer"); + + parametersMatch = slotMethod.parameterTypes() == NON_SOURCED_PACKET_LISTENER_PARAMETERS; + + qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" + << NON_SOURCED_PACKET_LISTENER_PARAMETERS + << "but parameter method takes" << signalMethod.parameterTypes(); + } else { + const QList SOURCED_PACKET_LISTENER_PARAMETERS = QList() + << QString("QSharedPointer") << QString("QSharedPointer"); + + parametersMatch = slotMethod.parameterTypes() == SOURCED_PACKET_LISTENER_PARAMETERS; + + if (!parametersMatch) { + qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" + << SOURCED_PACKET_LISTENER_PARAMETERS + << "but parameter method takes" << signalMethod.parameterTypes(); + } + } + + // make sure the parameters match + assert(parametersMatch); + + // add the mapping + _packetListenerMap[type] = ObjectMethodPair(object, slotMethod); + _packetListenerLock.unlock(); } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 609797cc26..9e20a381e1 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -36,14 +36,16 @@ public: void shutdown() { _isShuttingDown = true; } - void registerPacketListener(PacketType::Value type, QObject* object, QString methodName); + bool registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); public slots: void processDatagrams(); private: + using ObjectMethodPair = QPair; + QMutex _packetListenerLock; - QMap> _packetListenerMap; + QMap _packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; int _inByteCount = 0; From 99121a3a209c5ff61c0ab08e699366ae0ec32e87 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:22:53 -0700 Subject: [PATCH 036/146] Fix AudioMixer not using PacketReceiver correctly --- assignment-client/src/audio/AudioMixer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 0d0237b7e1..abd43ba907 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -96,13 +96,13 @@ AudioMixer::AudioMixer(const QByteArray& packet) : // we will soon find a better common home for these audio-related constants // SOON - auto nodeList = DependencyManager::get(); - nodeList->registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); - nodeList->registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); - nodeList->registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); - nodeList->registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); - nodeList->registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); - nodeList->registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver->registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); + packetReceiver->registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); + packetReceiver->registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); + packetReceiver->registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); + packetReceiver->registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); + packetReceiver->registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f; From 1ee7a839271669373646535895f12f2b4c2c217a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:23:35 -0700 Subject: [PATCH 037/146] Add EntityServer packet handling --- .../src/entities/EntityServer.cpp | 24 ++++++++++++++++++- assignment-client/src/entities/EntityServer.h | 5 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index b928adde53..c09e068b21 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -23,7 +23,11 @@ const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo"; EntityServer::EntityServer(const QByteArray& packet) : OctreeServer(packet), _entitySimulation(NULL) { - // nothing special to do here... + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); + packetReceiver.registerPacketListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); + packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket"); } EntityServer::~EntityServer() { @@ -36,6 +40,24 @@ EntityServer::~EntityServer() { tree->removeNewlyCreatedHook(this); } +void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + if (_octreeInboundPacketProcessor) { + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + } +} + +void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + if (_octreeInboundPacketProcessor) { + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + } +} + +void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + if (_octreeInboundPacketProcessor) { + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + } +} + OctreeQueryNode* EntityServer::createOctreeQueryNode() { return new EntityNodeData(); } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index b73ace6048..cacf8f3457 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -49,6 +49,11 @@ public slots: protected: virtual Octree* createTree(); +private slots: + void handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + private: EntitySimulation* _entitySimulation; QTimer* _pruneDeletedEntitiesTimer = nullptr; From 09f978207b304fa90374376856c96fa7b8f7f923 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:23:58 -0700 Subject: [PATCH 038/146] Add packet handling to OctreeServer --- assignment-client/src/octree/OctreeServer.cpp | 36 +++++++++++++++++++ assignment-client/src/octree/OctreeServer.h | 5 +++ 2 files changed, 41 insertions(+) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 3a3b5dec37..55d6f0be81 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -247,6 +247,11 @@ OctreeServer::OctreeServer(const QByteArray& packet) : // make sure the AccountManager has an Auth URL for payment redemptions AccountManager::getInstance().setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); + + auto packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver->registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver->registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); + packetReceiver->registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); } OctreeServer::~OctreeServer() { @@ -855,6 +860,37 @@ void OctreeServer::readPendingDatagram(const QByteArray& receivedPacket, const H } } +void handleOctreeQueryPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + // If we got a query packet, then we're talking to an agent, and we + // need to make sure we have it in our nodeList. + SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); + if (matchingNode) { + nodeList->updateNodeWithDataFromPacket(matchingNode, packet->getData()); + + OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); + if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { + nodeData->initializeOctreeSendThread(this, matchingNode); + } + } +} + +void handleOctreeDataNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + // If we got a nack packet, then we're talking to an agent, and we + // need to make sure we have it in our nodeList. + SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); + if (matchingNode) { + OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); + if (nodeData) { + nodeData->parseNackPacket(packet->getData()); + } + } +} + +void handleJurisdictionRequestPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); + _jurisdictionSender->queueReceivedPacket(matchingNode, packet->getData()); +} + void OctreeServer::setupDatagramProcessingThread() { auto nodeList = DependencyManager::get(); diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index ec5c85c3f5..d25ef3183b 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -128,6 +128,11 @@ public slots: void readPendingDatagrams() { }; // this will not be called since our datagram processing thread will handle void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); +private slots: + void handleOctreeQueryPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleOctreeDataNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleJurisdictionRequestPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + protected: virtual Octree* createTree() = 0; bool readOptionBool(const QString& optionName, const QJsonObject& settingsSectionObject, bool& result); From 5a862739aaa9fd3cddd516ad3a2b80d2597e7a4d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:24:17 -0700 Subject: [PATCH 039/146] Fix shared ptr call in AvatarHashMap --- libraries/avatars/src/AvatarHashMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 15d161aa84..03187a02bc 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -85,7 +85,7 @@ void AvatarHashMap::processAvatarDataPacket(QSharedPointer packet, Hif void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { // setup a data stream to parse the packet - QDataStream identityStream { packet.get() }; + QDataStream identityStream { packet.data() }; QUuid sessionUUID; From 2f0c21a603b6950ebdedecb90171bab770439c1c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:24:35 -0700 Subject: [PATCH 040/146] Temporarily disable packet dispatching in PacketReceiver --- libraries/networking/src/PacketReceiver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 6b4628e62c..d40ce40ba1 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -67,9 +67,9 @@ void PacketReceiver::processDatagrams() { auto& listener = _packetListenerMap[incomingType]; //TODO Update packet QSharedPointer packet; - bool success = QMetaObject::invokeMethod(listener.first, listener.second, - Q_ARG(QSharedPointer, packet), - Q_ARG(HifiSockAddr, senderSockAddr)); + bool success = true; //QMetaObject::invokeMethod(listener.first, listener.second, + // Q_ARG(QSharedPointer, packet), + // Q_ARG(HifiSockAddr, senderSockAddr)); if (!success) { qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first->objectName() << "::" << listener.second; } From 972c465bdb09292f8ce43ebca1b9ca218b6b1e60 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 12:25:01 -0700 Subject: [PATCH 041/146] Remove PacketReceiver copy ctor and = operator --- libraries/networking/src/PacketReceiver.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 609797cc26..403ac79864 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -26,6 +26,9 @@ class PacketReceiver : public QObject { Q_OBJECT public: PacketReceiver(QObject* parent = 0); + PacketReceiver(const PacketReceiver&) = delete; + + PacketReceiver& operator=(const PacketReceiver&) = delete; int getInPacketCount() const { return _inPacketCount; } int getOutPacketCount() const { return _outPacketCount; } From 2d1c3e27daecf61049a7d4699004bea663aefa1b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 12:27:44 -0700 Subject: [PATCH 042/146] fix parameter matching in PacketReceiver --- libraries/networking/src/PacketReceiver.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index a0a5e0ca6f..02f948dc5f 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -34,10 +34,10 @@ void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* obj } // convert the const char* slot to a QMetaMethod - int methodIndex = object->indexOfSlot(slot); + int methodIndex = object->metaObject()->indexOfSlot(slot); Q_ASSERT(methodIndex >= 0); - QMetaMethod slotMethod = object->method(methodIndex); + QMetaMethod slotMethod = object->metaObject()->method(methodIndex); Q_ASSERT(method.isValid()); // compare the parameters we expect and the parameters the QMetaMethod has @@ -45,7 +45,7 @@ void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* obj if (NON_SOURCED_PACKETS.contains(type)) { const QList NON_SOURCED_PACKET_LISTENER_PARAMETERS = QList() - << QString("QSharedPointer"); + << QMetaObject::normalizedType("QSharedPointer"); parametersMatch = slotMethod.parameterTypes() == NON_SOURCED_PACKET_LISTENER_PARAMETERS; @@ -54,7 +54,8 @@ void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* obj << "but parameter method takes" << signalMethod.parameterTypes(); } else { const QList SOURCED_PACKET_LISTENER_PARAMETERS = QList() - << QString("QSharedPointer") << QString("QSharedPointer"); + << QMetaObject::normalizedType(("QSharedPointer") + << QMetaObject::normalizedType(("QSharedPointer"); parametersMatch = slotMethod.parameterTypes() == SOURCED_PACKET_LISTENER_PARAMETERS; From 74afbd7de725af29578a409af451999b2aa2a0a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 14:22:46 -0700 Subject: [PATCH 043/146] Fix AudioMixer packetReceiver calls --- assignment-client/src/audio/AudioMixer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index abd43ba907..ec9998c881 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -97,12 +97,12 @@ AudioMixer::AudioMixer(const QByteArray& packet) : // SOON auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver->registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); - packetReceiver->registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); - packetReceiver->registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); - packetReceiver->registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); - packetReceiver->registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); - packetReceiver->registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); + packetReceiver.registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); + packetReceiver.registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); + packetReceiver.registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); + packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); + packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f; From 6e53a5ad978b408f6fefaaa512a79e4521810b6a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 14:23:09 -0700 Subject: [PATCH 044/146] Update OctreePacketProcessor to use SharedNodePointer --- .../src/octree/OctreePacketProcessor.cpp | 28 ++++++------------- interface/src/octree/OctreePacketProcessor.h | 10 +++---- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 4f3a4765ed..dba75b0c5f 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -26,32 +26,20 @@ OctreePacketProcessor::OctreePacketProcessor() { } // TODO implement packet processing in PacketType-specific methods -void OctreePacketProcessor::handleEntityDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (sendingNode) { - processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - } +void OctreePacketProcessor::handleEntityDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } -void OctreePacketProcessor::handleEntityErasePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (sendingNode) { - processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - } +void OctreePacketProcessor::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } -void OctreePacketProcessor::handleOctreeStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (sendingNode) { - processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - } +void OctreePacketProcessor::handleOctreeStatsPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } -void OctreePacketProcessor::handleEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer sendingNode = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (sendingNode) { - processPacket(sendingNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - } +void OctreePacketProcessor::handleEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 73d9161a74..5274353b83 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -16,7 +16,7 @@ /// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() -class OctreePacketProcessor : public GenericThread { +class OctreePacketProcessor : public ReceivedPacketProcessor { Q_OBJECT public: OctreePacketProcessor(); @@ -30,9 +30,9 @@ protected: virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); private slots: - void handleEntityDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleEntityErasePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleOctreeStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleEntityDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleOctreeStatsPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); }; #endif // hifi_OctreePacketProcessor_h From 99aaefbd0331922f921af44f8fbf8df010d510a5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 15:00:29 -0700 Subject: [PATCH 045/146] Fix and update signature of Application::handleDomainConnectionDeniedPacket --- interface/src/Application.cpp | 24 ++++++++++++------------ interface/src/Application.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 20878205a9..98d9325403 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3822,19 +3822,19 @@ void Application::domainConnectionDenied(const QString& reason) { } } -void handleDomainConnectionDeniedPacket(std::unique_ptr, HifiSockAddr senderSockAddr) { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); - QDataStream packetStream(QByteArray(incomingPacket.constData() + headerSize, - incomingPacket.size() - headerSize)); - QString reason; - packetStream >> reason; +void Application::handleDomainConnectionDeniedPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); + QDataStream packetStream(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - // output to the log so the user knows they got a denied connection request - // and check and signal for an access token so that we can make sure they are logged in - qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; - qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; - domainConnectionDenied(reason); - AccountManager::getInstance().checkAndSignalForAccessToken(); + QString reason; + packetStream >> reason; + + // output to the log so the user knows they got a denied connection request + // and check and signal for an access token so that we can make sure they are logged in + qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; + qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; + domainConnectionDenied(reason); + AccountManager::getInstance().checkAndSignalForAccessToken(); } void Application::connectedToDomain(const QString& hostname) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 9653556da0..c3f31a107c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -444,7 +444,7 @@ public slots: void notifyPacketVersionMismatch(); void domainConnectionDenied(const QString& reason); - void handleDomainConnectionDeniedPacket(std::unique_ptr, HifiSockAddr senderSockAddr); + void handleDomainConnectionDeniedPacket(QSharedPointer, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); void cameraMenuChanged(); From dee117500bddb961b5d22bdc819fa6362b340806 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 15:00:46 -0700 Subject: [PATCH 046/146] Remove process() from OctreePacketProcessor --- interface/src/octree/OctreePacketProcessor.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 5274353b83..50d68fe713 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -21,8 +21,6 @@ class OctreePacketProcessor : public ReceivedPacketProcessor { public: OctreePacketProcessor(); - virtual bool process() override { }; - signals: void packetVersionMismatch(); From d74ce120986ed7ec024fdc4f9e47f93df0916a7a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 15:01:21 -0700 Subject: [PATCH 047/146] Remove declaration processAvatarMixerDatagram from AvatarHashMap --- libraries/avatars/src/AvatarHashMap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 95f996dec3..3c979e35f8 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -34,7 +34,6 @@ public: int size() { return _avatarHash.size(); } public slots: - void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); bool isAvatarInRange(const glm::vec3 & position, const float range); private slots: From 1c212ba1a18e74c8b992f5f9d1afc91e4f6702ea Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 15:01:45 -0700 Subject: [PATCH 048/146] Disable disabling of entity nack packet temporarily --- libraries/entities/src/EntityEditPacketSender.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 3b938b9f1d..a798b83412 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -23,9 +23,9 @@ EntityEditPacketSender::EntityEditPacketSender() { } void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { + // if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { processNackPacket(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - } + // } } void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew) { From 1fb4c13b3c9d4740f3c07a1b39144f633c41ae3f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 15:51:12 -0700 Subject: [PATCH 049/146] Update AssignmentClient to use PacketReceiver --- assignment-client/src/AssignmentClient.cpp | 110 +++++++++------------ assignment-client/src/AssignmentClient.h | 5 +- 2 files changed, 48 insertions(+), 67 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index fd9e4f4f71..971da41df6 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -104,9 +104,6 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri connect(&_requestTimer, SIGNAL(timeout()), SLOT(sendAssignmentRequest())); _requestTimer.start(ASSIGNMENT_REQUEST_INTERVAL_MSECS); - // connect our readPendingDatagrams method to the readyRead() signal of the socket - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); - // connections to AccountManager for authentication connect(&AccountManager::getInstance(), &AccountManager::authRequired, this, &AssignmentClient::handleAuthenticationRequest); @@ -123,6 +120,9 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri // Hook up a timer to send this child's status to the Monitor once per second setUpStatsToMonitor(); } + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); + packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleStopNodePacket"); } @@ -206,85 +206,63 @@ void AssignmentClient::sendAssignmentRequest() { } } -void AssignmentClient::readPendingDatagrams() { - auto nodeList = DependencyManager::get(); +void AssignmentClient::handleCreateAssignementPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + qDebug() << "Received a PacketType::CreateAssignment - attempting to unpack."; - QByteArray receivedPacket; - HifiSockAddr senderSockAddr; + // construct the deployed assignment from the packet data + _currentAssignment = AssignmentFactory::unpackAssignment(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - while (nodeList->getNodeSocket().hasPendingDatagrams()) { - receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); - nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + if (_currentAssignment) { + qDebug() << "Received an assignment -" << *_currentAssignment; - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - if (packetTypeForPacket(receivedPacket) == PacketType::CreateAssignment) { + // switch our DomainHandler hostname and port to whoever sent us the assignment - qDebug() << "Received a PacketType::CreateAssignment - attempting to unpack."; + nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); + nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); - // construct the deployed assignment from the packet data - _currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket); + qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); - if (_currentAssignment) { - qDebug() << "Received an assignment -" << *_currentAssignment; + // start the deployed assignment + QThread* workerThread = new QThread; + workerThread->setObjectName("ThreadedAssignment Worker"); - // switch our DomainHandler hostname and port to whoever sent us the assignment + connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run); - nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); - nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); + // Once the ThreadedAssignment says it is finished - we ask it to deleteLater + // This is a queued connection so that it is put into the event loop to be processed by the worker + // thread when it is ready. + connect(_currentAssignment.data(), &ThreadedAssignment::finished, _currentAssignment.data(), + &ThreadedAssignment::deleteLater, Qt::QueuedConnection); - qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); + // once it is deleted, we quit the worker thread + connect(_currentAssignment.data(), &ThreadedAssignment::destroyed, workerThread, &QThread::quit); - // start the deployed assignment - QThread* workerThread = new QThread; - workerThread->setObjectName("ThreadedAssignment Worker"); + // have the worker thread remove itself once it is done + connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater); - connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run); + // once the worker thread says it is done, we consider the assignment completed + connect(workerThread, &QThread::destroyed, this, &AssignmentClient::assignmentCompleted); - // Once the ThreadedAssignment says it is finished - we ask it to deleteLater - // This is a queued connection so that it is put into the event loop to be processed by the worker - // thread when it is ready. - connect(_currentAssignment.data(), &ThreadedAssignment::finished, _currentAssignment.data(), - &ThreadedAssignment::deleteLater, Qt::QueuedConnection); + _currentAssignment->moveToThread(workerThread); - // once it is deleted, we quit the worker thread - connect(_currentAssignment.data(), &ThreadedAssignment::destroyed, workerThread, &QThread::quit); + // move the NodeList to the thread used for the _current assignment + nodeList->moveToThread(workerThread); - // have the worker thread remove itself once it is done - connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater); + // Starts an event loop, and emits workerThread->started() + workerThread->start(); + } else { + qDebug() << "Received an assignment that could not be unpacked. Re-requesting."; + } +} - // once the worker thread says it is done, we consider the assignment completed - connect(workerThread, &QThread::destroyed, this, &AssignmentClient::assignmentCompleted); +void AssignmentClient::handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || + senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + qDebug() << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode."; - _currentAssignment->moveToThread(workerThread); - - // move the NodeList to the thread used for the _current assignment - nodeList->moveToThread(workerThread); - - // let the assignment handle the incoming datagrams for its duration - disconnect(&nodeList->getNodeSocket(), 0, this, 0); - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _currentAssignment.data(), - &ThreadedAssignment::readPendingDatagrams); - - // Starts an event loop, and emits workerThread->started() - workerThread->start(); - } else { - qDebug() << "Received an assignment that could not be unpacked. Re-requesting."; - } - } else if (packetTypeForPacket(receivedPacket) == PacketType::StopNode) { - if (senderSockAddr.getAddress() == QHostAddress::LocalHost || - senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { - qDebug() << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode."; - - QCoreApplication::quit(); - } else { - qDebug() << "Got a stop packet from other than localhost."; - } - } else { - // have the NodeList attempt to handle it - nodeList->processNodeData(senderSockAddr, receivedPacket); - } - } + QCoreApplication::quit(); + } else { + qDebug() << "Got a stop packet from other than localhost."; } } diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 60e81a94eb..ba0a2e096e 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -28,7 +28,6 @@ public: quint16 assignmentMonitorPort); private slots: void sendAssignmentRequest(); - void readPendingDatagrams(); void assignmentCompleted(); void handleAuthenticationRequest(); void sendStatsPacketToACM(); @@ -37,6 +36,10 @@ private slots: public slots: void aboutToQuit(); +private slots: + void handleCreateAssignementPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + private: void setUpStatsToMonitor(); From 5c831efe64e9ffe1bd90599970217d9553c6fd6f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:13:57 -0700 Subject: [PATCH 050/146] Remove avatar packet processing from Agent --- assignment-client/src/Agent.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0a4408cbf0..916e07d7e9 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -118,18 +118,6 @@ void Agent::readPendingDatagrams() { // let this continue through to the NodeList so it updates last heard timestamp // for the sending audio mixer DependencyManager::get()->processNodeData(senderSockAddr, receivedPacket); - } else if (datagramPacketType == PacketType::BulkAvatarData - || datagramPacketType == PacketType::AvatarIdentity - || datagramPacketType == PacketType::AvatarBillboard - || datagramPacketType == PacketType::KillAvatar) { - // let the avatar hash map process it - DependencyManager::get()->processAvatarMixerDatagram(receivedPacket, nodeList->sendingNodeForPacket(receivedPacket)); - - // let this continue through to the NodeList so it updates last heard timestamp - // for the sending avatar-mixer - DependencyManager::get()->processNodeData(senderSockAddr, receivedPacket); - } else { - DependencyManager::get()->processNodeData(senderSockAddr, receivedPacket); } } } From 0d920c7b7c4e9bf8c85bedc108b8e608b4748e31 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:14:23 -0700 Subject: [PATCH 051/146] Update method name in AssignmentClient --- assignment-client/src/AssignmentClient.cpp | 7 +++---- assignment-client/src/AssignmentClient.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 971da41df6..dda505429d 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -206,7 +206,7 @@ void AssignmentClient::sendAssignmentRequest() { } } -void AssignmentClient::handleCreateAssignementPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { qDebug() << "Received a PacketType::CreateAssignment - attempting to unpack."; // construct the deployed assignment from the packet data @@ -215,6 +215,8 @@ void AssignmentClient::handleCreateAssignementPacket(QSharedPointer pa if (_currentAssignment) { qDebug() << "Received an assignment -" << *_currentAssignment; + auto nodeList = DependencyManager::get(); + // switch our DomainHandler hostname and port to whoever sent us the assignment nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); @@ -305,9 +307,6 @@ void AssignmentClient::assignmentCompleted() { auto nodeList = DependencyManager::get(); - // have us handle incoming NodeList datagrams again, and make sure our ThreadedAssignment isn't handling them - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); - // reset our NodeList by switching back to unassigned and clearing the list nodeList->setOwnerType(NodeType::Unassigned); nodeList->reset(); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index ba0a2e096e..268683fa3c 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -37,7 +37,7 @@ public slots: void aboutToQuit(); private slots: - void handleCreateAssignementPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleCreateAssignmentPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); void handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); private: From 910836fa5a830be203ff89e20903b2ab1af5bfa4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:14:40 -0700 Subject: [PATCH 052/146] Remove readPendingDatagrams from AudioMixer --- assignment-client/src/audio/AudioMixer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index a800ffbe68..c88c5a6242 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -35,7 +35,6 @@ public slots: /// threaded run of assignment void run(); - void readPendingDatagrams() { }; // this will not be called since our datagram processing thread will handle void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); void sendStatsPacket(); From fe5b17f061be489a3df9d5f8198525b8ad040e31 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:15:05 -0700 Subject: [PATCH 053/146] Remove readPendingDatagrams from ThreadedAssignment --- libraries/networking/src/ThreadedAssignment.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index e2e0aa0fed..daca2cfe00 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -30,7 +30,6 @@ public slots: /// threaded run of assignment virtual void run() = 0; Q_INVOKABLE virtual void stop() { setFinished(true); } - virtual void readPendingDatagrams() = 0; virtual void sendStatsPacket(); signals: From cc7bfd90f120a7f5e97b17775780c1ae4d631215 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:27:42 -0700 Subject: [PATCH 054/146] Move audio packet handling to listener in Agent --- assignment-client/src/Agent.cpp | 24 ++++++++++++------------ assignment-client/src/Agent.h | 3 +++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 916e07d7e9..0576a0d4f0 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -47,6 +47,10 @@ Agent::Agent(const QByteArray& packet) : DependencyManager::set(); DependencyManager::set(); + + auto& packetReceiver = DependencyManager::get()->getPackingReceiver(); + packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioPacket"); } void Agent::readPendingDatagrams() { @@ -106,23 +110,19 @@ void Agent::readPendingDatagrams() { if (datagramPacketType == PacketType::EntityData || datagramPacketType == PacketType::EntityErase) { _entityViewer.processDatagram(mutablePacket, sourceNode); } - - } else if (datagramPacketType == PacketType::MixedAudio || datagramPacketType == PacketType::SilentAudioFrame) { - - _receivedAudioStream.parseData(receivedPacket); - - _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); - - _receivedAudioStream.clearBuffer(); - - // let this continue through to the NodeList so it updates last heard timestamp - // for the sending audio mixer - DependencyManager::get()->processNodeData(senderSockAddr, receivedPacket); } } } } +void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + _receivedAudioStream.parseData(receivedPacket); + + _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); + + _receivedAudioStream.clearBuffer(); +} + const QString AGENT_LOGGING_NAME = "agent"; void Agent::run() { diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 415b14c0da..bee043f6f4 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -55,6 +55,9 @@ public slots: void readPendingDatagrams(); void playAvatarSound(Sound* avatarSound) { _scriptEngine.setAvatarSound(avatarSound); } +private slots: + void handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + private: ScriptEngine _scriptEngine; EntityEditPacketSender _entityEditSender; From 990f7b7332887565776f5b680e55a29d56c2eab3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 16:45:44 -0700 Subject: [PATCH 055/146] changes for new packet receive API --- libraries/networking/src/LimitedNodeList.cpp | 93 +++---------- libraries/networking/src/LimitedNodeList.h | 15 +-- libraries/networking/src/NLPacket.cpp | 70 ++++++++-- libraries/networking/src/NLPacket.h | 19 ++- libraries/networking/src/NetworkPeer.h | 6 +- libraries/networking/src/Packet.cpp | 40 ++++-- libraries/networking/src/Packet.h | 16 ++- libraries/networking/src/PacketHeaders.cpp | 9 -- libraries/networking/src/PacketHeaders.h | 3 - libraries/networking/src/PacketReceiver.cpp | 134 ++++++++++++++----- libraries/networking/src/PacketReceiver.h | 18 ++- 11 files changed, 258 insertions(+), 165 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 9532a1a389..962f8dbc30 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -168,54 +168,33 @@ void LimitedNodeList::changeSocketBufferSizes(int numBytes) { } } -bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { - PacketType::Value checkType = packetTypeForPacket(packet); - int numPacketTypeBytes = numBytesArithmeticCodingFromBuffer(packet.data()); - - if (packet[numPacketTypeBytes] != versionForPacketType(checkType) - && checkType != PacketType::StunResponse) { - PacketType::Value mismatchType = packetTypeForPacket(packet); - - static QMultiMap versionDebugSuppressMap; - - QUuid senderUUID = uuidFromPacketHeader(packet); - if (!versionDebugSuppressMap.contains(senderUUID, checkType)) { - qCDebug(networking) << "Packet version mismatch on" << packetTypeForPacket(packet) << "- Sender" - << uuidFromPacketHeader(packet) << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but" - << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; - - emit packetVersionMismatch(); - - versionDebugSuppressMap.insert(senderUUID, checkType); - } - - return false; - } - - if (!NON_VERIFIED_PACKETS.contains(checkType)) { +bool LimitedNodeList::packetSourceAndHashMatch(const NLPacket& packet, SharedNodePointer& matchingNode) { + + if (!NON_VERIFIED_PACKETS.contains(packet.getType()) && !NON_SOURCED_PACKETS.contains(packet.getType())) { // figure out which node this is from - SharedNodePointer sendingNode = sendingNodeForPacket(packet); - if (sendingNode) { + matchingNode = nodeWithUUID(packet.getSourceID()); + + if (matchingNode) { // check if the md5 hash in the header matches the hash we would expect - if (hashFromPacketHeader(packet) == hashForPacketAndConnectionUUID(packet, sendingNode->getConnectionSecret())) { + if (packet.getVerificationHash() == packet.payloadHashWithConnectionUUID(matchingNode->getConnectionSecret())) { return true; } else { static QMultiMap hashDebugSuppressMap; + + const QUuid& senderID = packet.getSourceID(); - QUuid senderUUID = uuidFromPacketHeader(packet); - if (!hashDebugSuppressMap.contains(senderUUID, checkType)) { - qCDebug(networking) << "Packet hash mismatch on" << checkType << "- Sender" - << uuidFromPacketHeader(packet); + if (!hashDebugSuppressMap.contains(senderID, packet.getType())) { + qCDebug(networking) << "Packet hash mismatch on" << packet.getType() << "- Sender" << senderID; - hashDebugSuppressMap.insert(senderUUID, checkType); + hashDebugSuppressMap.insert(senderID, packet.getType()); } } } else { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ received from unknown node with UUID"); - qCDebug(networking) << "Packet of type" << checkType << "received from unknown node with UUID" - << qPrintable(uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet))); + qCDebug(networking) << "Packet of type" << packet.getType() << "received from unknown node with UUID" + << qPrintable(uuidStringWithoutCurlyBraces(packet.getSourceID())); } } else { return true; @@ -224,19 +203,6 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { return false; } -qint64 LimitedNodeList::readDatagram(QByteArray& incomingPacket, QHostAddress* address = 0, quint16* port = 0) { - qint64 result = getNodeSocket().readDatagram(incomingPacket.data(), incomingPacket.size(), address, port); - - SharedNodePointer sendingNode = sendingNodeForPacket(incomingPacket); - if (sendingNode) { - emit dataReceived(sendingNode->getType(), incomingPacket.size()); - } else { - emit dataReceived(NodeType::Unassigned, incomingPacket.size()); - } - - return result; -} - qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) { // XXX can BandwidthRecorder be used for this? // stat collection for packets @@ -262,25 +228,13 @@ PacketSequenceNumber LimitedNodeList::getNextSequenceNumberForPacket(const QUuid return _packetSequenceNumbers[nodeUUID][packetType]++; } -void LimitedNodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { - // the node decided not to do anything with this packet - // if it comes from a known source we should keep that node alive - SharedNodePointer matchingNode = sendingNodeForPacket(packet); - if (matchingNode) { - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - } -} - -int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray &packet) { +int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet) { QMutexLocker locker(&matchingNode->getMutex()); - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - // if this was a sequence numbered packet we should store the last seq number for // a packet of this type for this node - PacketType::Value packetType = packetTypeForPacket(packet); - if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) { - matchingNode->setLastSequenceNumberForPacketType(sequenceNumberFromHeader(packet, packetType), packetType); + if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { + matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); } NodeData* linkedData = matchingNode->getLinkedData(); @@ -290,13 +244,13 @@ int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& match if (linkedData) { QMutexLocker linkedDataLocker(&linkedData->getMutex()); - return linkedData->parseData(packet); + return linkedData->parseData(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); } return 0; } -int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { - SharedNodePointer matchingNode = sendingNodeForPacket(packet); +int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(QSharedPointer packet) { + SharedNodePointer matchingNode = nodeWithUUID(packet->getSourceID()); if (matchingNode) { return updateNodeWithDataFromPacket(matchingNode, packet); @@ -313,13 +267,6 @@ SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) { return it == _nodeHash.cend() ? SharedNodePointer() : it->second; } -SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) { - QUuid nodeUUID = uuidFromPacketHeader(packet); - - // return the matching node, or NULL if there is no match - return nodeWithUUID(nodeUUID); -} - void LimitedNodeList::eraseAllNodes() { qCDebug(networking) << "Clearing the NodeList. Deleting all nodes in list."; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 5cb59364d6..b2dd95f71c 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -120,7 +120,8 @@ public: QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getDTLSSocket(); - bool packetVersionAndHashMatch(const QByteArray& packet); + bool packetVersionMatch(const NLPacket& packet); + bool packetSourceAndHashMatch(const NLPacket& packet, SharedNodePointer& matchingNode); PacketReceiver& getPacketReceiver() { return _packetReceiver; } @@ -130,7 +131,6 @@ public: // { return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); } // int populatePacketHeader(char* packet, PacketType::Value packetType) // { return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); } - qint64 readDatagram(QByteArray& incomingPacket, QHostAddress* address, quint16 * port); qint64 sendUnreliablePacket(const NLPacket& packet, const SharedNodePointer& destinationNode) { assert(false); return 0; } qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr) { assert(false); return 0; } @@ -146,7 +146,6 @@ public: int size() const { return _nodeHash.size(); } SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); - SharedNodePointer sendingNodeForPacket(const QByteArray& packet); SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, @@ -158,11 +157,10 @@ public: const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } - void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void processKillNode(const QByteArray& datagram); - int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray& packet); - int findNodeAndUpdateWithDataFromPacket(const QByteArray& packet); + int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet); + int findNodeAndUpdateWithDataFromPacket(const QSharedPointer packet); unsigned broadcastToNodes(std::unique_ptr packet, const NodeSet& destinationNodeTypes) { assert(false); return 0; } SharedNodePointer soloNodeOfType(char nodeType); @@ -256,11 +254,6 @@ signals: void canAdjustLocksChanged(bool canAdjustLocks); void canRezChanged(bool canRez); - void dataSent(const quint8 channel_type, const int bytes); - void dataReceived(const quint8 channel_type, const int bytes); - - void packetVersionMismatch(); - protected: LimitedNodeList(unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0); LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 1b1ac50eda..79d881c930 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -13,7 +13,7 @@ qint64 NLPacket::localHeaderSize(PacketType::Value type) { qint64 size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) + - ((NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID); + ((NON_VERIFIED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); return size; } @@ -43,6 +43,19 @@ std::unique_ptr NLPacket::create(PacketType::Value type, qint64 size) return std::unique_ptr(new NLPacket(type, size)); } +std::unique_ptr NLPacket::fromReceivedPacket(std::unique_ptr data, qint64 size, + const HifiSockAddr& senderSockAddr) { + // Fail with null data + Q_ASSERT(data); + + // Fail with invalid size + Q_ASSERT(size >= 0); + + // allocate memory + return std::unique_ptr(new NLPacket(std::move(data), size, senderSockAddr)); + +} + std::unique_ptr NLPacket::createCopy(const NLPacket& other) { return std::unique_ptr(new NLPacket(other)); } @@ -53,15 +66,52 @@ NLPacket::NLPacket(PacketType::Value type, qint64 size) : Packet(type, localHead NLPacket::NLPacket(const NLPacket& other) : Packet(other) { } -void NLPacket::setSourceUuid(QUuid sourceUuid) { - Q_ASSERT(!NON_SOURCED_PACKETS.contains(_type)); - auto offset = Packet::totalHeadersSize(); - memcpy(_packet.get() + offset, sourceUuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); +NLPacket::NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr) : + Packet(std::move(data), size, senderSockAddr) +{ + readSourceID(); + readVerificationHash(); } -void NLPacket::setConnectionUuid(QUuid connectionUuid) { - Q_ASSERT(!NON_VERIFIED_PACKETS.contains(_type)); - auto offset = Packet::totalHeadersSize() + - ((NON_SOURCED_PACKETS.contains(_type)) ? 0 : NUM_BYTES_RFC4122_UUID); - memcpy(_packet.get() + offset, connectionUuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); +void NLPacket::readSourceID() { + if (!NON_SOURCED_PACKETS.contains(_type)) { + auto offset = Packet::totalHeadersSize(); + _sourceID = QUuid::fromRfc4122(QByteArray::fromRawData(_packet.get() + offset, NUM_BYTES_RFC4122_UUID)); + } +} + +void NLPacket::readVerificationHash() { + if (!NON_SOURCED_PACKETS.contains(_type) && !NON_VERIFIED_PACKETS.contains(_type)) { + auto offset = Packet::totalHeadersSize() + NUM_BYTES_RFC4122_UUID; + _verificationHash = QByteArray(_packet.get() + offset, NUM_BYTES_MD5_HASH); + } +} + +void NLPacket::setSourceID(const QUuid& sourceID) { + Q_ASSERT(!NON_SOURCED_PACKETS.contains(_type)); + + auto offset = Packet::totalHeadersSize(); + memcpy(_packet.get() + offset, sourceID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); + + _sourceID = sourceID; +} + +void NLPacket::setVerificationHash(const QByteArray& verificationHash) { + Q_ASSERT(!NON_SOURCED_PACKETS.contains(_type) && !NON_VERIFIED_PACKETS.contains(_type)); + + auto offset = Packet::totalHeadersSize() + NUM_BYTES_RFC4122_UUID; + memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); + + _verificationHash = verificationHash; +} + +QByteArray NLPacket::payloadHashWithConnectionUUID(const QUuid& connectionUUID) const { + QCryptographicHash hash(QCryptographicHash::Md5); + + // add the packet payload and the connection UUID + hash.addData(_payloadStart, _sizeUsed); + hash.addData(connectionUUID.toRfc4122()); + + // return the hash + return hash.result(); } diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index e3b1778c39..8652bb3371 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -18,6 +18,8 @@ class NLPacket : public Packet { Q_OBJECT public: static std::unique_ptr create(PacketType::Value type, qint64 size = -1); + static std::unique_ptr fromReceivedPacket(std::unique_ptr data, qint64 size, + const HifiSockAddr& senderSockAddr); // Provided for convenience, try to limit use static std::unique_ptr createCopy(const NLPacket& other); @@ -27,15 +29,24 @@ public: virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 localHeaderSize() const; // Current level's header size - // TODO Implement this :) - QUuid getSourceID() const { return QUuid(); } + void readSourceID(); + void readVerificationHash(); + + const QUuid& getSourceID() const { return _sourceID; } + const QByteArray& getVerificationHash() const { return _verificationHash; } + + QByteArray payloadHashWithConnectionUUID(const QUuid& connectionUUID) const; protected: NLPacket(PacketType::Value type, qint64 size); + NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); NLPacket(const NLPacket& other); - void setSourceUuid(QUuid sourceUuid); - void setConnectionUuid(QUuid connectionUuid); + void setSourceID(const QUuid& sourceID); + void setVerificationHash(const QByteArray& verificationHash); + + QUuid _sourceID; + QByteArray _verificationHash; }; #endif // hifi_NLPacket_h diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index d2802a1308..1c39ad96e1 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -59,8 +59,8 @@ public: quint64 getWakeTimestamp() const { return _wakeTimestamp; } void setWakeTimestamp(quint64 wakeTimestamp) { _wakeTimestamp = wakeTimestamp; } - quint64 getLastHeardMicrostamp() const { return _lastHeardMicrostamp; } - void setLastHeardMicrostamp(quint64 lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; } + quint64 getLastHeardMicrostamp() const { return _lastHeardMicrostamp.load(); } + void setLastHeardMicrostamp(quint64 lastHeardMicrostamp) { _lastHeardMicrostamp.store(lastHeardMicrostamp); } QByteArray toByteArray() const; @@ -92,7 +92,7 @@ protected: HifiSockAddr* _activeSocket; quint64 _wakeTimestamp; - quint64 _lastHeardMicrostamp; + std::atomic_ullong _lastHeardMicrostamp; QTimer* _pingTimer = NULL; diff --git a/libraries/networking/src/Packet.cpp b/libraries/networking/src/Packet.cpp index 876cd91962..1b40a704f6 100644 --- a/libraries/networking/src/Packet.cpp +++ b/libraries/networking/src/Packet.cpp @@ -37,6 +37,14 @@ std::unique_ptr Packet::create(PacketType::Value type, qint64 size) { return std::unique_ptr(new Packet(type, size)); } +std::unique_ptr Packet::fromReceivedPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr) { + // Fail with invalid size + Q_ASSERT(size >= 0); + + // allocate memory + return std::unique_ptr(new Packet(std::move(data), size, senderSockAddr)); +} + std::unique_ptr Packet::createCopy(const Packet& other) { return std::unique_ptr(new Packet(other)); } @@ -51,20 +59,34 @@ qint64 Packet::localHeaderSize() const { Packet::Packet(PacketType::Value type, qint64 size) : _type(type), + _version(0), _packetSize(localHeaderSize(_type) + size), _packet(new char(_packetSize)), _payloadStart(_packet.get() + localHeaderSize(_type)), - _capacity(size) { - // Sanity check - Q_ASSERT(size <= maxPayloadSize(type)); + _capacity(size) +{ + // Sanity check + Q_ASSERT(size <= maxPayloadSize(type)); - // copy packet type and version in header - writePacketTypeAndVersion(type); + // copy packet type and version in header + writePacketTypeAndVersion(type); - // Set control bit and sequence number to 0 if necessary - if (SEQUENCE_NUMBERED_PACKETS.contains(type)) { - writeSequenceNumber(0); - } + // Set control bit and sequence number to 0 if necessary + if (SEQUENCE_NUMBERED_PACKETS.contains(type)) { + writeSequenceNumber(0); + } +} + +Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr) : + _packetSize(size), + _packet(std::move(data)), + _senderSockAddr(senderSockAddr) +{ + _type = readType(); + _version = readVersion(); + _capacity = _packetSize - localHeaderSize(_type); + _sizeUsed = _capacity; + _payloadStart = _packet.get() + (_packetSize - _capacity); } Packet::Packet(const Packet& other) { diff --git a/libraries/networking/src/Packet.h b/libraries/networking/src/Packet.h index c52fb88e49..4ad6ffa6f3 100644 --- a/libraries/networking/src/Packet.h +++ b/libraries/networking/src/Packet.h @@ -16,6 +16,7 @@ #include +#include "HifiSockAddr.h" #include "PacketHeaders.h" class Packet : public QIODevice { @@ -24,6 +25,8 @@ public: using SequenceNumber = uint16_t; static std::unique_ptr create(PacketType::Value type, qint64 size = -1); + static std::unique_ptr fromReceivedPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); + // Provided for convenience, try to limit use static std::unique_ptr createCopy(const Packet& other); @@ -43,7 +46,9 @@ public: PacketType::Value getType() const { return _type; } void setType(PacketType::Value type); - + + PacketVersion getVersion() const { return _version; } + qint64 getSizeWithHeader() const { return localHeaderSize() + getSizeUsed(); } qint64 getSizeUsed() const { return _sizeUsed; } void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; } @@ -51,9 +56,6 @@ public: HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; } - // Header readers - PacketType::Value readType() const; - PacketVersion readVersion() const; SequenceNumber readSequenceNumber() const; bool readIsControlPacket() const; @@ -68,11 +70,16 @@ public: protected: Packet(PacketType::Value type, int64_t size); + Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); Packet(const Packet& other); Packet& operator=(const Packet& other); Packet(Packet&& other); Packet& operator=(Packet&& other); + // Header readers + PacketType::Value readType() const; + PacketVersion readVersion() const; + // QIODevice virtual functions virtual qint64 writeData(const char* data, qint64 maxSize); virtual qint64 readData(char* data, qint64 maxSize); @@ -82,6 +89,7 @@ protected: void writeSequenceNumber(SequenceNumber seqNum); PacketType::Value _type; // Packet type + PacketVersion _version; // Packet version qint64 _packetSize = 0; // Total size of the allocated memory std::unique_ptr _packet; // Allocated memory diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index bea061ae74..03a7260315 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -208,15 +208,6 @@ int sequenceNumberOffsetForPacketType(PacketType::Value packetType) { return numBytesForPacketHeaderGivenPacketType(packetType) - sizeof(PacketSequenceNumber); } -QByteArray hashFromPacketHeader(const QByteArray& packet) { - return packet.mid(hashOffsetForPacketType(packetTypeForPacket(packet)), NUM_BYTES_MD5_HASH); -} - -QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID) { - return QCryptographicHash::hash(packet.mid(numBytesForPacketHeader(packet)) + connectionUUID.toRfc4122(), - QCryptographicHash::Md5); -} - PacketSequenceNumber sequenceNumberFromHeader(const QByteArray& packet, PacketType::Value packetType) { if (packetType == PacketType::Unknown) { packetType = packetTypeForPacket(packet); diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 0108e3e03a..2f7eac3a63 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -121,9 +121,6 @@ QUuid uuidFromPacketHeader(const QByteArray& packet); int hashOffsetForPacketType(PacketType::Value packetType); int sequenceNumberOffsetForPacketType(PacketType::Value packetType); -QByteArray hashFromPacketHeader(const QByteArray& packet); -QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID); - // NOTE: The following four methods accept a PacketType::Value which defaults to PacketType::Unknown. // If the caller has already looked at the packet type and can provide it then the methods below won't have to look it up. diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 02f948dc5f..7214915b30 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -13,8 +13,9 @@ #include "PacketReceiver.h" #include "DependencyManager.h" -#include "NLPacket.h" +#include "NetworkLogging.h" #include "NodeList.h" +#include "SharedUtil.h" PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent), @@ -51,18 +52,18 @@ void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* obj qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" << NON_SOURCED_PACKET_LISTENER_PARAMETERS - << "but parameter method takes" << signalMethod.parameterTypes(); + << "but parameter method takes" << slotMethod.parameterTypes(); } else { const QList SOURCED_PACKET_LISTENER_PARAMETERS = QList() - << QMetaObject::normalizedType(("QSharedPointer") - << QMetaObject::normalizedType(("QSharedPointer"); + << QMetaObject::normalizedType("QSharedPointer") + << QMetaObject::normalizedType("QSharedPointer"); parametersMatch = slotMethod.parameterTypes() == SOURCED_PACKET_LISTENER_PARAMETERS; if (!parametersMatch) { qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" << SOURCED_PACKET_LISTENER_PARAMETERS - << "but parameter method takes" << signalMethod.parameterTypes(); + << "but parameter method takes" << slotMethod.parameterTypes(); } } @@ -70,11 +71,37 @@ void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* obj assert(parametersMatch); // add the mapping - _packetListenerMap[type] = ObjectMethodPair(object, slotMethod); + _packetListenerMap[type] = ObjectMethodPair(QPointer(object), slotMethod); _packetListenerLock.unlock(); } +bool PacketReceiver::packetVersionMatch(const NLPacket& packet) { + + if (packet.getVersion() != versionForPacketType(packet.getType()) + && packet.getType() != PacketType::StunResponse) { + + static QMultiMap versionDebugSuppressMap; + + const QUuid& senderID = packet.getSourceID(); + + if (!versionDebugSuppressMap.contains(senderID, packet.getType())) { + + qCDebug(networking) << "Packet version mismatch on" << packet.getType() << "- Sender" + << senderID << "sent" << qPrintable(QString::number(packet.getVersion())) << "but" + << qPrintable(QString::number(versionForPacketType(packet.getType()))) << "expected."; + + emit packetVersionMismatch(packet.getType()); + + versionDebugSuppressMap.insert(senderID, packet.getType()); + } + + return false; + } else { + return true; + } +} + void PacketReceiver::processDatagrams() { //PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), //"PacketReceiver::processDatagrams()"); @@ -83,42 +110,83 @@ void PacketReceiver::processDatagrams() { return; // bail early... we're shutting down. } - static QByteArray incomingPacket; - auto nodeList = DependencyManager::get(); while (DependencyManager::get()->getNodeSocket().hasPendingDatagrams()) { - incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); + // setup a buffer to read the packet into + int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize(); + std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); + + // setup a HifiSockAddr to read into HifiSockAddr senderSockAddr; - nodeList->readDatagram(incomingPacket, senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + // pull the datagram + nodeList->getNodeSocket().readDatagram(buffer.get(), packetSizeWithHeader, + senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + + // setup an NLPacket from the data we just read + auto packet = NLPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + _inPacketCount++; - _inByteCount += incomingPacket.size(); + _inByteCount += packetSizeWithHeader; - if (nodeList->packetVersionAndHashMatch(incomingPacket)) { - PacketType::Value incomingType = packetTypeForPacket(incomingPacket); - - // TODO What do we do about this? - //nodeList->processNodeData(senderSockAddr, incomingPacket); - - _packetListenerLock.lock(); - auto& listener = _packetListenerMap[incomingType]; - _packetListenerLock.unlock(); - - if (_packetListenerMap.contains(incomingType)) { - auto& listener = _packetListenerMap[incomingType]; - //TODO Update packet - QSharedPointer packet; - bool success = QMetaObject::invokeMethod(listener.first, listener.second, - Q_ARG(QSharedPointer, packet), - Q_ARG(HifiSockAddr, senderSockAddr)); - if (!success) { - qDebug() << "Error sending packet " << incomingType << " to listener: " << listener.first->objectName() << "::" << listener.second; + if (packetVersionMatch(*packet)) { + + SharedNodePointer matchingNode; + if (nodeList->packetSourceAndHashMatch(*packet, matchingNode)) { + + if (matchingNode) { + // No matter if this packet is handled or not, we update the timestamp for the last time we heard + // from this sending node + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); } - } else { - qDebug() << "No listener found for packet type: " << incomingType; - } + _packetListenerLock.lock(); + + auto it = _packetListenerMap.find(packet->getType()); + + if (it != _packetListenerMap.end()) { + + auto listener = it.value(); + + if (!listener.first.isNull()) { + + if (matchingNode) { + emit dataReceived(matchingNode->getType(), packet->getSizeWithHeader()); + } else { + emit dataReceived(NodeType::Unassigned, packet->getSizeWithHeader()); + } + + bool success = false; + + if (matchingNode) { + success = listener.second.invoke(listener.first, + Q_ARG(QSharedPointer, QSharedPointer(packet.release()))); + } else { + success = listener.second.invoke(listener.first, + Q_ARG(QSharedPointer, QSharedPointer(packet.release())), + Q_ARG(SharedNodePointer, matchingNode)); + } + + if (!success) { + qDebug() << "Error delivering packet " << nameForPacketType(packet->getType()) << " to listener: " + << listener.first->objectName() << "::" << listener.second.name(); + } + + } else { + // we have a dead listener - remove this mapping from the _packetListenerMap + qDebug() << "Listener for packet type" << nameForPacketType(packet->getType()) + << "has been destroyed - removing mapping."; + _packetListenerMap.erase(it); + } + + _packetListenerLock.unlock(); + + } else { + _packetListenerLock.unlock(); + qDebug() << "No listener found for packet type " << nameForPacketType(packet->getType()); + } + } } } } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 9e20a381e1..8c03af4b7b 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -14,12 +14,11 @@ #define hifi_PacketReceiver_h #include +#include #include #include -#include - -#include +#include "NLPacket.h" #include "PacketHeaders.h" class PacketReceiver : public QObject { @@ -36,16 +35,23 @@ public: void shutdown() { _isShuttingDown = true; } - bool registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); + void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); public slots: void processDatagrams(); + +signals: + void dataSent(quint8 channel_type, int bytes); + void dataReceived(quint8 channel_type, int bytes); + void packetVersionMismatch(PacketType::Value type); private: - using ObjectMethodPair = QPair; + bool packetVersionMatch(const NLPacket& packet); + + using ObjectMethodPair = std::pair, QMetaMethod>; QMutex _packetListenerLock; - QMap _packetListenerMap; + QHash _packetListenerMap; int _inPacketCount = 0; int _outPacketCount = 0; int _inByteCount = 0; From e0d165bdd88236ae69566c41f9e5b279f39facb2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 16:48:28 -0700 Subject: [PATCH 056/146] Fix packet type in AssignmentClient for StopNode --- assignment-client/src/AssignmentClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index dda505429d..499ed93c89 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -122,7 +122,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri } auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); - packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleStopNodePacket"); + packetReceiver.registerPacketListener(PacketType::StopNode, this, "handleStopNodePacket"); } From 8c04aafe67e25a4b5094fe051026d5924ecb5abd Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 17:08:07 -0700 Subject: [PATCH 057/146] Update Agent to use PacketReceiver --- assignment-client/src/Agent.cpp | 83 +++++++++++++++++++-------------- assignment-client/src/Agent.h | 2 + 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0576a0d4f0..6166923832 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -48,9 +48,36 @@ Agent::Agent(const QByteArray& packet) : DependencyManager::set(); DependencyManager::set(); - auto& packetReceiver = DependencyManager::get()->getPackingReceiver(); + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioPacket"); packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioPacket"); + packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleOctreePacket"); + packetReceiver.registerPacketListener(PacketType::EntityData, this, "handleOctreePacket"); + packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleOctreePacket"); + packetReceiver.registerPacketListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); +} + +void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + QByteArray mutablePacket = QByteArray(packet->getData(), packet->getSizeWithHeader()); + int messageLength = mutablePacket.size(); + + auto packetType = packet->getType(); + + if (packetType == PacketType::OctreeStats) { + + int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(mutablePacket, senderNode); + if (messageLength > statsMessageLength) { + mutablePacket = mutablePacket.mid(statsMessageLength); + } else { + return; // bail since no piggyback data + } + + packetType = packetTypeForPacket(mutablePacket); + } // fall through to piggyback message + + if (packetType == PacketType::EntityData || packetType == PacketType::EntityErase) { + _entityViewer.processDatagram(mutablePacket, senderNode); + } } void Agent::readPendingDatagrams() { @@ -76,47 +103,31 @@ void Agent::readPendingDatagrams() { break; } } - - } else if (datagramPacketType == PacketType::OctreeStats - || datagramPacketType == PacketType::EntityData - || datagramPacketType == PacketType::EntityErase - ) { - // Make sure our Node and NodeList knows we've heard from this node. - SharedNodePointer sourceNode = nodeList->sendingNodeForPacket(receivedPacket); - sourceNode->setLastHeardMicrostamp(usecTimestampNow()); - - QByteArray mutablePacket = receivedPacket; - int messageLength = mutablePacket.size(); - - if (datagramPacketType == PacketType::OctreeStats) { - - int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(mutablePacket, sourceNode); - if (messageLength > statsMessageLength) { - mutablePacket = mutablePacket.mid(statsMessageLength); - - // TODO: this needs to be fixed, the goal is to test the packet version for the piggyback, but - // this is testing the version and hash of the original packet - // need to use numBytesArithmeticCodingFromBuffer()... - if (!DependencyManager::get()->packetVersionAndHashMatch(receivedPacket)) { - return; // bail since piggyback data doesn't match our versioning - } - } else { - return; // bail since no piggyback data - } - - datagramPacketType = packetTypeForPacket(mutablePacket); - } // fall through to piggyback message - - if (datagramPacketType == PacketType::EntityData || datagramPacketType == PacketType::EntityErase) { - _entityViewer.processDatagram(mutablePacket, sourceNode); - } } } } } +void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + QByteArray receivedPacket = QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()); + int headerBytes = numBytesForPacketHeader(receivedPacket); + + auto nodeList = DependencyManager::get(); + SharedNodePointer matchedNode = nodeList->sendingNodeForPacket(receivedPacket); + + if (matchedNode) { + // PacketType_JURISDICTION, first byte is the node type... + switch (receivedPacket[headerBytes]) { + case NodeType::EntityServer: + DependencyManager::get()->getJurisdictionListener()-> + queueReceivedPacket(senderNode, receivedPacket); + break; + } + } +} + void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - _receivedAudioStream.parseData(receivedPacket); + _receivedAudioStream.parseData(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index bee043f6f4..70e1913b54 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -57,6 +57,8 @@ public slots: private slots: void handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); private: ScriptEngine _scriptEngine; From bfb878210f5b430153dcf7a9dc7952de41275bfc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 17:27:45 -0700 Subject: [PATCH 058/146] Fix compilation errors in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index ec9998c881..dc790e99f4 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -544,28 +544,34 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { } void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { + auto nodeList = DependencyManager::get(); if (nodeList->packetVersionAndHashMatch(receivedPacket)) { nodeList->processNodeData(senderSockAddr, receivedPacket); } } void AudioMixer::handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); } void AudioMixer::handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); } void AudioMixer::handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); } void AudioMixer::handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); } void AudioMixer::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { + auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); } @@ -573,14 +579,14 @@ void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, Hi auto nodeList = DependencyManager::get(); SharedNodePointer sendingNode = nodeList->nodeWithUUID(packet->getSourceID()); if (sendingNode->getCanAdjustLocks()) { - auto packet = NLPacket::create(PacketType::MuteEnvironment); + auto newPacket = NLPacket::create(PacketType::MuteEnvironment); // Copy payload - packet->write(receivedPacket.mid(numBytesForPacketHeader(receivedPacket))); + newPacket->write(newPacket->getPayload()); nodeList->eachNode([&](const SharedNodePointer& node){ if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != sendingNode) { - nodeList->sendPacket(std::move(packet), node); + nodeList->sendPacket(std::move(newPacket), node); } }); } From 28f6c4021bc181147039a740b56db8ea5f28fab5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 17:27:56 -0700 Subject: [PATCH 059/146] Fix compilation errors in EntityServer --- assignment-client/src/entities/EntityServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index c09e068b21..b7e6fe3a29 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -42,19 +42,19 @@ EntityServer::~EntityServer() { void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); } } void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); } } void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, receivedPacket->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); } } From c86e481d4f380c5a0e6964bd3ef00356952d86a7 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 17:28:27 -0700 Subject: [PATCH 060/146] Update OctreeServer packet receive handling --- assignment-client/src/octree/OctreeServer.cpp | 38 ++++++++----------- assignment-client/src/octree/OctreeServer.h | 6 +-- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 55d6f0be81..2488c92439 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -248,10 +248,10 @@ OctreeServer::OctreeServer(const QByteArray& packet) : AccountManager::getInstance().setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); - auto packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver->registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); - packetReceiver->registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); - packetReceiver->registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver.registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); + packetReceiver.registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); } OctreeServer::~OctreeServer() { @@ -860,35 +860,29 @@ void OctreeServer::readPendingDatagram(const QByteArray& receivedPacket, const H } } -void handleOctreeQueryPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { // If we got a query packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. - SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); - if (matchingNode) { - nodeList->updateNodeWithDataFromPacket(matchingNode, packet->getData()); + auto nodeList = DependencyManager::get(); + nodeList->updateNodeWithDataFromPacket(senderNode, packet->getData()); - OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); - if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { - nodeData->initializeOctreeSendThread(this, matchingNode); - } + OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); + if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { + nodeData->initializeOctreeSendThread(this, senderNode); } } -void handleOctreeDataNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void OctreeServer::handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { // If we got a nack packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. - SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); - if (matchingNode) { - OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); - if (nodeData) { - nodeData->parseNackPacket(packet->getData()); - } + OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); + if (nodeData) { + nodeData->parseNackPacket(packet->getData()); } } -void handleJurisdictionRequestPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer matchingNode = nodeList->nodeWithUUID(packet->getSourceID()); - _jurisdictionSender->queueReceivedPacket(matchingNode, packet->getData()); +void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { + _jurisdictionSender->queueReceivedPacket(senderNode, packet->getData()); } void OctreeServer::setupDatagramProcessingThread() { diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index d25ef3183b..df36580f57 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -129,9 +129,9 @@ public slots: void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); private slots: - void handleOctreeQueryPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleOctreeDataNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleJurisdictionRequestPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); protected: virtual Octree* createTree() = 0; From d85fbbfb745d790f74de50a013b418b6b4fc453c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 17:45:23 -0700 Subject: [PATCH 061/146] update NodeList for new packet receive code --- domain-server/src/DomainServer.cpp | 10 +- libraries/networking/src/DomainHandler.cpp | 18 +- libraries/networking/src/DomainHandler.h | 5 +- libraries/networking/src/LimitedNodeList.cpp | 25 +- libraries/networking/src/LimitedNodeList.h | 6 +- libraries/networking/src/NodeList.cpp | 249 +++++++------------ libraries/networking/src/NodeList.h | 20 +- libraries/networking/src/PacketHeaders.cpp | 12 +- 8 files changed, 143 insertions(+), 202 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a77156a8c9..00efd818a5 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -933,15 +933,17 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // always send the node their own UUID back QDataStream domainListStream(&domainListPackets); - const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + 2; + const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NUM_BYTES_RFC4122_UUID + 2; // setup the extended header for the domain list packets // this data is at the beginning of each of the domain list packets QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0); - extendedHeader.replace(0, NUM_BYTES_RFC4122_UUID, node->getUUID().toRfc4122()); + QDataStream extendedHeaderStream(&extendedHeader, &QIODevice::Append); - extendedHeader[NUM_BYTES_RFC4122_UUID] = (char) node->getCanAdjustLocks(); - extendedHeader[NUM_BYTES_RFC4122_UUID + 1] = (char) node->getCanRez(); + extendedHeaderStream << limitedNodeList->getSessionUUID().toRfc4122(); + extendedHeaderStream << node->getUUID().toRfc4122(); + extendedHeaderStream << (quint8) node->getCanAdjustLocks(); + extendedHeaderStream << (quint8) node->getCanRez(); domainListPackets.setExtendedHeader(extendedHeader); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 38d1ade2ad..6d76e09028 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -281,12 +281,10 @@ void DomainHandler::settingsRequestFinished() { settingsReply->deleteLater(); } -void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket) { +void DomainHandler::processDTLSRequirementPacket(QSharedPointer dtlsRequirementPacket) { // figure out the port that the DS wants us to use for us to talk to them with DTLS - int numBytesPacketHeader = numBytesForPacketHeader(dtlsRequirementPacket); - - unsigned short dtlsPort = 0; - memcpy(&dtlsPort, dtlsRequirementPacket.data() + numBytesPacketHeader, sizeof(dtlsPort)); + unsigned short dtlsPort; + dtlsRequirementPacket->readPrimitive(&dtlsPort); qCDebug(networking) << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS."; @@ -295,9 +293,13 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement // initializeDTLSSession(); } -void DomainHandler::processICEResponsePacket(const QByteArray& icePacket) { - QDataStream iceResponseStream(icePacket); - iceResponseStream.skipRawData(numBytesForPacketHeader(icePacket)); +void DomainHandler::processICEResponsePacket(QSharedPointer icePacket) { + if (!_icePeer.hasSockets()) { + // bail on processing this packet if our ice peer doesn't have sockets + return; + } + + QDataStream iceResponseStream(icePacket.data()); iceResponseStream >> _icePeer; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 0c1698f5ec..716138a4f1 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -21,6 +21,7 @@ #include "HifiSockAddr.h" #include "NetworkPeer.h" +#include "NLPacket.h" const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; @@ -69,8 +70,8 @@ public: void requestDomainSettings(); const QJsonObject& getSettingsObject() const { return _settingsObject; } - void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); - void processICEResponsePacket(const QByteArray& icePacket); + void processDTLSRequirementPacket(QSharedPointer dtlsRequirementPacket); + void processICEResponsePacket(QSharedPointer icePacket); void setPendingPath(const QString& pendingPath) { _pendingPath = pendingPath; } const QString& getPendingPath() { return _pendingPath; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 962f8dbc30..764a9eed7e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -369,9 +369,8 @@ std::unique_ptr LimitedNodeList::constructPingPacket(PingType_t pingTy return pingPacket; } -std::unique_ptr LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacket) { - QDataStream pingPacketStream(pingPacket); - pingPacketStream.skipRawData(numBytesForPacketHeader(pingPacket)); +std::unique_ptr LimitedNodeList::constructPingReplyPacket(QSharedPointer pingPacket) { + QDataStream pingPacketStream(pingPacket.data()); PingType_t typeFromOriginalPing; pingPacketStream >> typeFromOriginalPing; @@ -400,11 +399,11 @@ std::unique_ptr LimitedNodeList::constructICEPingPacket(PingType_t pin return icePingPacket; } -std::unique_ptr LimitedNodeList::constructICEPingReplyPacket(const QByteArray& pingPacket, const QUuid& iceID) { +std::unique_ptr LimitedNodeList::constructICEPingReplyPacket(QSharedPointer pingPacket, const QUuid& iceID) { // pull out the ping type so we can reply back with that PingType_t pingType; - memcpy(&pingType, pingPacket.data() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t)); + memcpy(&pingType, pingPacket->getPayload() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t)); int packetSize = NUM_BYTES_RFC4122_UUID + sizeof(PingType_t); auto icePingReplyPacket = NLPacket::create(PacketType::ICEPingReply, packetSize); @@ -514,7 +513,7 @@ void LimitedNodeList::rebindNodeSocket() { _nodeSocket.bind(QHostAddress::AnyIPv4, oldPort); } -bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { +bool LimitedNodeList::processSTUNResponse(QSharedPointer packet) { // check the cookie to make sure this is actually a STUN response // and read the first attribute and make sure it is a XOR_MAPPED_ADDRESS const int NUM_BYTES_MESSAGE_TYPE_AND_LENGTH = 4; @@ -524,13 +523,13 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { int attributeStartIndex = NUM_BYTES_STUN_HEADER; - if (memcmp(packet.data() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH, + if (memcmp(packet->getData() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH, &RFC_5389_MAGIC_COOKIE_NETWORK_ORDER, sizeof(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER)) == 0) { // enumerate the attributes to find XOR_MAPPED_ADDRESS_TYPE - while (attributeStartIndex < packet.size()) { - if (memcmp(packet.data() + attributeStartIndex, &XOR_MAPPED_ADDRESS_TYPE, sizeof(XOR_MAPPED_ADDRESS_TYPE)) == 0) { + while (attributeStartIndex < packet->getSizeWithHeader()) { + if (memcmp(packet->getData() + attributeStartIndex, &XOR_MAPPED_ADDRESS_TYPE, sizeof(XOR_MAPPED_ADDRESS_TYPE)) == 0) { const int NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH = 4; const int NUM_BYTES_FAMILY_ALIGN = 1; const uint8_t IPV4_FAMILY_NETWORK_ORDER = htons(0x01) >> 8; @@ -538,14 +537,14 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { int byteIndex = attributeStartIndex + NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH + NUM_BYTES_FAMILY_ALIGN; uint8_t addressFamily = 0; - memcpy(&addressFamily, packet.data() + byteIndex, sizeof(addressFamily)); + memcpy(&addressFamily, packet->getData() + byteIndex, sizeof(addressFamily)); byteIndex += sizeof(addressFamily); if (addressFamily == IPV4_FAMILY_NETWORK_ORDER) { // grab the X-Port uint16_t xorMappedPort = 0; - memcpy(&xorMappedPort, packet.data() + byteIndex, sizeof(xorMappedPort)); + memcpy(&xorMappedPort, packet->getData() + byteIndex, sizeof(xorMappedPort)); uint16_t newPublicPort = ntohs(xorMappedPort) ^ (ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER) >> 16); @@ -553,7 +552,7 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { // grab the X-Address uint32_t xorMappedAddress = 0; - memcpy(&xorMappedAddress, packet.data() + byteIndex, sizeof(xorMappedAddress)); + memcpy(&xorMappedAddress, packet->getData() + byteIndex, sizeof(xorMappedAddress)); uint32_t stunAddress = ntohl(xorMappedAddress) ^ ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER); @@ -583,7 +582,7 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { const int NUM_BYTES_ATTRIBUTE_TYPE = 2; uint16_t attributeLength = 0; - memcpy(&attributeLength, packet.data() + attributeStartIndex + NUM_BYTES_ATTRIBUTE_TYPE, + memcpy(&attributeLength, packet->getData() + attributeStartIndex + NUM_BYTES_ATTRIBUTE_TYPE, sizeof(attributeLength)); attributeLength = ntohs(attributeLength); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index b2dd95f71c..f48f2aaa31 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -169,12 +169,12 @@ public: void resetPacketStats(); std::unique_ptr constructPingPacket(PingType_t pingType = PingType::Agnostic); - std::unique_ptr constructPingReplyPacket(const QByteArray& pingPacket); + std::unique_ptr constructPingReplyPacket(QSharedPointer pingPacket); std::unique_ptr constructICEPingPacket(PingType_t pingType, const QUuid& iceID); - std::unique_ptr constructICEPingReplyPacket(const QByteArray& pingPacket, const QUuid& iceID); + std::unique_ptr constructICEPingReplyPacket(QSharedPointer pingPacket, const QUuid& iceID); - virtual bool processSTUNResponse(const QByteArray& packet); + virtual bool processSTUNResponse(QSharedPointer packet); void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr); void sendPeerQueryToIceServer(const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 61c8e90b0d..8d897e82b5 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -92,16 +92,16 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned startSTUNPublicSocketUpdate(); auto& packetReceiver = getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::DomainList, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::Ping, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::PingReply, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processReceivedPacket"); - packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processReceivedPacket"); + packetReceiver.registerPacketListener(PacketType::DomainList, this, "processDomainServerList"); + packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); + packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket"); + packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathQueryResponse"); + packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket"); + packetReceiver.registerPacketListener(PacketType::Ping, this, "processPingPacket"); + packetReceiver.registerPacketListener(PacketType::PingReply, this, "processPingReplyPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); + packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processSTUNResponse"); } qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { @@ -128,9 +128,8 @@ qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { return sendStats(statsObject, _domainHandler.getSockAddr()); } -void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); +void NodeList::timePingReply(QSharedPointer packet, const SharedNodePointer& sendingNode) { + QDataStream packetStream(packet.data()); quint8 pingType; quint64 ourOriginalTime, othersReplyTime; @@ -164,108 +163,52 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& } } -// TODO: Break this out into individual packet types -void NodeList::processReceivedPacket(std::unique_ptr, HifiSockAddr senderSockAddr) { - qDebug() << "Got packet!"; +void NodeList::processPingPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + // send back a reply + auto replyPacket = constructPingReplyPacket(packet); + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); + sendPacket(std::move(replyPacket), sendingNode, senderSockAddr); + + // If we don't have a symmetric socket for this node and this socket doesn't match + // what we have for public and local then set it as the symmetric. + // This allows a server on a reachable port to communicate with nodes on symmetric NATs + if (sendingNode->getSymmetricSocket().isNull()) { + if (senderSockAddr != sendingNode->getLocalSocket() && senderSockAddr != sendingNode->getPublicSocket()) { + sendingNode->setSymmetricSocket(senderSockAddr); + } + } } -void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { - PacketType::Value packetType = packetTypeForPacket(packet); - switch (packetType) { - case PacketType::DomainList: - case PacketType::DomainServerAddedNode: { - if (!_domainHandler.getSockAddr().isNull()) { - // only process a packet from domain-server if we're talking to a domain - // TODO: how do we make sure this is actually the domain we want the list from (DTLS probably) - if (packetType == PacketType::DomainList) { - processDomainServerList(packet); - } else if (packetType == PacketType::DomainServerAddedNode) { - processDomainServerAddedNode(packet); - } - } - break; - } - case PacketType::DomainServerRequireDTLS: { - _domainHandler.parseDTLSRequirementPacket(packet); - break; - } - case PacketType::ICEServerPeerInformation: { - if (!_domainHandler.getICEPeer().hasSockets()) { - _domainHandler.processICEResponsePacket(packet); - } - break; - } - case PacketType::Ping: { - // send back a reply - SharedNodePointer matchingNode = sendingNodeForPacket(packet); - if (matchingNode) { - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - auto replyPacket = constructPingReplyPacket(packet); - sendPacket(std::move(replyPacket), matchingNode, senderSockAddr); +void NodeList::processPingReplyPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + // activate the appropriate socket for this node, if not yet updated + activateSocketFromNodeCommunication(packet, sendingNode); - // If we don't have a symmetric socket for this node and this socket doesn't match - // what we have for public and local then set it as the symmetric. - // This allows a server on a reachable port to communicate with nodes on symmetric NATs - if (matchingNode->getSymmetricSocket().isNull()) { - if (senderSockAddr != matchingNode->getLocalSocket() && senderSockAddr != matchingNode->getPublicSocket()) { - matchingNode->setSymmetricSocket(senderSockAddr); - } - } - } + // set the ping time for this node for stat collection + timePingReply(packet, sendingNode); +} - break; +void NodeList::processICEPingPacket(QSharedPointer packet) { + // send back a reply + auto replyPacket = constructICEPingReplyPacket(packet, _domainHandler.getICEClientID()); + sendPacket(std::move(replyPacket), packet->getSenderSockAddr()); +} + +void NodeList::processICEPingReplyPacket(QSharedPointer packet) { + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); + qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr; + + if (_domainHandler.getIP().isNull()) { + // for now we're unsafely assuming this came back from the domain + if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) { + qCDebug(networking) << "Connecting to domain using local socket"; + _domainHandler.activateICELocalSocket(); + } else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) { + qCDebug(networking) << "Conecting to domain using public socket"; + _domainHandler.activateICEPublicSocket(); + } else { + qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect."; } - case PacketType::PingReply: { - SharedNodePointer sendingNode = sendingNodeForPacket(packet); - if (sendingNode) { - sendingNode->setLastHeardMicrostamp(usecTimestampNow()); - - // activate the appropriate socket for this node, if not yet updated - activateSocketFromNodeCommunication(packet, sendingNode); - - // set the ping time for this node for stat collection - timePingReply(packet, sendingNode); - } - - break; - } - case PacketType::ICEPing: { - // send back a reply - auto replyPacket = constructICEPingReplyPacket(packet, _domainHandler.getICEClientID()); - sendPacket(std::move(replyPacket), senderSockAddr); - break; - } - case PacketType::ICEPingReply: { - qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr; - - if (_domainHandler.getIP().isNull()) { - // for now we're unsafely assuming this came back from the domain - if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) { - qCDebug(networking) << "Connecting to domain using local socket"; - _domainHandler.activateICELocalSocket(); - } else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) { - qCDebug(networking) << "Conecting to domain using public socket"; - _domainHandler.activateICEPublicSocket(); - } else { - qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect."; - } - - } - } - case PacketType::StunResponse: { - // a STUN packet begins with 00, we've checked the second zero with packetVersionMatch - // pass it along so it can be processed into our public address and port - processSTUNResponse(packet); - break; - } - case PacketType::DomainServerPathResponse: { - handleDSPathQueryResponse(packet); - break; - } - default: - LimitedNodeList::processNodeData(senderSockAddr, packet); - break; } } @@ -436,43 +379,30 @@ void NodeList::sendDSPathQuery(const QString& newPath) { } } -void NodeList::handleDSPathQueryResponse(const QByteArray& packet) { +void NodeList::processDomainServerPathQueryResponse(QSharedPointer packet) { // This is a response to a path query we theoretically made. // In the future we may want to check that this was actually from our DS and for a query we actually made. - int numHeaderBytes = numBytesForPacketHeaderGivenPacketType(PacketType::DomainServerPathResponse); - const char* startPosition = packet.data() + numHeaderBytes; - const char* currentPosition = startPosition; - // figure out how many bytes the path query is qint16 numPathBytes; - memcpy(&numPathBytes, currentPosition, sizeof(numPathBytes)); - currentPosition += sizeof(numPathBytes); + packet->readPrimitive(&numPathBytes); - // make sure it is safe to pull the path - if (numPathBytes <= packet.size() - numHeaderBytes - (currentPosition - startPosition)) { - // pull the path from the packet - QString pathQuery = QString::fromUtf8(currentPosition, numPathBytes); - currentPosition += numPathBytes; + // pull the path from the packet + QString pathQuery = QString::fromUtf8(packet->read(numPathBytes)); - // figure out how many bytes the viewpoint is - qint16 numViewpointBytes; - memcpy(&numViewpointBytes, currentPosition, sizeof(numViewpointBytes)); - currentPosition += sizeof(numViewpointBytes); + // figure out how many bytes the viewpoint is + qint16 numViewpointBytes; + packet->readPrimitive(&numViewpointBytes); - // make sure it is safe to pull the viewpoint - if (numViewpointBytes <= packet.size() - numHeaderBytes - (currentPosition - startPosition)) { - // pull the viewpoint from the packet - QString viewpoint = QString::fromUtf8(currentPosition, numViewpointBytes); + // pull the viewpoint from the packet + QString viewpoint = QString::fromUtf8(packet->read(numViewpointBytes)); - // Hand it off to the AddressManager so it can handle it as a relative viewpoint - if (DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { - qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; - } else { - qCDebug(networking) << "Could not go to viewpoint" << viewpoint - << "which was the lookup result for path" << pathQuery; - } - } + // Hand it off to the AddressManager so it can handle it as a relative viewpoint + if (DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { + qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; + } else { + qCDebug(networking) << "Could not go to viewpoint" << viewpoint + << "which was the lookup result for path" << pathQuery; } } @@ -527,49 +457,51 @@ void NodeList::pingPunchForDomainServer() { } } -int NodeList::processDomainServerList(const QByteArray& packet) { +void NodeList::processDomainServerList(QSharedPointer packet) { + if (_domainHandler.getSockAddr().isNull()) { + // refuse to process this packet if we aren't currently connected to the DS + return; + } + // this is a packet from the domain server, reset the count of un-replied check-ins _numNoReplyDomainCheckIns = 0; DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); + QDataStream packetStream(packet.data()); + + // grab the domain's ID from the beginning of the packet + QUuid domainUUID; + packetStream >> domainUUID; + // if this was the first domain-server list from this domain, we've now connected if (!_domainHandler.isConnected()) { - _domainHandler.setUUID(uuidFromPacketHeader(packet)); + _domainHandler.setUUID(domainUUID); _domainHandler.setIsConnected(true); } - int readNodes = 0; - - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); - // pull our owner UUID from the packet, it's always the first thing QUuid newUUID; packetStream >> newUUID; setSessionUUID(newUUID); - // TODO: when fixing this read these are actually chars now, not bools - bool thisNodeCanAdjustLocks; + quint8 thisNodeCanAdjustLocks; packetStream >> thisNodeCanAdjustLocks; - setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks); + setThisNodeCanAdjustLocks((bool) thisNodeCanAdjustLocks); - bool thisNodeCanRez; + quint8 thisNodeCanRez; packetStream >> thisNodeCanRez; - setThisNodeCanRez(thisNodeCanRez); + setThisNodeCanRez((bool) thisNodeCanRez); // pull each node in the packet - while (packetStream.device()->pos() < packet.size()) { + while (packetStream.device()->pos() < packet->getSizeUsed()) { parseNodeFromPacketStream(packetStream); } - - return readNodes; } -void NodeList::processDomainServerAddedNode(const QByteArray& packet) { - // setup a QDataStream, skip the header - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); +void NodeList::processDomainServerAddedNode(QSharedPointer packet) { + // setup a QDataStream + QDataStream packetStream(packet.data()); // use our shared method to pull out the new node parseNodeFromPacketStream(packetStream); @@ -663,10 +595,9 @@ void NodeList::handleNodePingTimeout() { } } -void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) { +void NodeList::activateSocketFromNodeCommunication(QSharedPointer packet, const SharedNodePointer& sendingNode) { // deconstruct this ping packet to see if it is a public or local reply - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); + QDataStream packetStream(packet.data()); quint8 pingType; packetStream >> pingType; diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 6ac08fcbd9..4749f9c5ce 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -71,6 +71,16 @@ public slots: void reset(); void sendDomainServerCheckIn(); void handleDSPathQuery(const QString& newPath); + + void processDomainServerList(QSharedPointer packet); + void processDomainServerAddedNode(QSharedPointer packet); + void processDomainServerPathQueryResponse(QSharedPointer packet); + + void processPingPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void processPingReplyPacket(QSharedPointer packet, SharedNodePointer sendingNode); + + void processICEPingPacket(QSharedPointer packet); + void processICEPingReplyPacket(QSharedPointer packet); signals: void limitOfSilentDomainCheckInsReached(); private slots: @@ -89,15 +99,11 @@ private: void processDomainServerAuthRequest(const QByteArray& packet); void requestAuthForDomainServer(); - void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode); - void timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode); - - void handleDSPathQueryResponse(const QByteArray& packet); + void activateSocketFromNodeCommunication(QSharedPointer packet, const SharedNodePointer& sendingNode); + void timePingReply(QSharedPointer packet, const SharedNodePointer& sendingNode); void sendDSPathQuery(const QString& newPath); - - int processDomainServerList(const QByteArray& packet); - void processDomainServerAddedNode(const QByteArray& packet); + void parseNodeFromPacketStream(QDataStream& packetStream); void pingPunchForInactiveNode(const SharedNodePointer& node); diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 03a7260315..f6001711c0 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -18,21 +18,21 @@ using namespace PacketType; const QSet NON_VERIFIED_PACKETS = QSet() - << DomainServerRequireDTLS << DomainConnectRequest - << DomainList << DomainListRequest << DomainConnectionDenied << CreateAssignment << RequestAssignment << StunResponse << NodeJsonStats << EntityQuery << OctreeDataNack << EntityEditNack << Ping - << PingReply << StopNode - << DomainServerPathQuery << DomainServerPathResponse - << DomainServerAddedNode; + << PingReply << StopNode; const QSet SEQUENCE_NUMBERED_PACKETS = QSet() << AvatarData; const QSet NON_SOURCED_PACKETS = QSet() + << DomainServerRequireDTLS << DomainConnectRequest + << DomainList << DomainListRequest << DomainConnectionDenied + << DomainServerPathQuery << DomainServerPathResponse + << DomainServerAddedNode << ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat - << ICEPing << ICEPingReply << DomainConnectRequest; + << ICEPing << ICEPingReply; int arithmeticCodingValueFromBuffer(const char* checkValue) { if (((uchar) *checkValue) < 255) { From 9ee62a8a383bcd80599462ab52ad275e265c0cf0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 17:52:51 -0700 Subject: [PATCH 062/146] fix for connection denied packet in Application --- interface/src/Application.cpp | 19 ++++++++----------- interface/src/Application.h | 3 +-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 98d9325403..4698ff4993 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3815,16 +3815,8 @@ void Application::domainChanged(const QString& domainHostname) { _domainConnectionRefusals.clear(); } -void Application::domainConnectionDenied(const QString& reason) { - if (!_domainConnectionRefusals.contains(reason)) { - _domainConnectionRefusals.append(reason); - emit domainConnectionRefused(reason); - } -} - -void Application::handleDomainConnectionDeniedPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::DomainConnectionDenied); - QDataStream packetStream(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); +void Application::handleDomainConnectionDeniedPacket(QSharedPointer packet, SharedNodePointer senderNode) { + QDataStream packetStream(packet.data()); QString reason; packetStream >> reason; @@ -3833,7 +3825,12 @@ void Application::handleDomainConnectionDeniedPacket(QSharedPointer pa // and check and signal for an access token so that we can make sure they are logged in qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; - domainConnectionDenied(reason); + + if (!_domainConnectionRefusals.contains(reason)) { + _domainConnectionRefusals.append(reason); + emit domainConnectionRefused(reason); + } + AccountManager::getInstance().checkAndSignalForAccessToken(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index c3f31a107c..ae3661579b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -443,8 +443,7 @@ public slots: void notifyPacketVersionMismatch(); - void domainConnectionDenied(const QString& reason); - void handleDomainConnectionDeniedPacket(QSharedPointer, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleDomainConnectionDeniedPacket(QSharedPointer, SharedNodePointer senderNode); void cameraMenuChanged(); From ffcd8e1613c5e691d8b2f8778fd31c0a0935594d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jul 2015 17:54:07 -0700 Subject: [PATCH 063/146] update connection for packet version mismatch --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4698ff4993..64ef4ef743 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -462,7 +462,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); - connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch); + connect(&nodeList->getPacketReceiver(), &PacketReceiver::packetVersionMismatch, + this, &Application::notifyPacketVersionMismatch); // connect to appropriate slots on AccountManager AccountManager& accountManager = AccountManager::getInstance(); From ed3b8afbd9f044e4d781241b41aaeec6df1fd54c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Jul 2015 18:09:08 -0700 Subject: [PATCH 064/146] Update AssignmentClientMonitor to use PacketReceiver --- .../src/AssignmentClientMonitor.cpp | 84 +++++++------------ .../src/AssignmentClientMonitor.h | 3 +- 2 files changed, 32 insertions(+), 55 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 6796c122dc..954cf84df9 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -53,7 +53,9 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto addressManager = DependencyManager::set(); auto nodeList = DependencyManager::set(); - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams); + auto packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsPacket"); + packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsUnknownNodePacket"); // use QProcess to fork off a process for each of the child assignment clients for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { @@ -201,63 +203,37 @@ void AssignmentClientMonitor::checkSpares() { } } +void AssignmentClientMonitor::handleNodeJsonStatsPacket(QSharedPointer packet, SharedNodePointer senderNode) { + // update our records about how to reach this child + senderNode->setLocalSocket(senderSockAddr); -void AssignmentClientMonitor::readPendingDatagrams() { - auto nodeList = DependencyManager::get(); + QVariantMap packetVariantMap = JSONBreakableMarshal::fromStringBuffer(packet->getPayload()); + QJsonObject unpackedStatsJSON = QJsonObject::fromVariantMap(packetVariantMap); - QByteArray receivedPacket; - HifiSockAddr senderSockAddr; + // get child's assignment type out of the decoded json + QString childType = unpackedStatsJSON["assignment_type"].toString(); + AssignmentClientChildData *childData = + static_cast(matchingNode->getLinkedData()); + childData->setChildType(childType); + // note when this child talked + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); +} - while (nodeList->getNodeSocket().hasPendingDatagrams()) { - receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); - nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); +void AssignmentClientMonitor::handleNodeJsonStatsUnknownNodePacket(QSharedPointer packet, SharedNodePointer senderNode) { + // The parent only expects to be talking with prorams running on this same machine. + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || + senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + if (!packetUUID.isNull()) { + matchingNode = DependencyManager::get()->addOrUpdateNode + (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); + AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); + matchingNode->setLinkedData(childData); + } else { + // tell unknown assignment-client child to exit. + qDebug() << "asking unknown child to exit."; - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - if (packetTypeForPacket(receivedPacket) == PacketType::NodeJsonStats) { - QUuid packetUUID = uuidFromPacketHeader(receivedPacket); - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (!matchingNode) { - // The parent only expects to be talking with prorams running on this same machine. - if (senderSockAddr.getAddress() == QHostAddress::LocalHost || - senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { - if (!packetUUID.isNull()) { - matchingNode = DependencyManager::get()->addOrUpdateNode - (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); - AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); - matchingNode->setLinkedData(childData); - } else { - // tell unknown assignment-client child to exit. - qDebug() << "asking unknown child to exit."; - - auto diePacket = NLPacket::create(PacketType::StopNode, 0); - nodeList->sendPacket(std::move(diePacket), senderSockAddr); - } - } - } - - if (matchingNode) { - // update our records about how to reach this child - matchingNode->setLocalSocket(senderSockAddr); - - QVariantMap packetVariantMap = - JSONBreakableMarshal::fromStringBuffer(receivedPacket.mid(numBytesForPacketHeader(receivedPacket))); - QJsonObject unpackedStatsJSON = QJsonObject::fromVariantMap(packetVariantMap); - - // get child's assignment type out of the decoded json - QString childType = unpackedStatsJSON["assignment_type"].toString(); - AssignmentClientChildData *childData = - static_cast(matchingNode->getLinkedData()); - childData->setChildType(childType); - // note when this child talked - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - } - } else { - // have the NodeList attempt to handle it - nodeList->processNodeData(senderSockAddr, receivedPacket); - } + auto diePacket = NLPacket::create(PacketType::StopNode, 0); + nodeList->sendPacket(std::move(diePacket), senderSockAddr); } } } - - diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index f05ed3e661..0c2b958f5c 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -35,9 +35,10 @@ public: void stopChildProcesses(); private slots: - void readPendingDatagrams(); void checkSpares(); void childProcessFinished(); + void handleNodeJsonStatsPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleNodeJsonStatsUnknownNodePacket(QSharedPointer packet, SharedNodePointer senderNode); public slots: void aboutToQuit(); From 879b880254f235d42687a397a9b0679de2b3a182 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 08:30:13 -0700 Subject: [PATCH 065/146] Fix non-ref var to PacketReceiver --- assignment-client/src/AssignmentClientMonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 954cf84df9..4d892923e4 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -53,7 +53,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto addressManager = DependencyManager::set(); auto nodeList = DependencyManager::set(); - auto packetReceiver = DependencyManager::get()->getPacketReceiver(); + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsPacket"); packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsUnknownNodePacket"); From 582de1491736a68a02ab7d6751fbaf1ded53385d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 09:25:57 -0700 Subject: [PATCH 066/146] Fix compilation errors in AssignmentClientMonitor --- .../src/AssignmentClientMonitor.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 4d892923e4..5498322f58 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -54,8 +54,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto nodeList = DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsPacket"); - packetReceiver->registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsUnknownNodePacket"); + packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsPacket"); + packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsUnknownNodePacket"); // use QProcess to fork off a process for each of the child assignment clients for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { @@ -204,6 +204,8 @@ void AssignmentClientMonitor::checkSpares() { } void AssignmentClientMonitor::handleNodeJsonStatsPacket(QSharedPointer packet, SharedNodePointer senderNode) { + auto senderSockAddr = packet->getSenderSockAddr(); + // update our records about how to reach this child senderNode->setLocalSocket(senderSockAddr); @@ -213,26 +215,30 @@ void AssignmentClientMonitor::handleNodeJsonStatsPacket(QSharedPointer // get child's assignment type out of the decoded json QString childType = unpackedStatsJSON["assignment_type"].toString(); AssignmentClientChildData *childData = - static_cast(matchingNode->getLinkedData()); + static_cast(senderNode->getLinkedData()); childData->setChildType(childType); // note when this child talked - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + senderNode->setLastHeardMicrostamp(usecTimestampNow()); } void AssignmentClientMonitor::handleNodeJsonStatsUnknownNodePacket(QSharedPointer packet, SharedNodePointer senderNode) { + auto senderSockAddr = packet->getSenderSockAddr(); + // The parent only expects to be talking with prorams running on this same machine. if (senderSockAddr.getAddress() == QHostAddress::LocalHost || senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + QUuid packetUUID = uuidFromPacketHeader(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); if (!packetUUID.isNull()) { - matchingNode = DependencyManager::get()->addOrUpdateNode + senderNode = DependencyManager::get()->addOrUpdateNode (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); - matchingNode->setLinkedData(childData); + senderNode->setLinkedData(childData); } else { // tell unknown assignment-client child to exit. qDebug() << "asking unknown child to exit."; auto diePacket = NLPacket::create(PacketType::StopNode, 0); + auto nodeList = DependencyManager::get(); nodeList->sendPacket(std::move(diePacket), senderSockAddr); } } From 3d62162812b6a45b49fa6f6a106c0e73d50eec84 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 09:40:26 -0700 Subject: [PATCH 067/146] cleanup octree networking code to use new API --- domain-server/src/DomainServer.cpp | 2 +- interface/src/Application.cpp | 110 +++++++-------- interface/src/Application.h | 2 +- .../src/octree/OctreePacketProcessor.cpp | 82 +++++------- interface/src/octree/OctreePacketProcessor.h | 9 +- libraries/networking/src/NodeList.h | 1 + libraries/networking/src/PacketReceiver.cpp | 6 + libraries/networking/src/PacketReceiver.h | 4 +- .../src/ReceivedPacketProcessor.cpp | 15 +-- .../networking/src/ReceivedPacketProcessor.h | 6 +- libraries/octree/src/JurisdictionListener.cpp | 9 +- libraries/octree/src/JurisdictionListener.h | 2 +- libraries/octree/src/JurisdictionMap.cpp | 40 ++---- libraries/octree/src/JurisdictionMap.h | 4 +- libraries/octree/src/JurisdictionSender.cpp | 14 +- libraries/octree/src/JurisdictionSender.h | 2 +- libraries/octree/src/OctreeHeadlessViewer.cpp | 4 +- libraries/octree/src/OctreeHeadlessViewer.h | 2 +- libraries/octree/src/OctreeSceneStats.cpp | 125 ++++++------------ libraries/octree/src/OctreeSceneStats.h | 4 +- 20 files changed, 186 insertions(+), 257 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 00efd818a5..5e16949688 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -938,7 +938,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // setup the extended header for the domain list packets // this data is at the beginning of each of the domain list packets QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0); - QDataStream extendedHeaderStream(&extendedHeader, &QIODevice::Append); + QDataStream extendedHeaderStream(&extendedHeader, QIODevice::Append); extendedHeaderStream << limitedNodeList->getSessionUUID().toRfc4122(); extendedHeaderStream << node->getUUID().toRfc4122(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 64ef4ef743..8562e54ad0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3925,70 +3925,70 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar } } -int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) { +int Application::processOctreeStats(QSharedPointer packet, SharedNodePointer sendingNode) { // But, also identify the sender, and keep track of the contained jurisdiction root for this server // parse the incoming stats datas stick it in a temporary object for now, while we // determine which server it belongs to - OctreeSceneStats temp; - int statsMessageLength = temp.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); + int statsMessageLength = 0; - // quick fix for crash... why would voxelServer be NULL? - if (sendingNode) { - QUuid nodeUUID = sendingNode->getUUID(); + const QUuid& nodeUUID = sendingNode->getUUID(); + OctreeSceneStats* octreeStats; - // now that we know the node ID, let's add these stats to the stats for that node... - _octreeSceneStatsLock.lockForWrite(); - if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { - _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast(packet.data()), - packet.size()); - } else { - _octreeServerSceneStats[nodeUUID] = temp; + // now that we know the node ID, let's add these stats to the stats for that node... + _octreeSceneStatsLock.lockForWrite(); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + octreeStats = &_octreeServerSceneStats[nodeUUID]; + statsMessageLength = octreeStats->unpackFromPacket(*packet); + } else { + OctreeSceneStats temp; + statsMessageLength = temp.unpackFromPacket(*packet); + octreeStats = &temp; + } + _octreeSceneStatsLock.unlock(); + + VoxelPositionSize rootDetails; + voxelDetailsForCode(octreeStats->getJurisdictionRoot(), rootDetails); + + // see if this is the first we've heard of this node... + NodeToJurisdictionMap* jurisdiction = NULL; + QString serverType; + if (sendingNode->getType() == NodeType::EntityServer) { + jurisdiction = &_entityServerJurisdictions; + serverType = "Entity"; + } + + jurisdiction->lockForRead(); + if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { + jurisdiction->unlock(); + + qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", + qPrintable(serverType), + (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); + + // Add the jurisditionDetails object to the list of "fade outs" + if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { + OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); + fade.voxelDetails = rootDetails; + const float slightly_smaller = 0.99f; + fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _octreeFadesLock.lockForWrite(); + _octreeFades.push_back(fade); + _octreeFadesLock.unlock(); } - _octreeSceneStatsLock.unlock(); - - VoxelPositionSize rootDetails; - voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); - - // see if this is the first we've heard of this node... - NodeToJurisdictionMap* jurisdiction = NULL; - QString serverType; - if (sendingNode->getType() == NodeType::EntityServer) { - jurisdiction = &_entityServerJurisdictions; - serverType = "Entity"; - } - - jurisdiction->lockForRead(); - if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { - jurisdiction->unlock(); - - qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", - qPrintable(serverType), - (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); - - // Add the jurisditionDetails object to the list of "fade outs" - if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { - OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); - fade.voxelDetails = rootDetails; - const float slightly_smaller = 0.99f; - fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _octreeFadesLock.lockForWrite(); - _octreeFades.push_back(fade); - _octreeFadesLock.unlock(); - } - } else { - jurisdiction->unlock(); - } - // store jurisdiction details for later use - // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it - // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the - // details from the OctreeSceneStats to construct the JurisdictionMap - JurisdictionMap jurisdictionMap; - jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); - jurisdiction->lockForWrite(); - (*jurisdiction)[nodeUUID] = jurisdictionMap; + } else { jurisdiction->unlock(); } + // store jurisdiction details for later use + // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it + // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the + // details from the OctreeSceneStats to construct the JurisdictionMap + JurisdictionMap jurisdictionMap; + jurisdictionMap.copyContents(octreeStats->getJurisdictionRoot(), octreeStats->getJurisdictionEndNodes()); + jurisdiction->lockForWrite(); + (*jurisdiction)[nodeUUID] = jurisdictionMap; + jurisdiction->unlock(); + return statsMessageLength; } diff --git a/interface/src/Application.h b/interface/src/Application.h index ae3661579b..dd27080952 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -612,7 +612,7 @@ private: StDev _idleLoopStdev; float _idleLoopMeasuredJitter; - int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode); + int processOctreeStats(QSharedPointer packet, SharedNodePointer sendingNode); void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket); NodeToJurisdictionMap _entityServerJurisdictions; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index dba75b0c5f..0595bfbbc2 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -1,4 +1,4 @@ -//Merge branch 'master' of ssh://github.com/highfidelity/hifi into isentropic/ +// // OctreePacketProcessor.cpp // interface/src/octree // @@ -18,54 +18,41 @@ OctreePacketProcessor::OctreePacketProcessor() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleEntityDataPacket"); - packetReceiver.registerPacketListener(PacketType::EntityData, this, "handleEntityDataPacket"); - packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket"); - packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleOctreeStatsPacket"); - packetReceiver.registerPacketListener(PacketType::EnvironmentData, this, "handleEnvironmentDataPacket"); + + QSet types { + PacketType::OctreeStats, PacketType::EntityData, + PacketType::EntityErase, PacketType::OctreeStats, PacketType::EnvironmentData + } + + packetReceiver.registerPacketListeners(types, this, "handleOctreePacket"); } -// TODO implement packet processing in PacketType-specific methods -void OctreePacketProcessor::handleEntityDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); +void OctreePacketProcessor::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { + queueReceivedPacket(senderNode, packet); } -void OctreePacketProcessor::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); -} - -void OctreePacketProcessor::handleOctreeStatsPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); -} - -void OctreePacketProcessor::handleEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - queueReceivedPacket(senderNode, QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); -} - -void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { +void OctreePacketProcessor::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "OctreePacketProcessor::processPacket()"); - QByteArray mutablePacket = packet; - const int WAY_BEHIND = 300; if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) { qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } - int messageLength = mutablePacket.size(); + + int messageLength = packet->getSizeUsed(); Application* app = Application::getInstance(); bool wasStatsPacket = false; - - PacketType::Value voxelPacketType = packetTypeForPacket(mutablePacket); + PacketType::Value octreePacketType = packet->getType(); // note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // then process any remaining bytes as if it was another packet - if (voxelPacketType == PacketType::OctreeStats) { - int statsMessageLength = app->parseOctreeStats(mutablePacket, sendingNode); + if (octreePacketType == PacketType::OctreeStats) { + int statsMessageLength = app->processOctreeStats(packet, sendingNode); wasStatsPacket = true; if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); @@ -104,29 +91,26 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode, app->trackIncomingOctreePacket(mutablePacket, sendingNode, wasStatsPacket); - if (sendingNode) { + switch(voxelPacketType) { + case PacketType::EntityErase: { + if (DependencyManager::get()->shouldRenderEntities()) { + app->_entities.processEraseMessage(mutablePacket, sendingNode); + } + } break; - switch(voxelPacketType) { - case PacketType::EntityErase: { - if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processEraseMessage(mutablePacket, sendingNode); - } - } break; + case PacketType::EntityData: { + if (DependencyManager::get()->shouldRenderEntities()) { + app->_entities.processDatagram(mutablePacket, sendingNode); + } + } break; - case PacketType::EntityData: { - if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processDatagram(mutablePacket, sendingNode); - } - } break; + case PacketType::EnvironmentData: { + app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); + } break; - case PacketType::EnvironmentData: { - app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); - } break; - - default: { - // nothing to do - } break; - } + default: { + // nothing to do + } break; } } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 50d68fe713..47ebdc73bc 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -14,7 +14,7 @@ #include -/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes +/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() class OctreePacketProcessor : public ReceivedPacketProcessor { Q_OBJECT @@ -25,12 +25,9 @@ signals: void packetVersionMismatch(); protected: - virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + virtual void processPacket(QSharedPointer packet, SharedNodePointer sendingNode); private slots: - void handleEntityDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleOctreeStatsPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode); }; #endif // hifi_OctreePacketProcessor_h diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 4749f9c5ce..6578326f4a 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -38,6 +38,7 @@ const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000; const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5; using NodePacketPair = std::pair>; +using NodeSharedPacketPair = std::pair>; class Application; class Assignment; diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 7214915b30..f410fe69c3 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -24,6 +24,12 @@ PacketReceiver::PacketReceiver(QObject* parent) : } +void PacketReceiver::registerPacketListeners(const QSet& types, QObject* object, const char* slot) { + foreach(PacketType::Value type, types) { + registerPacketListener(type, object, slot); + } +} + void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, const char* slot) { Q_ASSERT(object); diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 9f397c5c41..990d8fc19d 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "NLPacket.h" #include "PacketHeaders.h" @@ -37,7 +38,8 @@ public: void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; } void shutdown() { _isShuttingDown = true; } - + + void registerPacketListeners(const QSet& types, QObject* listener, const char* slot); void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); public slots: diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 826968ae32..15b46cdf8f 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -24,15 +24,9 @@ void ReceivedPacketProcessor::terminating() { _hasPackets.wakeAll(); } -void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { - // Make sure our Node and NodeList knows we've heard from this node. - sendingNode->setLastHeardMicrostamp(usecTimestampNow()); - - // TODO: fix the NodePacketPair once we've figured out receive API - NodePacketPair networkPacket(sendingNode, NLPacket::create(PacketType::OctreeStats)); - +void ReceivedPacketProcessor::queueReceivedPacket(QSharedPointer packet, SharedNodePointer sendingNode) { lock(); - _packets.push_back(std::move(networkPacket)); + _packets.push_back({ sendingNode, packet }); _nodePacketCounts[sendingNode->getUUID()]++; _lastWindowIncomingPackets++; unlock(); @@ -73,13 +67,12 @@ bool ReceivedPacketProcessor::process() { } lock(); - std::list currentPackets; + std::list currentPackets; currentPackets.swap(_packets); unlock(); for(auto& packetPair : currentPackets) { - // TODO: Replace QByteArray() once NLPacket is coming through on receive side - processPacket(packetPair.first, QByteArray()); + processPacket(packetPair.second, packetPair.first); _lastWindowProcessedPackets++; midProcess(); } diff --git a/libraries/networking/src/ReceivedPacketProcessor.h b/libraries/networking/src/ReceivedPacketProcessor.h index a833ca5a8b..db75c9c4d1 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.h +++ b/libraries/networking/src/ReceivedPacketProcessor.h @@ -23,7 +23,7 @@ public: ReceivedPacketProcessor(); /// Add packet from network receive thread to the processing queue. - void queueReceivedPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + void queueReceivedPacket(QSharedPointer packet, SharedNodePointer sendingNode); /// Are there received packets waiting to be processed bool hasPacketsToProcess() const { return _packets.size() > 0; } @@ -58,7 +58,7 @@ protected: /// Callback for processing of recieved packets. Implement this to process the incoming packets. /// \param SharedNodePointer& sendingNode the node that sent this packet /// \param QByteArray& the packet to be processed - virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) = 0; + virtual void processPacket(QSharedPointer packet, SharedNodePointer sendingNode) = 0; /// Implements generic processing behavior for this thread. virtual bool process(); @@ -76,7 +76,7 @@ protected: virtual void postProcess() { } protected: - std::list _packets; + std::list _packets; QHash _nodePacketCounts; QWaitCondition _hasPackets; diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index d725ce3555..7f4cb2d474 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -56,12 +56,11 @@ bool JurisdictionListener::queueJurisdictionRequest() { return isStillRunning(); } -void JurisdictionListener::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { - if (packetTypeForPacket(packet) == PacketType::Jurisdiction && sendingNode) { - QUuid nodeUUID = sendingNode->getUUID(); +void JurisdictionListener::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + if (packet->getType() == PacketType::Jurisdiction && sendingNode) { JurisdictionMap map; - map.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); - _jurisdictions[nodeUUID] = map; + map.unpackFromPacket(*packet); + _jurisdictions[sendingNode->getUUID()] = map; } } diff --git a/libraries/octree/src/JurisdictionListener.h b/libraries/octree/src/JurisdictionListener.h index 72e4b5faf7..02fce896f5 100644 --- a/libraries/octree/src/JurisdictionListener.h +++ b/libraries/octree/src/JurisdictionListener.h @@ -47,7 +47,7 @@ public slots: protected: /// Callback for processing of received packets. Will process any queued PacketType::_JURISDICTION and update the /// jurisdiction map member variable - virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + virtual void processPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: NodeToJurisdictionMap _jurisdictions; diff --git a/libraries/octree/src/JurisdictionMap.cpp b/libraries/octree/src/JurisdictionMap.cpp index d6e4ad8003..2a9b43f20a 100644 --- a/libraries/octree/src/JurisdictionMap.cpp +++ b/libraries/octree/src/JurisdictionMap.cpp @@ -280,7 +280,7 @@ std::unique_ptr JurisdictionMap::packEmptyJurisdictionIntoMessage(Node return std::move(packet); // includes header! } -std::unique_ptr JurisdictionMap::packIntoMessage() { +std::unique_ptr JurisdictionMap::packIntoPacket() { auto packet = NLPacket::create(PacketType::Jurisdiction); // Pack the Node Type in first byte @@ -315,42 +315,28 @@ std::unique_ptr JurisdictionMap::packIntoMessage() { return std::move(packet); } -int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) { +int JurisdictionMap::unpackFromPacket(NLPacket& packet) { clear(); - const unsigned char* startPosition = sourceBuffer; - - // increment to push past the packet header - int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(sourceBuffer)); - sourceBuffer += numBytesPacketHeader; - int remainingBytes = availableBytes - numBytesPacketHeader; - + // read the root jurisdiction int bytes = 0; - memcpy(&bytes, sourceBuffer, sizeof(bytes)); - sourceBuffer += sizeof(bytes); - remainingBytes -= sizeof(bytes); + packet.readPrimitive(&bytes); - if (bytes > 0 && bytes <= remainingBytes) { + if (bytes > 0 && bytes <= packet.bytesAvailable()) { _rootOctalCode = new unsigned char[bytes]; - memcpy(_rootOctalCode, sourceBuffer, bytes); - sourceBuffer += bytes; - remainingBytes -= bytes; + packet.read(reinterpret_cast(_rootOctalCode), bytes); // if and only if there's a root jurisdiction, also include the end nodes int endNodeCount = 0; - memcpy(&endNodeCount, sourceBuffer, sizeof(endNodeCount)); - sourceBuffer += sizeof(endNodeCount); - for (int i=0; i < endNodeCount; i++) { + packet.readPrimitive(&endNodeCount); + + for (int i = 0; i < endNodeCount; i++) { int bytes = 0; - memcpy(&bytes, sourceBuffer, sizeof(bytes)); - sourceBuffer += sizeof(bytes); - remainingBytes -= sizeof(bytes); + packet.readPrimitive(&bytes); - if (bytes <= remainingBytes) { + if (bytes <= packet.bytesAvailable()) { unsigned char* endNodeCode = new unsigned char[bytes]; - memcpy(endNodeCode, sourceBuffer, bytes); - sourceBuffer += bytes; - remainingBytes -= bytes; + packet.read(reinterpret_cast(endNodeCode), bytes); // if the endNodeCode was 0 length then don't add it if (bytes > 0) { @@ -360,5 +346,5 @@ int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int av } } - return sourceBuffer - startPosition; // includes header! + return packet.pos(); // excludes header } diff --git a/libraries/octree/src/JurisdictionMap.h b/libraries/octree/src/JurisdictionMap.h index eccaef0a60..49a6f5a166 100644 --- a/libraries/octree/src/JurisdictionMap.h +++ b/libraries/octree/src/JurisdictionMap.h @@ -61,8 +61,8 @@ public: void copyContents(unsigned char* rootCodeIn, const std::vector& endNodesIn); - int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes); - std::unique_ptr packIntoMessage(); + int unpackFromPacket(NLPacket& packet); + std::unique_ptr packIntoPacket(); /// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available static std::unique_ptr packEmptyJurisdictionIntoMessage(NodeType_t type); diff --git a/libraries/octree/src/JurisdictionSender.cpp b/libraries/octree/src/JurisdictionSender.cpp index 1ade2412b8..cc620d87c1 100644 --- a/libraries/octree/src/JurisdictionSender.cpp +++ b/libraries/octree/src/JurisdictionSender.cpp @@ -28,13 +28,11 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NodeType_t type) : JurisdictionSender::~JurisdictionSender() { } -void JurisdictionSender::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { - if (packetTypeForPacket(packet) == PacketType::JurisdictionRequest) { - if (sendingNode) { - lockRequestingNodes(); - _nodesRequestingJurisdictions.push(sendingNode->getUUID()); - unlockRequestingNodes(); - } +void JurisdictionSender::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + if (packet->getType() == PacketType::JurisdictionRequest) { + lockRequestingNodes(); + _nodesRequestingJurisdictions.push(sendingNode->getUUID()); + unlockRequestingNodes(); } } @@ -43,7 +41,7 @@ bool JurisdictionSender::process() { // call our ReceivedPacketProcessor base class process so we'll get any pending packets if (continueProcessing && (continueProcessing = ReceivedPacketProcessor::process())) { - auto packet = (_jurisdictionMap) ? _jurisdictionMap->packIntoMessage() + auto packet = (_jurisdictionMap) ? _jurisdictionMap->packIntoPacket() : JurisdictionMap::packEmptyJurisdictionIntoMessage(getNodeType()); int nodeCount = 0; diff --git a/libraries/octree/src/JurisdictionSender.h b/libraries/octree/src/JurisdictionSender.h index bc40f92a2c..a9b6fb03b5 100644 --- a/libraries/octree/src/JurisdictionSender.h +++ b/libraries/octree/src/JurisdictionSender.h @@ -38,7 +38,7 @@ public: void setNodeType(NodeType_t type) { _nodeType = type; } protected: - virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + virtual void processPacket(QSharedPointer pack, SharedNodePointer sendingNode); /// Locks all the resources of the thread. void lockRequestingNodes() { _requestingNodeMutex.lock(); } diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 2a9dd1dd33..950d676886 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -225,10 +225,10 @@ void OctreeHeadlessViewer::queryOctree() { } -int OctreeHeadlessViewer::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode) { +int OctreeHeadlessViewer::parseOctreeStats(QSharedPointer packet, SharedNodePointer sourceNode) { OctreeSceneStats temp; - int statsMessageLength = temp.unpackFromMessage(reinterpret_cast(packet.data()), packet.size()); + int statsMessageLength = temp.unpackFromPacket(*packet); // TODO: actually do something with these stats, like expose them to JS... diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 70ee43be35..399b5de69b 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -37,7 +37,7 @@ public: void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } - static int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sourceNode); + static int parseOctreeStats(QSharedPointer packet, SharedNodePointer sourceNode); static void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket); public slots: diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index c4367b43d8..a3799c2f36 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -442,30 +442,16 @@ int OctreeSceneStats::packIntoPacket() { return _statsPacket->getSizeUsed(); } -int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) { - const unsigned char* startPosition = sourceBuffer; +int OctreeSceneStats::unpackFromPacket(NLPacket& packet) { + packet.readPrimitive(&_start); + packet.readPrimitive(&_end); + packet.readPrimitive(&_elapsed); + packet.readPrimitive(&_totalEncodeTime); - // increment to push past the packet header - int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(sourceBuffer)); - sourceBuffer += numBytesPacketHeader; - - memcpy(&_start, sourceBuffer, sizeof(_start)); - sourceBuffer += sizeof(_start); - memcpy(&_end, sourceBuffer, sizeof(_end)); - sourceBuffer += sizeof(_end); - memcpy(&_elapsed, sourceBuffer, sizeof(_elapsed)); - sourceBuffer += sizeof(_elapsed); - memcpy(&_totalEncodeTime, sourceBuffer, sizeof(_totalEncodeTime)); - sourceBuffer += sizeof(_totalEncodeTime); - - memcpy(&_isFullScene, sourceBuffer, sizeof(_isFullScene)); - sourceBuffer += sizeof(_isFullScene); - memcpy(&_isMoving, sourceBuffer, sizeof(_isMoving)); - sourceBuffer += sizeof(_isMoving); - memcpy(&_packets, sourceBuffer, sizeof(_packets)); - sourceBuffer += sizeof(_packets); - memcpy(&_bytes, sourceBuffer, sizeof(_bytes)); - sourceBuffer += sizeof(_bytes); + packet.readPrimitive(&_isFullScene); + packet.readPrimitive(&_isMoving); + packet.readPrimitive(&_packets); + packet.readPrimitive(&_bytes); if (_isFullScene) { _lastFullElapsed = _elapsed; @@ -474,75 +460,52 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a _lastFullTotalBytes = _bytes; } - memcpy(&_totalInternal, sourceBuffer, sizeof(_totalInternal)); - sourceBuffer += sizeof(_totalInternal); - memcpy(&_totalLeaves, sourceBuffer, sizeof(_totalLeaves)); - sourceBuffer += sizeof(_totalLeaves); + packet.readPrimitive(&_totalInternal); + packet.readPrimitive(&_totalLeaves); _totalElements = _totalInternal + _totalLeaves; - memcpy(&_internal, sourceBuffer, sizeof(_internal)); - sourceBuffer += sizeof(_internal); - memcpy(&_leaves, sourceBuffer, sizeof(_leaves)); - sourceBuffer += sizeof(_leaves); + packet.readPrimitive(&_internal); + packet.readPrimitive(&_leaves); _traversed = _internal + _leaves; - memcpy(&_internalSkippedDistance, sourceBuffer, sizeof(_internalSkippedDistance)); - sourceBuffer += sizeof(_internalSkippedDistance); - memcpy(&_leavesSkippedDistance, sourceBuffer, sizeof(_leavesSkippedDistance)); - sourceBuffer += sizeof(_leavesSkippedDistance); + packet.readPrimitive(&_internalSkippedDistance); + packet.readPrimitive(&_leavesSkippedDistance); _skippedDistance = _internalSkippedDistance + _leavesSkippedDistance; - memcpy(&_internalSkippedOutOfView, sourceBuffer, sizeof(_internalSkippedOutOfView)); - sourceBuffer += sizeof(_internalSkippedOutOfView); - memcpy(&_leavesSkippedOutOfView, sourceBuffer, sizeof(_leavesSkippedOutOfView)); - sourceBuffer += sizeof(_leavesSkippedOutOfView); + packet.readPrimitive(&_internalSkippedOutOfView); + packet.readPrimitive(&_leavesSkippedOutOfView); _skippedOutOfView = _internalSkippedOutOfView + _leavesSkippedOutOfView; - memcpy(&_internalSkippedWasInView, sourceBuffer, sizeof(_internalSkippedWasInView)); - sourceBuffer += sizeof(_internalSkippedWasInView); - memcpy(&_leavesSkippedWasInView, sourceBuffer, sizeof(_leavesSkippedWasInView)); - sourceBuffer += sizeof(_leavesSkippedWasInView); + packet.readPrimitive(&_internalSkippedWasInView); + packet.readPrimitive(&_leavesSkippedWasInView); _skippedWasInView = _internalSkippedWasInView + _leavesSkippedWasInView; - memcpy(&_internalSkippedNoChange, sourceBuffer, sizeof(_internalSkippedNoChange)); - sourceBuffer += sizeof(_internalSkippedNoChange); - memcpy(&_leavesSkippedNoChange, sourceBuffer, sizeof(_leavesSkippedNoChange)); - sourceBuffer += sizeof(_leavesSkippedNoChange); + packet.readPrimitive(&_internalSkippedNoChange); + packet.readPrimitive(&_leavesSkippedNoChange); _skippedNoChange = _internalSkippedNoChange + _leavesSkippedNoChange; - memcpy(&_internalSkippedOccluded, sourceBuffer, sizeof(_internalSkippedOccluded)); - sourceBuffer += sizeof(_internalSkippedOccluded); - memcpy(&_leavesSkippedOccluded, sourceBuffer, sizeof(_leavesSkippedOccluded)); - sourceBuffer += sizeof(_leavesSkippedOccluded); + packet.readPrimitive(&_internalSkippedOccluded); + packet.readPrimitive(&_leavesSkippedOccluded); _skippedOccluded = _internalSkippedOccluded + _leavesSkippedOccluded; - memcpy(&_internalColorSent, sourceBuffer, sizeof(_internalColorSent)); - sourceBuffer += sizeof(_internalColorSent); - memcpy(&_leavesColorSent, sourceBuffer, sizeof(_leavesColorSent)); - sourceBuffer += sizeof(_leavesColorSent); + packet.readPrimitive(&_internalColorSent); + packet.readPrimitive(&_leavesColorSent); _colorSent = _internalColorSent + _leavesColorSent; - memcpy(&_internalDidntFit, sourceBuffer, sizeof(_internalDidntFit)); - sourceBuffer += sizeof(_internalDidntFit); - memcpy(&_leavesDidntFit, sourceBuffer, sizeof(_leavesDidntFit)); - sourceBuffer += sizeof(_leavesDidntFit); + packet.readPrimitive(&_internalDidntFit); + packet.readPrimitive(&_leavesDidntFit); _didntFit = _internalDidntFit + _leavesDidntFit; - memcpy(&_colorBitsWritten, sourceBuffer, sizeof(_colorBitsWritten)); - sourceBuffer += sizeof(_colorBitsWritten); - memcpy(&_existsBitsWritten, sourceBuffer, sizeof(_existsBitsWritten)); - sourceBuffer += sizeof(_existsBitsWritten); - memcpy(&_existsInPacketBitsWritten, sourceBuffer, sizeof(_existsInPacketBitsWritten)); - sourceBuffer += sizeof(_existsInPacketBitsWritten); - memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved)); - sourceBuffer += sizeof(_treesRemoved); - + packet.readPrimitive(&_colorBitsWritten); + packet.readPrimitive(&_existsBitsWritten); + packet.readPrimitive(&_existsInPacketBitsWritten); + packet.readPrimitive(&_treesRemoved); // before allocating new juridiction, clean up existing ones if (_jurisdictionRoot) { delete[] _jurisdictionRoot; _jurisdictionRoot = NULL; } - + // clear existing endNodes before copying new ones... for (size_t i = 0; i < _jurisdictionEndNodes.size(); i++) { if (_jurisdictionEndNodes[i]) { @@ -553,28 +516,29 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a // read the root jurisdiction int bytes = 0; - memcpy(&bytes, sourceBuffer, sizeof(bytes)); - sourceBuffer += sizeof(bytes); + packet.readPrimitive(&bytes); if (bytes == 0) { _jurisdictionRoot = NULL; _jurisdictionEndNodes.clear(); } else { _jurisdictionRoot = new unsigned char[bytes]; - memcpy(_jurisdictionRoot, sourceBuffer, bytes); - sourceBuffer += bytes; + packet.read(reinterpret_cast(_jurisdictionRoot), bytes); + // if and only if there's a root jurisdiction, also include the end elements _jurisdictionEndNodes.clear(); + int endNodeCount = 0; - memcpy(&endNodeCount, sourceBuffer, sizeof(endNodeCount)); - sourceBuffer += sizeof(endNodeCount); + packet.readPrimitive(&endNodeCount); + for (int i=0; i < endNodeCount; i++) { int bytes = 0; - memcpy(&bytes, sourceBuffer, sizeof(bytes)); - sourceBuffer += sizeof(bytes); + + packet.readPrimitive(&bytes); + unsigned char* endNodeCode = new unsigned char[bytes]; - memcpy(endNodeCode, sourceBuffer, bytes); - sourceBuffer += bytes; + packet.read(reinterpret_cast(endNodeCode), bytes); + _jurisdictionEndNodes.push_back(endNodeCode); } } @@ -585,8 +549,7 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a float calculatedBPV = total == 0 ? 0 : (_bytes * 8) / total; _bitsPerOctreeAverage.updateAverage(calculatedBPV); - - return sourceBuffer - startPosition; // includes header! + return packet.pos(); // excludes header! } diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index 280f0e2a35..a71360a4cf 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -93,8 +93,8 @@ public: /// Pack the details of the statistics into a buffer for sending as a network packet int packIntoPacket(); - /// Unpack the details of the statistics from a buffer typically received as a network packet - int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes); + /// Unpack the details of the statistics from a network packet + int unpackFromPacket(NLPacket& packet); /// Indicates that a scene has been completed and the statistics are ready to be sent bool isReadyToSend() const { return _isReadyToSend; } From 26e78a79c065a61107e34320b85e5db5a1d525f3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 09:42:52 -0700 Subject: [PATCH 068/146] Add Packet::getSenderSockAddr --- libraries/networking/src/Packet.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/networking/src/Packet.h b/libraries/networking/src/Packet.h index e9483ca1f1..6bb39d20b8 100644 --- a/libraries/networking/src/Packet.h +++ b/libraries/networking/src/Packet.h @@ -16,6 +16,7 @@ #include +#include "HifiSockAddr.h" #include "PacketHeaders.h" class Packet : public QIODevice { @@ -48,6 +49,8 @@ public: qint64 getSizeUsed() const { return _sizeUsed; } void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; } + HifiSockAddr getSenderSockAddr() const { return HifiSockAddr(); } + // Header readers PacketType::Value readType() const; PacketVersion readVersion() const; From c23899aec2ed833e02dbe95ddf828e696e8204ae Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 10:02:53 -0700 Subject: [PATCH 069/146] repairs to packet listener registration --- libraries/networking/src/PacketReceiver.cpp | 104 +++++++++++++------- libraries/networking/src/PacketReceiver.h | 2 + 2 files changed, 68 insertions(+), 38 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index f410fe69c3..bfb98ff25e 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -25,61 +25,89 @@ PacketReceiver::PacketReceiver(QObject* parent) : } void PacketReceiver::registerPacketListeners(const QSet& types, QObject* object, const char* slot) { + QSet nonSourcedTypes; + QSet sourceTypes; + foreach(PacketType::Value type, types) { - registerPacketListener(type, object, slot); + if (NON_SOURCED_PACKETS.contains(type)) { + nonSourcedTypes << type; + } else { + sourceTypes << type; + } + } + + if (nonSourcedTypes.size() > 0) { + QMetaMethod nonSourcedMethod = matchingMethodForListener(nonSourcedTypes[0], object, slot); + foreach(PacketType::Value type, nonSourcedTypes) { + registerVerifiedListener(type, object, nonSourcedMethod); + } + } + + if (sourceTypes.size() > 0) { + QMetaMethod sourcedMethod = matchingMethodForListener(sourcedTypes[0], object, slot); + foreach(PacketType::Value type, sourcedTypes) { + registerVerifiedListener(type, object, sourcedMethod); + } } } void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, const char* slot) { + QMetaMethod matchingMethod = matchingMethodForListener(type, object, slot); + if (matchingMethod.isValid()) { + registerVerifiedListener(type, object, slotMethod); + } +} + +QMetaMethod PacketReciever::matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) { Q_ASSERT(object); + + // normalize the slot with the expected parameters + QString normalizedSlot; + + if (NON_SOURCED_PACKETS.contains(type)) { + const QString NON_SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer"; + + normalizedSlot = + QMetaObject::normalizedSignature(QString("%1(%2)").arg(slot).arg(NON_SOURCED_PACKET_LISTENER_PARAMETERS)); + } else { + const QList SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; + + normalizedSlot = QMetaObject::normalizedSignature(QString("%1(%2)").arg(slot).arg(SOURCED_PACKET_LISTENER_PARAMETERS)); + } + + // does the constructed normalized method exist? + int methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.data()); + if (methodIndex < 0) { + qDebug() << "PacketReceiver::registerPacketListener expected a method with a normalized signature of" + << normalizedSlot << "but such a method was not found."; + } + + Q_ASSERT(methodIndex >= 0); + + // return the converted QMetaMethod + if (methodIndex >= 0) { + return object->metaObject()->method(methodIndex); + } else { + // if somehow (scripting?) something bad gets in here at runtime that doesn't hit the asserts above + // return a non-valid QMetaMethod + return QMetaMethod(); + } +} + +void PacketReceiver::registerVerifiedListener(PacketType::Value type, QObject* object, const QMetaMethod& slot) { _packetListenerLock.lock(); if (_packetListenerMap.contains(type)) { qDebug() << "Warning: Registering a packet listener for packet type " << type << "that will remove a previously registered listener"; } - - // convert the const char* slot to a QMetaMethod - int methodIndex = object->metaObject()->indexOfSlot(slot); - Q_ASSERT(methodIndex >= 0); - - QMetaMethod slotMethod = object->metaObject()->method(methodIndex); - Q_ASSERT(method.isValid()); - - // compare the parameters we expect and the parameters the QMetaMethod has - bool parametersMatch = false; - - if (NON_SOURCED_PACKETS.contains(type)) { - const QList NON_SOURCED_PACKET_LISTENER_PARAMETERS = QList() - << QMetaObject::normalizedType("QSharedPointer"); - - parametersMatch = slotMethod.parameterTypes() == NON_SOURCED_PACKET_LISTENER_PARAMETERS; - - qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" - << NON_SOURCED_PACKET_LISTENER_PARAMETERS - << "but parameter method takes" << slotMethod.parameterTypes(); - } else { - const QList SOURCED_PACKET_LISTENER_PARAMETERS = QList() - << QMetaObject::normalizedType("QSharedPointer") - << QMetaObject::normalizedType("QSharedPointer"); - - parametersMatch = slotMethod.parameterTypes() == SOURCED_PACKET_LISTENER_PARAMETERS; - - if (!parametersMatch) { - qDebug() << "PacketReceiver::registerPacketListener expected a method that takes" - << SOURCED_PACKET_LISTENER_PARAMETERS - << "but parameter method takes" << slotMethod.parameterTypes(); - } - } - - // make sure the parameters match - assert(parametersMatch); // add the mapping - _packetListenerMap[type] = ObjectMethodPair(QPointer(object), slotMethod); + _packetListenerMap[type] = ObjectMethodPair(QPointer(object), slot); _packetListenerLock.unlock(); + } bool PacketReceiver::packetVersionMatch(const NLPacket& packet) { diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 990d8fc19d..0a8ddba8d9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -52,6 +52,8 @@ signals: private: bool packetVersionMatch(const NLPacket& packet); + + void registerVerifiedListener(PacketType::Value type, QObject* listener, const QMetaMethod& slot); using ObjectMethodPair = std::pair, QMetaMethod>; From 1dccc144e792cec77204c36df7347b81b9838fd8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 10:10:22 -0700 Subject: [PATCH 070/146] fix compile errors after PacketReceiver changes --- libraries/networking/src/PacketReceiver.cpp | 27 ++++++++++++--------- libraries/networking/src/PacketReceiver.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index bfb98ff25e..6511185fa4 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -26,25 +26,25 @@ PacketReceiver::PacketReceiver(QObject* parent) : void PacketReceiver::registerPacketListeners(const QSet& types, QObject* object, const char* slot) { QSet nonSourcedTypes; - QSet sourceTypes; + QSet sourcedTypes; foreach(PacketType::Value type, types) { if (NON_SOURCED_PACKETS.contains(type)) { nonSourcedTypes << type; } else { - sourceTypes << type; + sourcedTypes << type; } } if (nonSourcedTypes.size() > 0) { - QMetaMethod nonSourcedMethod = matchingMethodForListener(nonSourcedTypes[0], object, slot); + QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), object, slot); foreach(PacketType::Value type, nonSourcedTypes) { registerVerifiedListener(type, object, nonSourcedMethod); } } - if (sourceTypes.size() > 0) { - QMetaMethod sourcedMethod = matchingMethodForListener(sourcedTypes[0], object, slot); + if (sourcedTypes.size() > 0) { + QMetaMethod sourcedMethod = matchingMethodForListener(*sourcedTypes.begin(), object, slot); foreach(PacketType::Value type, sourcedTypes) { registerVerifiedListener(type, object, sourcedMethod); } @@ -54,11 +54,11 @@ void PacketReceiver::registerPacketListeners(const QSet& type void PacketReceiver::registerPacketListener(PacketType::Value type, QObject* object, const char* slot) { QMetaMethod matchingMethod = matchingMethodForListener(type, object, slot); if (matchingMethod.isValid()) { - registerVerifiedListener(type, object, slotMethod); + registerVerifiedListener(type, object, matchingMethod); } } -QMetaMethod PacketReciever::matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) { +QMetaMethod PacketReceiver::matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const { Q_ASSERT(object); // normalize the slot with the expected parameters @@ -67,16 +67,19 @@ QMetaMethod PacketReciever::matchingMethodForListener(PacketType::Value type, QO if (NON_SOURCED_PACKETS.contains(type)) { const QString NON_SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer"; + QString nonNormalizedSignature = QString("%1(%2)").arg(slot).arg(NON_SOURCED_PACKET_LISTENER_PARAMETERS); normalizedSlot = - QMetaObject::normalizedSignature(QString("%1(%2)").arg(slot).arg(NON_SOURCED_PACKET_LISTENER_PARAMETERS)); + QMetaObject::normalizedSignature(nonNormalizedSignature.toStdString().c_str()); } else { - const QList SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; - - normalizedSlot = QMetaObject::normalizedSignature(QString("%1(%2)").arg(slot).arg(SOURCED_PACKET_LISTENER_PARAMETERS)); + const QString SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; + + QString nonNormalizedSignature = QString("%1(%2)").arg(slot).arg(SOURCED_PACKET_LISTENER_PARAMETERS); + normalizedSlot = + QMetaObject::normalizedSignature(nonNormalizedSignature.toStdString().c_str()); } // does the constructed normalized method exist? - int methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.data()); + int methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str()); if (methodIndex < 0) { qDebug() << "PacketReceiver::registerPacketListener expected a method with a normalized signature of" diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 0a8ddba8d9..e5b6693fe4 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -53,6 +53,7 @@ signals: private: bool packetVersionMatch(const NLPacket& packet); + QMetaMethod matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const; void registerVerifiedListener(PacketType::Value type, QObject* listener, const QMetaMethod& slot); using ObjectMethodPair = std::pair, QMetaMethod>; From e5d8a39ddea284ce11ca3bd9158490e4fa1f5f97 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 11:11:52 -0700 Subject: [PATCH 071/146] update DomainServer to new packet receive API --- domain-server/src/DomainServer.cpp | 287 +++++++----------- domain-server/src/DomainServer.h | 24 +- domain-server/src/DomainServerNodeData.cpp | 4 +- domain-server/src/DomainServerNodeData.h | 3 +- libraries/networking/src/Assignment.cpp | 13 +- libraries/networking/src/Assignment.h | 7 +- libraries/networking/src/LimitedNodeList.cpp | 3 + libraries/networking/src/LimitedNodeList.h | 1 + libraries/networking/src/NodeList.cpp | 1 - libraries/networking/src/PacketHeaders.cpp | 3 +- .../networking/src/ThreadedAssignment.cpp | 2 +- libraries/networking/src/ThreadedAssignment.h | 2 +- 12 files changed, 149 insertions(+), 201 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5e16949688..d6d6956a12 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -278,7 +278,16 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled); - connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(readAvailableDatagrams())); + // register as the packet receiver for the types we want + PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket"); + packetReceiver.registerPacketListener(PacketType::DomainConnectRequest, this, "processConnectRequestPackets"); + packetReceiver.registerPacketListener(PacketType::DomainListRequest, this, "processListRequestPacket"); + packetReceiver.registerPacketListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket"); + packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket"); + packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); + packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, this, "processICEPeerInformationPacket"); // add whatever static assignments that have been parsed to the queue addStaticAssignmentsToQueue(); @@ -566,17 +575,18 @@ void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSet packet) { NodeType_t nodeType; HifiSockAddr publicSockAddr, localSockAddr; - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); + QDataStream packetStream(packet.data()); QUuid connectUUID; packetStream >> connectUUID; - parseNodeDataFromByteArray(packetStream, nodeType, publicSockAddr, localSockAddr, senderSockAddr); + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); + + parseNodeData(packetStream, nodeType, publicSockAddr, localSockAddr, senderSockAddr); // check if this connect request matches an assignment in the queue bool isAssignment = _pendingAssignedNodes.contains(connectUUID); @@ -715,6 +725,33 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock } } +void DomainServer::processListRequestPacket(QSharedPointer packet) { + QDataStream packetStream(packet.data()); + + const QUuid& nodeUUID = packet->getSourceID(); + + auto limitedNodeList = DependencyManager::get(); + + SharedNodePointer checkInNode = limitedNodeList->nodeWithUUID(nodeUUID); + + if (!nodeUUID.isNull() && checkInNode) { + NodeType_t throwawayNodeType; + HifiSockAddr nodePublicAddress, nodeLocalAddress; + + QDataStream packetStream(packet.data()); + + parseNodeData(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, packet->getSenderSockAddr()); + + checkInNode->setPublicSocket(nodePublicAddress); + checkInNode->setLocalSocket(nodeLocalAddress); + + QList nodeInterestList; + packetStream >> nodeInterestList; + + sendDomainListToNode(checkInNode, packet->getSenderSockAddr(), nodeInterestList.toSet()); + } +} + unsigned int DomainServer::countConnectedUsers() { unsigned int result = 0; auto nodeList = DependencyManager::get(); @@ -902,9 +939,9 @@ QUrl DomainServer::oauthAuthorizationURL(const QUuid& stateUUID) { return authorizationURL; } -int DomainServer::parseNodeDataFromByteArray(QDataStream& packetStream, NodeType_t& nodeType, - HifiSockAddr& publicSockAddr, HifiSockAddr& localSockAddr, - const HifiSockAddr& senderSockAddr) { +int DomainServer::parseNodeData(QDataStream& packetStream, NodeType_t& nodeType, + HifiSockAddr& publicSockAddr, HifiSockAddr& localSockAddr, + const HifiSockAddr& senderSockAddr) { packetStream >> nodeType; packetStream >> publicSockAddr >> localSockAddr; @@ -1037,97 +1074,68 @@ void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) { ); } -void DomainServer::readAvailableDatagrams() { - auto limitedNodeList = DependencyManager::get(); +void DomainServer::processRequestAssignmentPacket(QSharedPointer packet) { + // construct the requested assignment from the packet data + Assignment requestAssignment(*packet); - HifiSockAddr senderSockAddr; - QByteArray receivedPacket; + // Suppress these for Assignment::AgentType to once per 5 seconds + static QElapsedTimer noisyMessageTimer; + static bool wasNoisyTimerStarted = false; - while (limitedNodeList->getNodeSocket().hasPendingDatagrams()) { - receivedPacket.resize(limitedNodeList->getNodeSocket().pendingDatagramSize()); - limitedNodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - if (packetTypeForPacket(receivedPacket) == PacketType::RequestAssignment - && limitedNodeList->packetVersionAndHashMatch(receivedPacket)) { + if (!wasNoisyTimerStarted) { + noisyMessageTimer.start(); + wasNoisyTimerStarted = true; + } - // construct the requested assignment from the packet data - Assignment requestAssignment(receivedPacket); + const qint64 NOISY_MESSAGE_INTERVAL_MSECS = 5 * 1000; - // Suppress these for Assignment::AgentType to once per 5 seconds - static QElapsedTimer noisyMessageTimer; - static bool wasNoisyTimerStarted = false; + if (requestAssignment.getType() != Assignment::AgentType + || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS) { + static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex + ("Received a request for assignment type [^ ]+ from [^ ]+"); + qDebug() << "Received a request for assignment type" << requestAssignment.getType() + << "from" << packet->getSenderSockAddr(); + noisyMessageTimer.restart(); + } - if (!wasNoisyTimerStarted) { - noisyMessageTimer.start(); - wasNoisyTimerStarted = true; - } + SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); - const qint64 NOISY_MESSAGE_INTERVAL_MSECS = 5 * 1000; + if (assignmentToDeploy) { + qDebug() << "Deploying assignment -" << *assignmentToDeploy.data() << "- to" << packet->getSenderSockAddr(); - if (requestAssignment.getType() != Assignment::AgentType - || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS) { - static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex - ("Received a request for assignment type [^ ]+ from [^ ]+"); - qDebug() << "Received a request for assignment type" << requestAssignment.getType() - << "from" << senderSockAddr; - noisyMessageTimer.restart(); - } + // give this assignment out, either the type matches or the requestor said they will take any + static std::unique_ptr assignmentPacket; - SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); + if (!assignmentPacket) { + assignmentPacket = NLPacket::create(PacketType::CreateAssignment); + } - if (assignmentToDeploy) { - qDebug() << "Deploying assignment -" << *assignmentToDeploy.data() << "- to" << senderSockAddr; + // setup a copy of this assignment that will have a unique UUID, for packaging purposes + Assignment uniqueAssignment(*assignmentToDeploy.data()); + uniqueAssignment.setUUID(QUuid::createUuid()); - // give this assignment out, either the type matches or the requestor said they will take any - static std::unique_ptr assignmentPacket; + // reset the assignmentPacket + assignmentPacket->reset(); - if (!assignmentPacket) { - assignmentPacket = NLPacket::create(PacketType::CreateAssignment); - } + QDataStream assignmentStream(assignmentPacket.get()); - // setup a copy of this assignment that will have a unique UUID, for packaging purposes - Assignment uniqueAssignment(*assignmentToDeploy.data()); - uniqueAssignment.setUUID(QUuid::createUuid()); + assignmentStream << uniqueAssignment; - // reset the assignmentPacket - assignmentPacket->reset(); + auto limitedNodeList = DependencyManager::get(); + limitedNodeList->sendUnreliablePacket(*assignmentPacket, packet->getSenderSockAddr()); - QDataStream assignmentStream(assignmentPacket.get()); - - assignmentStream << uniqueAssignment; - - limitedNodeList->sendUnreliablePacket(*assignmentPacket, senderSockAddr); - - // add the information for that deployed assignment to the hash of pending assigned nodes - PendingAssignedNodeData* pendingNodeData = new PendingAssignedNodeData(assignmentToDeploy->getUUID(), - requestAssignment.getWalletUUID()); - _pendingAssignedNodes.insert(uniqueAssignment.getUUID(), pendingNodeData); - } 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 [^ ]+"); - qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() - << "from" << senderSockAddr; - noisyMessageTimer.restart(); - } - } - } else if (!_isUsingDTLS) { - // not using DTLS, process datagram normally - processDatagram(receivedPacket, senderSockAddr); - } else { - // we're using DTLS, so tell the sender to get back to us using DTLS - static std::unique_ptr dtlsRequiredPacket; - - if (!dtlsRequiredPacket) { - dtlsRequiredPacket = NLPacket::create(PacketType::DomainServerRequireDTLS, sizeof(unsigned short)); - - // pack the port that we accept DTLS traffic on - unsigned short dtlsPort = limitedNodeList->getDTLSSocket().localPort(); - dtlsRequiredPacket->writePrimitive(dtlsPort); - } - - limitedNodeList->sendUnreliablePacket(*dtlsRequiredPacket, senderSockAddr); + // add the information for that deployed assignment to the hash of pending assigned nodes + PendingAssignedNodeData* pendingNodeData = new PendingAssignedNodeData(assignmentToDeploy->getUUID(), + requestAssignment.getWalletUUID()); + _pendingAssignedNodes.insert(uniqueAssignment.getUUID(), pendingNodeData); + } 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 [^ ]+"); + qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() + << "from" << packet->getSenderSockAddr(); + noisyMessageTimer.restart(); } } } @@ -1355,11 +1363,10 @@ void DomainServer::handlePeerPingTimeout() { } } -void DomainServer::processICEPeerInformation(const QByteArray& packet) { +void DomainServer::processICEPeerInformationPacket(QSharedPointer packet) { // loop through the packet and pull out network peers // any peer we don't have we add to the hash, otherwise we update - QDataStream iceResponseStream(packet); - iceResponseStream.skipRawData(numBytesForPacketHeader(packet)); + QDataStream iceResponseStream(packet.data()); NetworkPeer* receivedPeer = new NetworkPeer; iceResponseStream >> *receivedPeer; @@ -1384,86 +1391,30 @@ void DomainServer::processICEPeerInformation(const QByteArray& packet) { } } -void DomainServer::processICEPingReply(const QByteArray& packet, const HifiSockAddr& senderSockAddr) { - QUuid nodeUUID = uuidFromPacketHeader(packet); +void DomainServer::processICEPingPacket(QSharedPointer packet) { + auto limitedNodeList = DependencyManager::get(); + auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(packet, limitedNodeList->getSessionUUID()); + + limitedNodeList->sendPacket(std::move(pingReplyPacket), packet->getSenderSockAddr()); +} + +void DomainServer::processICEPingReplyPacket(QSharedPointer packet) { + QDataStream packetStream(packet.data()); + + QUuid nodeUUID; + packetStream >> nodeUUID; + SharedNetworkPeer sendingPeer = _icePeers.value(nodeUUID); if (sendingPeer) { // we had this NetworkPeer in our connecting list - add the right sock addr to our connected list - sendingPeer->activateMatchingOrNewSymmetricSocket(senderSockAddr); + sendingPeer->activateMatchingOrNewSymmetricSocket(packet->getSenderSockAddr()); } } -void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - auto nodeList = DependencyManager::get(); - - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - PacketType::Value requestType = packetTypeForPacket(receivedPacket); - switch (requestType) { - case PacketType::DomainConnectRequest: - handleConnectRequest(receivedPacket, senderSockAddr); - break; - case PacketType::DomainListRequest: { - QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); - - if (!nodeUUID.isNull() && nodeList->nodeWithUUID(nodeUUID)) { - NodeType_t throwawayNodeType; - HifiSockAddr nodePublicAddress, nodeLocalAddress; - - QDataStream packetStream(receivedPacket); - packetStream.skipRawData(numBytesForPacketHeader(receivedPacket)); - - parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, - senderSockAddr); - - SharedNodePointer checkInNode = nodeList->nodeWithUUID(nodeUUID); - checkInNode->setPublicSocket(nodePublicAddress); - checkInNode->setLocalSocket(nodeLocalAddress); - - // update last receive to now - quint64 timeNow = usecTimestampNow(); - checkInNode->setLastHeardMicrostamp(timeNow); - - QList nodeInterestList; - packetStream >> nodeInterestList; - - sendDomainListToNode(checkInNode, senderSockAddr, nodeInterestList.toSet()); - } - - break; - } - case PacketType::DomainServerPathQuery: { - // have our private method attempt to respond to this path query - respondToPathQuery(receivedPacket, senderSockAddr); - break; - } - case PacketType::NodeJsonStats: { - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (matchingNode) { - reinterpret_cast(matchingNode->getLinkedData())->parseJSONStatsPacket(receivedPacket); - } - - break; - } - case PacketType::StunResponse: - nodeList->processSTUNResponse(receivedPacket); - break; - case PacketType::ICEPing: { - auto pingReplyPacket = nodeList->constructPingReplyPacket(receivedPacket); - nodeList->sendPacket(std::move(pingReplyPacket), senderSockAddr); - - break; - } - case PacketType::ICEPingReply: { - processICEPingReply(receivedPacket, senderSockAddr); - break; - } - case PacketType::ICEServerPeerInformation: - processICEPeerInformation(receivedPacket); - break; - default: - break; - } +void DomainServer::processNodeJSONStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + if (sendingNode->getLinkedData()) { + reinterpret_cast(sendingNode->getLinkedData())->processJSONStatsPacket(*packet); } } @@ -2231,19 +2182,17 @@ void DomainServer::addStaticAssignmentsToQueue() { } } -void DomainServer::respondToPathQuery(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { +void DomainServer::processPathQueryPacket(QSharedPointer packet) { // this is a query for the viewpoint resulting from a path // first pull the query path from the packet - int numHeaderBytes = 0; - const char* packetDataStart = receivedPacket.data() + numHeaderBytes; - // figure out how many bytes the sender said this path is - quint16 numPathBytes = *packetDataStart; + quint16 numPathBytes; + packet->readPrimitive(&numPathBytes); - if (numPathBytes <= receivedPacket.size() - numHeaderBytes - sizeof(numPathBytes)) { + if (numPathBytes <= packet->bytesAvailable()) { // the number of path bytes makes sense for the sent packet - pull out the path - QString pathQuery = QString::fromUtf8(packetDataStart + sizeof(numPathBytes), numPathBytes); + QString pathQuery = QString::fromUtf8(packet->getPayload() + packet->pos(), numPathBytes); // our settings contain paths that start with a leading slash, so make sure this query has that if (!pathQuery.startsWith("/")) { @@ -2291,7 +2240,7 @@ void DomainServer::respondToPathQuery(const QByteArray& receivedPacket, const Hi // send off the packet - see if we can associate this outbound data to a particular node // TODO: does this senderSockAddr always work for a punched DS client? - nodeList->sendPacket(std::move(pathResponsePacket), senderSockAddr); + nodeList->sendPacket(std::move(pathResponsePacket), packet->getSenderSockAddr()); } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index b46ccf3884..0c287c4c55 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -55,11 +55,19 @@ public slots: void restart(); + void processRequestAssignmentPacket(QSharedPointer packet); + void processConnectRequestPacket(QSharedPointer packet); + void processListRequestPacket(QSharedPointer packet); + void processNodeJSONStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void processPathQueryPacket(QSharedPointer packet); + void processICEPingPacket(QSharedPointer packet); + void processICEPingReplyPacket(QSharedPointer packet); + void processICEPeerInformationPacket(QSharedPointer packet); + private slots: void aboutToQuit(); void loginFailed(); - void readAvailableDatagrams(); void setupPendingAssignmentCredits(); void sendPendingTransactionsToServer(); @@ -78,14 +86,9 @@ private: void setupAutomaticNetworking(); void sendHeartbeatToDataServer(const QString& networkAddress); - void processICEPingReply(const QByteArray& packet, const HifiSockAddr& senderSockAddr); - void processICEPeerInformation(const QByteArray& packet); void pingPunchForConnectingPeer(const SharedNetworkPeer& peer); - void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); - - void handleConnectRequest(const QByteArray& packet, const HifiSockAddr& senderSockAddr); unsigned int countConnectedUsers(); bool verifyUsersKey (const QString& username, const QByteArray& usernameSignature, QString& reasonReturn); bool shouldAllowConnectionFromNode(const QString& username, const QByteArray& usernameSignature, @@ -94,11 +97,8 @@ private: void preloadAllowedUserPublicKeys(); void requestUserPublicKey(const QString& username); - int parseNodeDataFromByteArray(QDataStream& packetStream, - NodeType_t& nodeType, - HifiSockAddr& publicSockAddr, - HifiSockAddr& localSockAddr, - const HifiSockAddr& senderSockAddr); + int parseNodeData(QDataStream& packetStream, NodeType_t& nodeType, + HifiSockAddr& publicSockAddr, HifiSockAddr& localSockAddr, const HifiSockAddr& senderSockAddr); void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr, const NodeSet& nodeInterestSet); @@ -117,8 +117,6 @@ private: void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment); void addStaticAssignmentsToQueue(); - void respondToPathQuery(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); - QUrl oauthRedirectURL(); QUrl oauthAuthorizationURL(const QUuid& stateUUID = QUuid::createUuid()); diff --git a/domain-server/src/DomainServerNodeData.cpp b/domain-server/src/DomainServerNodeData.cpp index 0d7efa064c..02528cc70e 100644 --- a/domain-server/src/DomainServerNodeData.cpp +++ b/domain-server/src/DomainServerNodeData.cpp @@ -31,8 +31,8 @@ DomainServerNodeData::DomainServerNodeData() : _paymentIntervalTimer.start(); } -void DomainServerNodeData::parseJSONStatsPacket(const QByteArray& statsPacket) { - QVariantMap packetVariantMap = JSONBreakableMarshal::fromStringBuffer(statsPacket.mid(numBytesForPacketHeader(statsPacket))); +void DomainServerNodeData::processJSONStatsPacket(NLPacket& statsPacket) { + QVariantMap packetVariantMap = JSONBreakableMarshal::fromStringBuffer(statsPacket.readAll()); _statsJSONObject = mergeJSONStatsFromNewObject(QJsonObject::fromVariantMap(packetVariantMap), _statsJSONObject); } diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index a91a7e0b9c..d2efced1ef 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -27,7 +28,7 @@ public: const QJsonObject& getStatsJSONObject() const { return _statsJSONObject; } - void parseJSONStatsPacket(const QByteArray& statsPacket); + void processJSONStatsPacket(NLPacket& packet); void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } const QUuid& getAssignmentUUID() const { return _assignmentUUID; } diff --git a/libraries/networking/src/Assignment.cpp b/libraries/networking/src/Assignment.cpp index 3da1fb9a41..bd28361eb7 100644 --- a/libraries/networking/src/Assignment.cpp +++ b/libraries/networking/src/Assignment.cpp @@ -60,28 +60,25 @@ Assignment::Assignment(Assignment::Command command, Assignment::Type type, const } } -Assignment::Assignment(const QByteArray& packet) : +Assignment::Assignment(NLPacket& packet) : _pool(), _location(GlobalLocation), _payload(), _walletUUID() { - PacketType::Value packetType = packetTypeForPacket(packet); - - if (packetType == PacketType::RequestAssignment) { + if (packet.getType() == PacketType::RequestAssignment) { _command = Assignment::RequestCommand; - } else if (packetType == PacketType::CreateAssignment) { + } else if (packet.getType() == PacketType::CreateAssignment) { _command = Assignment::CreateCommand; } - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); + QDataStream packetStream(&packet); packetStream >> *this; } #ifdef WIN32 -#pragma warning(default:4351) +#pragma warning(default:4351) #endif diff --git a/libraries/networking/src/Assignment.h b/libraries/networking/src/Assignment.h index 26b38914ba..a8338a7b5a 100644 --- a/libraries/networking/src/Assignment.h +++ b/libraries/networking/src/Assignment.h @@ -59,10 +59,9 @@ public: void swap(Assignment& otherAssignment); - /// Constructs an Assignment from the data in the buffer - /// \param dataBuffer the source buffer to un-pack the assignment from - /// \param numBytes the number of bytes left to read in the source buffer - Assignment(const QByteArray& packet); + /// Constructs an Assignment from a network packet + /// \param packet the packet to un-pack the assignment from + Assignment(NLPacket& packet); void setUUID(const QUuid& uuid) { _uuid = uuid; } const QUuid& getUUID() const { return _uuid; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 764a9eed7e..47a7a4b99b 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -98,6 +98,9 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short connect(&_nodeSocket, &QUdpSocket::readyRead, &_packetReceiver, &PacketReceiver::processDatagrams); _packetStatTimer.start(); + + // make sure we handle STUN response packets + _packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processSTUNResponse"); } void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index f48f2aaa31..2e0bb5b6b7 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -243,6 +243,7 @@ public slots: virtual void sendSTUNRequest(); void killNodeWithUUID(const QUuid& nodeUUID); + signals: void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID); void nodeAdded(SharedNodePointer); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 8d897e82b5..1daf8a1c02 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -101,7 +101,6 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned packetReceiver.registerPacketListener(PacketType::PingReply, this, "processPingReplyPacket"); packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket"); packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); - packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processSTUNResponse"); } qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index f6001711c0..6fdd421ea0 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -21,6 +21,7 @@ const QSet NON_VERIFIED_PACKETS = QSet() << CreateAssignment << RequestAssignment << StunResponse << NodeJsonStats << EntityQuery << OctreeDataNack << EntityEditNack + << DomainListRequest << Ping << PingReply << StopNode; @@ -28,7 +29,7 @@ const QSet SEQUENCE_NUMBERED_PACKETS = QSet NON_SOURCED_PACKETS = QSet() << DomainServerRequireDTLS << DomainConnectRequest - << DomainList << DomainListRequest << DomainConnectionDenied + << DomainList << DomainConnectionDenied << DomainServerPathQuery << DomainServerPathResponse << DomainServerAddedNode << ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 2406df4602..b1c4bdbc7f 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -18,7 +18,7 @@ #include "ThreadedAssignment.h" -ThreadedAssignment::ThreadedAssignment(const QByteArray& packet) : +ThreadedAssignment::ThreadedAssignment(NLPacket& packet) : Assignment(packet), _isFinished(false), _datagramProcessingThread(NULL) diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index daca2cfe00..c4c6127b7b 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -19,7 +19,7 @@ class ThreadedAssignment : public Assignment { Q_OBJECT public: - ThreadedAssignment(const QByteArray& packet); + ThreadedAssignment(NLPacket& packet); ~ThreadedAssignment() { stop(); } void setFinished(bool isFinished); From f3d5b8f7c6c47117883afae4e0ccf3dc9a7662e3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 11:18:20 -0700 Subject: [PATCH 072/146] add a missing semicolon --- interface/src/octree/OctreePacketProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 0595bfbbc2..7574f88753 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -22,7 +22,7 @@ OctreePacketProcessor::OctreePacketProcessor() { QSet types { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::OctreeStats, PacketType::EnvironmentData - } + }; packetReceiver.registerPacketListeners(types, this, "handleOctreePacket"); } From cdbcaf0f7f4668f2b54c2e676166825211f2c83d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 12:06:12 -0700 Subject: [PATCH 073/146] Fix AudioMixer compilation errors --- assignment-client/src/Agent.cpp | 47 ++++------------------ assignment-client/src/Agent.h | 1 - assignment-client/src/audio/AudioMixer.cpp | 14 +++---- 3 files changed, 13 insertions(+), 49 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 6166923832..0037f989ef 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -65,7 +65,7 @@ void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointe if (packetType == PacketType::OctreeStats) { - int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(mutablePacket, senderNode); + int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(packet, senderNode); if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); } else { @@ -80,49 +80,16 @@ void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointe } } -void Agent::readPendingDatagrams() { - QByteArray receivedPacket; - HifiSockAddr senderSockAddr; - auto nodeList = DependencyManager::get(); - - while (readAvailableDatagram(receivedPacket, senderSockAddr)) { - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - PacketType::Value datagramPacketType = packetTypeForPacket(receivedPacket); - - if (datagramPacketType == PacketType::Jurisdiction) { - int headerBytes = numBytesForPacketHeader(receivedPacket); - - SharedNodePointer matchedNode = nodeList->sendingNodeForPacket(receivedPacket); - - if (matchedNode) { - // PacketType_JURISDICTION, first byte is the node type... - switch (receivedPacket[headerBytes]) { - case NodeType::EntityServer: - DependencyManager::get()->getJurisdictionListener()-> - queueReceivedPacket(matchedNode, receivedPacket); - break; - } - } - } - } - } -} - void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { QByteArray receivedPacket = QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()); int headerBytes = numBytesForPacketHeader(receivedPacket); - auto nodeList = DependencyManager::get(); - SharedNodePointer matchedNode = nodeList->sendingNodeForPacket(receivedPacket); - - if (matchedNode) { - // PacketType_JURISDICTION, first byte is the node type... - switch (receivedPacket[headerBytes]) { - case NodeType::EntityServer: - DependencyManager::get()->getJurisdictionListener()-> - queueReceivedPacket(senderNode, receivedPacket); - break; - } + // PacketType_JURISDICTION, first byte is the node type... + switch (receivedPacket[headerBytes]) { + case NodeType::EntityServer: + DependencyManager::get()->getJurisdictionListener()-> + queueReceivedPacket(packet, senderNode); + break; } } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 70e1913b54..3e202f2d0d 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -52,7 +52,6 @@ public: public slots: void run(); - void readPendingDatagrams(); void playAvatarSound(Sound* avatarSound) { _scriptEngine.setAvatarSound(avatarSound); } private slots: diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index dc790e99f4..d8c01dafcd 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -545,34 +545,32 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { auto nodeList = DependencyManager::get(); - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - nodeList->processNodeData(senderSockAddr, receivedPacket); - } + nodeList->processNodeData(senderSockAddr, receivedPacket); } void AudioMixer::handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); } void AudioMixer::handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); } void AudioMixer::handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); } void AudioMixer::handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); } void AudioMixer::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet->getData()); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); } void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { From 9a977149a4652a425fb8e016f26192646212c6c2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 12:06:32 -0700 Subject: [PATCH 074/146] Update AvatarMixer to use packetReceiver --- assignment-client/src/avatars/AvatarMixer.cpp | 88 ++++++++----------- assignment-client/src/avatars/AvatarMixer.h | 8 +- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 0d4e5b5934..3559793ff5 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -46,6 +46,12 @@ AvatarMixer::AvatarMixer(const QByteArray& packet) : { // make sure we hear about node kills so we can tell the other nodes connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled); + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(PacketType::AvatarData, this, "handleAvatarDataPacket"); + packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); + packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, "handleAvatarBillboardPacket"); + packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); } AvatarMixer::~AvatarMixer() { @@ -394,65 +400,43 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) { } } -void AvatarMixer::readPendingDatagrams() { - QByteArray receivedPacket; - HifiSockAddr senderSockAddr; - +void AvatarMixer::handleAvatarDataPacket(QSharedPointer packet, SharedNodePointer senderNode) { auto nodeList = DependencyManager::get(); + nodeList->findNodeAndUpdateWithDataFromPacket(packet); +} - while (readAvailableDatagram(receivedPacket, senderSockAddr)) { - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - switch (packetTypeForPacket(receivedPacket)) { - case PacketType::AvatarData: { - nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); - break; - } - case PacketType::AvatarIdentity: { - // check if we have a matching node in our list - SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(receivedPacket); +void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer senderNode) { + if (senderNode->getLinkedData()) { + AvatarMixerClientData* nodeData = reinterpret_cast(senderNode->getLinkedData()); + AvatarData& avatar = nodeData->getAvatar(); - if (avatarNode && avatarNode->getLinkedData()) { - AvatarMixerClientData* nodeData = reinterpret_cast(avatarNode->getLinkedData()); - AvatarData& avatar = nodeData->getAvatar(); - - // parse the identity packet and update the change timestamp if appropriate - if (avatar.hasIdentityChangedAfterParsing(receivedPacket)) { - QMutexLocker nodeDataLocker(&nodeData->getMutex()); - nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); - } - } - break; - } - case PacketType::AvatarBillboard: { - // check if we have a matching node in our list - SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(receivedPacket); - - if (avatarNode && avatarNode->getLinkedData()) { - AvatarMixerClientData* nodeData = static_cast(avatarNode->getLinkedData()); - AvatarData& avatar = nodeData->getAvatar(); - - // parse the billboard packet and update the change timestamp if appropriate - if (avatar.hasBillboardChangedAfterParsing(receivedPacket)) { - QMutexLocker nodeDataLocker(&nodeData->getMutex()); - nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); - } - - } - break; - } - case PacketType::KillAvatar: { - nodeList->processKillNode(receivedPacket); - break; - } - default: - // hand this off to the NodeList - nodeList->processNodeData(senderSockAddr, receivedPacket); - break; - } + // parse the identity packet and update the change timestamp if appropriate + if (avatar.hasIdentityChangedAfterParsing(*packet)) { + QMutexLocker nodeDataLocker(&nodeData->getMutex()); + nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); } } } +void AvatarMixer::handleAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer senderNode) { + if (senderNode->getLinkedData()) { + AvatarMixerClientData* nodeData = static_cast(senderNode->getLinkedData()); + AvatarData& avatar = nodeData->getAvatar(); + + // parse the billboard packet and update the change timestamp if appropriate + if (avatar.hasBillboardChangedAfterParsing(*packet)) { + QMutexLocker nodeDataLocker(&nodeData->getMutex()); + nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); + } + + } +} + +void AvatarMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer senderNode) { + auto nodeList = DependencyManager::get(); + nodeList->processKillNode(*packet); +} + void AvatarMixer::sendStatsPacket() { QJsonObject statsObject; statsObject["average_listeners_last_second"] = (float) _sumListeners / (float) _numStatFrames; diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 7505c4324e..90473f754f 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -29,9 +29,13 @@ public slots: void nodeAdded(SharedNodePointer nodeAdded); void nodeKilled(SharedNodePointer killedNode); - void readPendingDatagrams(); - void sendStatsPacket(); + +private slots: + void handleAvatarDataPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer senderNode); private: void broadcastAvatarData(); From 591c5d4b6084607f1b8218d14edcbae0077e5c4e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 12:06:43 -0700 Subject: [PATCH 075/146] Fix EntityServer compilation errors --- assignment-client/src/entities/EntityServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index b7e6fe3a29..bdd619ccf1 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -42,19 +42,19 @@ EntityServer::~EntityServer() { void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } } void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } } void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(senderNode, packet->getData()); + _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } } From 6a7cd7417c8aa3eb37346e42aa28308c78a24f1c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 12:07:01 -0700 Subject: [PATCH 076/146] Update AvatarData packet processing to work with NLPacket --- libraries/avatars/src/AvatarData.cpp | 9 ++++----- libraries/avatars/src/AvatarData.h | 5 +++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 5ea3b4c669..1afb92ef9a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -867,9 +867,8 @@ void AvatarData::clearJointsData() { } } -bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); +bool AvatarData::hasIdentityChangedAfterParsing(NLPacket& packet) { + QDataStream packetStream(&packet); QUuid avatarUUID; QUrl faceModelURL, skeletonModelURL; @@ -911,8 +910,8 @@ QByteArray AvatarData::identityByteArray() { return identityData; } -bool AvatarData::hasBillboardChangedAfterParsing(const QByteArray& packet) { - QByteArray newBillboard = packet.mid(numBytesForPacketHeader(packet)); +bool AvatarData::hasBillboardChangedAfterParsing(NLPacket& packet) { + QByteArray newBillboard = QByteArray(packet.getPayload()); if (newBillboard == _billboard) { return false; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c482f52bf1..c826fd9f0e 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -47,6 +47,7 @@ typedef unsigned long long quint64; #include #include +#include #include #include #include @@ -260,10 +261,10 @@ public: return false; } - bool hasIdentityChangedAfterParsing(const QByteArray& packet); + bool hasIdentityChangedAfterParsing(NLPacket& packet); QByteArray identityByteArray(); - bool hasBillboardChangedAfterParsing(const QByteArray& packet); + bool hasBillboardChangedAfterParsing(NLPacket& packet); const QUrl& getFaceModelURL() const { return _faceModelURL; } QString getFaceModelURLString() const { return _faceModelURL.toString(); } From 2efa2877dacce6ecccb98a9fadfe75956200ea9c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 12:07:21 -0700 Subject: [PATCH 077/146] Update LimitedNodeList::processKillNode to work with NLPacket --- libraries/networking/src/LimitedNodeList.cpp | 4 ++++ libraries/networking/src/LimitedNodeList.h | 1 + 2 files changed, 5 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 764a9eed7e..20b62a490e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -308,6 +308,10 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { } } +void LimitedNodeList::processKillNode(NLPacket& packet) { + processKillNode(QByteArray::fromRawData(packet.getData(), packet.getSizeWithHeader())); +} + void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { // read the node id QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID)); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index f48f2aaa31..770da8f876 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -157,6 +157,7 @@ public: const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } + void processKillNode(NLPacket& packet); void processKillNode(const QByteArray& datagram); int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet); From d990420565c898ba243a4e9cea3668cd1e92b7d8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 13:10:57 -0700 Subject: [PATCH 078/146] repairs to octree packet receiving in interface --- interface/src/Application.cpp | 12 +-- interface/src/Application.h | 4 +- .../src/octree/OctreePacketProcessor.cpp | 53 +++++++------ .../src/EntityTreeRenderer.cpp | 50 ++++++------ .../src/EntityTreeRenderer.h | 8 +- .../entities/src/EntityItemProperties.cpp | 11 ++- libraries/entities/src/EntityItemProperties.h | 4 +- libraries/entities/src/EntityTree.cpp | 61 +++++---------- libraries/entities/src/EntityTree.h | 12 +-- .../entities/src/EntityTreeHeadlessViewer.cpp | 4 +- .../entities/src/EntityTreeHeadlessViewer.h | 2 +- libraries/octree/src/Octree.h | 20 ++--- libraries/octree/src/OctreeRenderer.cpp | 76 +++++++++---------- libraries/octree/src/OctreeRenderer.h | 2 +- libraries/octree/src/OctreeSceneStats.cpp | 23 +++--- libraries/octree/src/OctreeSceneStats.h | 2 +- libraries/render-utils/src/Environment.cpp | 44 ++++------- libraries/render-utils/src/Environment.h | 9 +-- 18 files changed, 179 insertions(+), 218 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dfae996e49..80a4e7bcca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3910,12 +3910,12 @@ void Application::nodeKilled(SharedNodePointer node) { DependencyManager::get()->clearOtherAvatars(); } } - -void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) { + +void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) { // Attempt to identify the sender from its address. if (sendingNode) { - QUuid nodeUUID = sendingNode->getUUID(); + const QUuid& nodeUUID = sendingNode->getUUID(); // now that we know the node ID, let's add these stats to the stats for that node... _octreeSceneStatsLock.lockForWrite(); @@ -3927,7 +3927,7 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar } } -int Application::processOctreeStats(QSharedPointer packet, SharedNodePointer sendingNode) { +int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) { // But, also identify the sender, and keep track of the contained jurisdiction root for this server // parse the incoming stats datas stick it in a temporary object for now, while we @@ -3941,10 +3941,10 @@ int Application::processOctreeStats(QSharedPointer packet, SharedNodeP _octreeSceneStatsLock.lockForWrite(); if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { octreeStats = &_octreeServerSceneStats[nodeUUID]; - statsMessageLength = octreeStats->unpackFromPacket(*packet); + statsMessageLength = octreeStats->unpackFromPacket(packet); } else { OctreeSceneStats temp; - statsMessageLength = temp.unpackFromPacket(*packet); + statsMessageLength = temp.unpackFromPacket(packet); octreeStats = &temp; } _octreeSceneStatsLock.unlock(); diff --git a/interface/src/Application.h b/interface/src/Application.h index dd27080952..1326ac5180 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -612,8 +612,8 @@ private: StDev _idleLoopStdev; float _idleLoopMeasuredJitter; - int processOctreeStats(QSharedPointer packet, SharedNodePointer sendingNode); - void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket); + int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode); + void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket); NodeToJurisdictionMap _entityServerJurisdictions; NodeToOctreeSceneStats _octreeServerSceneStats; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 7574f88753..b9a111aa3f 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -28,7 +28,7 @@ OctreePacketProcessor::OctreePacketProcessor() { } void OctreePacketProcessor::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { - queueReceivedPacket(senderNode, packet); + queueReceivedPacket(packet, senderNode); } void OctreePacketProcessor::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { @@ -41,8 +41,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } - int messageLength = packet->getSizeUsed(); - Application* app = Application::getInstance(); bool wasStatsPacket = false; @@ -52,60 +50,61 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // then process any remaining bytes as if it was another packet if (octreePacketType == PacketType::OctreeStats) { - int statsMessageLength = app->processOctreeStats(packet, sendingNode); - wasStatsPacket = true; - if (messageLength > statsMessageLength) { - mutablePacket = mutablePacket.mid(statsMessageLength); + int statsMessageLength = app->processOctreeStats(*packet, sendingNode); - // TODO: this does not look correct, the goal is to test the packet version for the piggyback, but - // this is testing the version and hash of the original packet - if (!DependencyManager::get()->packetVersionAndHashMatch(packet)) { - return; // bail since piggyback data doesn't match our versioning - } + wasStatsPacket = true; + int piggybackBytes = packet->getSizeUsed() - statsMessageLength; + + if (piggybackBytes) { + // construct a new packet from the piggybacked one + std::unique_ptr buffer = std::unique_ptr(new char[piggybackBytes]); + memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggybackBytes); + + auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, packet->getSenderSockAddr()); + packet = QSharedPointer(newPacket.release()); } else { // Note... stats packets don't have sequence numbers, so we don't want to send those to trackIncomingVoxelPacket() return; // bail since no piggyback data } } // fall through to piggyback message - voxelPacketType = packetTypeForPacket(mutablePacket); - PacketVersion packetVersion = mutablePacket[1]; - PacketVersion expectedVersion = versionForPacketType(voxelPacketType); + PacketType::Value packetType = packet->getType(); // check version of piggyback packet against expected version - if (packetVersion != expectedVersion) { + if (packetType != versionForPacketType(packet->getType())) { static QMultiMap versionDebugSuppressMap; - QUuid senderUUID = uuidFromPacketHeader(packet); - if (!versionDebugSuppressMap.contains(senderUUID, voxelPacketType)) { - qDebug() << "Packet version mismatch on" << voxelPacketType << "- Sender" - << senderUUID << "sent" << (int)packetVersion << "but" - << (int)expectedVersion << "expected."; + const QUuid& senderUUID = packet->getSourceID(); + if (!versionDebugSuppressMap.contains(senderUUID, packet->getType())) { + + qDebug() << "Packet version mismatch on" << packetType << "- Sender" + << senderUUID << "sent" << (int) packetType << "but" + << (int) versionForPacketType(packetType) << "expected."; emit packetVersionMismatch(); - versionDebugSuppressMap.insert(senderUUID, voxelPacketType); + versionDebugSuppressMap.insert(senderUUID, packetType); } return; // bail since piggyback version doesn't match } - app->trackIncomingOctreePacket(mutablePacket, sendingNode, wasStatsPacket); + app->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket); - switch(voxelPacketType) { + switch(packetType) { case PacketType::EntityErase: { if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processEraseMessage(mutablePacket, sendingNode); + app->_entities.processEraseMessage(*packet, sendingNode); } } break; case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processDatagram(mutablePacket, sendingNode); + app->_entities.processDatagram(*packet, sendingNode); } } break; case PacketType::EnvironmentData: { - app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); + app->_environment.processPacket(*packet); } break; default: { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 11d24c6d9d..650eb97e21 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -45,7 +45,7 @@ #include "EntitiesRendererLogging.h" #include "AddressManager.h" -EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState, +EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState, AbstractScriptingServicesInterface* scriptingServices) : OctreeRenderer(), _wantScripts(wantScripts), @@ -75,13 +75,13 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf } EntityTreeRenderer::~EntityTreeRenderer() { - // NOTE: we don't need to delete _entitiesScriptEngine because it is registered with the application and has a + // NOTE: we don't need to delete _entitiesScriptEngine because it is registered with the application and has a // signal tied to call it's deleteLater on doneRunning if (_sandboxScriptEngine) { // TODO: consider reworking how _sandboxScriptEngine is managed. It's treated differently than _entitiesScriptEngine - // because we don't call registerScriptEngineWithApplicationServices() for it. This implementation is confusing and - // potentially error prone because it's not a full fledged ScriptEngine that has been fully connected to the - // application. We did this so that scripts that were ill-formed could be evaluated but not execute against the + // because we don't call registerScriptEngineWithApplicationServices() for it. This implementation is confusing and + // potentially error prone because it's not a full fledged ScriptEngine that has been fully connected to the + // application. We did this so that scripts that were ill-formed could be evaluated but not execute against the // application services. But this means it's shutdown behavior is different from other ScriptEngines delete _sandboxScriptEngine; _sandboxScriptEngine = NULL; @@ -119,7 +119,7 @@ void EntityTreeRenderer::init() { } // make sure our "last avatar position" is something other than our current position, so that on our - // first chance, we'll check for enter/leave entity events. + // first chance, we'll check for enter/leave entity events. _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity, Qt::QueuedConnection); @@ -138,7 +138,7 @@ void EntityTreeRenderer::scriptContentsAvailable(const QUrl& url, const QString& _waitingOnPreload.remove(url); foreach(EntityItemID entityID, entityIDs) { checkAndCallPreload(entityID); - } + } } } @@ -154,7 +154,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItem } -QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& urlOut, +QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& urlOut, bool& reload) { isPending = false; QUrl url(scriptMaybeURLorText); @@ -353,7 +353,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { // Note: at this point we don't need to worry about the tree being locked, because we only deal with // EntityItemIDs from here. The loadEntityScript() method is robust against attempting to load scripts - // for entity IDs that no longer exist. + // for entity IDs that no longer exist. // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { @@ -400,7 +400,7 @@ void EntityTreeRenderer::leaveAllEntities() { _currentEntitiesInside.clear(); // make sure our "last avatar position" is something other than our current position, so that on our - // first chance, we'll check for enter/leave entity events. + // first chance, we'll check for enter/leave entity events. _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); } } @@ -513,7 +513,7 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer en const FBXGeometry* result = NULL; if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = + std::shared_ptr modelEntityItem = std::dynamic_pointer_cast(entityItem); assert(modelEntityItem); // we need this!!! Model* model = modelEntityItem->getModel(this); @@ -527,7 +527,7 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer en const Model* EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityItem) { const Model* result = NULL; if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = + std::shared_ptr modelEntityItem = std::dynamic_pointer_cast(entityItem); result = modelEntityItem->getModel(this); } @@ -538,7 +538,7 @@ const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemP const FBXGeometry* result = NULL; if (entityItem->getType() == EntityTypes::Model) { - std::shared_ptr modelEntityItem = + std::shared_ptr modelEntityItem = std::dynamic_pointer_cast(entityItem); if (modelEntityItem->hasCompoundShapeURL()) { Model* model = modelEntityItem->getModel(this); @@ -678,20 +678,20 @@ float EntityTreeRenderer::getSizeScale() const { return _viewState->getSizeScale(); } -int EntityTreeRenderer::getBoundaryLevelAdjust() const { +int EntityTreeRenderer::getBoundaryLevelAdjust() const { return _viewState->getBoundaryLevelAdjust(); } -void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { - static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); +void EntityTreeRenderer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) { + static_cast(_tree)->processEraseMessage(packet, sourceNode); } Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) { Model* model = NULL; // Make sure we only create and delete models on the thread that owns the EntityTreeRenderer if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "allocateModel", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(this, "allocateModel", Qt::BlockingQueuedConnection, Q_RETURN_ARG(Model*, model), Q_ARG(const QString&, url)); @@ -715,7 +715,7 @@ Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl, c // Before we do any creating or deleting, make sure we're on our renderer thread if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "updateModel", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(this, "updateModel", Qt::BlockingQueuedConnection, Q_RETURN_ARG(Model*, model), Q_ARG(Model*, original), Q_ARG(const QString&, newUrl)); @@ -756,7 +756,7 @@ void EntityTreeRenderer::deleteReleasedModels() { } } -RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, +RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, bool precisionPicking) { RayToEntityIntersectionResult result; if (_tree) { @@ -764,8 +764,8 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons OctreeElement* element; EntityItemPointer intersectedEntity = NULL; - result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face, - (void**)&intersectedEntity, lockType, &result.accurate, + result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face, + (void**)&intersectedEntity, lockType, &result.accurate, precisionPicking); if (result.intersects && intersectedEntity) { result.entityID = intersectedEntity->getEntityItemID(); @@ -778,15 +778,15 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons } void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) { - connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, + connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId){ entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); }); - connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, + connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) { entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); }); - connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, + connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) { entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event, deviceId)); }); @@ -966,7 +966,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI } else { // handle the hover logic... - // if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to + // if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to // send the hover leave for our previous entity if (!_currentHoverOverEntityID.isInvalidID()) { emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event, deviceID)); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 84aa3fa8cb..39f088f06d 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -38,7 +38,7 @@ public: class EntityTreeRenderer : public OctreeRenderer, public EntityItemFBXService, public ScriptUser { Q_OBJECT public: - EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState, + EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState, AbstractScriptingServicesInterface* scriptingServices); virtual ~EntityTreeRenderer(); @@ -55,7 +55,7 @@ public: EntityTree* getTree() { return static_cast(_tree); } - void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); + void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode); virtual void init(); virtual void render(RenderArgs* renderArgs) override; @@ -71,7 +71,7 @@ public: Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl); /// if a renderable entity item needs to update the URL of a model, we will handle that for the entity - Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl, const QString& collisionUrl); + Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl, const QString& collisionUrl); /// if a renderable entity item is done with a model, it should return it to us void releaseModel(Model* model); @@ -136,7 +136,7 @@ private: QList _releasedModels; void renderProxies(EntityItemPointer entity, RenderArgs* args); - RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, + RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, bool precisionPicking); EntityItemID _currentHoverOverEntityID; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8d96e0a60a..a6df04e31e 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -128,8 +128,8 @@ void EntityItemProperties::setSittingPoints(const QVector& sitting } } -bool EntityItemProperties::animationSettingsChanged() const { - return _animationSettingsChanged; +bool EntityItemProperties::animationSettingsChanged() const { + return _animationSettingsChanged; } void EntityItemProperties::setAnimationSettings(const QString& value) { @@ -900,11 +900,14 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent // // TODO: Implement support for script and visible properties. // -bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes, +bool EntityItemProperties::decodeEntityEditPacket(NLPacket& packet, int& processedBytes, EntityItemID& entityID, EntityItemProperties& properties) { bool valid = false; - + + const unsigned char* data = reinterpret_cast(packet.getPayload()); const unsigned char* dataAt = data; + + int bytesToRead = packet.getSizeUsed(); processedBytes = 0; // the first part of the data is an octcode, this is a required element of the edit packet format, but we don't diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 34c15043c0..f9a4d499d2 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -179,8 +179,8 @@ public: static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer); - static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes, - EntityItemID& entityID, EntityItemProperties& properties); + static bool decodeEntityEditPacket(NLPacket& packet, int& processedBytes, + EntityItemID& entityID, EntityItemProperties& properties); bool glowLevelChanged() const { return _glowLevelChanged; } bool localRenderAlphaChanged() const { return _localRenderAlphaChanged; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a98b529e07..a5c5d58936 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -26,7 +26,7 @@ #include "LogHandler.h" -EntityTree::EntityTree(bool shouldReaverage) : +EntityTree::EntityTree(bool shouldReaverage) : Octree(shouldReaverage), _fbxService(NULL), _simulation(NULL) @@ -568,8 +568,8 @@ EntityItemPointer EntityTree::findEntityByEntityItemID(const EntityItemID& entit return foundEntity; } -int EntityTree::processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, - const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { +int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, + const SharedNodePointer& senderNode) { if (!getIsServer()) { qCDebug(entities) << "UNEXPECTED!!! processEditPacketData() should only be called on a server tree."; @@ -578,9 +578,9 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign int processedBytes = 0; // we handle these types of "edit" packets - switch (packetType) { + switch (packet.getType()) { case PacketType::EntityErase: { - QByteArray dataByteArray((const char*)editData, maxLength); + QByteArray dataByteArray = QByteArray::fromRawData(reinterpret_cast(editData), maxLength); processedBytes = processEraseMessageDetails(dataByteArray, senderNode); break; } @@ -598,8 +598,8 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign EntityItemID entityItemID; EntityItemProperties properties; startDecode = usecTimestampNow(); - bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, - processedBytes, entityItemID, properties); + bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(packet, processedBytes, + entityItemID, properties); endDecode = usecTimestampNow(); // If we got a valid edit packet, then it could be a new entity or it could be an update to @@ -609,7 +609,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign startLookup = usecTimestampNow(); EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID); endLookup = usecTimestampNow(); - if (existingEntity && packetType == PacketType::EntityEdit) { + if (existingEntity && packet.getType() == PacketType::EntityEdit) { // if the EntityItem exists, then update it startLogging = usecTimestampNow(); if (wantEditLogging()) { @@ -623,7 +623,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign existingEntity->markAsChangedOnServer(); endUpdate = usecTimestampNow(); _totalUpdates++; - } else if (packetType == PacketType::EntityAdd) { + } else if (packet.getType() == PacketType::EntityAdd) { if (senderNode->getCanRez()) { // this is a new entity... assign a new entityID properties.setCreated(properties.getLastEdited()); @@ -651,7 +651,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign } else { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("^Add or Edit failed.*"); - qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get(); + qCDebug(entities) << "Add or Edit failed." << packet.getType() << existingEntity.get(); } } @@ -854,45 +854,26 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) { // TODO: consider consolidating processEraseMessageDetails() and processEraseMessage() -int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { +int EntityTree::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) { lockForWrite(); - const unsigned char* packetData = (const unsigned char*)dataByteArray.constData(); - const unsigned char* dataAt = packetData; - size_t packetLength = dataByteArray.size(); - size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); - size_t processedBytes = numBytesPacketHeader; - dataAt += numBytesPacketHeader; + packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME)); - dataAt += sizeof(OCTREE_PACKET_FLAGS); - processedBytes += sizeof(OCTREE_PACKET_FLAGS); - - dataAt += sizeof(OCTREE_PACKET_SEQUENCE); - processedBytes += sizeof(OCTREE_PACKET_SEQUENCE); - - dataAt += sizeof(OCTREE_PACKET_SENT_TIME); - processedBytes += sizeof(OCTREE_PACKET_SENT_TIME); - - uint16_t numberOfIds = 0; // placeholder for now - memcpy(&numberOfIds, dataAt, sizeof(numberOfIds)); - dataAt += sizeof(numberOfIds); - processedBytes += sizeof(numberOfIds); - - if (numberOfIds > 0) { + uint16_t numberOfIDs = 0; // placeholder for now + packet.readPrimitive(&numberOfIDs); + + if (numberOfIDs > 0) { QSet entityItemIDsToDelete; - for (size_t i = 0; i < numberOfIds; i++) { + for (size_t i = 0; i < numberOfIDs; i++) { - if (processedBytes + NUM_BYTES_RFC4122_UUID > packetLength) { + if (NUM_BYTES_RFC4122_UUID > packet.bytesAvailable()) { qCDebug(entities) << "EntityTree::processEraseMessage().... bailing because not enough bytes in buffer"; break; // bail to prevent buffer overflow } - QByteArray encodedID = dataByteArray.mid(processedBytes, NUM_BYTES_RFC4122_UUID); - QUuid entityID = QUuid::fromRfc4122(encodedID); - dataAt += encodedID.size(); - processedBytes += encodedID.size(); - + QUuid entityID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); + EntityItemID entityItemID(entityID); entityItemIDsToDelete << entityItemID; @@ -904,7 +885,7 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share deleteEntities(entityItemIDsToDelete, true, true); } unlock(); - return processedBytes; + return packet.pos(); } // This version skips over the header diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 27ae47c265..4ade0afc6d 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -66,8 +66,8 @@ public: virtual bool canProcessVersion(PacketVersion thisVersion) const { return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; } virtual bool handlesEditPacketType(PacketType::Value packetType) const; - virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, - const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode); + virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, + const SharedNodePointer& senderNode); virtual bool rootElementHasData() const { return true; } @@ -133,8 +133,8 @@ public: bool& hasMore); void forgetEntitiesDeletedBefore(quint64 sinceTime); - int processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); - int processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); + int processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode); + int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode); EntityItemFBXService* getFBXService() const { return _fbxService; } void setFBXService(EntityItemFBXService* service) { _fbxService = service; } @@ -186,9 +186,9 @@ public: virtual quint64 getAverageLoggingTime() const { return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; } void trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytesRead); - quint64 getAverageEditDeltas() const + quint64 getAverageEditDeltas() const { return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; } - quint64 getAverageEditBytes() const + quint64 getAverageEditBytes() const { return _totalTrackedEdits == 0 ? 0 : _totalEditBytes / _totalTrackedEdits; } quint64 getMaxEditDelta() const { return _maxEditDelta; } quint64 getTotalTrackedEdits() const { return _totalTrackedEdits; } diff --git a/libraries/entities/src/EntityTreeHeadlessViewer.cpp b/libraries/entities/src/EntityTreeHeadlessViewer.cpp index 45d21c0987..80c0a7fa7f 100644 --- a/libraries/entities/src/EntityTreeHeadlessViewer.cpp +++ b/libraries/entities/src/EntityTreeHeadlessViewer.cpp @@ -40,6 +40,6 @@ void EntityTreeHeadlessViewer::update() { } } -void EntityTreeHeadlessViewer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { - static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); +void EntityTreeHeadlessViewer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) { + static_cast(_tree)->processEraseMessage(packet, sourceNode); } diff --git a/libraries/entities/src/EntityTreeHeadlessViewer.h b/libraries/entities/src/EntityTreeHeadlessViewer.h index fedbc74430..9c2efc06ab 100644 --- a/libraries/entities/src/EntityTreeHeadlessViewer.h +++ b/libraries/entities/src/EntityTreeHeadlessViewer.h @@ -38,7 +38,7 @@ public: EntityTree* getTree() { return (EntityTree*)_tree; } - void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); + void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode); virtual void init(); diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 846784559f..a3f9bbbac4 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -229,12 +229,12 @@ public: // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const { return false; } virtual PacketType::Value expectedDataPacketType() const { return PacketType::Unknown; } - virtual bool canProcessVersion(PacketVersion thisVersion) const { + virtual bool canProcessVersion(PacketVersion thisVersion) const { return thisVersion == versionForPacketType(expectedDataPacketType()); } virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); } virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; } - virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, - const unsigned char* editData, int maxLength, const SharedNodePointer& sourceNode) { return 0; } + virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, + const SharedNodePointer& sourceNode) { return 0; } virtual bool recurseChildrenWithData() const { return true; } virtual bool rootElementHasData() const { return false; } @@ -304,16 +304,16 @@ public: } lockType; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - OctreeElement*& node, float& distance, BoxFace& face, + OctreeElement*& node, float& distance, BoxFace& face, void** intersectedObject = NULL, - Octree::lockType lockType = Octree::TryLock, - bool* accurateResult = NULL, + Octree::lockType lockType = Octree::TryLock, + bool* accurateResult = NULL, bool precisionPicking = false); - bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL, + bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL); - bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration, + bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL); /// \param cube query cube in world-frame (meters) @@ -323,7 +323,7 @@ public: /// \param point query point in world-frame (meters) /// \param lockType how to lock the tree (Lock, TryLock, NoLock) /// \param[out] accurateResult pointer to output result, will be set "true" or "false" if non-null - OctreeElement* getElementEnclosingPoint(const glm::vec3& point, + OctreeElement* getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL); // Note: this assumes the fileFormat is the HIO individual voxels code files @@ -411,7 +411,7 @@ protected: QReadWriteLock _lock; - bool _isViewing; + bool _isViewing; bool _isServer; }; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 16d2f4285a..17ed302a9a 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -40,15 +40,15 @@ OctreeRenderer::~OctreeRenderer() { } } -void OctreeRenderer::setTree(Octree* newTree) { +void OctreeRenderer::setTree(Octree* newTree) { if (_tree && _managedTree) { delete _tree; _managedTree = false; } - _tree = newTree; + _tree = newTree; } -void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { +void OctreeRenderer::processDatagram(NLPacket& packet, SharedNodePointer sourceNode) { bool extraDebugging = false; if (extraDebugging) { @@ -61,30 +61,21 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar } bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); + PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()", showTimingDetails); - unsigned int packetLength = dataByteArray.size(); - PacketType::Value command = packetTypeForPacket(dataByteArray); - unsigned int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); - QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); - PacketType::Value expectedType = getExpectedPacketType(); - // packetVersion is the second byte - PacketVersion packetVersion = dataByteArray[1]; - - if(command == expectedType) { + if (packet.getType() == getExpectedPacketType()) { PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails); // if we are getting inbound packets, then our tree is also viewing, and we should remember that fact. _tree->setIsViewing(true); - const unsigned char* dataAt = reinterpret_cast(dataByteArray.data()) + numBytesPacketHeader; + OCTREE_PACKET_FLAGS flags; + packet.readPrimitive(&flags); + + OCTREE_PACKET_SEQUENCE sequence; + packet.readPrimitive(&sequence); - OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt)); - dataAt += sizeof(OCTREE_PACKET_FLAGS); - OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt); - dataAt += sizeof(OCTREE_PACKET_SEQUENCE); - - OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); - dataAt += sizeof(OCTREE_PACKET_SENT_TIME); + OCTREE_PACKET_SENT_TIME sentAt; + packet.readPrimitive(&sentAt); bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); @@ -94,13 +85,12 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; - unsigned int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u", + " color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), - sequence, flightTime, packetLength, dataBytes); + sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable()); } _packetsInLastWindow++; @@ -111,42 +101,48 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar quint64 totalWaitingForLock = 0; quint64 totalUncompress = 0; quint64 totalReadBitsteam = 0; + + const QUuid& sourceUUID = packet.getSourceID(); int subsection = 1; - while (dataBytes > 0) { + + bool error = false; + + while (packet.bytesAvailable() && !error) { if (packetIsCompressed) { - if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { - sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt); - dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); - dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); + if (packet.bytesAvailable() > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { + packet.readPrimitive(§ionLength); } else { sectionLength = 0; - dataBytes = 0; // stop looping something is wrong + error = true; } } else { - sectionLength = dataBytes; + sectionLength = packet.bytesAvailable(); } if (sectionLength) { // ask the VoxelTree to read the bitstream into the tree - ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, - sourceUUID, sourceNode, false, packetVersion); + ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, + sourceUUID, sourceNode, false, packet.getVersion()); quint64 startLock = usecTimestampNow(); // FIXME STUTTER - there may be an opportunity to bump this lock outside of the // loop to reduce the amount of locking/unlocking we're doing _tree->lockForWrite(); quint64 startUncompress = usecTimestampNow(); + OctreePacketData packetData(packetIsCompressed); - packetData.loadFinalizedContent(dataAt, sectionLength); + packetData.loadFinalizedContent(reinterpret_cast(packet.getPayload() + packet.pos()), + sectionLength); if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u" + " color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), - sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, + sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable(), subsection, sectionLength, packetData.getUncompressedSize()); } + if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()..."; } @@ -158,8 +154,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar } _tree->unlock(); - dataBytes -= sectionLength; - dataAt += sectionLength; + // seek forwards in packet + packet.seek(packet.pos() + sectionLength); elementsPerPacket += args.elementsPerPacket; entitiesPerPacket += args.entitiesPerPacket; @@ -228,10 +224,10 @@ void OctreeRenderer::render(RenderArgs* renderArgs) { } } -void OctreeRenderer::clear() { +void OctreeRenderer::clear() { if (_tree) { _tree->lockForWrite(); - _tree->eraseAllOctreeElements(); + _tree->eraseAllOctreeElements(); _tree->unlock(); } } diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index f6c92f81c9..e5114cd760 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -45,7 +45,7 @@ public: virtual void setTree(Octree* newTree); /// process incoming data - virtual void processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); + virtual void processDatagram(NLPacket& packet, SharedNodePointer sourceNode); /// initialize and GPU/rendering related resources virtual void init(); diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index a3799c2f36..d8013f2c03 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -747,20 +747,17 @@ const char* OctreeSceneStats::getItemValue(Item item) { return _itemValueBuffer; } -void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, - bool wasStatsPacket, int nodeClockSkewUsec) { +void OctreeSceneStats::trackIncomingOctreePacket(NLPacket& packet, bool wasStatsPacket, int nodeClockSkewUsec) { const bool wantExtraDebugging = false; - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const unsigned char* dataAt = reinterpret_cast(packet.data()) + numBytesPacketHeader; + // skip past the flags + packet.seek(sizeof(OCTREE_PACKET_FLAGS)); + + OCTREE_PACKET_SEQUENCE sequence; + packet.readPrimitive(&sequence); - //VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt)); - dataAt += sizeof(OCTREE_PACKET_FLAGS); - OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt); - dataAt += sizeof(OCTREE_PACKET_SEQUENCE); - - OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); - dataAt += sizeof(OCTREE_PACKET_SENT_TIME); + OCTREE_PACKET_SENT_TIME sentAt; + packet.readPrimitive(&sentAt); //bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); //bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); @@ -792,8 +789,8 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, // track packets here... _incomingPacket++; - _incomingBytes += packet.size(); + _incomingBytes += packet.getSizeWithHeader(); if (!wasStatsPacket) { - _incomingWastedBytes += (MAX_PACKET_SIZE - packet.size()); + _incomingWastedBytes += (MAX_PACKET_SIZE - packet.getSizeWithHeader()); } } diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index a71360a4cf..d840c0d6f6 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -160,7 +160,7 @@ public: quint64 getLastFullTotalBytes() const { return _lastFullTotalBytes; } // Used in client implementations to track individual octree packets - void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec); + void trackIncomingOctreePacket(NLPacket& packet, bool wasStatsPacket, int nodeClockSkewUsec); quint32 getIncomingPackets() const { return _incomingPacket; } quint64 getIncomingBytes() const { return _incomingBytes; } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 411beca0ae..62ec423f62 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -28,15 +28,6 @@ #include "SkyFromAtmosphere_vert.h" #include "SkyFromAtmosphere_frag.h" -uint qHash(const HifiSockAddr& sockAddr) { - if (sockAddr.getAddress().isNull()) { - return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash - } - quint32 address = sockAddr.getAddress().toIPv4Address(); - return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address, - sizeof(address))); -} - Environment::Environment() : _initialized(false) { } @@ -53,7 +44,7 @@ void Environment::init() { setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations); // start off with a default-constructed environment data - _data[HifiSockAddr()][0]; + _data[QUuid()][0]; _initialized = true; } @@ -98,10 +89,10 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra void Environment::resetToDefault() { _data.clear(); - _data[HifiSockAddr()][0]; + _data[QUuid()][0]; } -void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) { +void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) { // get the lock for the duration of the call QMutexLocker locker(&_mutex); @@ -142,7 +133,7 @@ EnvironmentData Environment::getClosestData(const glm::vec3& position) { // NOTE: Deprecated - I'm leaving this in for now, but it's not actually used. I made it private -// so that if anyone wants to start using this in the future they will consider how to make it +// so that if anyone wants to start using this in the future they will consider how to make it // work with new physics systems. glm::vec3 Environment::getGravity (const glm::vec3& position) { // @@ -169,7 +160,7 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { // At or inside a planet, gravity is as set for the planet gravity += glm::normalize(vector) * environmentData.getGravity(); } else { - // Outside a planet, the gravity falls off with distance + // Outside a planet, the gravity falls off with distance gravityStrength = 1.0f / powf(glm::length(vector) / surfaceRadius, 2.0f); gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength; } @@ -205,33 +196,28 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3 return found; } -int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) { - // push past the packet header - int bytesRead = numBytesForPacketHeader(packet); - +int Environment::processPacket(NLPacket& packet) { // push past flags, sequence, timestamp - bytesRead += sizeof(OCTREE_PACKET_FLAGS); - bytesRead += sizeof(OCTREE_PACKET_SEQUENCE); - bytesRead += sizeof(OCTREE_PACKET_SENT_TIME); + packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME)); // get the lock for the duration of the call QMutexLocker locker(&_mutex); EnvironmentData newData; - while (bytesRead < packet.size()) { - int dataLength = newData.parseData(reinterpret_cast(packet.data()) + bytesRead, - packet.size() - bytesRead); + + while (packet.bytesAvailable() > 0) { + int dataLength = newData.parseData(reinterpret_cast(packet.getPayload() + packet.pos()), + packet.bytesAvailable()); + packet.seek(packet.pos() + dataLength); // update the mapping by address/ID - _data[senderAddress][newData.getID()] = newData; - - bytesRead += dataLength; + _data[packet.getSourceID()][newData.getID()] = newData; } // remove the default mapping, if any - _data.remove(HifiSockAddr()); + _data.remove(QUuid()); - return bytesRead; + return packet.pos(); } void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) { diff --git a/libraries/render-utils/src/Environment.h b/libraries/render-utils/src/Environment.h index 65e0df4b36..f2c7d57fa5 100644 --- a/libraries/render-utils/src/Environment.h +++ b/libraries/render-utils/src/Environment.h @@ -36,13 +36,12 @@ public: void endOverride() { _environmentIsOverridden = false; } EnvironmentData getClosestData(const glm::vec3& position); - - - int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); + + int processPacket(NLPacket& packet); private: glm::vec3 getGravity (const glm::vec3& position); // NOTE: Deprecated - bool findCapsulePenetration(const glm::vec3& start, + bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration); // NOTE: Deprecated void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data); @@ -79,7 +78,7 @@ private: typedef QHash ServerData; - QHash _data; + QHash _data; EnvironmentData _overrideData; bool _environmentIsOverridden = false; From 859122db5dbdea4fd061e84486a77d4d02a31c59 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 13:32:46 -0700 Subject: [PATCH 079/146] update signature of callbacks for avatar packets --- interface/src/avatar/Avatar.cpp | 6 +-- interface/src/avatar/Avatar.h | 16 +++--- interface/src/avatar/AvatarManager.cpp | 4 ++ interface/src/avatar/AvatarManager.h | 1 + interface/src/avatar/MyAvatar.cpp | 7 ++- interface/src/avatar/MyAvatar.h | 2 +- libraries/avatars/src/AvatarData.cpp | 6 +-- libraries/avatars/src/AvatarData.h | 8 +-- libraries/avatars/src/AvatarHashMap.cpp | 58 +++++++--------------- libraries/avatars/src/AvatarHashMap.h | 8 +-- libraries/networking/src/LimitedNodeList.h | 4 -- libraries/networking/src/Node.h | 5 +- 12 files changed, 53 insertions(+), 72 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0dde96c7ce..a8067b8dcb 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -988,7 +988,7 @@ void Avatar::setBillboard(const QByteArray& billboard) { _billboardTexture.reset(); } -int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) { +int Avatar::parseDataFromBuffer(const QByteArray& buffer) { if (!_initialized) { // now that we have data for this Avatar we are go for init init(); @@ -997,7 +997,7 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) { // change in position implies movement glm::vec3 oldPosition = _position; - int bytesRead = AvatarData::parseDataAtOffset(packet, offset); + int bytesRead = AvatarData::parseDataFromBuffer(buffer); const float MOVE_DISTANCE_THRESHOLD = 0.001f; _moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD; @@ -1123,7 +1123,7 @@ void Avatar::setShowDisplayName(bool showDisplayName) { } } -// virtual +// virtual void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) { const CapsuleShape& capsule = _skeletonModel.getBoundingShape(); shapeInfo.setCapsuleY(capsule.getRadius(), capsule.getHalfHeight()); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b23059acb0..b4bf0cf097 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -85,10 +85,10 @@ public: virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false); - bool addToScene(AvatarSharedPointer self, std::shared_ptr scene, + bool addToScene(AvatarSharedPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); - void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, + void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); //setters @@ -146,7 +146,7 @@ public: void setShowDisplayName(bool showDisplayName); - virtual int parseDataAtOffset(const QByteArray& packet, int offset); + virtual int parseDataFromBuffer(const QByteArray& buffer); static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, float radius1, float radius2, const glm::vec4& color); @@ -163,7 +163,7 @@ public: Q_INVOKABLE glm::quat getJointCombinedRotation(const QString& name) const; Q_INVOKABLE void setJointModelPositionAndOrientation(int index, const glm::vec3 position, const glm::quat& rotation); - Q_INVOKABLE void setJointModelPositionAndOrientation(const QString& name, const glm::vec3 position, + Q_INVOKABLE void setJointModelPositionAndOrientation(const QString& name, const glm::vec3 position, const glm::quat& rotation); Q_INVOKABLE glm::vec3 getNeckPosition() const; @@ -179,8 +179,8 @@ public: void slamPosition(const glm::vec3& position); - // Call this when updating Avatar position with a delta. This will allow us to - // _accurately_ measure position changes and compute the resulting velocity + // Call this when updating Avatar position with a delta. This will allow us to + // _accurately_ measure position changes and compute the resulting velocity // (otherwise floating point error will cause problems at large positions). void applyPositionDelta(const glm::vec3& delta); @@ -203,9 +203,9 @@ protected: // These position histories and derivatives are in the world-frame. // The derivatives are the MEASURED results of all external and internal forces - // and are therefore READ-ONLY --> motion control of the Avatar is NOT obtained + // and are therefore READ-ONLY --> motion control of the Avatar is NOT obtained // by setting these values. - // Floating point error prevents us from accurately measuring velocity using a naive approach + // Floating point error prevents us from accurately measuring velocity using a naive approach // (e.g. vel = (pos - lastPos)/dt) so instead we use _positionDeltaAccumulator. glm::vec3 _positionDeltaAccumulator; glm::vec3 _lastVelocity; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 944f16fd34..47d7ff06c5 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -56,6 +56,10 @@ static void localLightFromScriptValue(const QScriptValue& value, AvatarManager:: vec3FromScriptValue(value.property("color"), light.color); } +AvatarManager::AvatarManager() { + +} + void AvatarManager::registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); qScriptRegisterSequenceMetaType >(engine); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 9d1c94a47e..dad3f488cf 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -29,6 +29,7 @@ class AvatarManager : public AvatarHashMap { SINGLETON_DEPENDENCY public: + AvatarManager(); /// Registers the script types associated with the avatar manager. static void registerMetaTypes(QScriptEngine* engine); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2dfe4216be..ef93485a38 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -870,12 +870,11 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& return attachment; } -int MyAvatar::parseDataAtOffset(const QByteArray& packet, int offset) { +int MyAvatar::parseDataFromBuffer(const QByteArray& buffer) { qCDebug(interfaceapp) << "Error: ignoring update packet for MyAvatar" - << " packetLength = " << packet.size() - << " offset = " << offset; + << " packetLength = " << buffer.size() // this packet is just bad, so we pretend that we unpacked it ALL - return packet.size() - offset; + return buffer.size(); } void MyAvatar::sendKillAvatar() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 34dfcad2ad..62d7cc57d3 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -102,7 +102,7 @@ public: eyeContactTarget getEyeContactTarget(); - virtual int parseDataAtOffset(const QByteArray& packet, int offset); + virtual int parseDataFromBuffer(const QByteArray& buffer); static void sendKillAvatar(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 5ea3b4c669..01a7a1c1dd 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -265,7 +265,7 @@ bool AvatarData::shouldLogError(const quint64& now) { } // read data in packet starting at byte offset and return number of bytes parsed -int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { +int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { @@ -277,7 +277,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { _handData = new HandData(this); } - const unsigned char* startPosition = reinterpret_cast(packet.data()) + offset; + const unsigned char* startPosition = reinterpret_cast(buffer.data()); const unsigned char* sourceBuffer = startPosition; quint64 now = usecTimestampNow(); @@ -299,7 +299,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { // = 45 bytes int minPossibleSize = 45; - int maxAvailableSize = packet.size() - offset; + int maxAvailableSize = buffer.size(); if (minPossibleSize > maxAvailableSize) { if (shouldLogError(now)) { qCDebug(avatars) << "Malformed AvatarData packet at the start; " diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c482f52bf1..ad6be52a61 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -66,12 +66,12 @@ typedef QHash AvatarHash; const quint32 AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED = 1U << 0; const quint32 AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED = 1U << 1; -const quint32 AVATAR_MOTION_DEFAULTS = +const quint32 AVATAR_MOTION_DEFAULTS = AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED | AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; // these bits will be expanded as features are exposed -const quint32 AVATAR_MOTION_SCRIPTABLE_BITS = +const quint32 AVATAR_MOTION_SCRIPTABLE_BITS = AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND; @@ -181,7 +181,7 @@ public: /// \param packet byte array of data /// \param offset number of bytes into packet where data starts /// \return number of bytes parsed - virtual int parseDataAtOffset(const QByteArray& packet, int offset); + virtual int parseDataFromBuffer(const QByteArray& buffer); // Body Rotation (degrees) float getBodyYaw() const { return _bodyYaw; } @@ -241,7 +241,7 @@ public: Q_INVOKABLE virtual void clearJointsData(); /// Returns the index of the joint with the specified name, or -1 if not found/unknown. - Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return _jointIndices.value(name) - 1; } + Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return _jointIndices.value(name) - 1; } Q_INVOKABLE virtual QStringList getJointNames() const { return _jointNames; } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 03187a02bc..c00ba1f08c 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -52,48 +52,37 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe return avatar; } -void AvatarHashMap::processAvatarDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); - int bytesRead = 0; - - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (avatarMixer) { - avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); - } +void AvatarHashMap::processAvatarDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // enumerate over all of the avatars in this packet // only add them if mixerWeakPointer points to something (meaning that mixer is still around) - while (bytesRead < data.size() && avatarMixer.data()) { - QUuid sessionUUID = QUuid::fromRfc4122(data.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); - bytesRead += NUM_BYTES_RFC4122_UUID; + while (packet->bytesAvailable()) { + QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); if (sessionUUID != _lastOwnerSessionUUID) { AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, avatarMixer); + avatar = addAvatar(sessionUUID, sendingNode); } // have the matching (or new) avatar parse the data from the packet - bytesRead += avatar->parseDataAtOffset(data, bytesRead); + int bytesRead = avatar->parseDataFromBuffer(QByteArray::fromRawData(packet->getPayload(), packet->pos())); + packet->seek(packet->pos() + bytesRead); } else { // create a dummy AvatarData class to throw this data on the ground AvatarData dummyData; - bytesRead += dummyData.parseDataAtOffset(data, bytesRead); + int bytesRead = dummyData.parseDataFromBuffer(QByteArray::fromRawData(packet->getPayload(), packet->pos())); + packet->seek(packet->pos() + bytesRead); } } } -void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // setup a data stream to parse the packet - QDataStream identityStream { packet.data() }; + QDataStream identityStream(packet.data()); QUuid sessionUUID; - - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (avatarMixer) { - avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); - } - + while (!identityStream.atEnd()) { QUrl faceMeshURL, skeletonURL; @@ -104,7 +93,7 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, // mesh URL for a UUID, find avatar in our list AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, avatarMixer); + avatar = addAvatar(sessionUUID, sendingNode); } if (avatar->getFaceModelURL() != faceMeshURL) { avatar->setFaceModelURL(faceMeshURL); @@ -124,34 +113,23 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer packet, } } -void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size()); - QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID)); - - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (avatarMixer) { - avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); - } +void AvatarHashMap::processAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); AvatarSharedPointer avatar = _avatarHash.value(sessionUUID); if (!avatar) { - avatar = addAvatar(sessionUUID, avatarMixer); + avatar = addAvatar(sessionUUID, sendingNode); } - QByteArray billboard = data.mid(NUM_BYTES_RFC4122_UUID); + QByteArray billboard = packet->read(packet->bytesAvailable()); if (avatar->getBillboard() != billboard) { avatar->setBillboard(billboard); } } -void AvatarHashMap::processKillAvatar(QSharedPointer packet, HifiSockAddr senderSockAddr) { - SharedNodePointer avatarMixer = DependencyManager::get()->nodeWithUUID(packet->getSourceID()); - if (avatarMixer) { - avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); - } - +void AvatarHashMap::processKillAvatar(QSharedPointer packet, SharedNodePointer sendingNode) { // read the node id - QUuid sessionUUID = QUuid::fromRfc4122(QByteArray(packet->getPayload(), NUM_BYTES_RFC4122_UUID)); + QUuid sessionUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); removeAvatar(sessionUUID); } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 3c979e35f8..071798e4f8 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -38,10 +38,10 @@ public slots: private slots: void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); - void processAvatarDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void processAvatarIdentityPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void processAvatarBillboardPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void processKillAvatar(QSharedPointer packet, HifiSockAddr senderSockAddr); + void processAvatarDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void processAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void processAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void processKillAvatar(QSharedPointer packet, SharedNodePointer sendingNode); protected: AvatarHashMap(); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 2e0bb5b6b7..bfcfd61c20 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -64,9 +63,6 @@ const QString USERNAME_UUID_REPLACEMENT_STATS_KEY = "$username"; class HifiSockAddr; -typedef QSharedPointer SharedNodePointer; -Q_DECLARE_METATYPE(SharedNodePointer) - using namespace tbb; typedef std::pair UUIDNodePair; typedef concurrent_unordered_map NodeHash; diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 83bdf0ebd3..a10b5ec087 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -17,8 +17,8 @@ #include #include +#include #include -#include #include "HifiSockAddr.h" #include "NetworkPeer.h" @@ -92,6 +92,9 @@ private: PacketTypeSequenceMap _lastSequenceNumbers; }; +typedef QSharedPointer SharedNodePointer; +Q_DECLARE_METATYPE(SharedNodePointer) + QDebug operator<<(QDebug debug, const Node &message); #endif // hifi_Node_h From ca1ff9b0f5a87a50e1802035380a286f7538fcf6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 13:34:36 -0700 Subject: [PATCH 080/146] fix a couple of compile errors for avatar changes --- interface/src/avatar/AvatarManager.cpp | 4 ---- interface/src/avatar/AvatarManager.h | 2 -- interface/src/avatar/MyAvatar.cpp | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 47d7ff06c5..944f16fd34 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -56,10 +56,6 @@ static void localLightFromScriptValue(const QScriptValue& value, AvatarManager:: vec3FromScriptValue(value.property("color"), light.color); } -AvatarManager::AvatarManager() { - -} - void AvatarManager::registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); qScriptRegisterSequenceMetaType >(engine); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index dad3f488cf..5e3fe9543a 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -29,8 +29,6 @@ class AvatarManager : public AvatarHashMap { SINGLETON_DEPENDENCY public: - AvatarManager(); - /// Registers the script types associated with the avatar manager. static void registerMetaTypes(QScriptEngine* engine); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ef93485a38..bb6188f52c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -872,7 +872,7 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& int MyAvatar::parseDataFromBuffer(const QByteArray& buffer) { qCDebug(interfaceapp) << "Error: ignoring update packet for MyAvatar" - << " packetLength = " << buffer.size() + << " packetLength = " << buffer.size(); // this packet is just bad, so we pretend that we unpacked it ALL return buffer.size(); } From 9de6828b032b71e8ccb743643708e9ec0b02f8b4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 14:24:06 -0700 Subject: [PATCH 081/146] Remove readPendingDatagram from AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 27 ---------------------- assignment-client/src/audio/AudioMixer.h | 2 -- 2 files changed, 29 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index d8c01dafcd..018f946771 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -543,11 +543,6 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { } } -void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->processNodeData(senderSockAddr, receivedPacket); -} - void AudioMixer::handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { auto nodeList = DependencyManager::get(); nodeList->findNodeAndUpdateWithDataFromPacket(packet); @@ -684,28 +679,6 @@ void AudioMixer::run() { _datagramProcessingThread = new QThread(this); _datagramProcessingThread->setObjectName("Datagram Processor Thread"); - // create an AudioMixerDatagramProcessor and move it to that thread - AudioMixerDatagramProcessor* datagramProcessor = new AudioMixerDatagramProcessor(nodeList->getNodeSocket(), thread()); - datagramProcessor->moveToThread(_datagramProcessingThread); - - // remove the NodeList as the parent of the node socket - nodeList->getNodeSocket().setParent(NULL); - nodeList->getNodeSocket().moveToThread(_datagramProcessingThread); - - // let the datagram processor handle readyRead from node socket - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, - datagramProcessor, &AudioMixerDatagramProcessor::readPendingDatagrams); - - // connect to the datagram processing thread signal that tells us we have to handle a packet - connect(datagramProcessor, &AudioMixerDatagramProcessor::packetRequiresProcessing, this, &AudioMixer::readPendingDatagram); - - // delete the datagram processor and the associated thread when the QThread quits - connect(_datagramProcessingThread, &QThread::finished, datagramProcessor, &QObject::deleteLater); - connect(datagramProcessor, &QObject::destroyed, _datagramProcessingThread, &QThread::deleteLater); - - // start the datagram processing thread - _datagramProcessingThread->start(); - nodeList->addNodeTypeToInterestSet(NodeType::Agent); nodeList->linkedDataCreateCallback = [](Node* node) { diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index c88c5a6242..50ec3c6d18 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -35,8 +35,6 @@ public slots: /// threaded run of assignment void run(); - void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); - void sendStatsPacket(); static const InboundAudioStream::Settings& getStreamSettings() { return _streamSettings; } From ede39515d8a08eae5d65ca43ad4b74be91e2ac42 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 14:26:10 -0700 Subject: [PATCH 082/146] update parseData for new network API --- domain-server/src/DomainServerNodeData.h | 2 +- libraries/audio-client/src/AudioClient.cpp | 65 ++++++-------------- libraries/audio-client/src/AudioClient.h | 11 ++-- libraries/audio-client/src/AudioIOStats.cpp | 17 +++-- libraries/audio-client/src/AudioIOStats.h | 6 +- libraries/audio/src/InboundAudioStream.cpp | 38 ++++++------ libraries/audio/src/InboundAudioStream.h | 8 +-- libraries/networking/src/Assignment.h | 2 +- libraries/networking/src/LimitedNodeList.cpp | 24 +++----- libraries/networking/src/LimitedNodeList.h | 3 +- libraries/networking/src/NodeData.h | 5 +- libraries/octree/src/OctreeQuery.cpp | 11 ++-- libraries/octree/src/OctreeQuery.h | 2 +- 13 files changed, 76 insertions(+), 118 deletions(-) diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index d2efced1ef..00c5f659ca 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -24,7 +24,7 @@ class DomainServerNodeData : public NodeData { public: DomainServerNodeData(); - int parseData(const QByteArray& packet) { return 0; } + int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } const QJsonObject& getStatsJSONObject() const { return _statsJSONObject; } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index c946586074..ef7a16f983 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -33,7 +33,7 @@ #include #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -142,10 +142,10 @@ AudioClient::AudioClient() : configureGverbFilter(_gverb); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioStreamStatsPacket"); - packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::AudioStreamStats, &_stats, "handleAudioStreamStatsPacket"); + packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); - packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFrame"); packetReceiver.registerPacketListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } @@ -535,35 +535,24 @@ void AudioClient::stop() { } } -void AudioClient::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - _stats.parseAudioStreamStatsPacket(packet->getData()); - - updateLastHeardFromAudioMixer(packet); -} - -void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - const char* dataAt = packet->getPayload(); +void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { char bitset; - memcpy(&bitset, dataAt, sizeof(char)); - dataAt += sizeof(char); + packet->readPrimitive(&bitset); - bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; + bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); + if (hasReverb) { float reverbTime, wetLevel; - memcpy(&reverbTime, dataAt, sizeof(float)); - dataAt += sizeof(float); - memcpy(&wetLevel, dataAt, sizeof(float)); - dataAt += sizeof(float); + packet->readPrimitive(&reverbTime); + packet->readPrimitive(&wetLevel); _receivedAudioStream.setReverb(reverbTime, wetLevel); } else { _receivedAudioStream.clearReverb(); - } - - updateLastHeardFromAudioMixer(packet); + } } -void AudioClient::handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto nodeList = DependencyManager::get(); nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); @@ -577,45 +566,29 @@ void AudioClient::handleAudioDataPacket(QSharedPointer packet, HifiSoc } // Audio output must exist and be correctly set up if we're going to process received audio - _receivedAudioStream.parseData(packet->getData()); + _receivedAudioStream.parseData(*packet, sendingNode); } - - updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr) { - updateLastHeardFromAudioMixer(packet); -} - -void AudioClient::handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode) { if (!_muted) { toggleMute(); + // TODO reimplement on interface side //AudioScriptingInterface::getInstance().mutedByMixer(); } } -void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode) { glm::vec3 position; float radius; - - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); - memcpy(&position, packet->getPayload(), sizeof(glm::vec3)); - memcpy(&radius, packet->getPayload() + sizeof(glm::vec3), sizeof(float)); + + packet->readPrimitive(&position); + packet->readPrimitive(&radius); emit muteEnvironmentRequested(position, radius); } -void AudioClient::updateLastHeardFromAudioMixer(QSharedPointer& packet) { - // update having heard from the audio-mixer and record the bytes received - auto nodeList = DependencyManager::get(); - SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); - if (audioMixer) { - audioMixer->setLastHeardMicrostamp(usecTimestampNow()); - } - -} - QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) { QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode); return deviceInfo.deviceName(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 8812473a79..cf57b9dca1 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -139,12 +139,10 @@ public slots: void start(); void stop(); - void handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode); void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } void handleAudioInput(); @@ -214,7 +212,6 @@ private slots: void audioStateChanged(QAudio::State state); private: - void updateLastHeardFromAudioMixer(QSharedPointer& packet); void outputFormatChanged(); QByteArray firstInputFrame; diff --git a/libraries/audio-client/src/AudioIOStats.cpp b/libraries/audio-client/src/AudioIOStats.cpp index 8f7ab2ecaa..931e9badeb 100644 --- a/libraries/audio-client/src/AudioIOStats.cpp +++ b/libraries/audio-client/src/AudioIOStats.cpp @@ -63,27 +63,24 @@ void AudioIOStats::sentPacket() { _lastSentAudioPacket = now; } } -void AudioIOStats::parseAudioStreamStatsPacket(const QByteArray& packet) { - - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const char* dataAt = packet.constData() + numBytesPacketHeader; +void AudioIOStats::processStreamStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // parse the appendFlag, clear injected audio stream stats if 0 - quint8 appendFlag = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint8); + quint8 appendFlag; + packet->readPrimitive(&appendFlag); + if (!appendFlag) { _mixerInjectedStreamStatsMap.clear(); } // parse the number of stream stats structs to follow - quint16 numStreamStats = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint16); + quint16 numStreamStats; + packet->readPrimitive(&numStreamStats); // parse the stream stats AudioStreamStats streamStats; for (quint16 i = 0; i < numStreamStats; i++) { - memcpy(&streamStats, dataAt, sizeof(AudioStreamStats)); - dataAt += sizeof(AudioStreamStats); + packet->readPrimitive(&streamStats); if (streamStats._streamType == PositionalAudioStream::Microphone) { _mixerAvatarStreamStats = streamStats; diff --git a/libraries/audio-client/src/AudioIOStats.h b/libraries/audio-client/src/AudioIOStats.h index 07bf349ad9..da0acf2fa3 100644 --- a/libraries/audio-client/src/AudioIOStats.h +++ b/libraries/audio-client/src/AudioIOStats.h @@ -17,6 +17,8 @@ #include #include +#include +#include class MixedProcessedAudioStream; @@ -41,7 +43,7 @@ public: const MovingMinMaxAvg& getPacketSentTimeGaps() const { return _packetSentTimeGaps; } void sendDownstreamAudioStatsPacket(); - void parseAudioStreamStatsPacket(const QByteArray& packet); + void processStreamStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: MixedProcessedAudioStream* _receivedAudioStream; @@ -57,4 +59,4 @@ private: MovingMinMaxAvg _packetSentTimeGaps; }; -#endif // hifi_AudioIOStats_h \ No newline at end of file +#endif // hifi_AudioIOStats_h diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 928662d2e8..1c061b3aaa 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -11,6 +11,9 @@ #include +#include +#include + #include "InboundAudioStream.h" #include "PacketHeaders.h" @@ -96,28 +99,23 @@ void InboundAudioStream::perSecondCallbackForUpdatingStats() { _timeGapStatsForStatsPacket.currentIntervalComplete(); } -int InboundAudioStream::parseData(const QByteArray& packet) { - - PacketType::Value packetType = packetTypeForPacket(packet); - QUuid senderUUID = uuidFromPacketHeader(packet); - - // parse header - int numBytesHeader = numBytesForPacketHeader(packet); - const char* dataAt = packet.constData() + numBytesHeader; - int readBytes = numBytesHeader; +int InboundAudioStream::parseData(NLPacket& packet, SharedNodePointer sendingNode) { // parse sequence number and track it - quint16 sequence = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint16); - readBytes += sizeof(quint16); - SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, senderUUID); + quint16 sequence; + packet.readPrimitive(&sequence); + SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, + sendingNode->getUUID()); packetReceivedUpdateTimingStats(); int networkSamples; // parse the info after the seq number and before the audio data (the stream properties) - readBytes += parseStreamProperties(packetType, packet.mid(readBytes), networkSamples); + int propertyBytes = parseStreamProperties(packet.getType(), + QByteArray::fromRawData(packet.getPayload(), packet.pos()), + networkSamples); + packet.seek(packet.pos() + propertyBytes); // handle this packet based on its arrival status. switch (arrivalInfo._status) { @@ -132,10 +130,12 @@ int InboundAudioStream::parseData(const QByteArray& packet) { } case SequenceNumberStats::OnTime: { // Packet is on time; parse its data to the ringbuffer - if (packetType == PacketType::SilentAudioFrame) { + if (packet.getType() == PacketType::SilentAudioFrame) { writeDroppableSilentSamples(networkSamples); } else { - readBytes += parseAudioData(packetType, packet.mid(readBytes), networkSamples); + int audioBytes = parseAudioData(packet.getType(), QByteArray::fromRawData(packet.getPayload(), packet.pos()), + networkSamples); + packet.seek(packet.pos() + audioBytes); } break; } @@ -165,7 +165,7 @@ int InboundAudioStream::parseData(const QByteArray& packet) { framesAvailableChanged(); - return readBytes; + return packet.pos(); } int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { @@ -314,7 +314,7 @@ void InboundAudioStream::setToStarved() { starvesInWindow++; } while (starvesIterator != end); - // this starve put us over the starve threshold. update _desiredJitterBufferFrames to + // this starve put us over the starve threshold. update _desiredJitterBufferFrames to // value determined by window A. if (starvesInWindow >= _starveThreshold) { int calculatedJitterBufferFrames; @@ -398,7 +398,7 @@ void InboundAudioStream::packetReceivedUpdateTimingStats() { _timeGapStatsForDesiredReduction.update(gap); if (_timeGapStatsForDesiredCalcOnTooManyStarves.getNewStatsAvailableFlag()) { - _calculatedJitterBufferFramesUsingMaxGap = ceilf((float)_timeGapStatsForDesiredCalcOnTooManyStarves.getWindowMax() + _calculatedJitterBufferFramesUsingMaxGap = ceilf((float)_timeGapStatsForDesiredCalcOnTooManyStarves.getWindowMax() / (float) AudioConstants::NETWORK_FRAME_USECS); _timeGapStatsForDesiredCalcOnTooManyStarves.clearNewStatsAvailableFlag(); } diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index cb8494f23e..106caa11ef 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -80,7 +80,7 @@ public: {} // max number of frames over desired in the ringbuffer. - int _maxFramesOverDesired; + int _maxFramesOverDesired; // if false, _desiredJitterBufferFrames will always be _staticDesiredJitterBufferFrames. Otherwise, // either fred or philip's method will be used to calculate _desiredJitterBufferFrames based on packet timegaps. @@ -107,7 +107,7 @@ public: virtual void resetStats(); void clearBuffer(); - virtual int parseData(const QByteArray& packet); + virtual int parseData(NLPacket& packet, QSharedPointer sendingNode); int popFrames(int maxFrames, bool allOrNothing, bool starveIfNoFramesPopped = true); int popSamples(int maxSamples, bool allOrNothing, bool starveIfNoSamplesPopped = true); @@ -131,7 +131,7 @@ public: virtual AudioStreamStats getAudioStreamStats() const; /// returns the desired number of jitter buffer frames under the dyanmic jitter buffers scheme - int getCalculatedJitterBufferFrames() const { return _useStDevForJitterCalc ? + int getCalculatedJitterBufferFrames() const { return _useStDevForJitterCalc ? _calculatedJitterBufferFramesUsingStDev : _calculatedJitterBufferFramesUsingMaxGap; }; /// returns the desired number of jitter buffer frames using Philip's method @@ -217,7 +217,7 @@ protected: bool _dynamicJitterBuffers; // if false, _desiredJitterBufferFrames is locked at 1 (old behavior) int _staticDesiredJitterBufferFrames; - // if jitter buffer is dynamic, this determines what method of calculating _desiredJitterBufferFrames + // if jitter buffer is dynamic, this determines what method of calculating _desiredJitterBufferFrames // if true, Philip's timegap std dev calculation is used. Otherwise, Freddy's max timegap calculation is used bool _useStDevForJitterCalc; diff --git a/libraries/networking/src/Assignment.h b/libraries/networking/src/Assignment.h index a8338a7b5a..1e4c985583 100644 --- a/libraries/networking/src/Assignment.h +++ b/libraries/networking/src/Assignment.h @@ -86,7 +86,7 @@ public: const char* getTypeName() const; // implement parseData to return 0 so we can be a subclass of NodeData - int parseData(const QByteArray& packet) { return 0; } + int parseData(NLPacket& packet, SharedNodePointer sendingNode) { return 0; } friend QDebug operator<<(QDebug debug, const Assignment& assignment); friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 47a7a4b99b..d269db8bed 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -231,35 +231,25 @@ PacketSequenceNumber LimitedNodeList::getNextSequenceNumberForPacket(const QUuid return _packetSequenceNumbers[nodeUUID][packetType]++; } -int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet) { - QMutexLocker locker(&matchingNode->getMutex()); +int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + QMutexLocker locker(&sendingNode->getMutex()); // if this was a sequence numbered packet we should store the last seq number for // a packet of this type for this node if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { - matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); + sendingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); } - NodeData* linkedData = matchingNode->getLinkedData(); + NodeData* linkedData = sendingNode->getLinkedData(); if (!linkedData && linkedDataCreateCallback) { - linkedDataCreateCallback(matchingNode.data()); + linkedDataCreateCallback(sendingNode.data()); } if (linkedData) { QMutexLocker linkedDataLocker(&linkedData->getMutex()); - return linkedData->parseData(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + return linkedData->parseData(*packet, sendingNode); } - return 0; -} - -int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(QSharedPointer packet) { - SharedNodePointer matchingNode = nodeWithUUID(packet->getSourceID()); - - if (matchingNode) { - return updateNodeWithDataFromPacket(matchingNode, packet); - } - - // we weren't able to match the sender address to the address we have for this node, unlock and don't parse + return 0; } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index bfcfd61c20..44d853919a 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -155,8 +155,7 @@ public: void processKillNode(const QByteArray& datagram); - int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet); - int findNodeAndUpdateWithDataFromPacket(const QSharedPointer packet); + int updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer matchingNode); unsigned broadcastToNodes(std::unique_ptr packet, const NodeSet& destinationNodeTypes) { assert(false); return 0; } SharedNodePointer soloNodeOfType(char nodeType); diff --git a/libraries/networking/src/NodeData.h b/libraries/networking/src/NodeData.h index b865e444a9..d323c72184 100644 --- a/libraries/networking/src/NodeData.h +++ b/libraries/networking/src/NodeData.h @@ -14,6 +14,9 @@ #include #include +#include + +#include "NLPacket.h" class Node; @@ -22,7 +25,7 @@ class NodeData : public QObject { public: NodeData(); virtual ~NodeData() = 0; - virtual int parseData(const QByteArray& packet) = 0; + virtual int parseData(NLPacket& packet, QSharedPointer sendingNode) = 0; QMutex& getMutex() { return _mutex; } diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 08197a587e..ea568387f5 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -64,13 +64,10 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { } // called on the other nodes - assigns it to my views of the others -int OctreeQuery::parseData(const QByteArray& packet) { - - // increment to push past the packet header - int numBytesPacketHeader = numBytesForPacketHeader(packet); - - const unsigned char* startPosition = reinterpret_cast(packet.data()); - const unsigned char* sourceBuffer = startPosition + numBytesPacketHeader; +int OctreeQuery::parseData(NLPacket& packet, QSharedPointer sendingNode) { + + const unsigned char* startPosition = reinterpret_cast(packet.getPayload()); + const unsigned char* sourceBuffer = startPosition; // camera details memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition)); diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 3c204ff938..83cb828112 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -48,7 +48,7 @@ public: virtual ~OctreeQuery() {} int getBroadcastData(unsigned char* destinationBuffer); - int parseData(const QByteArray& packet); + int parseData(NLPacket& packet, QSharedPointer sendingNode); // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; } From 601e8d6e6863901dc1dd23fe1cc99d27ba041008 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 14:28:46 -0700 Subject: [PATCH 083/146] fix AssignmentClientChildData parseData override --- assignment-client/src/AssignmentClientChildData.cpp | 11 +++++++++++ assignment-client/src/AssignmentClientChildData.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClientChildData.cpp b/assignment-client/src/AssignmentClientChildData.cpp index de34613ec9..cc714e629d 100644 --- a/assignment-client/src/AssignmentClientChildData.cpp +++ b/assignment-client/src/AssignmentClientChildData.cpp @@ -1,3 +1,13 @@ +// +// AssignmentClientChildData.cpp +// assignment-client/src +// +// Created by Stephen Birarda on 07/13/15. +// Copyright 2015 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 "AssignmentClientChildData.h" @@ -5,4 +15,5 @@ AssignmentClientChildData::AssignmentClientChildData(QString childType) : _childType(childType) { + } diff --git a/assignment-client/src/AssignmentClientChildData.h b/assignment-client/src/AssignmentClientChildData.h index 6fd5f72f7f..c8116a9959 100644 --- a/assignment-client/src/AssignmentClientChildData.h +++ b/assignment-client/src/AssignmentClientChildData.h @@ -23,7 +23,7 @@ class AssignmentClientChildData : public NodeData { void setChildType(QString childType) { _childType = childType; } // implement parseData to return 0 so we can be a subclass of NodeData - int parseData(const QByteArray& packet) { return 0; } + int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } private: QString _childType; From d242f5d5d980f76d54baf733f557172bf42816c1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 14:35:03 -0700 Subject: [PATCH 084/146] repair AudioMixerClientData parseData --- .../src/audio/AudioMixerClientData.cpp | 35 +++++++++++-------- .../src/audio/AudioMixerClientData.h | 4 +-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 13cfe4d1a0..59f5982159 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -49,20 +49,18 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() const { return NULL; } -int AudioMixerClientData::parseData(const QByteArray& packet) { - PacketType::Value packetType = packetTypeForPacket(packet); +int AudioMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingNode) { + PacketType::Value packetType = packet.getType(); + if (packetType == PacketType::AudioStreamStats) { - const char* dataAt = packet.data(); - // skip over header, appendFlag, and num stats packed - dataAt += (numBytesForPacketHeader(packet) + sizeof(quint8) + sizeof(quint16)); + packet.seek(sizeof(quint8) + sizeof(quint16)); // read the downstream audio stream stats - memcpy(&_downstreamAudioStreamStats, dataAt, sizeof(AudioStreamStats)); - dataAt += sizeof(AudioStreamStats); + packet.readPrimitive(&_downstreamAudioStreamStats); - return dataAt - packet.data(); + return packet.pos(); } else { PositionalAudioStream* matchingStream = NULL; @@ -76,8 +74,11 @@ int AudioMixerClientData::parseData(const QByteArray& packet) { // we don't have a mic stream yet, so add it // read the channel flag to see if our stream is stereo or not - const char* channelFlagAt = packet.constData() + numBytesForPacketHeader(packet) + sizeof(quint16); - quint8 channelFlag = *(reinterpret_cast(channelFlagAt)); + packet.seek(sizeof(quint16)); + + quint8 channelFlag; + packet.readPrimitive(&channelFlag); + bool isStereo = channelFlag == 1; _audioStreams.insert(nullUUID, matchingStream = new AvatarAudioStream(isStereo, AudioMixer::getStreamSettings())); @@ -88,20 +89,24 @@ int AudioMixerClientData::parseData(const QByteArray& packet) { // this is injected audio // grab the stream identifier for this injected audio - int bytesBeforeStreamIdentifier = numBytesForPacketHeader(packet) + sizeof(quint16); - QUuid streamIdentifier = QUuid::fromRfc4122(packet.mid(bytesBeforeStreamIdentifier, NUM_BYTES_RFC4122_UUID)); - int bytesBeforeStereoIdentifier = bytesBeforeStreamIdentifier + NUM_BYTES_RFC4122_UUID; + packet.seek(sizeof(quint16)); + QUuid streamIdentifier = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); + bool isStereo; - QDataStream(packet.mid(bytesBeforeStereoIdentifier)) >> isStereo; + packet.readPrimitive(&isStereo); if (!_audioStreams.contains(streamIdentifier)) { // we don't have this injected stream yet, so add it - _audioStreams.insert(streamIdentifier, matchingStream = new InjectedAudioStream(streamIdentifier, isStereo, AudioMixer::getStreamSettings())); + _audioStreams.insert(streamIdentifier, + matchingStream = new InjectedAudioStream(streamIdentifier, isStereo, AudioMixer::getStreamSettings())); } else { matchingStream = _audioStreams.value(streamIdentifier); } } + // seek to the beginning of the packet so that the next reader is in the right spot + packet.seek(0); + return matchingStream->parseData(packet); } return 0; diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 4f3f8e360d..99f8683b70 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -25,7 +25,7 @@ class PerListenerSourcePairData { public: - PerListenerSourcePairData() { + PerListenerSourcePairData() { _penumbraFilter.initialize(AudioConstants::SAMPLE_RATE, AudioConstants::NETWORK_FRAME_SAMPLES_STEREO / 2); }; AudioFilterHSF1s& getPenumbraFilter() { return _penumbraFilter; } @@ -42,7 +42,7 @@ public: const QHash& getAudioStreams() const { return _audioStreams; } AvatarAudioStream* getAvatarAudioStream() const; - int parseData(const QByteArray& packet); + int parseData(NLPacket& packet, QSharedPointer sendingNode); void checkBuffersBeforeFrameSend(); From 26be49247539c1eb1ae42f9c7e01ac9c0c6c51c8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 14:46:56 -0700 Subject: [PATCH 085/146] use same listener for many packets in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 40 +++++-------------- assignment-client/src/audio/AudioMixer.h | 10 ++--- .../src/audio/AudioMixerClientData.cpp | 2 +- .../src/avatars/AvatarMixerClientData.cpp | 5 +-- .../src/avatars/AvatarMixerClientData.h | 8 ++-- libraries/networking/src/PacketReceiver.cpp | 2 +- libraries/networking/src/PacketReceiver.h | 2 +- 7 files changed, 23 insertions(+), 46 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 018f946771..54ffb95fbf 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -75,7 +75,7 @@ bool AudioMixer::shouldMute(float quietestFrame) { return (quietestFrame > _noiseMutingThreshold); } -AudioMixer::AudioMixer(const QByteArray& packet) : +AudioMixer::AudioMixer(NLPacket& packet) : ThreadedAssignment(packet), _trailingSleepRatio(1.0f), _minAudibilityThreshold(LOUDNESS_TO_DISTANCE_RATIO / 2.0f), @@ -97,11 +97,14 @@ AudioMixer::AudioMixer(const QByteArray& packet) : // SOON auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::MicrophoneAudioNoEcho, this, "handleMicrophoneAudioNoEchoPacket"); - packetReceiver.registerPacketListener(PacketType::MicrophoneAudioWithEcho, this, "handleMicrophoneAudioWithEchoPacket"); - packetReceiver.registerPacketListener(PacketType::InjectAudio, this, "handleInjectAudioPacket"); - packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFramePacket"); - packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioStreamStatsPacket"); + + QSet nodeAudioPackets { + PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho, + PacketType::InjectAudio, PacketType::SilentAudioFrame, + PacketType::AudioStreamStats + }; + + packetReceiver.registerPacketListenerForSet(nodeAudioPackets, this, "handleNodeAudioPacket"); packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } @@ -543,29 +546,8 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { } } -void AudioMixer::handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); -} - -void AudioMixer::handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); -} - -void AudioMixer::handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); -} - -void AudioMixer::handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); -} - -void AudioMixer::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); +void AudioMixer::handleNodeAudioPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + DependencyManager::get()->updateNodeWithDataFromPacket(packet, sendingNode); } void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 50ec3c6d18..9e7a010f61 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -28,7 +28,7 @@ const int READ_DATAGRAMS_STATS_WINDOW_SECONDS = 30; class AudioMixer : public ThreadedAssignment { Q_OBJECT public: - AudioMixer(const QByteArray& packet); + AudioMixer(NLPacket& packet); void deleteLater() { qDebug() << "DELETE LATER CALLED?"; QObject::deleteLater(); } public slots: @@ -40,12 +40,8 @@ public slots: static const InboundAudioStream::Settings& getStreamSettings() { return _streamSettings; } private slots: - void handleMicrophoneAudioNoEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleMicrophoneAudioWithEchoPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleInjectAudioPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleSilentAudioFramePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleNodeAudioPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: /// adds one stream to the mix for a listening node diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 59f5982159..dc2d60be51 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -107,7 +107,7 @@ int AudioMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingN // seek to the beginning of the packet so that the next reader is in the right spot packet.seek(0); - return matchingStream->parseData(packet); + return matchingStream->parseData(packet, sendingNode); } return 0; } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 197e9baf5e..9f658e1b48 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -13,10 +13,9 @@ #include "AvatarMixerClientData.h" -int AvatarMixerClientData::parseData(const QByteArray& packet) { +int AvatarMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingNode) { // compute the offset to the data payload - int offset = numBytesForPacketHeader(packet); - return _avatar.parseDataAtOffset(packet, offset); + return _avatar.parseDataFromBuffer(QByteArray::fromRawData(packet.getPayload(), packet.getSizeUsed())); } bool AvatarMixerClientData::checkAndSetHasReceivedFirstPackets() { diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 3e10b8473a..4497f17da7 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -31,13 +31,13 @@ const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps"; class AvatarMixerClientData : public NodeData { Q_OBJECT public: - int parseData(const QByteArray& packet); + int parseData(NLPacket& packet, SharedNodePointer sendingNode); AvatarData& getAvatar() { return _avatar; } bool checkAndSetHasReceivedFirstPackets(); PacketSequenceNumber getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const; - void setLastBroadcastSequenceNumber(const QUuid& nodeUUID, PacketSequenceNumber sequenceNumber) + void setLastBroadcastSequenceNumber(const QUuid& nodeUUID, PacketSequenceNumber sequenceNumber) { _lastBroadcastSequenceNumbers[nodeUUID] = sequenceNumber; } Q_INVOKABLE void removeLastBroadcastSequenceNumber(const QUuid& nodeUUID) { _lastBroadcastSequenceNumbers.erase(nodeUUID); } @@ -57,7 +57,7 @@ public: void incrementNumAvatarsSentLastFrame() { ++_numAvatarsSentLastFrame; } int getNumAvatarsSentLastFrame() const { return _numAvatarsSentLastFrame; } - void recordNumOtherAvatarStarves(int numAvatarsHeldBack) { _otherAvatarStarves.updateAverage((float) numAvatarsHeldBack); } + void recordNumOtherAvatarStarves(int numAvatarsHeldBack) { _otherAvatarStarves.updateAverage((float) numAvatarsHeldBack); } float getAvgNumOtherAvatarStarvesPerSecond() const { return _otherAvatarStarves.getAverageSampleValuePerSecond(); } void recordNumOtherAvatarSkips(int numOtherAvatarSkips) { _otherAvatarSkips.updateAverage((float) numOtherAvatarSkips); } @@ -71,7 +71,7 @@ public: void recordSentAvatarData(int numBytes) { _avgOtherAvatarDataRate.updateAverage((float) numBytes); } - float getOutboundAvatarDataKbps() const + float getOutboundAvatarDataKbps() const { return _avgOtherAvatarDataRate.getAverageSampleValuePerSecond() / (float) BYTES_PER_KILOBIT; } void loadJSONStats(QJsonObject& jsonObject) const; diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 6511185fa4..8e6c5c7929 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -24,7 +24,7 @@ PacketReceiver::PacketReceiver(QObject* parent) : } -void PacketReceiver::registerPacketListeners(const QSet& types, QObject* object, const char* slot) { +void PacketReceiver::registerPacketListenerForSet(const QSet& types, QObject* object, const char* slot) { QSet nonSourcedTypes; QSet sourcedTypes; diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index e5b6693fe4..a410e9eef9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -39,7 +39,7 @@ public: void shutdown() { _isShuttingDown = true; } - void registerPacketListeners(const QSet& types, QObject* listener, const char* slot); + void registerPacketListenerForSet(const QSet& types, QObject* listener, const char* slot); void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); public slots: From a4ff18d9ec7173189262abadb8364e830b42c53a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Jul 2015 15:03:10 -0700 Subject: [PATCH 086/146] Remove OctreeServerDatagramProcessor --- .../octree/OctreeServerDatagramProcessor.cpp | 55 ------------------- .../octree/OctreeServerDatagramProcessor.h | 32 ----------- 2 files changed, 87 deletions(-) delete mode 100644 assignment-client/src/octree/OctreeServerDatagramProcessor.cpp delete mode 100644 assignment-client/src/octree/OctreeServerDatagramProcessor.h diff --git a/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp b/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp deleted file mode 100644 index 94249e7517..0000000000 --- a/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// OctreeServerDatagramProcessor.cpp -// assignment-client/src -// -// Created by Brad Hefta-Gaub on 2014-09-05 -// Copyright 2014 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 - -#include -#include -#include -#include - -#include "OctreeServerDatagramProcessor.h" - -OctreeServerDatagramProcessor::OctreeServerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread) : - _nodeSocket(nodeSocket), - _previousNodeSocketThread(previousNodeSocketThread) -{ - -} - -OctreeServerDatagramProcessor::~OctreeServerDatagramProcessor() { - // return the node socket to its previous thread - _nodeSocket.moveToThread(_previousNodeSocketThread); -} - -void OctreeServerDatagramProcessor::readPendingDatagrams() { - - HifiSockAddr senderSockAddr; - static QByteArray incomingPacket; - - // read everything that is available - while (_nodeSocket.hasPendingDatagrams()) { - incomingPacket.resize(_nodeSocket.pendingDatagramSize()); - - // just get this packet off the stack - _nodeSocket.readDatagram(incomingPacket.data(), incomingPacket.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - - PacketType::Value packetType = packetTypeForPacket(incomingPacket); - if (packetType == PacketType::Ping) { - DependencyManager::get()->processNodeData(senderSockAddr, incomingPacket); - return; // don't emit - } - - // emit the signal to tell AudioMixer it needs to process a packet - emit packetRequiresProcessing(incomingPacket, senderSockAddr); - } -} diff --git a/assignment-client/src/octree/OctreeServerDatagramProcessor.h b/assignment-client/src/octree/OctreeServerDatagramProcessor.h deleted file mode 100644 index 8c1d4943dd..0000000000 --- a/assignment-client/src/octree/OctreeServerDatagramProcessor.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// OctreeServerDatagramProcessor.h -// assignment-client/src -// -// Created by Brad Hefta-Gaub on 2014-09-05 -// Copyright 2014 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_OctreeServerDatagramProcessor_h -#define hifi_OctreeServerDatagramProcessor_h - -#include -#include - -class OctreeServerDatagramProcessor : public QObject { - Q_OBJECT -public: - OctreeServerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread); - ~OctreeServerDatagramProcessor(); -public slots: - void readPendingDatagrams(); -signals: - void packetRequiresProcessing(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); -private: - QUdpSocket& _nodeSocket; - QThread* _previousNodeSocketThread; -}; - -#endif // hifi_OctreeServerDatagramProcessor_h \ No newline at end of file From f06636d45ec12eef386beb3ae0599d908168d671 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:16:55 -0700 Subject: [PATCH 087/146] repairs for other ThreadedAssignment subclasses --- assignment-client/src/Agent.cpp | 16 +++-- assignment-client/src/Agent.h | 8 +-- assignment-client/src/audio/AudioMixer.cpp | 12 ++-- assignment-client/src/avatars/AvatarMixer.cpp | 4 +- assignment-client/src/avatars/AvatarMixer.h | 2 +- .../octree/OctreeInboundPacketProcessor.cpp | 66 +++++++++---------- .../src/octree/OctreeInboundPacketProcessor.h | 18 ++--- assignment-client/src/octree/OctreeServer.cpp | 13 ++-- assignment-client/src/octree/OctreeServer.h | 2 +- libraries/networking/src/PacketReceiver.cpp | 2 +- libraries/networking/src/PacketReceiver.h | 2 +- libraries/octree/src/OctreeRenderer.cpp | 2 +- 12 files changed, 75 insertions(+), 72 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0037f989ef..449d8b5362 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -32,7 +32,7 @@ static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 10; -Agent::Agent(const QByteArray& packet) : +Agent::Agent(NLPacket& packet) : ThreadedAssignment(packet), _entityEditSender(), _receivedAudioStream(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO, RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES, @@ -49,15 +49,17 @@ Agent::Agent(const QByteArray& packet) : DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioPacket"); - packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioPacket"); - packetReceiver.registerPacketListener(PacketType::OctreeStats, this, "handleOctreePacket"); - packetReceiver.registerPacketListener(PacketType::EntityData, this, "handleOctreePacket"); - packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleOctreePacket"); + + packetReceiver.registerPacketListenerForTypes( + QSet({ PacketType::MixedAudio, PacketType::SilentAudioFrame }), + this, "handleAudioPacket"); + packetReceiver.registerPacketListenerForTypes( + QSet({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }), + this, "handleOctreePacket"); packetReceiver.registerPacketListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); } -void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { QByteArray mutablePacket = QByteArray(packet->getData(), packet->getSizeWithHeader()); int messageLength = mutablePacket.size(); diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 3e202f2d0d..840c1d6d22 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -35,7 +35,7 @@ class Agent : public ThreadedAssignment { Q_PROPERTY(bool isListeningToAudioStream READ isListeningToAudioStream WRITE setIsListeningToAudioStream) Q_PROPERTY(float lastReceivedAudioLoudness READ getLastReceivedAudioLoudness) public: - Agent(const QByteArray& packet); + Agent(NLPacket& packet); void setIsAvatar(bool isAvatar) { QMetaObject::invokeMethod(&_scriptEngine, "setIsAvatar", Q_ARG(bool, isAvatar)); } bool isAvatar() const { return _scriptEngine.isAvatar(); } @@ -55,9 +55,9 @@ public slots: void playAvatarSound(Sound* avatarSound) { _scriptEngine.setAvatarSound(avatarSound); } private slots: - void handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode); private: ScriptEngine _scriptEngine; diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 54ffb95fbf..19b9ebe868 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -104,7 +104,7 @@ AudioMixer::AudioMixer(NLPacket& packet) : PacketType::AudioStreamStats }; - packetReceiver.registerPacketListenerForSet(nodeAudioPackets, this, "handleNodeAudioPacket"); + packetReceiver.registerPacketListenerForTypes(nodeAudioPackets, this, "handleNodeAudioPacket"); packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } @@ -475,7 +475,6 @@ int AudioMixer::prepareMixForListeningNode(Node* node) { } void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { - static char clientEnvBuffer[MAX_PACKET_SIZE]; // Send stream properties bool hasReverb = false; @@ -501,6 +500,7 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { break; } } + AudioMixerClientData* nodeData = static_cast(node->getLinkedData()); AvatarAudioStream* stream = nodeData->getAvatarAudioStream(); bool dataChanged = (stream->hasReverb() != hasReverb) || @@ -550,13 +550,13 @@ void AudioMixer::handleNodeAudioPacket(QSharedPointer packet, SharedNo DependencyManager::get()->updateNodeWithDataFromPacket(packet, sendingNode); } -void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto nodeList = DependencyManager::get(); - SharedNodePointer sendingNode = nodeList->nodeWithUUID(packet->getSourceID()); + if (sendingNode->getCanAdjustLocks()) { - auto newPacket = NLPacket::create(PacketType::MuteEnvironment); + auto newPacket = NLPacket::create(PacketType::MuteEnvironment, packet->getSizeUsed()); // Copy payload - newPacket->write(newPacket->getPayload()); + newPacket->write(packet->getPayload(), packet->getSizeUsed()); nodeList->eachNode([&](const SharedNodePointer& node){ if (node->getType() == NodeType::Agent && node->getActiveSocket() && diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 3559793ff5..35cd3d4885 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -33,7 +33,7 @@ const QString AVATAR_MIXER_LOGGING_NAME = "avatar-mixer"; const int AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND = 60; const unsigned int AVATAR_DATA_SEND_INTERVAL_MSECS = (1.0f / (float) AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND) * 1000; -AvatarMixer::AvatarMixer(const QByteArray& packet) : +AvatarMixer::AvatarMixer(NLPacket& packet) : ThreadedAssignment(packet), _broadcastThread(), _lastFrameTimestamp(QDateTime::currentMSecsSinceEpoch()), @@ -402,7 +402,7 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) { void AvatarMixer::handleAvatarDataPacket(QSharedPointer packet, SharedNodePointer senderNode) { auto nodeList = DependencyManager::get(); - nodeList->findNodeAndUpdateWithDataFromPacket(packet); + nodeList->updateNodeWithDataFromPacket(packet, senderNode); } void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer senderNode) { diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 90473f754f..d0ced8cdfd 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -20,7 +20,7 @@ /// Handles assignments of type AvatarMixer - distribution of avatar data to various clients class AvatarMixer : public ThreadedAssignment { public: - AvatarMixer(const QByteArray& packet); + AvatarMixer(NLPacket& packet); ~AvatarMixer(); public slots: /// runs the avatar mixer diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 613eec18df..e71ab5e848 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -74,7 +74,7 @@ void OctreeInboundPacketProcessor::midProcess() { } } -void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { +void OctreeInboundPacketProcessor::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { if (_shuttingDown) { qDebug() << "OctreeInboundPacketProcessor::processPacket() while shutting down... ignoring incoming packet"; return; @@ -83,22 +83,24 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin bool debugProcessPacket = _myServer->wantsVerboseDebug(); if (debugProcessPacket) { - qDebug("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%d", &packet, packet.size()); + qDebug("OctreeInboundPacketProcessor::processPacket() payload=%p payloadLength=%lld", + packet->getPayload(), + packet->getSizeUsed()); } - int numBytesPacketHeader = numBytesForPacketHeader(packet); - - // Ask our tree subclass if it can handle the incoming packet... - PacketType::Value packetType = packetTypeForPacket(packet); + PacketType::Value packetType = packet->getType(); + if (_myServer->getOctree()->handlesEditPacketType(packetType)) { - PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket); + PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket); _receivedPacketCount++; - const unsigned char* packetData = reinterpret_cast(packet.data()); + unsigned short int sequence; + packet->readPrimitive(&sequence); - unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader))); - quint64 sentAt = (*((quint64*)(packetData + numBytesPacketHeader + sizeof(sequence)))); + quint64 sentAt; + packet->readPrimitive(&sentAt); + quint64 arrivedAt = usecTimestampNow(); if (sentAt > arrivedAt) { if (debugProcessPacket || _myServer->wantsDebugReceiving()) { @@ -107,6 +109,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin } sentAt = arrivedAt; } + quint64 transitTime = arrivedAt - sentAt; int editsInPacket = 0; quint64 processTime = 0; @@ -114,7 +117,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin if (debugProcessPacket || _myServer->wantsDebugReceiving()) { qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount << " command from client"; - qDebug() << " receivedBytes=" << packet.size(); + qDebug() << " receivedBytes=" << packet->getSizeWithHeader(); qDebug() << " sequence=" << sequence; qDebug() << " sentAt=" << sentAt << " usecs"; qDebug() << " arrivedAt=" << arrivedAt << " usecs"; @@ -125,42 +128,41 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin } if (debugProcessPacket) { - qDebug() << " numBytesPacketHeader=" << numBytesPacketHeader; + qDebug() << " numBytesPacketHeader=" << packet->localHeaderSize(); qDebug() << " sizeof(sequence)=" << sizeof(sequence); qDebug() << " sizeof(sentAt)=" << sizeof(sentAt); } - int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt); - if (debugProcessPacket) { - qDebug() << " atByte=" << atByte; - qDebug() << " packet.size()=" << packet.size(); - if (atByte >= packet.size()) { + qDebug() << " atByte (in payload)=" << packet->pos(); + qDebug() << " payload size=" << packet->getSizeUsed(); + if (!packet->bytesAvailable()) { qDebug() << " ----- UNEXPECTED ---- got a packet without any edit details!!!! --------"; } } + + const unsigned char* editData = nullptr; + while (packet->bytesAvailable() > 0) { - unsigned char* editData = (unsigned char*)&packetData[atByte]; - while (atByte < packet.size()) { + editData = reinterpret_cast(packet->getPayload() + packet->pos()); - int maxSize = packet.size() - atByte; + int maxSize = packet->bytesAvailable(); if (debugProcessPacket) { qDebug() << " --- inside while loop ---"; qDebug() << " maxSize=" << maxSize; qDebug("OctreeInboundPacketProcessor::processPacket() %c " - "packetData=%p packetLength=%d editData=%p atByte=%d maxSize=%d", - packetType, packetData, packet.size(), editData, atByte, maxSize); + "payload=%p payloadLength=%lld editData=%p payloadPosition=%lld maxSize=%d", + packetType, packet->getPayload(), packet->getSizeUsed(), editData, + packet->pos(), maxSize); } quint64 startLock = usecTimestampNow(); _myServer->getOctree()->lockForWrite(); quint64 startProcess = usecTimestampNow(); - int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType, - reinterpret_cast(packet.data()), - packet.size(), - editData, maxSize, sendingNode); + int editDataBytesRead = + _myServer->getOctree()->processEditPacketData(*packet, editData, maxSize, sendingNode); if (debugProcessPacket) { qDebug() << "OctreeInboundPacketProcessor::processPacket() after processEditPacketData()..." @@ -177,27 +179,25 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin lockWaitTime += thisLockWaitTime; // skip to next edit record in the packet - editData += editDataBytesRead; - atByte += editDataBytesRead; + packet->seek(packet->pos() + editDataBytesRead); if (debugProcessPacket) { qDebug() << " editDataBytesRead=" << editDataBytesRead; - qDebug() << " AFTER processEditPacketData atByte=" << atByte; - qDebug() << " AFTER processEditPacketData packet.size()=" << packet.size(); + qDebug() << " AFTER processEditPacketData payload position=" << packet->pos(); + qDebug() << " AFTER processEditPacketData payload size=" << packet->getSizeUsed(); } } if (debugProcessPacket) { qDebug("OctreeInboundPacketProcessor::processPacket() DONE LOOPING FOR %c " - "packetData=%p packetLength=%d editData=%p atByte=%d", - packetType, packetData, packet.size(), editData, atByte); + "payload=%p payloadLength=%lld editData=%p payloadPosition=%lld", + packetType, packet->getPayload(), packet->getSizeUsed(), editData, packet->pos()); } // Make sure our Node and NodeList knows we've heard from this node. QUuid& nodeUUID = DEFAULT_NODE_ID_REF; if (sendingNode) { - sendingNode->setLastHeardMicrostamp(usecTimestampNow()); nodeUUID = sendingNode->getUUID(); if (debugProcessPacket) { qDebug() << "sender has uuid=" << nodeUUID; diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.h b/assignment-client/src/octree/OctreeInboundPacketProcessor.h index 156e09b493..3ddb76b3fa 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.h +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.h @@ -29,9 +29,9 @@ public: quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; } quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; } quint64 getTotalPacketsProcessed() const { return _totalPackets; } - quint64 getAverageProcessTimePerElement() const + quint64 getAverageProcessTimePerElement() const { return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; } - quint64 getAverageLockWaitTimePerElement() const + quint64 getAverageLockWaitTimePerElement() const { return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; } const SequenceNumberStats& getIncomingEditSequenceNumberStats() const { return _incomingEditSequenceNumberStats; } @@ -40,7 +40,7 @@ public: void trackInboundPacket(unsigned short int incomingSequence, quint64 transitTime, int editsInPacket, quint64 processTime, quint64 lockWaitTime); - quint64 _totalTransitTime; + quint64 _totalTransitTime; quint64 _totalProcessTime; quint64 _totalLockWaitTime; quint64 _totalElementsInPacket; @@ -53,7 +53,7 @@ typedef QHash::iterator NodeToSenderStatsMapIterator; typedef QHash::const_iterator NodeToSenderStatsMapConstIterator; -/// Handles processing of incoming network packets for the octee servers. As with other ReceivedPacketProcessor classes +/// Handles processing of incoming network packets for the octee servers. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() class OctreeInboundPacketProcessor : public ReceivedPacketProcessor { Q_OBJECT @@ -65,9 +65,9 @@ public: quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; } quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; } quint64 getTotalPacketsProcessed() const { return _totalPackets; } - quint64 getAverageProcessTimePerElement() const + quint64 getAverageProcessTimePerElement() const { return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; } - quint64 getAverageLockWaitTimePerElement() const + quint64 getAverageLockWaitTimePerElement() const { return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; } void resetStats(); @@ -78,7 +78,7 @@ public: protected: - virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); + virtual void processPacket(QSharedPointer packet, SharedNodePointer sendingNode); virtual unsigned long getMaxWait() const; virtual void preProcess(); @@ -88,13 +88,13 @@ private: int sendNackPackets(); private: - void trackInboundPacket(const QUuid& nodeUUID, unsigned short int sequence, quint64 transitTime, + void trackInboundPacket(const QUuid& nodeUUID, unsigned short int sequence, quint64 transitTime, int elementsInPacket, quint64 processTime, quint64 lockWaitTime); OctreeServer* _myServer; int _receivedPacketCount; - quint64 _totalTransitTime; + quint64 _totalTransitTime; quint64 _totalProcessTime; quint64 _totalLockWaitTime; quint64 _totalElementsInPacket; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 2488c92439..3002474714 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -213,7 +213,7 @@ void OctreeServer::trackProcessWaitTime(float time) { _averageProcessWaitTime.updateAverage(time); } -OctreeServer::OctreeServer(const QByteArray& packet) : +OctreeServer::OctreeServer(NLPacket& packet) : ThreadedAssignment(packet), _argc(0), _argv(NULL), @@ -247,11 +247,6 @@ OctreeServer::OctreeServer(const QByteArray& packet) : // make sure the AccountManager has an Auth URL for payment redemptions AccountManager::getInstance().setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); - - auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); - packetReceiver.registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); - packetReceiver.registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); } OctreeServer::~OctreeServer() { @@ -1108,6 +1103,12 @@ void OctreeServer::readConfiguration() { } void OctreeServer::run() { + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver.registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); + packetReceiver.registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); + _safeServerName = getMyServerName(); // Before we do anything else, create our tree... diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index df36580f57..e55af02715 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -32,7 +32,7 @@ const int DEFAULT_PACKETS_PER_INTERVAL = 2000; // some 120,000 packets per secon class OctreeServer : public ThreadedAssignment, public HTTPRequestHandler { Q_OBJECT public: - OctreeServer(const QByteArray& packet); + OctreeServer(NLPacket& packet); ~OctreeServer(); /// allows setting of run arguments diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 8e6c5c7929..7d40ba9187 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -24,7 +24,7 @@ PacketReceiver::PacketReceiver(QObject* parent) : } -void PacketReceiver::registerPacketListenerForSet(const QSet& types, QObject* object, const char* slot) { +void PacketReceiver::registerPacketListenerForTypes(const QSet& types, QObject* object, const char* slot) { QSet nonSourcedTypes; QSet sourcedTypes; diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index a410e9eef9..4caae47076 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -39,7 +39,7 @@ public: void shutdown() { _isShuttingDown = true; } - void registerPacketListenerForSet(const QSet& types, QObject* listener, const char* slot); + void registerPacketListenerForTypes(const QSet& types, QObject* listener, const char* slot); void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); public slots: diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 17ed302a9a..54ce95b803 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -110,7 +110,7 @@ void OctreeRenderer::processDatagram(NLPacket& packet, SharedNodePointer sourceN while (packet.bytesAvailable() && !error) { if (packetIsCompressed) { - if (packet.bytesAvailable() > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { + if (packet.bytesAvailable() > (qint64) sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { packet.readPrimitive(§ionLength); } else { sectionLength = 0; From 9d4f9aa21e24ebbada350bb5c9594543d3d21a64 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:38:45 -0700 Subject: [PATCH 088/146] final fixes to get ACs building again --- assignment-client/src/Agent.cpp | 32 ++++++----- assignment-client/src/AssignmentClient.cpp | 2 +- assignment-client/src/AssignmentFactory.cpp | 6 +- assignment-client/src/AssignmentFactory.h | 2 +- .../src/entities/EntityServer.cpp | 13 +++-- assignment-client/src/entities/EntityServer.h | 8 +-- assignment-client/src/octree/OctreeServer.cpp | 55 ++----------------- assignment-client/src/octree/OctreeServer.h | 9 +-- libraries/networking/src/NodeList.h | 1 - libraries/octree/src/JurisdictionSender.h | 2 +- 10 files changed, 42 insertions(+), 88 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 449d8b5362..a333f4afdd 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -60,34 +60,38 @@ Agent::Agent(NLPacket& packet) : } void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { - QByteArray mutablePacket = QByteArray(packet->getData(), packet->getSizeWithHeader()); - int messageLength = mutablePacket.size(); - auto packetType = packet->getType(); if (packetType == PacketType::OctreeStats) { int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(packet, senderNode); - if (messageLength > statsMessageLength) { - mutablePacket = mutablePacket.mid(statsMessageLength); + if (packet->getSizeUsed() > statsMessageLength) { + // pull out the piggybacked packet and create a new QSharedPointer for it + int packetSizeWithHeader = packet->getSizeUsed() - statsMessageLength; + + std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); + memcpy(buffer.get(), packet->getPayload() + statsMessageLength, packetSizeWithHeader); + + auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, packet->getSenderSockAddr()); + packet = QSharedPointer(newPacket.release()); } else { return; // bail since no piggyback data } - packetType = packetTypeForPacket(mutablePacket); + packetType = packet->getType(); } // fall through to piggyback message if (packetType == PacketType::EntityData || packetType == PacketType::EntityErase) { - _entityViewer.processDatagram(mutablePacket, senderNode); + _entityViewer.processDatagram(*packet, senderNode); } } -void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - QByteArray receivedPacket = QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader()); - int headerBytes = numBytesForPacketHeader(receivedPacket); - +void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode) { + NodeType_t nodeType; + packet->peek(reinterpret_cast(&nodeType), sizeof(nodeType)); + // PacketType_JURISDICTION, first byte is the node type... - switch (receivedPacket[headerBytes]) { + switch (nodeType) { case NodeType::EntityServer: DependencyManager::get()->getJurisdictionListener()-> queueReceivedPacket(packet, senderNode); @@ -95,8 +99,8 @@ void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNode } } -void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - _receivedAudioStream.parseData(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); +void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode) { + _receivedAudioStream.parseData(*packet, senderNode); _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 499ed93c89..e6934e8b1b 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -210,7 +210,7 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer pac qDebug() << "Received a PacketType::CreateAssignment - attempting to unpack."; // construct the deployed assignment from the packet data - _currentAssignment = AssignmentFactory::unpackAssignment(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + _currentAssignment = AssignmentFactory::unpackAssignment(*packet); if (_currentAssignment) { qDebug() << "Received an assignment -" << *_currentAssignment; diff --git a/assignment-client/src/AssignmentFactory.cpp b/assignment-client/src/AssignmentFactory.cpp index 4dafd64a92..705ff5179b 100644 --- a/assignment-client/src/AssignmentFactory.cpp +++ b/assignment-client/src/AssignmentFactory.cpp @@ -17,12 +17,10 @@ #include "avatars/AvatarMixer.h" #include "entities/EntityServer.h" -ThreadedAssignment* AssignmentFactory::unpackAssignment(const QByteArray& packet) { - QDataStream packetStream(packet); - packetStream.skipRawData(numBytesForPacketHeader(packet)); +ThreadedAssignment* AssignmentFactory::unpackAssignment(NLPacket& packet) { quint8 packedType; - packetStream >> packedType; + packet.peek(reinterpret_cast(&packedType), sizeof(packedType)); Assignment::Type unpackedType = (Assignment::Type) packedType; diff --git a/assignment-client/src/AssignmentFactory.h b/assignment-client/src/AssignmentFactory.h index 9c197f5747..3c1fef99ef 100644 --- a/assignment-client/src/AssignmentFactory.h +++ b/assignment-client/src/AssignmentFactory.h @@ -16,7 +16,7 @@ class AssignmentFactory { public: - static ThreadedAssignment* unpackAssignment(const QByteArray& packet); + static ThreadedAssignment* unpackAssignment(NLPacket& packet); }; #endif // hifi_AssignmentFactory_h diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index bdd619ccf1..3dee2af464 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -21,9 +21,10 @@ const char* MODEL_SERVER_NAME = "Entity"; const char* MODEL_SERVER_LOGGING_TARGET_NAME = "entity-server"; const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo"; -EntityServer::EntityServer(const QByteArray& packet) - : OctreeServer(packet), _entitySimulation(NULL) { - +EntityServer::EntityServer(NLPacket& packet) : + OctreeServer(packet), + _entitySimulation(NULL) +{ auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); packetReceiver.registerPacketListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); @@ -40,19 +41,19 @@ EntityServer::~EntityServer() { tree->removeNewlyCreatedHook(this); } -void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode) { if (_octreeInboundPacketProcessor) { _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } } -void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode) { if (_octreeInboundPacketProcessor) { _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } } -void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode) { if (_octreeInboundPacketProcessor) { _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index cacf8f3457..dde68dfebd 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -22,7 +22,7 @@ class EntityServer : public OctreeServer, public NewlyCreatedEntityHook { Q_OBJECT public: - EntityServer(const QByteArray& packet); + EntityServer(NLPacket& packet); ~EntityServer(); // Subclasses must implement these methods @@ -50,9 +50,9 @@ protected: virtual Octree* createTree(); private slots: - void handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode); private: EntitySimulation* _entitySimulation; diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 3002474714..9b93b3895e 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -813,53 +813,11 @@ void OctreeServer::parsePayload() { } } -void OctreeServer::readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - auto nodeList = DependencyManager::get(); - - // If we know we're shutting down we just drop these packets on the floor. - // This stops us from initializing send threads we just shut down. - - if (!_isShuttingDown) { - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - PacketType::Value packetType = packetTypeForPacket(receivedPacket); - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (packetType == getMyQueryMessageType()) { - // If we got a query packet, then we're talking to an agent, and we - // need to make sure we have it in our nodeList. - if (matchingNode) { - nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket); - - OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); - if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { - nodeData->initializeOctreeSendThread(this, matchingNode); - } - } - } else if (packetType == PacketType::OctreeDataNack) { - // If we got a nack packet, then we're talking to an agent, and we - // need to make sure we have it in our nodeList. - if (matchingNode) { - OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); - if (nodeData) { - nodeData->parseNackPacket(receivedPacket); - } - } - } else if (packetType == PacketType::JurisdictionRequest) { - _jurisdictionSender->queueReceivedPacket(matchingNode, receivedPacket); - } else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) { - _octreeInboundPacketProcessor->queueReceivedPacket(matchingNode, receivedPacket); - } else { - // let processNodeData handle it. - DependencyManager::get()->processNodeData(senderSockAddr, receivedPacket); - } - } - } -} - -void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode) { // If we got a query packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. auto nodeList = DependencyManager::get(); - nodeList->updateNodeWithDataFromPacket(senderNode, packet->getData()); + nodeList->updateNodeWithDataFromPacket(packet, senderNode); OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { @@ -867,7 +825,7 @@ void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, Shar } } -void OctreeServer::handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void OctreeServer::handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode) { // If we got a nack packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); @@ -876,8 +834,8 @@ void OctreeServer::handleOctreeDataNackPacket(QSharedPointer packet, S } } -void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { - _jurisdictionSender->queueReceivedPacket(senderNode, packet->getData()); +void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode) { + _jurisdictionSender->queueReceivedPacket(packet, senderNode); } void OctreeServer::setupDatagramProcessingThread() { @@ -902,9 +860,6 @@ void OctreeServer::setupDatagramProcessingThread() { connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, datagramProcessor, &OctreeServerDatagramProcessor::readPendingDatagrams); - // connect to the datagram processing thread signal that tells us we have to handle a packet - connect(datagramProcessor, &OctreeServerDatagramProcessor::packetRequiresProcessing, this, &OctreeServer::readPendingDatagram); - // delete the datagram processor and the associated thread when the QThread quits connect(_datagramProcessingThread, &QThread::finished, datagramProcessor, &QObject::deleteLater); connect(datagramProcessor, &QObject::destroyed, _datagramProcessingThread, &QThread::deleteLater); diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index e55af02715..bcc9f8cc43 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -125,13 +125,10 @@ public slots: void nodeKilled(SharedNodePointer node); void sendStatsPacket(); - void readPendingDatagrams() { }; // this will not be called since our datagram processing thread will handle - void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); - private slots: - void handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleOctreeQueryPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleJurisdictionRequestPacket(QSharedPointer packet, SharedNodePointer senderNode); protected: virtual Octree* createTree() = 0; diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 6578326f4a..65bd6a6983 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -63,7 +63,6 @@ public: void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); } void processReceivedPacket(std::unique_ptr, HifiSockAddr senderSockAddr); - void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void sendAssignment(Assignment& assignment); diff --git a/libraries/octree/src/JurisdictionSender.h b/libraries/octree/src/JurisdictionSender.h index a9b6fb03b5..dd0ff44a11 100644 --- a/libraries/octree/src/JurisdictionSender.h +++ b/libraries/octree/src/JurisdictionSender.h @@ -38,7 +38,7 @@ public: void setNodeType(NodeType_t type) { _nodeType = type; } protected: - virtual void processPacket(QSharedPointer pack, SharedNodePointer sendingNode); + virtual void processPacket(QSharedPointer packet, SharedNodePointer sendingNode); /// Locks all the resources of the thread. void lockRequestingNodes() { _requestingNodeMutex.lock(); } From 49ee35a41c85ff47e8b098bd01308e28f50844ca Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:39:35 -0700 Subject: [PATCH 089/146] remove call to processNodeData --- assignment-client/src/octree/OctreeServerDatagramProcessor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp b/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp index 94249e7517..2bb1a03bdb 100644 --- a/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp +++ b/assignment-client/src/octree/OctreeServerDatagramProcessor.cpp @@ -25,7 +25,7 @@ OctreeServerDatagramProcessor::OctreeServerDatagramProcessor(QUdpSocket& nodeSoc } -OctreeServerDatagramProcessor::~OctreeServerDatagramProcessor() { +OctreeServerDatagramProcessor::~OctreeServerDatagramProcessor() { // return the node socket to its previous thread _nodeSocket.moveToThread(_previousNodeSocketThread); } @@ -45,7 +45,6 @@ void OctreeServerDatagramProcessor::readPendingDatagrams() { PacketType::Value packetType = packetTypeForPacket(incomingPacket); if (packetType == PacketType::Ping) { - DependencyManager::get()->processNodeData(senderSockAddr, incomingPacket); return; // don't emit } From 57c3f0fd208b0909c6919b09ba096cdd6686c373 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:40:20 -0700 Subject: [PATCH 090/146] fix unmatched diagnostic pop --- libraries/audio-client/src/AudioClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index ef7a16f983..fc515c0c4c 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -43,7 +43,7 @@ extern "C" { #include } -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif From 34f9b1881ef4b059c0c7aa9425a80541baaa679d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:40:55 -0700 Subject: [PATCH 091/146] fix registration of OctreePacketProcessor for set of types --- interface/src/octree/OctreePacketProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index b9a111aa3f..80528612b6 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -24,7 +24,7 @@ OctreePacketProcessor::OctreePacketProcessor() { PacketType::EntityErase, PacketType::OctreeStats, PacketType::EnvironmentData }; - packetReceiver.registerPacketListeners(types, this, "handleOctreePacket"); + packetReceiver.registerPacketListenerForTypes(types, this, "handleOctreePacket"); } void OctreePacketProcessor::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { From 8d38cd567091f8290334cb516f5e77e857ba0e39 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 15:58:44 -0700 Subject: [PATCH 092/146] use a specific packet type for AC child status --- assignment-client/src/AssignmentClient.cpp | 21 ++++-- assignment-client/src/AssignmentClient.h | 4 +- .../src/AssignmentClientChildData.h | 6 +- .../src/AssignmentClientMonitor.cpp | 75 +++++++++++-------- .../src/AssignmentClientMonitor.h | 3 +- libraries/networking/src/PacketHeaders.cpp | 3 +- libraries/networking/src/PacketHeaders.h | 2 +- 7 files changed, 64 insertions(+), 50 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index e6934e8b1b..2f5dacc52a 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -160,23 +160,28 @@ void AssignmentClient::aboutToQuit() { } -void AssignmentClient::setUpStatsToMonitor() { +void AssignmentClient::setUpStatusToMonitor() { // send a stats packet every 1 seconds - connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatsPacketToACM); + connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatusPacketToACM); _statsTimerACM.start(1000); } -void AssignmentClient::sendStatsPacketToACM() { +void AssignmentClient::sendStatusPacketToACM() { // tell the assignment client monitor what this assignment client is doing (if anything) - QJsonObject statsObject; auto nodeList = DependencyManager::get(); + auto statusPacket = NLPacket::create(PacketType::AssignmentClientStatus, 1 + NUM_BYTES_RFC4122_UUID); + + quint8 assignmentType = Assignment::Type::AllTypes; + if (_currentAssignment) { - statsObject["assignment_type"] = _currentAssignment->getTypeName(); - } else { - statsObject["assignment_type"] = "none"; + assignmentType = _currentAssignment->getType(); } - nodeList->sendStats(statsObject, _assignmentClientMonitorSocket); + + statusPacket->write(nodeList->getSessionUUID().toRfc4122()); + statusPacket->writePrimitive(assignmentType); + + nodeList->sendPacket(statusPacket, _assignmentClientMonitorSocket); } void AssignmentClient::sendAssignmentRequest() { diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 268683fa3c..23e28968ed 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -30,7 +30,7 @@ private slots: void sendAssignmentRequest(); void assignmentCompleted(); void handleAuthenticationRequest(); - void sendStatsPacketToACM(); + void sendStatusPacketToACM(); void stopAssignmentClient(); public slots: @@ -41,7 +41,7 @@ private slots: void handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); private: - void setUpStatsToMonitor(); + void setUpStatusToMonitor(); Assignment _requestAssignment; QPointer _currentAssignment; diff --git a/assignment-client/src/AssignmentClientChildData.h b/assignment-client/src/AssignmentClientChildData.h index c8116a9959..77d8bd7e31 100644 --- a/assignment-client/src/AssignmentClientChildData.h +++ b/assignment-client/src/AssignmentClientChildData.h @@ -19,14 +19,14 @@ class AssignmentClientChildData : public NodeData { public: AssignmentClientChildData(QString childType); - QString getChildType() { return _childType; } - void setChildType(QString childType) { _childType = childType; } + Assignment::Type getChildType() { return _childType; } + void setChildType(Assignment::Type childType) { _childType = childType; } // implement parseData to return 0 so we can be a subclass of NodeData int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } private: - QString _childType; + Assignment::Type _childType; }; #endif // hifi_AssignmentClientChildData_h diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 5498322f58..6cc1577dea 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -54,8 +54,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto nodeList = DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsPacket"); - packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "handleNodeJsonStatsUnknownNodePacket"); + packetReceiver.registerPacketListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket"); // use QProcess to fork off a process for each of the child assignment clients for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { @@ -203,43 +202,53 @@ void AssignmentClientMonitor::checkSpares() { } } -void AssignmentClientMonitor::handleNodeJsonStatsPacket(QSharedPointer packet, SharedNodePointer senderNode) { - auto senderSockAddr = packet->getSenderSockAddr(); +void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer packet) { + QUuid senderUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); - // update our records about how to reach this child - senderNode->setLocalSocket(senderSockAddr); + auto nodeList = DependencyManager::get(); - QVariantMap packetVariantMap = JSONBreakableMarshal::fromStringBuffer(packet->getPayload()); - QJsonObject unpackedStatsJSON = QJsonObject::fromVariantMap(packetVariantMap); + SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderUUID); + const HifiSockAddr* senderSockAddr = packet->getSendingSockAddr(); - // get child's assignment type out of the decoded json - QString childType = unpackedStatsJSON["assignment_type"].toString(); - AssignmentClientChildData *childData = - static_cast(senderNode->getLinkedData()); - childData->setChildType(childType); - // note when this child talked - senderNode->setLastHeardMicrostamp(usecTimestampNow()); -} + AssignmentClientChildData *childData = nullptr; -void AssignmentClientMonitor::handleNodeJsonStatsUnknownNodePacket(QSharedPointer packet, SharedNodePointer senderNode) { - auto senderSockAddr = packet->getSenderSockAddr(); + if (!matchingNode) { + // The parent only expects to be talking with prorams running on this same machine. + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || + senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + + if (!senderUUID.isNull()) { + // We don't have this node yet - we should add it + matchingNode = DependencyManager::get()->addOrUpdateNode + (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); + + childData = new AssignmentClientChildData("unknown"); + senderNode->setLinkedData(childData); + } else { + // tell unknown assignment-client child to exit. + qDebug() << "Asking unknown child at" << senderSockAddr << "to exit."; - // The parent only expects to be talking with prorams running on this same machine. - if (senderSockAddr.getAddress() == QHostAddress::LocalHost || - senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { - QUuid packetUUID = uuidFromPacketHeader(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - if (!packetUUID.isNull()) { - senderNode = DependencyManager::get()->addOrUpdateNode - (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); - AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); - senderNode->setLinkedData(childData); - } else { - // tell unknown assignment-client child to exit. - qDebug() << "asking unknown child to exit."; + auto diePacket = NLPacket::create(PacketType::StopNode, 0); + nodeList->sendPacket(std::move(diePacket), senderSockAddr); - auto diePacket = NLPacket::create(PacketType::StopNode, 0); - auto nodeList = DependencyManager::get(); - nodeList->sendPacket(std::move(diePacket), senderSockAddr); + return; + } } + } else { + childData = dynamic_cast(senderNode->getLinkedData()); + } + + if (childData) { + // update our records about how to reach this child + matchingNode->setLocalSocket(senderSockAddr); + + // get child's assignment type out of the packet + quint8 assignmentType; + packet->readPrimitive(&assignmentType); + + childData->setChildType((Assignment::Type) assignmentType); + + // note when this child talked + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); } } diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 0c2b958f5c..895e0defb2 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -37,8 +37,7 @@ public: private slots: void checkSpares(); void childProcessFinished(); - void handleNodeJsonStatsPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleNodeJsonStatsUnknownNodePacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleChildStatusPacket(QSharedPointer packet); public slots: void aboutToQuit(); diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 6fdd421ea0..cb5f1c312d 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -33,7 +33,8 @@ const QSet NON_SOURCED_PACKETS = QSet() << DomainServerPathQuery << DomainServerPathResponse << DomainServerAddedNode << ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat - << ICEPing << ICEPingReply; + << ICEPing << ICEPingReply + << AssignmentClientStatus; int arithmeticCodingValueFromBuffer(const char* checkValue) { if (((uchar) *checkValue) < 255) { diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 2f7eac3a63..bc7f0fe3df 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -57,7 +57,7 @@ namespace PacketType { OctreeStats, Jurisdiction, JurisdictionRequest, - UNUSED_6, + AssignmentClientStatus, UNUSED_7, // 30 UNUSED_8, UNUSED_9, From 1c9f43e5aa6a576723fcefd89e3ee1f6d8f00f1e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 16:03:05 -0700 Subject: [PATCH 093/146] compile fixes for AC status packet --- assignment-client/src/AssignmentClient.cpp | 4 ++-- .../src/AssignmentClientChildData.cpp | 2 +- .../src/AssignmentClientChildData.h | 2 +- .../src/AssignmentClientMonitor.cpp | 18 +++++++++--------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 2f5dacc52a..9957619134 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -118,7 +118,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri qDebug() << "Assignment-client monitor socket is" << _assignmentClientMonitorSocket; // Hook up a timer to send this child's status to the Monitor once per second - setUpStatsToMonitor(); + setUpStatusToMonitor(); } auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); @@ -181,7 +181,7 @@ void AssignmentClient::sendStatusPacketToACM() { statusPacket->write(nodeList->getSessionUUID().toRfc4122()); statusPacket->writePrimitive(assignmentType); - nodeList->sendPacket(statusPacket, _assignmentClientMonitorSocket); + nodeList->sendPacket(std::move(statusPacket), _assignmentClientMonitorSocket); } void AssignmentClient::sendAssignmentRequest() { diff --git a/assignment-client/src/AssignmentClientChildData.cpp b/assignment-client/src/AssignmentClientChildData.cpp index cc714e629d..577124c982 100644 --- a/assignment-client/src/AssignmentClientChildData.cpp +++ b/assignment-client/src/AssignmentClientChildData.cpp @@ -12,7 +12,7 @@ #include "AssignmentClientChildData.h" -AssignmentClientChildData::AssignmentClientChildData(QString childType) : +AssignmentClientChildData::AssignmentClientChildData(Assignment::Type childType) : _childType(childType) { diff --git a/assignment-client/src/AssignmentClientChildData.h b/assignment-client/src/AssignmentClientChildData.h index 77d8bd7e31..926a160d08 100644 --- a/assignment-client/src/AssignmentClientChildData.h +++ b/assignment-client/src/AssignmentClientChildData.h @@ -17,7 +17,7 @@ class AssignmentClientChildData : public NodeData { public: - AssignmentClientChildData(QString childType); + AssignmentClientChildData(Assignment::Type childType); Assignment::Type getChildType() { return _childType; } void setChildType(Assignment::Type childType) { _childType = childType; } diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 6cc1577dea..df912ef519 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -175,7 +175,7 @@ void AssignmentClientMonitor::checkSpares() { nodeList->eachNode([&](const SharedNodePointer& node) { AssignmentClientChildData *childData = static_cast(node->getLinkedData()); totalCount ++; - if (childData->getChildType() == "none") { + if (childData->getChildType() == Assignment::Type::AllTypes) { spareCount ++; aSpareId = node->getUUID(); } @@ -203,12 +203,12 @@ void AssignmentClientMonitor::checkSpares() { } void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer packet) { - QUuid senderUUID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); + QUuid senderID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); auto nodeList = DependencyManager::get(); - SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderUUID); - const HifiSockAddr* senderSockAddr = packet->getSendingSockAddr(); + SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderID); + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); AssignmentClientChildData *childData = nullptr; @@ -217,13 +217,13 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer p if (senderSockAddr.getAddress() == QHostAddress::LocalHost || senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { - if (!senderUUID.isNull()) { + if (!senderID.isNull()) { // We don't have this node yet - we should add it matchingNode = DependencyManager::get()->addOrUpdateNode - (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); + (senderID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false); - childData = new AssignmentClientChildData("unknown"); - senderNode->setLinkedData(childData); + childData = new AssignmentClientChildData(Assignment::Type::AllTypes); + matchingNode->setLinkedData(childData); } else { // tell unknown assignment-client child to exit. qDebug() << "Asking unknown child at" << senderSockAddr << "to exit."; @@ -235,7 +235,7 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer p } } } else { - childData = dynamic_cast(senderNode->getLinkedData()); + childData = dynamic_cast(matchingNode->getLinkedData()); } if (childData) { From b45af742ef6b91476a50451c4e263b4f82070ae2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 09:37:09 -0700 Subject: [PATCH 094/146] Remove datagram processing from OctreeServer --- assignment-client/src/octree/OctreeServer.cpp | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 9b93b3895e..7fa82df0d7 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -28,7 +28,6 @@ #include "OctreeServer.h" #include "OctreeServerConsts.h" -#include "OctreeServerDatagramProcessor.h" OctreeServer* OctreeServer::_instance = NULL; int OctreeServer::_clientCount = 0; @@ -838,36 +837,6 @@ void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer pack _jurisdictionSender->queueReceivedPacket(packet, senderNode); } -void OctreeServer::setupDatagramProcessingThread() { - auto nodeList = DependencyManager::get(); - - // we do not want this event loop to be the handler for UDP datagrams, so disconnect - disconnect(&nodeList->getNodeSocket(), 0, this, 0); - - // setup a QThread with us as parent that will house the OctreeServerDatagramProcessor - _datagramProcessingThread = new QThread(this); - _datagramProcessingThread->setObjectName("Octree Datagram Processor"); - - // create an OctreeServerDatagramProcessor and move it to that thread - OctreeServerDatagramProcessor* datagramProcessor = new OctreeServerDatagramProcessor(nodeList->getNodeSocket(), thread()); - datagramProcessor->moveToThread(_datagramProcessingThread); - - // remove the NodeList as the parent of the node socket - nodeList->getNodeSocket().setParent(NULL); - nodeList->getNodeSocket().moveToThread(_datagramProcessingThread); - - // let the datagram processor handle readyRead from node socket - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, - datagramProcessor, &OctreeServerDatagramProcessor::readPendingDatagrams); - - // delete the datagram processor and the associated thread when the QThread quits - connect(_datagramProcessingThread, &QThread::finished, datagramProcessor, &QObject::deleteLater); - connect(datagramProcessor, &QObject::destroyed, _datagramProcessingThread, &QThread::deleteLater); - - // start the datagram processing thread - _datagramProcessingThread->start(); -} - bool OctreeServer::readOptionBool(const QString& optionName, const QJsonObject& settingsSectionObject, bool& result) { result = false; // assume it doesn't exist bool optionAvailable = false; @@ -1079,8 +1048,6 @@ void OctreeServer::run() { // use common init to setup common timers and logging commonInit(getMyLoggingServerTargetName(), getMyNodeType()); - setupDatagramProcessingThread(); - // read the configuration from either the payload or the domain server configuration readConfiguration(); From e3b5972344e03a41906050f2acad4f9882a95ea6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 11:21:02 -0700 Subject: [PATCH 095/146] use initializer list for packetReceiver register call --- assignment-client/src/Agent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index a333f4afdd..a67540738d 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -51,10 +51,10 @@ Agent::Agent(NLPacket& packet) : auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerPacketListenerForTypes( - QSet({ PacketType::MixedAudio, PacketType::SilentAudioFrame }), + { PacketType::MixedAudio, PacketType::SilentAudioFrame }, this, "handleAudioPacket"); packetReceiver.registerPacketListenerForTypes( - QSet({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }), + { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, this, "handleOctreePacket"); packetReceiver.registerPacketListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); } From c63d7144001e96ac8007e790789da1b47f68c9a4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 12:18:38 -0700 Subject: [PATCH 096/146] remove variables for out in PacketReceiver --- libraries/networking/src/PacketReceiver.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 4caae47076..21c27bcdac 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -31,9 +31,7 @@ public: PacketReceiver& operator=(const PacketReceiver&) = delete; int getInPacketCount() const { return _inPacketCount; } - int getOutPacketCount() const { return _outPacketCount; } int getInByteCount() const { return _inByteCount; } - int getOutByteCount() const { return _outByteCount; } void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; } @@ -61,9 +59,7 @@ private: QMutex _packetListenerLock; QHash _packetListenerMap; int _inPacketCount = 0; - int _outPacketCount = 0; int _inByteCount = 0; - int _outByteCount = 0; bool _isShuttingDown = false; }; From 0637f589b5d06b64fa64b9632692c27c9226ad24 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 13:52:38 -0700 Subject: [PATCH 097/146] add PacketListener to help unregister for packets --- assignment-client/src/Agent.cpp | 6 +- assignment-client/src/AssignmentClient.cpp | 5 +- assignment-client/src/AssignmentClient.h | 4 +- .../src/AssignmentClientMonitor.cpp | 2 +- .../src/AssignmentClientMonitor.h | 2 +- assignment-client/src/audio/AudioMixer.cpp | 4 +- assignment-client/src/avatars/AvatarMixer.cpp | 8 +- .../src/entities/EntityServer.cpp | 6 +- assignment-client/src/octree/OctreeServer.cpp | 6 +- domain-server/src/DomainServer.cpp | 17 ++-- domain-server/src/DomainServer.h | 3 +- interface/src/Application.cpp | 5 +- interface/src/Application.h | 6 +- .../src/octree/OctreePacketProcessor.cpp | 6 +- interface/src/octree/OctreePacketProcessor.h | 4 +- libraries/audio-client/src/AudioClient.cpp | 12 +-- libraries/audio-client/src/AudioClient.h | 3 +- libraries/audio-client/src/AudioIOStats.h | 3 +- libraries/avatars/src/AvatarHashMap.cpp | 8 +- libraries/avatars/src/AvatarHashMap.h | 3 +- .../entities/src/EntityEditPacketSender.cpp | 2 +- .../entities/src/EntityEditPacketSender.h | 4 +- libraries/networking/src/DomainHandler.cpp | 5 ++ libraries/networking/src/DomainHandler.h | 5 +- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/networking/src/LimitedNodeList.h | 3 +- libraries/networking/src/NodeList.cpp | 16 ++-- libraries/networking/src/PacketListener.cpp | 18 +++++ libraries/networking/src/PacketListener.h | 22 ++++++ libraries/networking/src/PacketReceiver.cpp | 77 +++++++++++++------ libraries/networking/src/PacketReceiver.h | 11 ++- .../networking/src/PacketReceiverListener.cpp | 0 .../networking/src/PacketReceiverListener.h | 22 ++++++ libraries/networking/src/ThreadedAssignment.h | 6 +- 34 files changed, 215 insertions(+), 91 deletions(-) create mode 100644 libraries/networking/src/PacketListener.cpp create mode 100644 libraries/networking/src/PacketListener.h create mode 100644 libraries/networking/src/PacketReceiverListener.cpp create mode 100644 libraries/networking/src/PacketReceiverListener.h diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index a67540738d..c25a0dc434 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -50,13 +50,13 @@ Agent::Agent(NLPacket& packet) : auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListenerForTypes( + packetReceiver.registerListenerForTypes( { PacketType::MixedAudio, PacketType::SilentAudioFrame }, this, "handleAudioPacket"); - packetReceiver.registerPacketListenerForTypes( + packetReceiver.registerListenerForTypes( { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, this, "handleOctreePacket"); - packetReceiver.registerPacketListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); + packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); } void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 9957619134..aab5d6af3b 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -121,11 +121,10 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri setUpStatusToMonitor(); } auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); - packetReceiver.registerPacketListener(PacketType::StopNode, this, "handleStopNodePacket"); + packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); + packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket"); } - void AssignmentClient::stopAssignmentClient() { qDebug() << "Forced stop of assignment-client."; diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 23e28968ed..e18e8eea4d 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -15,11 +15,13 @@ #include #include +#include + #include "ThreadedAssignment.h" class QSharedMemory; -class AssignmentClient : public QObject { +class AssignmentClient : public QObject, public PacketListener { Q_OBJECT public: diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index df912ef519..fc7697fc15 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -54,7 +54,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto nodeList = DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket"); + packetReceiver.registerListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket"); // use QProcess to fork off a process for each of the child assignment clients for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 895e0defb2..a75e876581 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -24,7 +24,7 @@ extern const char* NUM_FORKS_PARAMETER; -class AssignmentClientMonitor : public QObject { +class AssignmentClientMonitor : public QObject, public PacketListener { Q_OBJECT public: AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 19b9ebe868..a44759ae8d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -104,8 +104,8 @@ AudioMixer::AudioMixer(NLPacket& packet) : PacketType::AudioStreamStats }; - packetReceiver.registerPacketListenerForTypes(nodeAudioPackets, this, "handleNodeAudioPacket"); - packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); + packetReceiver.registerListenerForTypes(nodeAudioPackets, this, "handleNodeAudioPacket"); + packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f; diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 35cd3d4885..02202100be 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -48,10 +48,10 @@ AvatarMixer::AvatarMixer(NLPacket& packet) : connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::AvatarData, this, "handleAvatarDataPacket"); - packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); - packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, "handleAvatarBillboardPacket"); - packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); + packetReceiver.registerListener(PacketType::AvatarData, this, "handleAvatarDataPacket"); + packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); + packetReceiver.registerListener(PacketType::AvatarBillboard, this, "handleAvatarBillboardPacket"); + packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); } AvatarMixer::~AvatarMixer() { diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 3dee2af464..2a6815c2d5 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -26,9 +26,9 @@ EntityServer::EntityServer(NLPacket& packet) : _entitySimulation(NULL) { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); - packetReceiver.registerPacketListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); - packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket"); + packetReceiver.registerListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); + packetReceiver.registerListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); + packetReceiver.registerListener(PacketType::EntityErase, this, "handleEntityErasePacket"); } EntityServer::~EntityServer() { diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 9b93b3895e..efcde790f9 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1060,9 +1060,9 @@ void OctreeServer::readConfiguration() { void OctreeServer::run() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); - packetReceiver.registerPacketListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); - packetReceiver.registerPacketListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); + packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); + packetReceiver.registerListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket"); _safeServerName = getMyServerName(); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d6d6956a12..579ec1a002 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -111,6 +111,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : } void DomainServer::aboutToQuit() { + // clear the log handler so that Qt doesn't call the destructor on LogHandler qInstallMessageHandler(0); } @@ -280,14 +281,14 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { // register as the packet receiver for the types we want PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket"); - packetReceiver.registerPacketListener(PacketType::DomainConnectRequest, this, "processConnectRequestPackets"); - packetReceiver.registerPacketListener(PacketType::DomainListRequest, this, "processListRequestPacket"); - packetReceiver.registerPacketListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket"); - packetReceiver.registerPacketListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); - packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, this, "processICEPeerInformationPacket"); + packetReceiver.registerListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket"); + packetReceiver.registerListener(PacketType::DomainConnectRequest, this, "processConnectRequestPackets"); + packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket"); + packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket"); + packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket"); + packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket"); + packetReceiver.registerListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, this, "processICEPeerInformationPacket"); // add whatever static assignments that have been parsed to the queue addStaticAssignmentsToQueue(); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 0c287c4c55..7f7cba7445 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "DomainServerSettingsManager.h" #include "DomainServerWebSessionData.h" @@ -34,7 +35,7 @@ typedef QSharedPointer SharedAssignmentPointer; typedef QMultiHash TransactionHash; -class DomainServer : public QCoreApplication, public HTTPSRequestHandler { +class DomainServer : public QCoreApplication, public HTTPSRequestHandler, public PacketListener { Q_OBJECT public: DomainServer(int argc, char* argv[]); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 80a4e7bcca..7886041ff6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -654,7 +654,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : applicationUpdater->checkForUpdate(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); + packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); } void Application::aboutToQuit() { @@ -666,6 +666,9 @@ void Application::aboutToQuit() { void Application::cleanupBeforeQuit() { + // stop handling packets we've asked to handle + DependencyManager::get()->getPacketReceiver().unregisterListener(this); + _entities.clear(); // this will allow entity scripts to properly shutdown //_datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit diff --git a/interface/src/Application.h b/interface/src/Application.h index 1326ac5180..4580e762e6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,10 @@ class Application; typedef bool (Application::* AcceptURLMethod)(const QString &); -class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface { +class Application : public QApplication, + public AbstractViewStateInterface, + AbstractScriptingServicesInterface, + public PacketListener { Q_OBJECT friend class OctreePacketProcessor; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 80528612b6..64cf0696da 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -24,7 +24,11 @@ OctreePacketProcessor::OctreePacketProcessor() { PacketType::EntityErase, PacketType::OctreeStats, PacketType::EnvironmentData }; - packetReceiver.registerPacketListenerForTypes(types, this, "handleOctreePacket"); + packetReceiver.registerListenerForTypes(types, this, "handleOctreePacket"); +} + +OctreePacketProcessor::~OctreePacketProcessor() { + DependencyManager::get()->getPacketReceiver().unregisterListener(this); } void OctreePacketProcessor::handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode) { diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 47ebdc73bc..3476cd383e 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -13,13 +13,15 @@ #define hifi_OctreePacketProcessor_h #include +#include /// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() -class OctreePacketProcessor : public ReceivedPacketProcessor { +class OctreePacketProcessor : public ReceivedPacketProcessor, public PacketListener { Q_OBJECT public: OctreePacketProcessor(); + ~OctreePacketProcessor(); signals: void packetVersionMismatch(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index fc515c0c4c..a9e60f85e2 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -142,12 +142,12 @@ AudioClient::AudioClient() : configureGverbFilter(_gverb); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::AudioStreamStats, &_stats, "handleAudioStreamStatsPacket"); - packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); - packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); - packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); - packetReceiver.registerPacketListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); - packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); + packetReceiver.registerListener(PacketType::AudioStreamStats, &_stats, "handleAudioStreamStatsPacket"); + packetReceiver.registerListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); + packetReceiver.registerListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); + packetReceiver.registerListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); + packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } AudioClient::~AudioClient() { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index cf57b9dca1..dc9c40acf7 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ typedef glm::quat (*AudioOrientationGetter)(); class NLPacket; -class AudioClient : public AbstractAudioInterface, public Dependency { +class AudioClient : public AbstractAudioInterface, public Dependency, public PacketListener { Q_OBJECT SINGLETON_DEPENDENCY public: diff --git a/libraries/audio-client/src/AudioIOStats.h b/libraries/audio-client/src/AudioIOStats.h index da0acf2fa3..c5c2a47ff4 100644 --- a/libraries/audio-client/src/AudioIOStats.h +++ b/libraries/audio-client/src/AudioIOStats.h @@ -19,10 +19,11 @@ #include #include #include +#include class MixedProcessedAudioStream; -class AudioIOStats : public QObject { +class AudioIOStats : public QObject, public PacketListener { Q_OBJECT public: AudioIOStats(MixedProcessedAudioStream* receivedAudioStream); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c00ba1f08c..b219089f07 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -20,10 +20,10 @@ AvatarHashMap::AvatarHashMap() { connect(DependencyManager::get().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); - packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "processKillAvatar"); - packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); - packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket"); + packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); + packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar"); + packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); + packetReceiver.registerListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket"); } bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 071798e4f8..04988a81e2 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -21,11 +21,12 @@ #include #include #include +#include #include "AvatarData.h" #include -class AvatarHashMap : public QObject, public Dependency { +class AvatarHashMap : public QObject, public Dependency, public PacketListener { Q_OBJECT SINGLETON_DEPENDENCY diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index a798b83412..0dd3465b33 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -19,7 +19,7 @@ EntityEditPacketSender::EntityEditPacketSender() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); + packetReceiver.registerListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); } void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 667040c1df..39bd4cdffc 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -14,10 +14,12 @@ #include +#include + #include "EntityItem.h" /// Utility for processing, packing, queueing and sending of outbound edit voxel messages. -class EntityEditPacketSender : public OctreeEditPacketSender { +class EntityEditPacketSender : public OctreeEditPacketSender, public PacketListener { Q_OBJECT public: EntityEditPacketSender(); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 6d76e09028..174fbe8cb3 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -38,6 +38,11 @@ DomainHandler::DomainHandler(QObject* parent) : { // if we get a socket that make sure our NetworkPeer ping timer stops connect(this, &DomainHandler::completedSocketDiscovery, &_icePeer, &NetworkPeer::stopPingTimer); + + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, this, "processICEResponsePacket"); + packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, this, "processDTLSRequirementPacket"); } void DomainHandler::clearConnectionInfo() { diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 716138a4f1..82b0c163de 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -22,17 +22,18 @@ #include "HifiSockAddr.h" #include "NetworkPeer.h" #include "NLPacket.h" +#include "PacketListener.h" const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; const quint16 DOMAIN_SERVER_HTTP_PORT = 40100; const quint16 DOMAIN_SERVER_HTTPS_PORT = 40101; -class DomainHandler : public QObject { +class DomainHandler : public QObject, public PacketListener { Q_OBJECT public: DomainHandler(QObject* parent = 0); - + void clearConnectionInfo(); void clearSettings(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index a91076d6ca..d03a3c9f07 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -100,7 +100,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short _packetStatTimer.start(); // make sure we handle STUN response packets - _packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processSTUNResponse"); + _packetReceiver.registerListener(PacketType::StunResponse, this, "processSTUNResponse"); } void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 07d1eed644..5e23b2e93c 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -39,6 +39,7 @@ #include "NLPacket.h" #include "PacketHeaders.h" #include "PacketReceiver.h" +#include "PacketListener.h" #include "NLPacketList.h" #include "UUIDHasher.h" @@ -75,7 +76,7 @@ namespace PingType { const PingType_t Symmetric = 3; } -class LimitedNodeList : public QObject, public Dependency { +class LimitedNodeList : public QObject, public Dependency, public PacketListener { Q_OBJECT SINGLETON_DEPENDENCY public: diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 1daf8a1c02..b0de65ab85 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -92,15 +92,13 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned startSTUNPublicSocketUpdate(); auto& packetReceiver = getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::DomainList, this, "processDomainServerList"); - packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); - packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket"); - packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathQueryResponse"); - packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket"); - packetReceiver.registerPacketListener(PacketType::Ping, this, "processPingPacket"); - packetReceiver.registerPacketListener(PacketType::PingReply, this, "processPingReplyPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket"); - packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); + packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); + packetReceiver.registerListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); + packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathQueryResponse"); + packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); + packetReceiver.registerListener(PacketType::PingReply, this, "processPingReplyPacket"); + packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket"); + packetReceiver.registerListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); } qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { diff --git a/libraries/networking/src/PacketListener.cpp b/libraries/networking/src/PacketListener.cpp new file mode 100644 index 0000000000..a3d628c05b --- /dev/null +++ b/libraries/networking/src/PacketListener.cpp @@ -0,0 +1,18 @@ +// +// PacketListener.cpp +// libraries/networking/src +// +// Created by Stephen Birarda on 07/14/15. +// Copyright 2015 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 "PacketListener.h" + +#include "NodeList.h" + +PacketListener::~PacketListener() { + DependencyManager::get()->getPacketReceiver().unregisterListener(this); +} diff --git a/libraries/networking/src/PacketListener.h b/libraries/networking/src/PacketListener.h new file mode 100644 index 0000000000..ad0f1c6f7f --- /dev/null +++ b/libraries/networking/src/PacketListener.h @@ -0,0 +1,22 @@ +// +// PacketListener.h +// libraries/networking/src +// +// Created by Stephen Birarda on 07/14/15. +// Copyright 2015 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_PacketListener_h +#define hifi_PacketListener_h + +#pragma once + +class PacketListener { +public: + virtual ~PacketListener(); +}; + +#endif // hifi_PacketListener_h diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 7d40ba9187..20cc5c5b15 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -24,7 +24,7 @@ PacketReceiver::PacketReceiver(QObject* parent) : } -void PacketReceiver::registerPacketListenerForTypes(const QSet& types, QObject* object, const char* slot) { +void PacketReceiver::registerListenerForTypes(const QSet& types, PacketListener* listener, const char* slot) { QSet nonSourcedTypes; QSet sourcedTypes; @@ -36,6 +36,9 @@ void PacketReceiver::registerPacketListenerForTypes(const QSet(listener); + Q_ASSERT(object); + if (nonSourcedTypes.size() > 0) { QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), object, slot); foreach(PacketType::Value type, nonSourcedTypes) { @@ -51,8 +54,12 @@ void PacketReceiver::registerPacketListenerForTypes(const QSet(listener); + Q_ASSERT(object); + QMetaMethod matchingMethod = matchingMethodForListener(type, object, slot); + if (matchingMethod.isValid()) { registerVerifiedListener(type, object, matchingMethod); } @@ -62,28 +69,35 @@ QMetaMethod PacketReceiver::matchingMethodForListener(PacketType::Value type, QO Q_ASSERT(object); // normalize the slot with the expected parameters - QString normalizedSlot; - - if (NON_SOURCED_PACKETS.contains(type)) { - const QString NON_SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer"; - - QString nonNormalizedSignature = QString("%1(%2)").arg(slot).arg(NON_SOURCED_PACKET_LISTENER_PARAMETERS); - normalizedSlot = - QMetaObject::normalizedSignature(nonNormalizedSignature.toStdString().c_str()); - } else { - const QString SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; - QString nonNormalizedSignature = QString("%1(%2)").arg(slot).arg(SOURCED_PACKET_LISTENER_PARAMETERS); - normalizedSlot = - QMetaObject::normalizedSignature(nonNormalizedSignature.toStdString().c_str()); + const QString NON_SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer"; + + QSet possibleSignatures { QString("%1(%2)").arg(slot).arg(NON_SOURCED_PACKET_LISTENER_PARAMETERS) }; + + if (!NON_SOURCED_PACKETS.contains(type)) { + const QString SOURCED_PACKET_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; + + // a sourced packet must take the shared pointer to the packet but optionally could include + // a shared pointer to the node + + possibleSignatures << QString("%1(%2)").arg(slot).arg(SOURCED_PACKET_LISTENER_PARAMETERS); } - // does the constructed normalized method exist? - int methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str()); - + int methodIndex = -1; + + foreach(const QString& signature, possibleSignatures) { + QByteArray normalizedSlot = + QMetaObject::normalizedSignature(signature.toStdString().c_str()); + + // does the constructed normalized method exist? + methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str()); + + break; + } + if (methodIndex < 0) { - qDebug() << "PacketReceiver::registerPacketListener expected a method with a normalized signature of" - << normalizedSlot << "but such a method was not found."; + qDebug() << "PacketReceiver::registerListener expected a method with one of the following signatures:" + << possibleSignatures << "- but such a method was not found."; } Q_ASSERT(methodIndex >= 0); @@ -107,12 +121,29 @@ void PacketReceiver::registerVerifiedListener(PacketType::Value type, QObject* o } // add the mapping - _packetListenerMap[type] = ObjectMethodPair(QPointer(object), slot); + _packetListenerMap[type] = ObjectMethodPair(object, slot); _packetListenerLock.unlock(); } +void PacketReceiver::unregisterListener(PacketListener* listener) { + _packetListenerLock.lock(); + + auto it = _packetListenerMap.begin(); + + while (it != _packetListenerMap.end()) { + if (it.value().first == dynamic_cast(listener)) { + // this listener matches - erase it + it = _packetListenerMap.erase(it); + } else { + ++it; + } + } + + _packetListenerLock.unlock(); +} + bool PacketReceiver::packetVersionMatch(const NLPacket& packet) { if (packet.getVersion() != versionForPacketType(packet.getType()) @@ -149,7 +180,7 @@ void PacketReceiver::processDatagrams() { auto nodeList = DependencyManager::get(); - while (DependencyManager::get()->getNodeSocket().hasPendingDatagrams()) { + while (nodeList->getNodeSocket().hasPendingDatagrams()) { // setup a buffer to read the packet into int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize(); std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); @@ -186,7 +217,7 @@ void PacketReceiver::processDatagrams() { auto listener = it.value(); - if (!listener.first.isNull()) { + if (listener.first) { if (matchingNode) { emit dataReceived(matchingNode->getType(), packet->getSizeWithHeader()); diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 21c27bcdac..c84b5ef432 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -22,6 +22,8 @@ #include "NLPacket.h" #include "PacketHeaders.h" +class PacketListener; + class PacketReceiver : public QObject { Q_OBJECT public: @@ -33,12 +35,13 @@ public: int getInPacketCount() const { return _inPacketCount; } int getInByteCount() const { return _inByteCount; } - void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; } + void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } void shutdown() { _isShuttingDown = true; } - void registerPacketListenerForTypes(const QSet& types, QObject* listener, const char* slot); - void registerPacketListener(PacketType::Value type, QObject* listener, const char* slot); + void registerListenerForTypes(const QSet& types, PacketListener* listener, const char* slot); + void registerListener(PacketType::Value type, PacketListener* listener, const char* slot); + void unregisterListener(PacketListener* listener); public slots: void processDatagrams(); @@ -54,7 +57,7 @@ private: QMetaMethod matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const; void registerVerifiedListener(PacketType::Value type, QObject* listener, const QMetaMethod& slot); - using ObjectMethodPair = std::pair, QMetaMethod>; + using ObjectMethodPair = std::pair; QMutex _packetListenerLock; QHash _packetListenerMap; diff --git a/libraries/networking/src/PacketReceiverListener.cpp b/libraries/networking/src/PacketReceiverListener.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libraries/networking/src/PacketReceiverListener.h b/libraries/networking/src/PacketReceiverListener.h new file mode 100644 index 0000000000..ad0f1c6f7f --- /dev/null +++ b/libraries/networking/src/PacketReceiverListener.h @@ -0,0 +1,22 @@ +// +// PacketListener.h +// libraries/networking/src +// +// Created by Stephen Birarda on 07/14/15. +// Copyright 2015 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_PacketListener_h +#define hifi_PacketListener_h + +#pragma once + +class PacketListener { +public: + virtual ~PacketListener(); +}; + +#endif // hifi_PacketListener_h diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index c4c6127b7b..922a34b3e4 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -1,6 +1,6 @@ // // ThreadedAssignment.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 12/3/2013. // Copyright 2013 High Fidelity, Inc. @@ -14,9 +14,11 @@ #include +#include "PacketListener.h" + #include "Assignment.h" -class ThreadedAssignment : public Assignment { +class ThreadedAssignment : public Assignment, public PacketListener { Q_OBJECT public: ThreadedAssignment(NLPacket& packet); From fa9372875e48f0d465236c7cdb94b0ca452c927f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 13:54:10 -0700 Subject: [PATCH 098/146] fix headers in AvatarHashMap --- libraries/avatars/src/AvatarHashMap.cpp | 2 +- libraries/avatars/src/AvatarHashMap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index b219089f07..3eb5495aec 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -2,7 +2,7 @@ // AvatarHashMap.cpp // libraries/avatars/src // -// Created by AndrewMeadows on 1/28/2014. +// Created by Andrew Meadows on 1/28/2014. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 04988a81e2..fa61788816 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -2,7 +2,7 @@ // AvatarHashMap.h // libraries/avatars/src // -// Created by Stephen AndrewMeadows on 1/28/2014. +// Created by Andrew Meadows on 1/28/2014. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. From fbd287472d2d4b05240f3da78533f9693eb39791 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:09:00 -0700 Subject: [PATCH 099/146] make NodeData parseData take only packet --- assignment-client/src/Agent.cpp | 4 ++-- assignment-client/src/Agent.h | 2 +- assignment-client/src/AssignmentClientChildData.h | 7 ++----- assignment-client/src/audio/AudioMixerClientData.cpp | 4 ++-- assignment-client/src/audio/AudioMixerClientData.h | 2 +- .../src/avatars/AvatarMixerClientData.cpp | 2 +- assignment-client/src/avatars/AvatarMixerClientData.h | 2 +- domain-server/src/DomainServerNodeData.h | 1 - libraries/audio-client/src/AudioClient.cpp | 10 +++++----- libraries/audio-client/src/AudioClient.h | 8 ++++---- libraries/audio/src/InboundAudioStream.cpp | 4 ++-- libraries/audio/src/InboundAudioStream.h | 2 +- libraries/networking/src/Assignment.h | 3 --- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/networking/src/NodeData.h | 2 +- libraries/octree/src/OctreeQuery.cpp | 2 +- libraries/octree/src/OctreeQuery.h | 2 +- 17 files changed, 26 insertions(+), 33 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index c25a0dc434..051ae68ff2 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -99,8 +99,8 @@ void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNode } } -void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode) { - _receivedAudioStream.parseData(*packet, senderNode); +void Agent::handleAudioPacket(QSharedPointer packet) { + _receivedAudioStream.parseData(*packet); _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 840c1d6d22..241e14439c 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -55,7 +55,7 @@ public slots: void playAvatarSound(Sound* avatarSound) { _scriptEngine.setAvatarSound(avatarSound); } private slots: - void handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleAudioPacket(QSharedPointer packet); void handleOctreePacket(QSharedPointer packet, SharedNodePointer senderNode); void handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode); diff --git a/assignment-client/src/AssignmentClientChildData.h b/assignment-client/src/AssignmentClientChildData.h index 926a160d08..7858ede448 100644 --- a/assignment-client/src/AssignmentClientChildData.h +++ b/assignment-client/src/AssignmentClientChildData.h @@ -16,16 +16,13 @@ class AssignmentClientChildData : public NodeData { - public: +public: AssignmentClientChildData(Assignment::Type childType); Assignment::Type getChildType() { return _childType; } void setChildType(Assignment::Type childType) { _childType = childType; } - // implement parseData to return 0 so we can be a subclass of NodeData - int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } - - private: +private: Assignment::Type _childType; }; diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index dc2d60be51..c929d39224 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -49,7 +49,7 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() const { return NULL; } -int AudioMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingNode) { +int AudioMixerClientData::parseData(NLPacket& packet) { PacketType::Value packetType = packet.getType(); if (packetType == PacketType::AudioStreamStats) { @@ -107,7 +107,7 @@ int AudioMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingN // seek to the beginning of the packet so that the next reader is in the right spot packet.seek(0); - return matchingStream->parseData(packet, sendingNode); + return matchingStream->parseData(packet); } return 0; } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 99f8683b70..20bcaf5627 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -42,7 +42,7 @@ public: const QHash& getAudioStreams() const { return _audioStreams; } AvatarAudioStream* getAvatarAudioStream() const; - int parseData(NLPacket& packet, QSharedPointer sendingNode); + int parseData(NLPacket& packet); void checkBuffersBeforeFrameSend(); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 9f658e1b48..51543f0d5e 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -13,7 +13,7 @@ #include "AvatarMixerClientData.h" -int AvatarMixerClientData::parseData(NLPacket& packet, SharedNodePointer sendingNode) { +int AvatarMixerClientData::parseData(NLPacket& packet) { // compute the offset to the data payload return _avatar.parseDataFromBuffer(QByteArray::fromRawData(packet.getPayload(), packet.getSizeUsed())); } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 4497f17da7..5aef1b7822 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -31,7 +31,7 @@ const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps"; class AvatarMixerClientData : public NodeData { Q_OBJECT public: - int parseData(NLPacket& packet, SharedNodePointer sendingNode); + int parseData(NLPacket& packet); AvatarData& getAvatar() { return _avatar; } bool checkAndSetHasReceivedFirstPackets(); diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index 00c5f659ca..57ed96acab 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -24,7 +24,6 @@ class DomainServerNodeData : public NodeData { public: DomainServerNodeData(); - int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } const QJsonObject& getStatsJSONObject() const { return _statsJSONObject; } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a9e60f85e2..6ae8402d5e 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -535,7 +535,7 @@ void AudioClient::stop() { } } -void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { +void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet) { char bitset; packet->readPrimitive(&bitset); @@ -552,7 +552,7 @@ void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer pack } } -void AudioClient::handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { +void AudioClient::handleAudioDataPacket(QSharedPointer packet) { auto nodeList = DependencyManager::get(); nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); @@ -566,11 +566,11 @@ void AudioClient::handleAudioDataPacket(QSharedPointer packet, SharedN } // Audio output must exist and be correctly set up if we're going to process received audio - _receivedAudioStream.parseData(*packet, sendingNode); + _receivedAudioStream.parseData(*packet); } } -void AudioClient::handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode) { +void AudioClient::handleNoisyMutePacket(QSharedPointer packet) { if (!_muted) { toggleMute(); @@ -579,7 +579,7 @@ void AudioClient::handleNoisyMutePacket(QSharedPointer packet, SharedN } } -void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode) { +void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet) { glm::vec3 position; float radius; diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index dc9c40acf7..79a044601d 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -140,10 +140,10 @@ public slots: void start(); void stop(); - void handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); - void handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); - void handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode); - void handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleAudioEnvironmentDataPacket(QSharedPointer packet); + void handleAudioDataPacket(QSharedPointer packet); + void handleNoisyMutePacket(QSharedPointer packet); + void handleMuteEnvironmentPacket(QSharedPointer packet); void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } void handleAudioInput(); diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 1c061b3aaa..8df42ff76f 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -99,13 +99,13 @@ void InboundAudioStream::perSecondCallbackForUpdatingStats() { _timeGapStatsForStatsPacket.currentIntervalComplete(); } -int InboundAudioStream::parseData(NLPacket& packet, SharedNodePointer sendingNode) { +int InboundAudioStream::parseData(NLPacket& packet) { // parse sequence number and track it quint16 sequence; packet.readPrimitive(&sequence); SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, - sendingNode->getUUID()); + packet.getSourceID()); packetReceivedUpdateTimingStats(); diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 106caa11ef..6cd719d233 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -107,7 +107,7 @@ public: virtual void resetStats(); void clearBuffer(); - virtual int parseData(NLPacket& packet, QSharedPointer sendingNode); + virtual int parseData(NLPacket& packet); int popFrames(int maxFrames, bool allOrNothing, bool starveIfNoFramesPopped = true); int popSamples(int maxSamples, bool allOrNothing, bool starveIfNoSamplesPopped = true); diff --git a/libraries/networking/src/Assignment.h b/libraries/networking/src/Assignment.h index 1e4c985583..67f861f850 100644 --- a/libraries/networking/src/Assignment.h +++ b/libraries/networking/src/Assignment.h @@ -85,9 +85,6 @@ public: const char* getTypeName() const; - // implement parseData to return 0 so we can be a subclass of NodeData - int parseData(NLPacket& packet, SharedNodePointer sendingNode) { return 0; } - friend QDebug operator<<(QDebug debug, const Assignment& assignment); friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment); friend QDataStream& operator>>(QDataStream &in, Assignment& assignment); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index d03a3c9f07..f0193a1789 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -247,7 +247,7 @@ int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer packe if (linkedData) { QMutexLocker linkedDataLocker(&linkedData->getMutex()); - return linkedData->parseData(*packet, sendingNode); + return linkedData->parseData(*packet); } return 0; diff --git a/libraries/networking/src/NodeData.h b/libraries/networking/src/NodeData.h index d323c72184..78ef446938 100644 --- a/libraries/networking/src/NodeData.h +++ b/libraries/networking/src/NodeData.h @@ -25,7 +25,7 @@ class NodeData : public QObject { public: NodeData(); virtual ~NodeData() = 0; - virtual int parseData(NLPacket& packet, QSharedPointer sendingNode) = 0; + virtual int parseData(NLPacket& packet) { return 0; } QMutex& getMutex() { return _mutex; } diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index ea568387f5..cdda3a7a0e 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -64,7 +64,7 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { } // called on the other nodes - assigns it to my views of the others -int OctreeQuery::parseData(NLPacket& packet, QSharedPointer sendingNode) { +int OctreeQuery::parseData(NLPacket& packet) { const unsigned char* startPosition = reinterpret_cast(packet.getPayload()); const unsigned char* sourceBuffer = startPosition; diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 83cb828112..86474ffc02 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -48,7 +48,7 @@ public: virtual ~OctreeQuery() {} int getBroadcastData(unsigned char* destinationBuffer); - int parseData(NLPacket& packet, QSharedPointer sendingNode); + int parseData(NLPacket& packet); // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; } From 64bed72ae667645553d7c3dcc1ffc71fc37aad20 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:23:10 -0700 Subject: [PATCH 100/146] Add Packet::peekPrimitive --- libraries/networking/src/Packet.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/networking/src/Packet.h b/libraries/networking/src/Packet.h index 4ad6ffa6f3..dfd98b6726 100644 --- a/libraries/networking/src/Packet.h +++ b/libraries/networking/src/Packet.h @@ -65,6 +65,7 @@ public: virtual bool reset() { setSizeUsed(0); return QIODevice::reset(); } virtual qint64 size() const { return _capacity; } + template qint64 peekPrimitive(T* data); template qint64 readPrimitive(T* data); template qint64 writePrimitive(const T& data); @@ -103,6 +104,10 @@ protected: }; +template qint64 Packet::peekPrimitive(T* data) { + return QIODevice::peek(reinterpret_cast(data), sizeof(T)); +} + template qint64 Packet::readPrimitive(T* data) { return QIODevice::read(reinterpret_cast(data), sizeof(T)); } From 5cb8c1541a166d8247b13e87b9dc7108f959e4c1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:23:31 -0700 Subject: [PATCH 101/146] Update Agent to use peekPrimitive --- assignment-client/src/Agent.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index a333f4afdd..ef1aa7ab4c 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -88,16 +88,14 @@ void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointe void Agent::handleJurisdictionPacket(QSharedPointer packet, SharedNodePointer senderNode) { NodeType_t nodeType; - packet->peek(reinterpret_cast(&nodeType), sizeof(nodeType)); - + packet->peekPrimitive(&nodeType); + // PacketType_JURISDICTION, first byte is the node type... - switch (nodeType) { - case NodeType::EntityServer: - DependencyManager::get()->getJurisdictionListener()-> - queueReceivedPacket(packet, senderNode); - break; + if (nodeType == NodeType::EntityServer) { + DependencyManager::get()->getJurisdictionListener()-> + queueReceivedPacket(packet, senderNode); } -} +} void Agent::handleAudioPacket(QSharedPointer packet, SharedNodePointer senderNode) { _receivedAudioStream.parseData(*packet, senderNode); From 1af01c9003a594d2aae1d89261944c6177ac8970 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:23:53 -0700 Subject: [PATCH 102/146] Fix style issue in AssignmentClientMonitor --- assignment-client/src/AssignmentClientMonitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index df912ef519..430aa2990f 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -173,7 +173,7 @@ void AssignmentClientMonitor::checkSpares() { nodeList->removeSilentNodes(); nodeList->eachNode([&](const SharedNodePointer& node) { - AssignmentClientChildData *childData = static_cast(node->getLinkedData()); + AssignmentClientChildData* childData = static_cast(node->getLinkedData()); totalCount ++; if (childData->getChildType() == Assignment::Type::AllTypes) { spareCount ++; @@ -210,7 +210,7 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer p SharedNodePointer matchingNode = nodeList->nodeWithUUID(senderID); const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); - AssignmentClientChildData *childData = nullptr; + AssignmentClientChildData* childData = nullptr; if (!matchingNode) { // The parent only expects to be talking with prorams running on this same machine. From f7c1eaf967a2adb3b30acded9ebf8476217ebd01 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:24:08 -0700 Subject: [PATCH 103/146] Update AssignmentFactory to use peekPrimitive --- assignment-client/src/AssignmentFactory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/AssignmentFactory.cpp b/assignment-client/src/AssignmentFactory.cpp index 705ff5179b..746dea3bf3 100644 --- a/assignment-client/src/AssignmentFactory.cpp +++ b/assignment-client/src/AssignmentFactory.cpp @@ -20,10 +20,10 @@ ThreadedAssignment* AssignmentFactory::unpackAssignment(NLPacket& packet) { quint8 packedType; - packet.peek(reinterpret_cast(&packedType), sizeof(packedType)); - + packet.peekPrimitive(&packedType); + Assignment::Type unpackedType = (Assignment::Type) packedType; - + switch (unpackedType) { case Assignment::AudioMixerType: return new AudioMixer(packet); From 921ee024149e7cbcfe020e3f316bd023d4e1320a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:25:09 -0700 Subject: [PATCH 104/146] Update EntityServer to use only 1 packet callback for all packet types --- .../src/entities/EntityServer.cpp | 20 ++++--------------- assignment-client/src/entities/EntityServer.h | 4 +--- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 6bb16b7c46..cd9a56c83d 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -26,9 +26,9 @@ EntityServer::EntityServer(NLPacket& packet) : _entitySimulation(NULL) { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); - packetReceiver.registerPacketListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); - packetReceiver.registerPacketListener(PacketType::EntityErase, this, "handleEntityErasePacket"); + packetReceiver.registerPacketListener( + { PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase }, + this, "handleEntityPacket"); } EntityServer::~EntityServer() { @@ -41,19 +41,7 @@ EntityServer::~EntityServer() { tree->removeNewlyCreatedHook(this); } -void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode) { - if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); - } -} - -void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode) { - if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); - } -} - -void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode) { +void EntityServer::handleEntityPacket(QSharedPointer packet, SharedNodePointer senderNode) { if (_octreeInboundPacketProcessor) { _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index dde68dfebd..1c4eda3cc0 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -50,9 +50,7 @@ protected: virtual Octree* createTree(); private slots: - void handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleEntityPacket(QSharedPointer packet, SharedNodePointer senderNode); private: EntitySimulation* _entitySimulation; From 10c558962985f408db9076abd96b13bfe498d289 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:26:06 -0700 Subject: [PATCH 105/146] Update OctreeServer to use dynamic_cast --- assignment-client/src/octree/OctreeServer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7fa82df0d7..83cc22d7b4 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -818,7 +818,7 @@ void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, Shar auto nodeList = DependencyManager::get(); nodeList->updateNodeWithDataFromPacket(packet, senderNode); - OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); + OctreeQueryNode* nodeData = dynamic_cast(senderNode->getLinkedData()); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { nodeData->initializeOctreeSendThread(this, senderNode); } @@ -827,7 +827,7 @@ void OctreeServer::handleOctreeQueryPacket(QSharedPointer packet, Shar void OctreeServer::handleOctreeDataNackPacket(QSharedPointer packet, SharedNodePointer senderNode) { // If we got a nack packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. - OctreeQueryNode* nodeData = (OctreeQueryNode*)senderNode->getLinkedData(); + OctreeQueryNode* nodeData = dynamic_cast(senderNode->getLinkedData()); if (nodeData) { nodeData->parseNackPacket(packet->getData()); } @@ -1122,7 +1122,7 @@ void OctreeServer::nodeKilled(SharedNodePointer node) { _octreeInboundPacketProcessor->nodeKilled(node); qDebug() << qPrintable(_safeServerName) << "server killed node:" << *node; - OctreeQueryNode* nodeData = static_cast(node->getLinkedData()); + OctreeQueryNode* nodeData = dynamic_cast(node->getLinkedData()); if (nodeData) { nodeData->nodeKilled(); // tell our node data and sending threads that we'd like to shut down } else { @@ -1140,7 +1140,7 @@ void OctreeServer::forceNodeShutdown(SharedNodePointer node) { quint64 start = usecTimestampNow(); qDebug() << qPrintable(_safeServerName) << "server killed node:" << *node; - OctreeQueryNode* nodeData = static_cast(node->getLinkedData()); + OctreeQueryNode* nodeData = dynamic_cast(node->getLinkedData()); if (nodeData) { nodeData->forceNodeShutdown(); // tell our node data and sending threads that we'd like to shut down } else { From d617b71232cce6e3d8c43500e649f4d7559fa764 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:27:26 -0700 Subject: [PATCH 106/146] remove SharedNodePointer from some packet callbacks --- assignment-client/src/AssignmentClient.cpp | 8 ++++--- assignment-client/src/AssignmentClient.h | 4 ++-- assignment-client/src/avatars/AvatarMixer.cpp | 5 ++--- assignment-client/src/avatars/AvatarMixer.h | 2 +- .../src/entities/EntityServer.cpp | 19 +++------------- assignment-client/src/entities/EntityServer.h | 4 +--- domain-server/src/DomainServer.cpp | 2 +- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- .../entities/src/EntityEditPacketSender.cpp | 2 +- .../entities/src/EntityEditPacketSender.h | 2 +- libraries/networking/src/DomainHandler.cpp | 19 ++++++++++++++++ libraries/networking/src/DomainHandler.h | 8 ++++--- libraries/networking/src/NodeList.cpp | 22 ------------------- libraries/networking/src/NodeList.h | 1 - 15 files changed, 43 insertions(+), 59 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index aab5d6af3b..6da3786ef7 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -210,7 +210,7 @@ void AssignmentClient::sendAssignmentRequest() { } } -void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer packet) { qDebug() << "Received a PacketType::CreateAssignment - attempting to unpack."; // construct the deployed assignment from the packet data @@ -223,7 +223,7 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer pac // switch our DomainHandler hostname and port to whoever sent us the assignment - nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); + nodeList->getDomainHandler().setSockAddr(packet->getSenderSockAddr(), _assignmentServerHostname); nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); @@ -261,7 +261,9 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer pac } } -void AssignmentClient::handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr) { +void AssignmentClient::handleStopNodePacket(QSharedPointer packet) { + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { qDebug() << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode."; diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index e18e8eea4d..348255751c 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -39,8 +39,8 @@ public slots: void aboutToQuit(); private slots: - void handleCreateAssignmentPacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); - void handleStopNodePacket(QSharedPointer packet, SharedNodePointer senderNode, HifiSockAddr senderSockAddr); + void handleCreateAssignmentPacket(QSharedPointer packet); + void handleStopNodePacket(QSharedPointer packet); private: void setUpStatusToMonitor(); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 02202100be..b0a50403c6 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -432,9 +432,8 @@ void AvatarMixer::handleAvatarBillboardPacket(QSharedPointer packet, S } } -void AvatarMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer senderNode) { - auto nodeList = DependencyManager::get(); - nodeList->processKillNode(*packet); +void AvatarMixer::handleKillAvatarPacket(QSharedPointer packet) { + DependencyManager::get()->processKillNode(*packet); } void AvatarMixer::sendStatsPacket() { diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index d0ced8cdfd..034269f7fa 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -35,7 +35,7 @@ private slots: void handleAvatarDataPacket(QSharedPointer packet, SharedNodePointer senderNode); void handleAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer senderNode); void handleAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleKillAvatarPacket(QSharedPointer packet); private: void broadcastAvatarData(); diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 2a6815c2d5..c9c999077c 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -26,9 +26,8 @@ EntityServer::EntityServer(NLPacket& packet) : _entitySimulation(NULL) { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityAdd, this, "handleEntityAddPacket"); - packetReceiver.registerListener(PacketType::EntityEdit, this, "handleEntityEditPacket"); - packetReceiver.registerListener(PacketType::EntityErase, this, "handleEntityErasePacket"); + packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase }, + this, "handleEntityPacket"); } EntityServer::~EntityServer() { @@ -41,19 +40,7 @@ EntityServer::~EntityServer() { tree->removeNewlyCreatedHook(this); } -void EntityServer::handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode) { - if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); - } -} - -void EntityServer::handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode) { - if (_octreeInboundPacketProcessor) { - _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); - } -} - -void EntityServer::handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode) { +void EntityServer::handleEntityPacket(QSharedPointer packet, SharedNodePointer senderNode) { if (_octreeInboundPacketProcessor) { _octreeInboundPacketProcessor->queueReceivedPacket(packet, senderNode); } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index dde68dfebd..1c4eda3cc0 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -50,9 +50,7 @@ protected: virtual Octree* createTree(); private slots: - void handleEntityAddPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleEntityEditPacket(QSharedPointer packet, SharedNodePointer senderNode); - void handleEntityErasePacket(QSharedPointer packet, SharedNodePointer senderNode); + void handleEntityPacket(QSharedPointer packet, SharedNodePointer senderNode); private: EntitySimulation* _entitySimulation; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 579ec1a002..21b2ce0f58 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1415,7 +1415,7 @@ void DomainServer::processICEPingReplyPacket(QSharedPointer packet) { void DomainServer::processNodeJSONStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode) { if (sendingNode->getLinkedData()) { - reinterpret_cast(sendingNode->getLinkedData())->processJSONStatsPacket(*packet); + dynamic_cast(sendingNode->getLinkedData())->processJSONStatsPacket(*packet); } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7886041ff6..f06e01f4c5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3821,7 +3821,7 @@ void Application::domainChanged(const QString& domainHostname) { _domainConnectionRefusals.clear(); } -void Application::handleDomainConnectionDeniedPacket(QSharedPointer packet, SharedNodePointer senderNode) { +void Application::handleDomainConnectionDeniedPacket(QSharedPointer packet) { QDataStream packetStream(packet.data()); QString reason; diff --git a/interface/src/Application.h b/interface/src/Application.h index 4580e762e6..754698acc8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -447,7 +447,7 @@ public slots: void notifyPacketVersionMismatch(); - void handleDomainConnectionDeniedPacket(QSharedPointer, SharedNodePointer senderNode); + void handleDomainConnectionDeniedPacket(QSharedPointer packet); void cameraMenuChanged(); diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 0dd3465b33..160e8721f1 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -22,7 +22,7 @@ EntityEditPacketSender::EntityEditPacketSender() { packetReceiver.registerListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); } -void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet) { // if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { processNackPacket(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); // } diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 39bd4cdffc..235e340da2 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -32,7 +32,7 @@ public: void queueEraseEntityMessage(const EntityItemID& entityItemID); - void processEntityEditNackPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void processEntityEditNackPacket(QSharedPointer packet); // My server type is the model server virtual char getMyNodeType() const { return NodeType::EntityServer; } diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 174fbe8cb3..20d13169a3 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -43,6 +43,7 @@ DomainHandler::DomainHandler(QObject* parent) : packetReceiver.registerListener(PacketType::ICEServerPeerInformation, this, "processICEResponsePacket"); packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, this, "processDTLSRequirementPacket"); + packetReceiver.registerListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); } void DomainHandler::clearConnectionInfo() { @@ -286,6 +287,24 @@ void DomainHandler::settingsRequestFinished() { settingsReply->deleteLater(); } +void DomainHandler::processICEPingReplyPacket(QSharedPointer packet) { + const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); + qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr; + + if (getIP().isNull()) { + // for now we're unsafely assuming this came back from the domain + if (senderSockAddr == _icePeer.getLocalSocket()) { + qCDebug(networking) << "Connecting to domain using local socket"; + activateICELocalSocket(); + } else if (senderSockAddr == _icePeer.getPublicSocket()) { + qCDebug(networking) << "Conecting to domain using public socket"; + activateICEPublicSocket(); + } else { + qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect."; + } + } +} + void DomainHandler::processDTLSRequirementPacket(QSharedPointer dtlsRequirementPacket) { // figure out the port that the DS wants us to use for us to talk to them with DTLS unsigned short dtlsPort; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 82b0c163de..43453e46c5 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -71,9 +71,7 @@ public: void requestDomainSettings(); const QJsonObject& getSettingsObject() const { return _settingsObject; } - void processDTLSRequirementPacket(QSharedPointer dtlsRequirementPacket); - void processICEResponsePacket(QSharedPointer icePacket); - + void setPendingPath(const QString& pendingPath) { _pendingPath = pendingPath; } const QString& getPendingPath() { return _pendingPath; } void clearPendingPath() { _pendingPath.clear(); } @@ -85,6 +83,10 @@ public slots: void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT); void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id); + void processICEPingReplyPacket(QSharedPointer packet); + void processDTLSRequirementPacket(QSharedPointer dtlsRequirementPacket); + void processICEResponsePacket(QSharedPointer icePacket); + private slots: void completedHostnameLookup(const QHostInfo& hostInfo); void completedIceServerHostnameLookup(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index b0de65ab85..3773a8a540 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -93,12 +93,9 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned auto& packetReceiver = getPacketReceiver(); packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); - packetReceiver.registerListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); - packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathQueryResponse"); packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); packetReceiver.registerListener(PacketType::PingReply, this, "processPingReplyPacket"); packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket"); - packetReceiver.registerListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket"); } qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { @@ -190,25 +187,6 @@ void NodeList::processICEPingPacket(QSharedPointer packet) { sendPacket(std::move(replyPacket), packet->getSenderSockAddr()); } -void NodeList::processICEPingReplyPacket(QSharedPointer packet) { - const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); - qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr; - - if (_domainHandler.getIP().isNull()) { - // for now we're unsafely assuming this came back from the domain - if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) { - qCDebug(networking) << "Connecting to domain using local socket"; - _domainHandler.activateICELocalSocket(); - } else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) { - qCDebug(networking) << "Conecting to domain using public socket"; - _domainHandler.activateICEPublicSocket(); - } else { - qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect."; - } - - } -} - void NodeList::reset() { LimitedNodeList::reset(); diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 65bd6a6983..b9f782f717 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -80,7 +80,6 @@ public slots: void processPingReplyPacket(QSharedPointer packet, SharedNodePointer sendingNode); void processICEPingPacket(QSharedPointer packet); - void processICEPingReplyPacket(QSharedPointer packet); signals: void limitOfSilentDomainCheckInsReached(); private slots: From 1f4ac0f17c44aaac921d8d90258bfc1331731eb3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:30:46 -0700 Subject: [PATCH 107/146] emit mutedByMixer signal for a noisy mute --- interface/src/Application.cpp | 1 + libraries/audio-client/src/AudioClient.cpp | 4 ++-- libraries/audio-client/src/AudioClient.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f06e01f4c5..7be2b93645 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -420,6 +420,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); + connect(audioIO.data(), &AudioClient::mutedByMixer, this, &AudioScriptingInterface::mutedByMixer); connect(audioIO.data(), &AudioClient::receivedFirstPacket, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); connect(audioIO.data(), &AudioClient::disconnected, diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6ae8402d5e..c6c20a4ab2 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -574,8 +574,8 @@ void AudioClient::handleNoisyMutePacket(QSharedPointer packet) { if (!_muted) { toggleMute(); - // TODO reimplement on interface side - //AudioScriptingInterface::getInstance().mutedByMixer(); + // have the audio scripting interface emit a signal to say we were muted by the mixer + emit mutedByMixer(); } } diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 79a044601d..5292e51d91 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -188,6 +188,7 @@ public slots: signals: bool muteToggled(); + void mutedByMixer(); void inputReceived(const QByteArray& inputSamples); void outputBytesToNetwork(int numBytes); void inputBytesFromNetwork(int numBytes); From 8d4c9458749c7bd6d1e7ccc78e4995c9d470c45a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:34:39 -0700 Subject: [PATCH 108/146] cleanup audioIO connections in Application --- interface/src/Application.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7be2b93645..d02f5daea6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -416,15 +416,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : audioIO->setOrientationGetter(getOrientationForAudio); audioIO->moveToThread(audioThread); + + auto& audioScriptingInterface = AudioScriptingInterface::getInstance(); + connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); - connect(audioIO.data(), &AudioClient::mutedByMixer, this, &AudioScriptingInterface::mutedByMixer); - connect(audioIO.data(), &AudioClient::receivedFirstPacket, - &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); - connect(audioIO.data(), &AudioClient::disconnected, - &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected); + connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer); + connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket); + connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected); connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { auto audioClient = DependencyManager::get(); float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), From 027d131b2adf05a33dffb67e44515673d26e0927 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:40:39 -0700 Subject: [PATCH 109/146] Move sequence number updating to PacketReceiver --- libraries/networking/src/LimitedNodeList.cpp | 6 ------ libraries/networking/src/PacketReceiver.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index a91076d6ca..0b76de6304 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -234,12 +234,6 @@ PacketSequenceNumber LimitedNodeList::getNextSequenceNumberForPacket(const QUuid int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer sendingNode) { QMutexLocker locker(&sendingNode->getMutex()); - // if this was a sequence numbered packet we should store the last seq number for - // a packet of this type for this node - if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { - sendingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); - } - NodeData* linkedData = sendingNode->getLinkedData(); if (!linkedData && linkedDataCreateCallback) { linkedDataCreateCallback(sendingNode.data()); diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 7d40ba9187..f7e369ee17 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -194,6 +194,12 @@ void PacketReceiver::processDatagrams() { emit dataReceived(NodeType::Unassigned, packet->getSizeWithHeader()); } + // if this was a sequence numbered packet we should store the last seq number for + // a packet of this type for this node + if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { + matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); + } + bool success = false; if (matchingNode) { From 24dddac6b228520e9eef7085cfbf70b70c716312 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:41:28 -0700 Subject: [PATCH 110/146] Fix call to register for multiple packet types --- assignment-client/src/entities/EntityServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index cd9a56c83d..f363600c22 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -26,7 +26,7 @@ EntityServer::EntityServer(NLPacket& packet) : _entitySimulation(NULL) { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener( + packetReceiver.registerPacketListenerForTypes( { PacketType::EntityAdd, PacketType::EntityEdit, PacketType::EntityErase }, this, "handleEntityPacket"); } From d49c71d1321361adc5b3aef28bddb93624558e85 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:42:03 -0700 Subject: [PATCH 111/146] Update a shared ptr NLPacket parameter to use NLPacket& --- libraries/networking/src/LimitedNodeList.cpp | 8 ++++---- libraries/networking/src/LimitedNodeList.h | 4 ++-- libraries/networking/src/NodeList.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0b76de6304..55443b6265 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -360,8 +360,8 @@ std::unique_ptr LimitedNodeList::constructPingPacket(PingType_t pingTy return pingPacket; } -std::unique_ptr LimitedNodeList::constructPingReplyPacket(QSharedPointer pingPacket) { - QDataStream pingPacketStream(pingPacket.data()); +std::unique_ptr LimitedNodeList::constructPingReplyPacket(NLPacket& pingPacket) { + QDataStream pingPacketStream(&pingPacket); PingType_t typeFromOriginalPing; pingPacketStream >> typeFromOriginalPing; @@ -390,11 +390,11 @@ std::unique_ptr LimitedNodeList::constructICEPingPacket(PingType_t pin return icePingPacket; } -std::unique_ptr LimitedNodeList::constructICEPingReplyPacket(QSharedPointer pingPacket, const QUuid& iceID) { +std::unique_ptr LimitedNodeList::constructICEPingReplyPacket(NLPacket& pingPacket, const QUuid& iceID) { // pull out the ping type so we can reply back with that PingType_t pingType; - memcpy(&pingType, pingPacket->getPayload() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t)); + memcpy(&pingType, pingPacket.getPayload() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t)); int packetSize = NUM_BYTES_RFC4122_UUID + sizeof(PingType_t); auto icePingReplyPacket = NLPacket::create(PacketType::ICEPingReply, packetSize); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 07d1eed644..09bb439e18 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -165,10 +165,10 @@ public: void resetPacketStats(); std::unique_ptr constructPingPacket(PingType_t pingType = PingType::Agnostic); - std::unique_ptr constructPingReplyPacket(QSharedPointer pingPacket); + std::unique_ptr constructPingReplyPacket(NLPacket& pingPacket); std::unique_ptr constructICEPingPacket(PingType_t pingType, const QUuid& iceID); - std::unique_ptr constructICEPingReplyPacket(QSharedPointer pingPacket, const QUuid& iceID); + std::unique_ptr constructICEPingReplyPacket(NLPacket& pingPacket, const QUuid& iceID); virtual bool processSTUNResponse(QSharedPointer packet); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 1daf8a1c02..3fed4bf67b 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -164,7 +164,7 @@ void NodeList::timePingReply(QSharedPointer packet, const SharedNodePo void NodeList::processPingPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // send back a reply - auto replyPacket = constructPingReplyPacket(packet); + auto replyPacket = constructPingReplyPacket(*packet); const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr(); sendPacket(std::move(replyPacket), sendingNode, senderSockAddr); @@ -188,7 +188,7 @@ void NodeList::processPingReplyPacket(QSharedPointer packet, SharedNod void NodeList::processICEPingPacket(QSharedPointer packet) { // send back a reply - auto replyPacket = constructICEPingReplyPacket(packet, _domainHandler.getICEClientID()); + auto replyPacket = constructICEPingReplyPacket(*packet, _domainHandler.getICEClientID()); sendPacket(std::move(replyPacket), packet->getSenderSockAddr()); } From 23548a99bc0155e5d2629628120b146360dac956 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:43:01 -0700 Subject: [PATCH 112/146] move NACK packet disabling to EntityEditPacketSender --- interface/src/Application.h | 1 + interface/src/Menu.cpp | 6 ++++-- interface/src/Menu.h | 2 +- libraries/entities/src/EntityEditPacketSender.cpp | 4 ++-- libraries/entities/src/EntityEditPacketSender.h | 6 ++++++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 754698acc8..e6eee75b04 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -217,6 +217,7 @@ public: OctreeQuery& getOctreeQuery() { return _octreeQuery; } EntityTree* getEntityClipboard() { return &_entityClipboard; } EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } + EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } bool isMousePressed() const { return _mousePressed; } bool isMouseHidden() const { return !_cursorVisible; } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9f49361f79..0f7df50245 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -499,7 +499,9 @@ Menu::Menu() { #endif MenuWrapper* networkMenu = developerMenu->addMenu("Network"); - addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false); + addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, falsem + qApp()->getEntityEditPacketSender(), + SLOT(toggleNackPackets())); addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableActivityLogger, 0, @@ -542,7 +544,7 @@ Menu::Menu() { SLOT(toggleAudioNoiseReduction())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio, 0, false, - audioIO.data(), SLOT(toggleServerEcho())); + NackaudioIO.data(), SLOT(toggleServerEcho())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio, 0, false, audioIO.data(), SLOT(toggleLocalEcho())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 043bb53a7f..a0ffb05a4f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -169,7 +169,7 @@ namespace MenuOption { const QString DeleteBookmark = "Delete Bookmark..."; const QString DisableActivityLogger = "Disable Activity Logger"; const QString DisableLightEntities = "Disable Light Entities"; - const QString DisableNackPackets = "Disable NACK Packets"; + const QString DisableNackPackets = "Disable Entity NACK Packets"; const QString DiskCacheEditor = "Disk Cache Editor"; const QString DisplayHands = "Show Hand Info"; const QString DisplayHandTargets = "Show Hand Targets"; diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 160e8721f1..78bf787d54 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -23,9 +23,9 @@ EntityEditPacketSender::EntityEditPacketSender() { } void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet) { - // if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { + if (_shouldNack) { processNackPacket(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); - // } + } } void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew) { diff --git a/libraries/entities/src/EntityEditPacketSender.h b/libraries/entities/src/EntityEditPacketSender.h index 235e340da2..2e49a80f4f 100644 --- a/libraries/entities/src/EntityEditPacketSender.h +++ b/libraries/entities/src/EntityEditPacketSender.h @@ -37,5 +37,11 @@ public: // My server type is the model server virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual void adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew); + +public slots: + void toggleNackPackets() { _shouldNack = !_shouldNack; } + +private: + bool _shouldNack = false; }; #endif // hifi_EntityEditPacketSender_h From 4dd3dd63867e8702654fb66ed4f5c5b60a34acc5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:44:04 -0700 Subject: [PATCH 113/146] swap m for comma in Menu --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 0f7df50245..9edf996e2b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -499,7 +499,7 @@ Menu::Menu() { #endif MenuWrapper* networkMenu = developerMenu->addMenu("Network"); - addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, falsem + addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false, qApp()->getEntityEditPacketSender(), SLOT(toggleNackPackets())); addCheckableActionToQMenuAndActionHash(networkMenu, From e2188415fe8bc53fd2e821cd4e3bd487adc7ca8d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 14:45:26 -0700 Subject: [PATCH 114/146] fix ref to qApp, connection to audioIO --- interface/src/Menu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9edf996e2b..6c82fcb9d7 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -500,7 +500,7 @@ Menu::Menu() { MenuWrapper* networkMenu = developerMenu->addMenu("Network"); addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false, - qApp()->getEntityEditPacketSender(), + qApp->getEntityEditPacketSender(), SLOT(toggleNackPackets())); addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableActivityLogger, @@ -544,7 +544,7 @@ Menu::Menu() { SLOT(toggleAudioNoiseReduction())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio, 0, false, - NackaudioIO.data(), SLOT(toggleServerEcho())); + audioIO.data(), SLOT(toggleServerEcho())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio, 0, false, audioIO.data(), SLOT(toggleLocalEcho())); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio, From 90407e2720f7b6b7cb9151aa3c6ce9c6e51c40c5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:45:32 -0700 Subject: [PATCH 115/146] Remove redundant check in if --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d6d6956a12..0f0b1b2c3c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -734,7 +734,7 @@ void DomainServer::processListRequestPacket(QSharedPointer packet) { SharedNodePointer checkInNode = limitedNodeList->nodeWithUUID(nodeUUID); - if (!nodeUUID.isNull() && checkInNode) { + if (checkInNode) { NodeType_t throwawayNodeType; HifiSockAddr nodePublicAddress, nodeLocalAddress; From 84796b20e0722fcc8ae11156c2ef45b43a539e95 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:45:45 -0700 Subject: [PATCH 116/146] Fix call to constructICEPingReplyPacket --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 0f0b1b2c3c..a0c51564d4 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1393,7 +1393,7 @@ void DomainServer::processICEPeerInformationPacket(QSharedPointer pack void DomainServer::processICEPingPacket(QSharedPointer packet) { auto limitedNodeList = DependencyManager::get(); - auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(packet, limitedNodeList->getSessionUUID()); + auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(*packet, limitedNodeList->getSessionUUID()); limitedNodeList->sendPacket(std::move(pingReplyPacket), packet->getSenderSockAddr()); } From 4d9b28688de2848379092757736467d0017b22cc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:49:51 -0700 Subject: [PATCH 117/146] Update reinterpret_cast call that should be dynamic_cast --- domain-server/src/DomainServer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a0c51564d4..173f206665 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1413,8 +1413,9 @@ void DomainServer::processICEPingReplyPacket(QSharedPointer packet) { } void DomainServer::processNodeJSONStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - if (sendingNode->getLinkedData()) { - reinterpret_cast(sendingNode->getLinkedData())->processJSONStatsPacket(*packet); + auto nodeData = dynamic_cast(sendingNode->getLinkedData()); + if (nodeData) { + nodeData->processJSONStatsPacket(*packet); } } From 677ffb706868fbf9f35c1873bc98d22c0889a33d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:50:36 -0700 Subject: [PATCH 118/146] Remove redundant lookup for packetType --- interface/src/octree/OctreePacketProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 80528612b6..dcfc2bbeb1 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -75,7 +75,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share static QMultiMap versionDebugSuppressMap; const QUuid& senderUUID = packet->getSourceID(); - if (!versionDebugSuppressMap.contains(senderUUID, packet->getType())) { + if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { qDebug() << "Packet version mismatch on" << packetType << "- Sender" << senderUUID << "sent" << (int) packetType << "but" From dcb9c8d1255ed664cb0f42b0798743ad46eb44d2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 14:51:37 -0700 Subject: [PATCH 119/146] Fix AvatarMixer call to reinterpret_cast to use dynamic_cast --- assignment-client/src/avatars/AvatarMixer.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 35cd3d4885..022ae5b3df 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -407,13 +407,15 @@ void AvatarMixer::handleAvatarDataPacket(QSharedPointer packet, Shared void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer packet, SharedNodePointer senderNode) { if (senderNode->getLinkedData()) { - AvatarMixerClientData* nodeData = reinterpret_cast(senderNode->getLinkedData()); - AvatarData& avatar = nodeData->getAvatar(); + AvatarMixerClientData* nodeData = dynamic_cast(senderNode->getLinkedData()); + if (nodeData != nullptr) { + AvatarData& avatar = nodeData->getAvatar(); - // parse the identity packet and update the change timestamp if appropriate - if (avatar.hasIdentityChangedAfterParsing(*packet)) { - QMutexLocker nodeDataLocker(&nodeData->getMutex()); - nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); + // parse the identity packet and update the change timestamp if appropriate + if (avatar.hasIdentityChangedAfterParsing(*packet)) { + QMutexLocker nodeDataLocker(&nodeData->getMutex()); + nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); + } } } } From 9d9ac6eefcec57140d3b9f33bdd4e8338871e55d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:00:36 -0700 Subject: [PATCH 120/146] Rename packetSizeWithHeader to be more descriptive --- assignment-client/src/Agent.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 130e4a47fb..b922629391 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -67,12 +67,12 @@ void Agent::handleOctreePacket(QSharedPointer packet, SharedNodePointe int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(packet, senderNode); if (packet->getSizeUsed() > statsMessageLength) { // pull out the piggybacked packet and create a new QSharedPointer for it - int packetSizeWithHeader = packet->getSizeUsed() - statsMessageLength; + int piggyBackedSizeWithHeader = packet->getSizeUsed() - statsMessageLength; - std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); - memcpy(buffer.get(), packet->getPayload() + statsMessageLength, packetSizeWithHeader); + std::unique_ptr buffer = std::unique_ptr(new char[piggyBackedSizeWithHeader]); + memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggyBackedSizeWithHeader); - auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, packet->getSenderSockAddr()); + auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggyBackedSizeWithHeader, packet->getSenderSockAddr()); packet = QSharedPointer(newPacket.release()); } else { return; // bail since no piggyback data From 7e70e25db8df0d8f778f0aca27286b23e4e06aef Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:01:56 -0700 Subject: [PATCH 121/146] Update cast to dynamic_cast in AvatarMixer --- assignment-client/src/avatars/AvatarMixer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index d24bdf409d..73b3da554f 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -421,8 +421,8 @@ void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer packet, Sh } void AvatarMixer::handleAvatarBillboardPacket(QSharedPointer packet, SharedNodePointer senderNode) { - if (senderNode->getLinkedData()) { - AvatarMixerClientData* nodeData = static_cast(senderNode->getLinkedData()); + AvatarMixerClientData* nodeData = dynamic_cast(senderNode->getLinkedData()); + if (nodeData) { AvatarData& avatar = nodeData->getAvatar(); // parse the billboard packet and update the change timestamp if appropriate From 0c02933e668b4e1c0cbbe4d4c863271d3bff0193 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:09:45 -0700 Subject: [PATCH 122/146] Remove LimitedNodeList::processKillNode(const QByteArray& datagram) --- libraries/networking/src/LimitedNodeList.cpp | 6 +----- libraries/networking/src/LimitedNodeList.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 8cca09c971..0fd17eb4df 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -296,12 +296,8 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { } void LimitedNodeList::processKillNode(NLPacket& packet) { - processKillNode(QByteArray::fromRawData(packet.getData(), packet.getSizeWithHeader())); -} - -void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { // read the node id - QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID)); + QUuid nodeUUID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID)); // kill the node with this UUID, if it exists killNodeWithUUID(nodeUUID); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 0fb18bc834..b61fe6ea4e 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -155,7 +155,6 @@ public: const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } void processKillNode(NLPacket& packet); - void processKillNode(const QByteArray& datagram); int updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer matchingNode); From 86e4d5f6318ca3f8192f5e0de7fc52d267471c0a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:12:32 -0700 Subject: [PATCH 123/146] Remove PacketReceiverListener --- .../networking/src/PacketReceiverListener.cpp | 0 .../networking/src/PacketReceiverListener.h | 22 ------------------- 2 files changed, 22 deletions(-) delete mode 100644 libraries/networking/src/PacketReceiverListener.cpp delete mode 100644 libraries/networking/src/PacketReceiverListener.h diff --git a/libraries/networking/src/PacketReceiverListener.cpp b/libraries/networking/src/PacketReceiverListener.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libraries/networking/src/PacketReceiverListener.h b/libraries/networking/src/PacketReceiverListener.h deleted file mode 100644 index ad0f1c6f7f..0000000000 --- a/libraries/networking/src/PacketReceiverListener.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// PacketListener.h -// libraries/networking/src -// -// Created by Stephen Birarda on 07/14/15. -// Copyright 2015 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_PacketListener_h -#define hifi_PacketListener_h - -#pragma once - -class PacketListener { -public: - virtual ~PacketListener(); -}; - -#endif // hifi_PacketListener_h From 7bd10afbf2a916c373f78917766fafe9683a2f49 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:22:16 -0700 Subject: [PATCH 124/146] Remove packetVersionMatch from LimitedNodeList --- libraries/networking/src/LimitedNodeList.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index b61fe6ea4e..80973f8d46 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -117,7 +117,6 @@ public: QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getDTLSSocket(); - bool packetVersionMatch(const NLPacket& packet); bool packetSourceAndHashMatch(const NLPacket& packet, SharedNodePointer& matchingNode); PacketReceiver& getPacketReceiver() { return _packetReceiver; } From 96bd650b55a44d9add5c516273c3a9e346641eb0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:22:35 -0700 Subject: [PATCH 125/146] Fix NLPacket::localHeaderSize --- libraries/networking/src/NLPacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 456c75cf0c..6fa7c73d39 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -13,7 +13,7 @@ qint64 NLPacket::localHeaderSize(PacketType::Value type) { qint64 size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) + - ((NON_VERIFIED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); + ((NON_SOURCED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); return size; } From 47f3aad437bca64298cab4880713fa3c5a072c17 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:23:41 -0700 Subject: [PATCH 126/146] Update use of sendingNode->getUUID() to use packet->getSourceID instead --- libraries/octree/src/JurisdictionListener.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index 7f4cb2d474..c8bb111a1e 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -57,10 +57,10 @@ bool JurisdictionListener::queueJurisdictionRequest() { } void JurisdictionListener::processPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - if (packet->getType() == PacketType::Jurisdiction && sendingNode) { + if (packet->getType() == PacketType::Jurisdiction) { JurisdictionMap map; map.unpackFromPacket(*packet); - _jurisdictions[sendingNode->getUUID()] = map; + _jurisdictions[packet->getSourceID()] = map; } } From ef7a91af8f1dac7425a7d0384575055a05902843 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:27:38 -0700 Subject: [PATCH 127/146] Make NLPacket read SourceID/VerificaitionHash methods protected --- libraries/networking/src/NLPacket.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 8652bb3371..f269b27ec2 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -29,9 +29,6 @@ public: virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 localHeaderSize() const; // Current level's header size - void readSourceID(); - void readVerificationHash(); - const QUuid& getSourceID() const { return _sourceID; } const QByteArray& getVerificationHash() const { return _verificationHash; } @@ -42,7 +39,10 @@ protected: NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); NLPacket(const NLPacket& other); + void readSourceID(); void setSourceID(const QUuid& sourceID); + + void readVerificationHash(); void setVerificationHash(const QByteArray& verificationHash); QUuid _sourceID; From 789235b8c7e31e4efe512b886a0886b0a4e91537 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:28:38 -0700 Subject: [PATCH 128/146] make NodeList deleter be deleteLater --- assignment-client/src/AssignmentClient.cpp | 25 ++++++++-- assignment-client/src/AssignmentClient.h | 2 +- assignment-client/src/audio/AudioMixer.cpp | 5 -- .../src/audio/AudioMixerDatagramProcessor.cpp | 47 ------------------- .../src/audio/AudioMixerDatagramProcessor.h | 32 ------------- assignment-client/src/octree/OctreeServer.cpp | 34 +------------- assignment-client/src/octree/OctreeServer.h | 2 - interface/src/Application.cpp | 9 ++-- libraries/networking/src/NodeList.cpp | 5 ++ libraries/networking/src/NodeList.h | 2 - .../networking/src/PacketReceiverListener.cpp | 0 .../networking/src/PacketReceiverListener.h | 22 --------- .../networking/src/ThreadedAssignment.cpp | 39 +-------------- libraries/networking/src/ThreadedAssignment.h | 2 - 14 files changed, 33 insertions(+), 193 deletions(-) delete mode 100644 assignment-client/src/audio/AudioMixerDatagramProcessor.cpp delete mode 100644 assignment-client/src/audio/AudioMixerDatagramProcessor.h delete mode 100644 libraries/networking/src/PacketReceiverListener.cpp delete mode 100644 libraries/networking/src/PacketReceiverListener.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 6da3786ef7..c81a521552 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -62,6 +62,17 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri DependencyManager::registerInheritance(); auto actionFactory = DependencyManager::set(); + // setup a thread for the NodeList and its PacketReceiver + QThread* nodeThread = new QThread(this); + nodeThread->setObjectName("NodeList Thread"); + nodeThread->start(); + + // make sure the node thread is given highest priority + nodeThread->setPriority(QThread::TimeCriticalPriority); + + // put the NodeList on the node thread + nodeList->moveToThread(nodeThread); + // make up a uuid for this child so the parent can tell us apart. This id will be changed // when the domain server hands over an assignment. QUuid nodeUUID = QUuid::createUuid(); @@ -124,7 +135,6 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket"); } - void AssignmentClient::stopAssignmentClient() { qDebug() << "Forced stop of assignment-client."; @@ -150,6 +160,16 @@ void AssignmentClient::stopAssignmentClient() { } } +AssignmentClient::~AssignmentClient() { + QThread* nodeThread = DependencyManager::get()->thread(); + + // remove the NodeList from the DependencyManager + DependencyManager::destroy(); + + // ask the node thread to quit and wait until it is done + nodeThread->quit(); + nodeThread->wait(); +} void AssignmentClient::aboutToQuit() { stopAssignmentClient(); @@ -251,9 +271,6 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer pac _currentAssignment->moveToThread(workerThread); - // move the NodeList to the thread used for the _current assignment - nodeList->moveToThread(workerThread); - // Starts an event loop, and emits workerThread->started() workerThread->start(); } else { diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 348255751c..e74cd50065 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -24,10 +24,10 @@ class QSharedMemory; class AssignmentClient : public QObject, public PacketListener { Q_OBJECT public: - AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort, quint16 assignmentMonitorPort); + ~AssignmentClient(); private slots: void sendAssignmentRequest(); void assignmentCompleted(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index a44759ae8d..d43601707d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -52,7 +52,6 @@ #include "AudioRingBuffer.h" #include "AudioMixerClientData.h" -#include "AudioMixerDatagramProcessor.h" #include "AvatarAudioStream.h" #include "InjectedAudioStream.h" @@ -657,10 +656,6 @@ void AudioMixer::run() { // we do not want this event loop to be the handler for UDP datagrams, so disconnect disconnect(&nodeList->getNodeSocket(), 0, this, 0); - // setup a QThread with us as parent that will house the AudioMixerDatagramProcessor - _datagramProcessingThread = new QThread(this); - _datagramProcessingThread->setObjectName("Datagram Processor Thread"); - nodeList->addNodeTypeToInterestSet(NodeType::Agent); nodeList->linkedDataCreateCallback = [](Node* node) { diff --git a/assignment-client/src/audio/AudioMixerDatagramProcessor.cpp b/assignment-client/src/audio/AudioMixerDatagramProcessor.cpp deleted file mode 100644 index 73a4e01844..0000000000 --- a/assignment-client/src/audio/AudioMixerDatagramProcessor.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// AudioMixerDatagramProcessor.cpp -// assignment-client/src -// -// Created by Stephen Birarda on 2014-08-14. -// Copyright 2014 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 - -#include -#include - -#include "AudioMixerDatagramProcessor.h" - -AudioMixerDatagramProcessor::AudioMixerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread) : - _nodeSocket(nodeSocket), - _previousNodeSocketThread(previousNodeSocketThread) -{ - -} - -AudioMixerDatagramProcessor::~AudioMixerDatagramProcessor() { - // return the node socket to its previous thread - _nodeSocket.moveToThread(_previousNodeSocketThread); -} - -void AudioMixerDatagramProcessor::readPendingDatagrams() { - - HifiSockAddr senderSockAddr; - static QByteArray incomingPacket; - - // read everything that is available - while (_nodeSocket.hasPendingDatagrams()) { - incomingPacket.resize(_nodeSocket.pendingDatagramSize()); - - // just get this packet off the stack - _nodeSocket.readDatagram(incomingPacket.data(), incomingPacket.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - - // emit the signal to tell AudioMixer it needs to process a packet - emit packetRequiresProcessing(incomingPacket, senderSockAddr); - } -} diff --git a/assignment-client/src/audio/AudioMixerDatagramProcessor.h b/assignment-client/src/audio/AudioMixerDatagramProcessor.h deleted file mode 100644 index 94233a1373..0000000000 --- a/assignment-client/src/audio/AudioMixerDatagramProcessor.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// AudioMixerDatagramProcessor.h -// assignment-client/src -// -// Created by Stephen Birarda on 2014-08-14. -// Copyright 2014 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_AudioMixerDatagramProcessor_h -#define hifi_AudioMixerDatagramProcessor_h - -#include -#include - -class AudioMixerDatagramProcessor : public QObject { - Q_OBJECT -public: - AudioMixerDatagramProcessor(QUdpSocket& nodeSocket, QThread* previousNodeSocketThread); - ~AudioMixerDatagramProcessor(); -public slots: - void readPendingDatagrams(); -signals: - void packetRequiresProcessing(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); -private: - QUdpSocket& _nodeSocket; - QThread* _previousNodeSocketThread; -}; - -#endif // hifi_AudioMixerDatagramProcessor_h \ No newline at end of file diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index efcde790f9..dfb832eed4 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -838,36 +838,6 @@ void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer pack _jurisdictionSender->queueReceivedPacket(packet, senderNode); } -void OctreeServer::setupDatagramProcessingThread() { - auto nodeList = DependencyManager::get(); - - // we do not want this event loop to be the handler for UDP datagrams, so disconnect - disconnect(&nodeList->getNodeSocket(), 0, this, 0); - - // setup a QThread with us as parent that will house the OctreeServerDatagramProcessor - _datagramProcessingThread = new QThread(this); - _datagramProcessingThread->setObjectName("Octree Datagram Processor"); - - // create an OctreeServerDatagramProcessor and move it to that thread - OctreeServerDatagramProcessor* datagramProcessor = new OctreeServerDatagramProcessor(nodeList->getNodeSocket(), thread()); - datagramProcessor->moveToThread(_datagramProcessingThread); - - // remove the NodeList as the parent of the node socket - nodeList->getNodeSocket().setParent(NULL); - nodeList->getNodeSocket().moveToThread(_datagramProcessingThread); - - // let the datagram processor handle readyRead from node socket - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, - datagramProcessor, &OctreeServerDatagramProcessor::readPendingDatagrams); - - // delete the datagram processor and the associated thread when the QThread quits - connect(_datagramProcessingThread, &QThread::finished, datagramProcessor, &QObject::deleteLater); - connect(datagramProcessor, &QObject::destroyed, _datagramProcessingThread, &QThread::deleteLater); - - // start the datagram processing thread - _datagramProcessingThread->start(); -} - bool OctreeServer::readOptionBool(const QString& optionName, const QJsonObject& settingsSectionObject, bool& result) { result = false; // assume it doesn't exist bool optionAvailable = false; @@ -1079,15 +1049,13 @@ void OctreeServer::run() { // use common init to setup common timers and logging commonInit(getMyLoggingServerTargetName(), getMyNodeType()); - setupDatagramProcessingThread(); - // read the configuration from either the payload or the domain server configuration readConfiguration(); beforeRun(); // after payload has been processed connect(nodeList.data(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer))); - connect(nodeList.data(), SIGNAL(nodeKilled(SharedNodePointer)),SLOT(nodeKilled(SharedNodePointer))); + connect(nodeList.data(), SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); // we need to ask the DS about agents so we can ping/reply with them diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index bcc9f8cc43..419cdabc58 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -145,8 +145,6 @@ protected: QString getConfiguration(); QString getStatusLink(); - void setupDatagramProcessingThread(); - int _argc; const char** _argv; char** _parsedArgV; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d02f5daea6..57f2b7c523 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -380,17 +380,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // start the nodeThread so its event loop is running QThread* nodeThread = new QThread(this); - nodeThread->setObjectName("Datagram Processor Thread"); + nodeThread->setObjectName("NodeList Thread"); nodeThread->start(); // make sure the node thread is given highest priority nodeThread->setPriority(QThread::TimeCriticalPriority); - // have the NodeList use deleteLater from DM customDeleter - nodeList->setCustomDeleter([](Dependency* dependency) { - static_cast(dependency)->deleteLater(); - }); - // setup a timer for domain-server check ins QTimer* domainCheckInTimer = new QTimer(nodeList.data()); connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); @@ -748,6 +743,8 @@ Application::~Application() { DependencyManager::destroy(); QThread* nodeThread = DependencyManager::get()->thread(); + + // remove the NodeList from the DependencyManager DependencyManager::destroy(); // ask the node thread to quit and wait until it is done diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 3773a8a540..45fdb2590b 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -45,6 +45,11 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned qRegisterMetaType(); firstCall = false; } + + setCustomDeleter([](Dependency* dependency){ + static_cast(dependency)->deleteLater(); + }); + auto addressManager = DependencyManager::get(); // handle domain change signals from AddressManager diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index b9f782f717..72e8d577e0 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -112,8 +112,6 @@ private: DomainHandler _domainHandler; int _numNoReplyDomainCheckIns; HifiSockAddr _assignmentServerSocket; - - friend class Application; }; #endif // hifi_NodeList_h diff --git a/libraries/networking/src/PacketReceiverListener.cpp b/libraries/networking/src/PacketReceiverListener.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libraries/networking/src/PacketReceiverListener.h b/libraries/networking/src/PacketReceiverListener.h deleted file mode 100644 index ad0f1c6f7f..0000000000 --- a/libraries/networking/src/PacketReceiverListener.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// PacketListener.h -// libraries/networking/src -// -// Created by Stephen Birarda on 07/14/15. -// Copyright 2015 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_PacketListener_h -#define hifi_PacketListener_h - -#pragma once - -class PacketListener { -public: - virtual ~PacketListener(); -}; - -#endif // hifi_PacketListener_h diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index b1c4bdbc7f..fe63348e02 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -20,8 +20,8 @@ ThreadedAssignment::ThreadedAssignment(NLPacket& packet) : Assignment(packet), - _isFinished(false), - _datagramProcessingThread(NULL) + _isFinished(false) + { } @@ -42,31 +42,9 @@ void ThreadedAssignment::setFinished(bool isFinished) { _statsTimer->stop(); } - // stop processing datagrams from the node socket - // this ensures we won't process a domain list while we are going down - auto nodeList = DependencyManager::get(); - disconnect(&nodeList->getNodeSocket(), 0, this, 0); - // call our virtual aboutToFinish method - this gives the ThreadedAssignment subclass a chance to cleanup aboutToFinish(); - // if we have a datagram processing thread, quit it and wait on it to make sure that - // the node socket is back on the same thread as the NodeList - - - if (_datagramProcessingThread) { - // tell the datagram processing thread to quit and wait until it is done, - // then return the node socket to the NodeList - _datagramProcessingThread->quit(); - _datagramProcessingThread->wait(); - - // set node socket parent back to NodeList - nodeList->getNodeSocket().setParent(nodeList.data()); - } - - // move the NodeList back to the QCoreApplication instance's thread - nodeList->moveToThread(QCoreApplication::instance()->thread()); - emit finished(); } } @@ -120,16 +98,3 @@ void ThreadedAssignment::checkInWithDomainServerOrExit() { DependencyManager::get()->sendDomainServerCheckIn(); } } - -bool ThreadedAssignment::readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr) { - auto nodeList = DependencyManager::get(); - - if (nodeList->getNodeSocket().hasPendingDatagrams()) { - destinationByteArray.resize(nodeList->getNodeSocket().pendingDatagramSize()); - nodeList->getNodeSocket().readDatagram(destinationByteArray.data(), destinationByteArray.size(), - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - return true; - } else { - return false; - } -} diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index 922a34b3e4..cfe2363c98 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -38,10 +38,8 @@ signals: void finished(); protected: - bool readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr); void commonInit(const QString& targetName, NodeType_t nodeType, bool shouldSendStats = true); bool _isFinished; - QThread* _datagramProcessingThread; QTimer* _domainServerTimer = nullptr; QTimer* _statsTimer = nullptr; From 19c1ce2d6f3381de1cfdc5a2fb4de06f2f4002ee Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:29:41 -0700 Subject: [PATCH 129/146] remove the QUDPSocket readyRead hack --- libraries/networking/src/ThreadedAssignment.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index fe63348e02..7631a76a76 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -57,9 +57,6 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy auto nodeList = DependencyManager::get(); nodeList->setOwnerType(nodeType); - // this is a temp fix for Qt 5.3 - rebinding the node socket gives us readyRead for the socket on this thread - nodeList->rebindNodeSocket(); - _domainServerTimer = new QTimer(); connect(_domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit())); _domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); From e749b9727f1e0cdd7719f65009f33f973a00cfeb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:33:05 -0700 Subject: [PATCH 130/146] have threaded assignment de-register for packets in finished --- libraries/networking/src/ThreadedAssignment.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 7631a76a76..44d1aaf280 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -34,6 +34,9 @@ void ThreadedAssignment::setFinished(bool isFinished) { qDebug() << "ThreadedAssignment::setFinished(true) called - finishing up."; + // we should de-register immediately for any of our packets + DependencyManager::get()->getPacketReceiver().unregisterListener(this); + if (_domainServerTimer) { _domainServerTimer->stop(); } From 55eb24e69ef9a0268aa8c4a4ae9e93b9ab95961e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:41:31 -0700 Subject: [PATCH 131/146] call right method from packetReceiver --- libraries/networking/src/PacketReceiver.cpp | 32 ++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 20cc5c5b15..31460de3b9 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -218,24 +218,32 @@ void PacketReceiver::processDatagrams() { auto listener = it.value(); if (listener.first) { + + bool success = false; if (matchingNode) { emit dataReceived(matchingNode->getType(), packet->getSizeWithHeader()); + QMetaMethod metaMethod = listener.second; + + static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); + + if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) { + success = metaMethod.invoke(listener.first, + Q_ARG(QSharedPointer, QSharedPointer(packet.release())), + Q_ARG(SharedNodePointer, matchingNode)); + + } else { + success = metaMethod.invoke(listener.first, + Q_ARG(QSharedPointer, QSharedPointer(packet.release()))); + } + } else { emit dataReceived(NodeType::Unassigned, packet->getSizeWithHeader()); - } - - bool success = false; - if (matchingNode) { success = listener.second.invoke(listener.first, Q_ARG(QSharedPointer, QSharedPointer(packet.release()))); - } else { - success = listener.second.invoke(listener.first, - Q_ARG(QSharedPointer, QSharedPointer(packet.release())), - Q_ARG(SharedNodePointer, matchingNode)); } - + if (!success) { qDebug() << "Error delivering packet " << nameForPacketType(packet->getType()) << " to listener: " << listener.first->objectName() << "::" << listener.second.name(); @@ -247,13 +255,11 @@ void PacketReceiver::processDatagrams() { << "has been destroyed - removing mapping."; _packetListenerMap.erase(it); } - - _packetListenerLock.unlock(); - } else { - _packetListenerLock.unlock(); qDebug() << "No listener found for packet type " << nameForPacketType(packet->getType()); } + + _packetListenerLock.unlock(); } } } From ca47165d72473818444dce42212e8573030886cf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:42:28 -0700 Subject: [PATCH 132/146] compare bytesAvailable to 0 --- libraries/octree/src/OctreeRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 54ce95b803..9f4cd0d1a1 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -108,7 +108,7 @@ void OctreeRenderer::processDatagram(NLPacket& packet, SharedNodePointer sourceN bool error = false; - while (packet.bytesAvailable() && !error) { + while (packet.bytesAvailable() > 0 && !error) { if (packetIsCompressed) { if (packet.bytesAvailable() > (qint64) sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { packet.readPrimitive(§ionLength); From 71866d52ed329656717dee2befabd27d79140b9d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:43:00 -0700 Subject: [PATCH 133/146] Update packet reading to use fromRawData for reading uuid --- assignment-client/src/AssignmentClientMonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 3ec457598c..aa5b2f4749 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -203,7 +203,7 @@ void AssignmentClientMonitor::checkSpares() { } void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer packet) { - QUuid senderID = QUuid::fromRfc4122(packet->read(NUM_BYTES_RFC4122_UUID)); + QUuid senderID = QUuid::fromRfc4122(QByteArray::fromRawData(packet->getData(), NUM_BYTES_RFC4122_UUID)); auto nodeList = DependencyManager::get(); From b7b2cb73efa87e5d96274673e7c7a1206ff28f06 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:43:10 -0700 Subject: [PATCH 134/146] remove check for shutting down --- libraries/networking/src/PacketReceiver.cpp | 4 ---- libraries/networking/src/PacketReceiver.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 31460de3b9..1f163cdaf3 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -174,10 +174,6 @@ void PacketReceiver::processDatagrams() { //PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), //"PacketReceiver::processDatagrams()"); - if (_isShuttingDown) { - return; // bail early... we're shutting down. - } - auto nodeList = DependencyManager::get(); while (nodeList->getNodeSocket().hasPendingDatagrams()) { diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index c84b5ef432..bf5889af1e 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -37,8 +37,6 @@ public: void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } - void shutdown() { _isShuttingDown = true; } - void registerListenerForTypes(const QSet& types, PacketListener* listener, const char* slot); void registerListener(PacketType::Value type, PacketListener* listener, const char* slot); void unregisterListener(PacketListener* listener); From 38591a8edbe535eec7460f3b64dffe5b6c75c72d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:43:15 -0700 Subject: [PATCH 135/146] Update avatar billboard loading to use packet.readAll() --- libraries/avatars/src/AvatarData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 25a1247691..f036c0ca8f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -911,7 +911,7 @@ QByteArray AvatarData::identityByteArray() { } bool AvatarData::hasBillboardChangedAfterParsing(NLPacket& packet) { - QByteArray newBillboard = QByteArray(packet.getPayload()); + QByteArray newBillboard = packet.readAll(); if (newBillboard == _billboard) { return false; } From fb7cb7ff5368b8c0077055835c372204c8070207 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:49:54 -0700 Subject: [PATCH 136/146] add the option for PacketReceiver to drop packets --- assignment-client/src/AssignmentClient.cpp | 3 +++ interface/src/Application.cpp | 9 ++++----- libraries/networking/src/PacketReceiver.cpp | 5 +++++ libraries/networking/src/PacketReceiver.h | 4 +++- libraries/networking/src/ThreadedAssignment.cpp | 7 ++++++- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index c81a521552..bc2b18cb53 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -330,6 +330,9 @@ void AssignmentClient::assignmentCompleted() { auto nodeList = DependencyManager::get(); + // tell the packet receiver to stop dropping packets + nodeList->getPacketReceiver().setShouldDropPackets(false); + // reset our NodeList by switching back to unassigned and clearing the list nodeList->setOwnerType(NodeType::Unassigned); nodeList->reset(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 57f2b7c523..824de916d5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -663,12 +663,11 @@ void Application::aboutToQuit() { void Application::cleanupBeforeQuit() { - // stop handling packets we've asked to handle - DependencyManager::get()->getPacketReceiver().unregisterListener(this); - _entities.clear(); // this will allow entity scripts to properly shutdown - - //_datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit + + // tell the packet receiver we're shutting down, so it can drop packets + DependencyManager::get()->getPacketReceiver().setShouldDropPackets(true); + _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts ScriptEngine::stopAllScripts(this); // stop all currently running global scripts diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 1f163cdaf3..4c3f268d06 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -180,6 +180,11 @@ void PacketReceiver::processDatagrams() { // setup a buffer to read the packet into int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize(); std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); + + // if we're supposed to drop this packet then break out here + if (_shouldDropPackets) { + break; + } // setup a HifiSockAddr to read into HifiSockAddr senderSockAddr; diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index bf5889af1e..448ca07876 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -34,6 +34,8 @@ public: int getInPacketCount() const { return _inPacketCount; } int getInByteCount() const { return _inByteCount; } + + void setShouldDropPackets(bool shouldDropPackets) { _shouldDropPackets = shouldDropPackets; } void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } @@ -61,7 +63,7 @@ private: QHash _packetListenerMap; int _inPacketCount = 0; int _inByteCount = 0; - bool _isShuttingDown = false; + bool _shouldDropPackets = false; }; #endif // hifi_PacketReceiver_h diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 44d1aaf280..1c425806c9 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -34,8 +34,13 @@ void ThreadedAssignment::setFinished(bool isFinished) { qDebug() << "ThreadedAssignment::setFinished(true) called - finishing up."; + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + // we should de-register immediately for any of our packets - DependencyManager::get()->getPacketReceiver().unregisterListener(this); + packetReceiver.unregisterListener(this); + + // we should also tell the packet receiver to drop packets while we're cleaning up + packetReceiver.setShouldDropPackets(true); if (_domainServerTimer) { _domainServerTimer->stop(); From bbe5a3d682174464b4dc8ad33462b1a4657e3db7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:51:32 -0700 Subject: [PATCH 137/146] remove commented out call to resetCounters --- interface/src/Application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 824de916d5..f9ac9e3a2c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1797,7 +1797,6 @@ void Application::checkFPS() { _fps = (float)_frameCount / diffTime; _frameCount = 0; - //_datagramProcessor->resetCounters(); _timerStart.start(); } From b4d01c464408855e7a50ec9bd4ff459d2863ba79 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:52:16 -0700 Subject: [PATCH 138/146] fix variable name for coding standard --- libraries/networking/src/PacketReceiver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 448ca07876..f0066115e0 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -47,8 +47,8 @@ public slots: void processDatagrams(); signals: - void dataSent(quint8 channel_type, int bytes); - void dataReceived(quint8 channel_type, int bytes); + void dataSent(quint8 channelType, int bytes); + void dataReceived(quint8 channelType, int bytes); void packetVersionMismatch(PacketType::Value type); private: From a61fbff01870124b46444780ca3c6331aedf5106 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:52:28 -0700 Subject: [PATCH 139/146] Add error handling when reading path query response --- libraries/networking/src/NodeList.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 0bf478856e..f69b655306 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -370,14 +370,19 @@ void NodeList::processDomainServerPathQueryResponse(QSharedPointer pac packet->readPrimitive(&numViewpointBytes); // pull the viewpoint from the packet - QString viewpoint = QString::fromUtf8(packet->read(numViewpointBytes)); + auto stringData = packet->read(numViewpointBytes) + if (stringData.size() == numViewpointBytes) { + QString viewpoint = QString::fromUtf8(stringData); - // Hand it off to the AddressManager so it can handle it as a relative viewpoint - if (DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { - qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; + // Hand it off to the AddressManager so it can handle it as a relative viewpoint + if (DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { + qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; + } else { + qCDebug(networking) << "Could not go to viewpoint" << viewpoint + << "which was the lookup result for path" << pathQuery; + } } else { - qCDebug(networking) << "Could not go to viewpoint" << viewpoint - << "which was the lookup result for path" << pathQuery; + qCDebug(networking) << "Error loading viewpoint from path query response"; } } From 5edb809cd1509192e3b3ca3dbfd595bb45a9b5f1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 15:54:23 -0700 Subject: [PATCH 140/146] remove header packet methods from LimitedNodeList --- libraries/networking/src/LimitedNodeList.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 5e23b2e93c..d397d5dea8 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -122,13 +122,6 @@ public: PacketReceiver& getPacketReceiver() { return _packetReceiver; } - // QByteArray byteArrayWithPopulatedHeader(PacketType::Value packetType) - // { return byteArrayWithUUIDPopulatedHeader(packetType, _sessionUUID); } - // int populatePacketHeader(QByteArray& packet, PacketType::Value packetType) - // { return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); } - // int populatePacketHeader(char* packet, PacketType::Value packetType) - // { return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); } - qint64 sendUnreliablePacket(const NLPacket& packet, const SharedNodePointer& destinationNode) { assert(false); return 0; } qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr) { assert(false); return 0; } From e99df5b56d551cf939c5a38b2b04b905ee05a6ae Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 15:55:39 -0700 Subject: [PATCH 141/146] Fix size of statusPacket in AssignmentClient --- assignment-client/src/AssignmentClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 6da3786ef7..8507f5c898 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -168,8 +168,6 @@ void AssignmentClient::setUpStatusToMonitor() { void AssignmentClient::sendStatusPacketToACM() { // tell the assignment client monitor what this assignment client is doing (if anything) auto nodeList = DependencyManager::get(); - - auto statusPacket = NLPacket::create(PacketType::AssignmentClientStatus, 1 + NUM_BYTES_RFC4122_UUID); quint8 assignmentType = Assignment::Type::AllTypes; @@ -177,6 +175,8 @@ void AssignmentClient::sendStatusPacketToACM() { assignmentType = _currentAssignment->getType(); } + auto statusPacket = NLPacket::create(PacketType::AssignmentClientStatus, typeof(assignmentType) + NUM_BYTES_RFC4122_UUID); + statusPacket->write(nodeList->getSessionUUID().toRfc4122()); statusPacket->writePrimitive(assignmentType); From 6d6b9b81171782119bb8c0c9060c6ab47c2eaf27 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 16:11:48 -0700 Subject: [PATCH 142/146] pass sending node to processListRequestPacket --- domain-server/src/DomainServer.cpp | 29 ++++++++++------------------- domain-server/src/DomainServer.h | 2 +- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 21b2ce0f58..0a546d45db 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -726,31 +726,22 @@ void DomainServer::processConnectRequestPacket(QSharedPointer packet) } } -void DomainServer::processListRequestPacket(QSharedPointer packet) { - QDataStream packetStream(packet.data()); +void DomainServer::processListRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { - const QUuid& nodeUUID = packet->getSourceID(); + NodeType_t throwawayNodeType; + HifiSockAddr nodePublicAddress, nodeLocalAddress; - auto limitedNodeList = DependencyManager::get(); + QDataStream packetStream(packet.data()); - SharedNodePointer checkInNode = limitedNodeList->nodeWithUUID(nodeUUID); + parseNodeData(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, packet->getSenderSockAddr()); - if (!nodeUUID.isNull() && checkInNode) { - NodeType_t throwawayNodeType; - HifiSockAddr nodePublicAddress, nodeLocalAddress; + sendingNode->setPublicSocket(nodePublicAddress); + sendingNode->setLocalSocket(nodeLocalAddress); - QDataStream packetStream(packet.data()); + QList nodeInterestList; + packetStream >> nodeInterestList; - parseNodeData(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, packet->getSenderSockAddr()); - - checkInNode->setPublicSocket(nodePublicAddress); - checkInNode->setLocalSocket(nodeLocalAddress); - - QList nodeInterestList; - packetStream >> nodeInterestList; - - sendDomainListToNode(checkInNode, packet->getSenderSockAddr(), nodeInterestList.toSet()); - } + sendDomainListToNode(sendingNode, packet->getSenderSockAddr(), nodeInterestList.toSet()); } unsigned int DomainServer::countConnectedUsers() { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 7f7cba7445..c2d5db367f 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -58,7 +58,7 @@ public slots: void processRequestAssignmentPacket(QSharedPointer packet); void processConnectRequestPacket(QSharedPointer packet); - void processListRequestPacket(QSharedPointer packet); + void processListRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode); void processNodeJSONStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode); void processPathQueryPacket(QSharedPointer packet); void processICEPingPacket(QSharedPointer packet); From d36ed9cd0d6f1a9bde48e1c76d3e2cfeb5a9821a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 16:12:47 -0700 Subject: [PATCH 143/146] Fix missing semicolon --- libraries/networking/src/NodeList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 8a3aa618a4..9d0e6d566e 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -375,7 +375,7 @@ void NodeList::processDomainServerPathQueryResponse(QSharedPointer pac packet->readPrimitive(&numViewpointBytes); // pull the viewpoint from the packet - auto stringData = packet->read(numViewpointBytes) + auto stringData = packet->read(numViewpointBytes); if (stringData.size() == numViewpointBytes) { QString viewpoint = QString::fromUtf8(stringData); From e4849d29ec56c7e2de2519a19f21a6f556a0dc29 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 16:14:43 -0700 Subject: [PATCH 144/146] re-use iterator when checking _octreeServerSceneStats --- interface/src/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f9ac9e3a2c..46f14319d1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3939,8 +3939,9 @@ int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingN // now that we know the node ID, let's add these stats to the stats for that node... _octreeSceneStatsLock.lockForWrite(); - if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { - octreeStats = &_octreeServerSceneStats[nodeUUID]; + auto it = _octreeServerSceneStats.find(nodeUUID); + if (it != _octreeServerSceneStats.end()) { + octreeStats = &it.value(); statsMessageLength = octreeStats->unpackFromPacket(packet); } else { OctreeSceneStats temp; From cb9e12f76a2e29bd01e50d07e27907dbc35f2141 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Jul 2015 16:20:36 -0700 Subject: [PATCH 145/146] Fix using typeof when should be using sizeof --- assignment-client/src/AssignmentClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index d94ba703df..926a0da786 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -195,7 +195,7 @@ void AssignmentClient::sendStatusPacketToACM() { assignmentType = _currentAssignment->getType(); } - auto statusPacket = NLPacket::create(PacketType::AssignmentClientStatus, typeof(assignmentType) + NUM_BYTES_RFC4122_UUID); + auto statusPacket = NLPacket::create(PacketType::AssignmentClientStatus, sizeof(assignmentType) + NUM_BYTES_RFC4122_UUID); statusPacket->write(nodeList->getSessionUUID().toRfc4122()); statusPacket->writePrimitive(assignmentType); From e596733c8b3e6ca0c9bf03e381faa554b099d421 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 14 Jul 2015 16:21:34 -0700 Subject: [PATCH 146/146] fix for stats grab from iterator --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46f14319d1..362fd3660f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3941,7 +3941,7 @@ int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingN _octreeSceneStatsLock.lockForWrite(); auto it = _octreeServerSceneStats.find(nodeUUID); if (it != _octreeServerSceneStats.end()) { - octreeStats = &it.value(); + octreeStats = &it->second; statsMessageLength = octreeStats->unpackFromPacket(packet); } else { OctreeSceneStats temp;