bool AssetClient::uploadAsset(const QByteArray& data, const QString& extension, UploadResultCallback callback) { auto nodeList = DependencyManager::get<NodeList>(); SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer); if (assetServer) { auto packetList = NLPacketList::create(PacketType::AssetUpload, QByteArray(), true, true); auto messageID = ++_currentID; packetList->writePrimitive(messageID); packetList->writePrimitive(static_cast<uint8_t>(extension.length())); packetList->write(extension.toLatin1().constData(), extension.length()); uint64_t size = data.length(); packetList->writePrimitive(size); packetList->write(data.constData(), size); nodeList->sendPacketList(std::move(packetList), *assetServer); _pendingUploads[assetServer][messageID] = callback; return true; } return false; }
qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { auto statsPacketList = NLPacketList::create(PacketType::NodeJsonStats, QByteArray(), true, true); QJsonDocument jsonDocument(statsObject); statsPacketList->write(jsonDocument.toBinaryData()); sendPacketList(std::move(statsPacketList), destination); // enumerate the resulting strings, breaking them into MTU sized packets return 0; }
void MessagesClient::unsubscribe(const QString& channel) { _subscribedChannels.remove(channel); auto nodeList = DependencyManager::get<NodeList>(); SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer); if (messagesMixer) { auto packetList = NLPacketList::create(PacketType::MessagesUnsubscribe, QByteArray(), true, true); packetList->write(channel.toUtf8()); nodeList->sendPacketList(std::move(packetList), *messagesMixer); } }
void DomainServerSettingsManager::processSettingsRequestPacket(QSharedPointer<ReceivedMessage> message) { Assignment::Type type; message->readPrimitive(&type); QJsonObject responseObject = responseObjectForType(QString::number(type)); auto json = QJsonDocument(responseObject).toJson(); auto packetList = NLPacketList::create(PacketType::DomainSettings, QByteArray(), true, true); packetList->write(json); auto nodeList = DependencyManager::get<LimitedNodeList>(); nodeList->sendPacketList(std::move(packetList), message->getSenderSockAddr()); }
void MessagesMixer::handleMessages(QSharedPointer<NLPacketList> packetList, SharedNodePointer senderNode) { QString channel, message; QUuid senderID; MessagesClient::decodeMessagesPacket(packetList, channel, message, senderID); auto nodeList = DependencyManager::get<NodeList>(); nodeList->eachMatchingNode( [&](const SharedNodePointer& node)->bool { return node->getType() == NodeType::Agent && node->getActiveSocket() && _channelSubscribers[channel].contains(node->getUUID()); }, [&](const SharedNodePointer& node) { auto packetList = MessagesClient::encodeMessagesPacket(channel, message, senderID); nodeList->sendPacketList(std::move(packetList), *node); }); }
void MessagesMixer::handleMessages(QSharedPointer<NLPacketList> packetList, SharedNodePointer senderNode) { Q_ASSERT(packetList->getType() == PacketType::MessagesData); QByteArray packetData = packetList->getMessage(); QBuffer packet{ &packetData }; packet.open(QIODevice::ReadOnly); quint16 channelLength; packet.read(reinterpret_cast<char*>(&channelLength), sizeof(channelLength)); auto channelData = packet.read(channelLength); QString channel = QString::fromUtf8(channelData); quint16 messageLength; packet.read(reinterpret_cast<char*>(&messageLength), sizeof(messageLength)); auto messageData = packet.read(messageLength); QString message = QString::fromUtf8(messageData); auto nodeList = DependencyManager::get<NodeList>(); nodeList->eachMatchingNode( [&](const SharedNodePointer& node)->bool { return node->getType() == NodeType::Agent && node->getActiveSocket() && _channelSubscribers[channel].contains(node->getUUID()); }, [&](const SharedNodePointer& node) { auto packetList = NLPacketList::create(PacketType::MessagesData, QByteArray(), true, true); auto channelUtf8 = channel.toUtf8(); quint16 channelLength = channelUtf8.length(); packetList->writePrimitive(channelLength); packetList->write(channelUtf8); auto messageUtf8 = message.toUtf8(); quint16 messageLength = messageUtf8.length(); packetList->writePrimitive(messageLength); packetList->write(messageUtf8); nodeList->sendPacketList(std::move(packetList), *node); }); }
void MessagesClient::sendMessage(const QString& channel, const QString& message) { auto nodeList = DependencyManager::get<NodeList>(); SharedNodePointer messagesMixer = nodeList->soloNodeOfType(NodeType::MessagesMixer); if (messagesMixer) { auto packetList = NLPacketList::create(PacketType::MessagesData, QByteArray(), true, true); auto channelUtf8 = channel.toUtf8(); quint16 channelLength = channelUtf8.length(); packetList->writePrimitive(channelLength); packetList->write(channelUtf8); auto messageUtf8 = message.toUtf8(); quint16 messageLength = messageUtf8.length(); packetList->writePrimitive(messageLength); packetList->write(messageUtf8); nodeList->sendPacketList(std::move(packetList), *messagesMixer); } }
void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { MessageID messageID; message->readPrimitive(&messageID); auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID)); auto replyPacketList = NLPacketList::create(PacketType::EntityScriptGetStatusReply, QByteArray(), true, true); replyPacketList->writePrimitive(messageID); EntityScriptDetails details; if (_entitiesScriptEngine->getEntityScriptDetails(entityID, details)) { replyPacketList->writePrimitive(true); replyPacketList->writePrimitive(details.status); replyPacketList->writeString(details.errorInfo); } else { replyPacketList->writePrimitive(false); } auto nodeList = DependencyManager::get<NodeList>(); nodeList->sendPacketList(std::move(replyPacketList), *senderNode); } }
void EntityScriptServer::pushLogs() { std::string buffer; { Lock lock(logBufferMutex); std::swap(logBuffer, buffer); } if (buffer.empty()) { return; } if (_logListeners.empty()) { return; } auto nodeList = DependencyManager::get<NodeList>(); for (auto uuid : _logListeners) { auto node = nodeList->nodeWithUUID(uuid); if (node && node->getActiveSocket()) { auto packet = NLPacketList::create(PacketType::EntityServerScriptLog, QByteArray(), true, true); packet->write(buffer.data(), buffer.size()); nodeList->sendPacketList(std::move(packet), *node); } } }
void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { // These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them // about each other. if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { MessageID messageID; message->readPrimitive(&messageID); auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID)); auto replyPacketList = NLPacketList::create(PacketType::EntityScriptGetStatusReply, QByteArray(), true, true); replyPacketList->writePrimitive(messageID); EntityScriptDetails details; if (_entitiesScriptEngine->getEntityScriptDetails(entityID, details)) { replyPacketList->writePrimitive(true); replyPacketList->writePrimitive(details.status); replyPacketList->writeString(details.errorInfo); } else { replyPacketList->writePrimitive(false); } auto nodeList = DependencyManager::get<NodeList>(); nodeList->sendPacketList(std::move(replyPacketList), *senderNode); } }
int OctreeInboundPacketProcessor::sendNackPackets() { if (_shuttingDown) { qDebug() << "OctreeInboundPacketProcessor::sendNackPackets() while shutting down... ignore"; return 0; } auto nodeList = DependencyManager::get<NodeList>(); int packetsSent = 0; NodeToSenderStatsMapIterator i = _singleSenderStats.begin(); while (i != _singleSenderStats.end()) { QUuid nodeUUID = i.key(); SingleSenderStats nodeStats = i.value(); // check if this node is still alive. Remove its stats if it's dead. if (!isAlive(nodeUUID)) { i = _singleSenderStats.erase(i); continue; } // if there are packets from _node that are waiting to be processed, // don't send a NACK since the missing packets may be among those waiting packets. if (hasPacketsToProcessFrom(nodeUUID)) { ++i; continue; } const SharedNodePointer& destinationNode = DependencyManager::get<NodeList>()->nodeWithUUID(nodeUUID); // retrieve sequence number stats of node, prune its missing set SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats(); sequenceNumberStats.pruneMissingSet(); // construct nack packet(s) for this node const QSet<unsigned short int>& missingSequenceNumbers = sequenceNumberStats.getMissingSet(); auto it = missingSequenceNumbers.constBegin(); if (it != missingSequenceNumbers.constEnd()) { auto nackPacketList = NLPacketList::create(_myServer->getMyEditNackType()); while (it != missingSequenceNumbers.constEnd()) { unsigned short int sequenceNumber = *it; nackPacketList->writePrimitive(sequenceNumber); ++it; } qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID; packetsSent += nackPacketList->getNumPackets(); // send the list of nack packets nodeList->sendPacketList(std::move(nackPacketList), *destinationNode); } ++i; } return packetsSent; }