diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 919ac37ee9..61cc775e08 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -55,9 +55,9 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointergetSize() == 0) { return; } - + QDataStream packetStream(message->getMessage()); - + // read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr()); @@ -105,6 +105,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer(node->getLinkedData()); nodeData->setSendingSockAddr(message->getSenderSockAddr()); nodeData->setNodeInterestSet(nodeConnection.interestList.toSet()); + nodeData->setPlaceName(nodeConnection.placeName); // signal that we just connected a node so the DomainServer can get it a list // and broadcast its presence right away @@ -150,6 +151,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID()); nodeData->setWalletUUID(it->second.getWalletUUID()); nodeData->setNodeVersion(it->second.getNodeVersion()); + nodeData->setWasAssigned(true); // cleanup the PendingAssignedNodeData for this assignment now that it's connecting _pendingAssignedNodes.erase(it); @@ -282,7 +284,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect // set the edit rights for this user newNode->setIsAllowedEditor(isAllowedEditor); newNode->setCanRez(canRez); - + // grab the linked data for our new node so we can set the username DomainServerNodeData* nodeData = reinterpret_cast(newNode->getLinkedData()); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 0aab6b7e31..cfec72a24b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -462,7 +462,7 @@ void DomainServer::setupAutomaticNetworking() { nodeList->startSTUNPublicSocketUpdate(); } else { // send our heartbeat to data server so it knows what our network settings are - sendHeartbeatToDataServer(); + sendHeartbeatToMetaverse(); } } else { qDebug() << "Cannot enable domain-server automatic networking without a domain ID." @@ -471,7 +471,7 @@ void DomainServer::setupAutomaticNetworking() { return; } } else { - sendHeartbeatToDataServer(); + sendHeartbeatToMetaverse(); } qDebug() << "Updating automatic networking setting in domain-server to" << _automaticNetworkingSetting; @@ -480,7 +480,7 @@ void DomainServer::setupAutomaticNetworking() { const int DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS = 15 * 1000; QTimer* dataHeartbeatTimer = new QTimer(this); - connect(dataHeartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeatToDataServer())); + connect(dataHeartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeatToMetaverse())); dataHeartbeatTimer->start(DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS); } @@ -678,6 +678,9 @@ void DomainServer::processListRequestPacket(QSharedPointer mess DomainServerNodeData* nodeData = reinterpret_cast(sendingNode->getLinkedData()); nodeData->setNodeInterestSet(nodeRequestData.interestList.toSet()); + // update the connecting hostname in case it has changed + nodeData->setPlaceName(nodeRequestData.placeName); + sendDomainListToNode(sendingNode, message->getSenderSockAddr()); } @@ -1029,11 +1032,11 @@ QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) { const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking"; void DomainServer::performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr) { - sendHeartbeatToDataServer(newPublicSockAddr.getAddress().toString()); + sendHeartbeatToMetaverse(newPublicSockAddr.getAddress().toString()); } -void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { +void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) { const QString DOMAIN_UPDATE = "/api/v1/domains/%1"; auto nodeList = DependencyManager::get(); @@ -1056,20 +1059,34 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { domainObject[RESTRICTED_ACCESS_FLAG] = _settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool(); - // add the number of currently connected agent users - int numConnectedAuthedUsers = 0; + // figure out the breakdown of currently connected interface clients + int numConnectedUnassigned = 0; + QJsonObject userHostnames; - nodeList->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){ - if (node->getLinkedData() && !static_cast(node->getLinkedData())->getUsername().isEmpty()) { - ++numConnectedAuthedUsers; + static const QString DEFAULT_HOSTNAME = "*"; + + nodeList->eachNode([&numConnectedUnassigned, &userHostnames](const SharedNodePointer& node) { + if (node->getLinkedData()) { + auto nodeData = static_cast(node->getLinkedData()); + + if (!nodeData->wasAssigned()) { + ++numConnectedUnassigned; + + // increment the count for this hostname (or the default if we don't have one) + auto hostname = nodeData->getPlaceName().isEmpty() ? DEFAULT_HOSTNAME : nodeData->getPlaceName(); + userHostnames[hostname] = userHostnames[hostname].toInt() + 1; + } } }); - const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; - const QString HEARTBEAT_NUM_USERS_KEY = "num_users"; + static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; + static const QString HEARTBEAT_NUM_USERS_KEY = "num_users"; + static const QString HEARTBEAT_USER_HOSTNAMES_KEY = "user_hostnames"; QJsonObject heartbeatObject; - heartbeatObject[HEARTBEAT_NUM_USERS_KEY] = numConnectedAuthedUsers; + heartbeatObject[HEARTBEAT_NUM_USERS_KEY] = numConnectedUnassigned; + heartbeatObject[HEARTBEAT_USER_HOSTNAMES_KEY] = userHostnames; + domainObject[DOMAIN_HEARTBEAT_KEY] = heartbeatObject; QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson())); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 93bb5de494..fef3221b7d 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -71,7 +71,7 @@ private slots: void sendPendingTransactionsToServer(); void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr); - void sendHeartbeatToDataServer() { sendHeartbeatToDataServer(QString()); } + void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString()); } void sendHeartbeatToIceServer(); void handleConnectedNode(SharedNodePointer newNode); @@ -103,7 +103,7 @@ private: void setupAutomaticNetworking(); void setupICEHeartbeatForFullNetworking(); - void sendHeartbeatToDataServer(const QString& networkAddress); + void sendHeartbeatToMetaverse(const QString& networkAddress); void randomizeICEServerAddress(bool shouldTriggerHostLookup); diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index cd68aa3006..f95403c779 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -56,6 +56,12 @@ public: void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue); void removeOverrideForKey(const QString& key, const QString& value); + + const QString& getPlaceName() { return _placeName; } + void setPlaceName(const QString& placeName) { _placeName = placeName; } + + bool wasAssigned() const { return _wasAssigned; }; + void setWasAssigned(bool wasAssigned) { _wasAssigned = wasAssigned; } private: QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats); @@ -75,6 +81,10 @@ private: bool _isAuthenticated = true; NodeSet _nodeInterestSet; QString _nodeVersion; + + QString _placeName; + + bool _wasAssigned { false }; }; #endif // hifi_DomainServerNodeData_h diff --git a/domain-server/src/NodeConnectionData.cpp b/domain-server/src/NodeConnectionData.cpp index 80cb5950be..28f769298c 100644 --- a/domain-server/src/NodeConnectionData.cpp +++ b/domain-server/src/NodeConnectionData.cpp @@ -23,7 +23,7 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c dataStream >> newHeader.nodeType >> newHeader.publicSockAddr >> newHeader.localSockAddr - >> newHeader.interestList; + >> newHeader.interestList >> newHeader.placeName; newHeader.senderSockAddr = senderSockAddr; diff --git a/domain-server/src/NodeConnectionData.h b/domain-server/src/NodeConnectionData.h index 6b3b8eb7c1..34119ffdab 100644 --- a/domain-server/src/NodeConnectionData.h +++ b/domain-server/src/NodeConnectionData.h @@ -27,6 +27,7 @@ public: HifiSockAddr localSockAddr; HifiSockAddr senderSockAddr; QList interestList; + QString placeName; }; diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index a97f4df35d..36d9e621a9 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -295,14 +295,20 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const // set our current root place name to the name that came back const QString PLACE_NAME_KEY = "name"; QString placeName = rootMap[PLACE_NAME_KEY].toString(); + if (!placeName.isEmpty()) { if (setHost(placeName, trigger)) { trigger = LookupTrigger::Internal; } + + _placeName = placeName; } else { if (setHost(domainIDString, trigger)) { trigger = LookupTrigger::Internal; } + + // this isn't a place, so clear the place name + _placeName.clear(); } // check if we had a path to override the path returned @@ -580,7 +586,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16 bool AddressManager::setDomainInfo(const QString& hostname, quint16 port, LookupTrigger trigger) { bool hostChanged = setHost(hostname, trigger, port); + // clear any current place information _rootPlaceID = QUuid(); + _placeName.clear(); qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index dd0dbd9f38..643924ff5c 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -58,6 +58,7 @@ public: const QString currentPath(bool withOrientation = true) const; const QUuid& getRootPlaceID() const { return _rootPlaceID; } + const QString& getPlaceName() const { return _placeName; } const QString& getHost() const { return _host; } @@ -141,6 +142,7 @@ private: QString _host; quint16 _port; + QString _placeName; QUuid _rootPlaceID; PositionGetter _positionGetter; OrientationGetter _orientationGetter; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 482d0366fd..c295ffc700 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -314,8 +314,10 @@ void NodeList::sendDomainServerCheckIn() { packetStream << connectUUID; } - // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList(); + // pack our data to send to the domain-server including + // the hostname information (so the domain-server can see which place name we came in on) + packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList() + << DependencyManager::get()->getPlaceName(); if (!_domainHandler.isConnected()) { DataServerAccountInfo& accountInfo = accountManager->getAccountInfo(); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 6b917df87a..9f23d3834b 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -58,6 +58,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AssetUpload: // Removal of extension from Asset requests return 18; + case PacketType::DomainConnectRequest: + // addition of referring hostname information + return 18; default: return 17; }