void VoxelPacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "VoxelPacketProcessor::processPacket()"); QByteArray mutablePacket = packet; const int WAY_BEHIND = 300; if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) { qDebug("VoxelPacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } ssize_t messageLength = mutablePacket.size(); Application* app = Application::getInstance(); bool wasStatsPacket = false; // check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that if (app->_wantToKillLocalVoxels) { app->_voxels.killLocalVoxels(); app->_wantToKillLocalVoxels = false; } PacketType 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 if (voxelPacketType == PacketTypeOctreeStats) { int statsMessageLength = app->parseOctreeStats(mutablePacket, 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 (!NodeList::getInstance()->packetVersionAndHashMatch(packet)) { return; // bail since piggyback data doesn't match our versioning } } 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); if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { app->trackIncomingVoxelPacket(mutablePacket, sendingNode, wasStatsPacket); if (sendingNode) { switch(voxelPacketType) { case PacketTypeParticleErase: { app->_particles.processEraseMessage(mutablePacket, sendingNode); } break; case PacketTypeParticleData: { app->_particles.processDatagram(mutablePacket, sendingNode); } break; case PacketTypeEnvironmentData: { app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); } break; default : { app->_voxels.setDataSourceUUID(sendingNode->getUUID()); app->_voxels.parseData(mutablePacket); app->_voxels.setDataSourceUUID(QUuid()); } break; } } } }
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; if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) { qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } int messageLength = mutablePacket.size(); Application* app = Application::getInstance(); bool wasStatsPacket = false; PacketType 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 if (voxelPacketType == PacketTypeOctreeStats) { int statsMessageLength = app->parseOctreeStats(mutablePacket, 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<NodeList>()->packetVersionAndHashMatch(packet)) { return; // bail since piggyback data doesn't match our versioning } } 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); // check version of piggyback packet against expected version if (packetVersion != expectedVersion) { static QMultiMap<QUuid, PacketType> 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) { switch(voxelPacketType) { case PacketTypeEntityErase: { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { app->_entities.processEraseMessage(mutablePacket, sendingNode); } } break; case PacketTypeEntityData: { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { app->_entities.processDatagram(mutablePacket, sendingNode); } } break; case PacketTypeEnvironmentData: { app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); } break; default: { // nothing to do } break; } } }
void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "OctreePacketProcessor::processPacket()"); const int WAY_BEHIND = 300; if (packetsToProcessCount() > WAY_BEHIND && qApp->getLogger()->extraDebugging()) { qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } bool wasStatsPacket = false; PacketType octreePacketType = message->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 (octreePacketType == PacketType::OctreeStats) { int statsMessageLength = qApp->processOctreeStats(*message, sendingNode); wasStatsPacket = true; int piggybackBytes = message->getSize() - statsMessageLength; if (piggybackBytes) { // construct a new packet from the piggybacked one auto buffer = std::unique_ptr<char[]>(new char[piggybackBytes]); memcpy(buffer.get(), message->getRawMessage() + statsMessageLength, piggybackBytes); auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, message->getSenderSockAddr()); message = QSharedPointer<ReceivedMessage>::create(*newPacket); } 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 PacketType packetType = message->getType(); // check version of piggyback packet against expected version if (message->getVersion() != versionForPacketType(message->getType())) { static QMultiMap<QUuid, PacketType> versionDebugSuppressMap; const QUuid& senderUUID = message->getSourceID(); if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { qDebug() << "Was stats packet? " << wasStatsPacket; qDebug() << "OctreePacketProcessor - piggyback packet version mismatch on" << packetType << "- Sender" << senderUUID << "sent" << (int) message->getVersion() << "but" << (int) versionForPacketType(packetType) << "expected."; emit packetVersionMismatch(); versionDebugSuppressMap.insert(senderUUID, packetType); } return; // bail since piggyback version doesn't match } qApp->trackIncomingOctreePacket(*message, sendingNode, wasStatsPacket); // seek back to beginning of packet after tracking message->seek(0); switch(packetType) { case PacketType::EntityErase: { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { qApp->getEntities()->processEraseMessage(*message, sendingNode); } } break; case PacketType::EntityData: { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { qApp->getEntities()->processDatagram(*message, sendingNode); } } break; default: { // nothing to do } break; } }