repairs to octree packet receiving in interface

This commit is contained in:
Stephen Birarda 2015-07-13 13:10:57 -07:00
parent 264f39fa59
commit d990420565
18 changed files with 179 additions and 218 deletions

View file

@ -3911,11 +3911,11 @@ void Application::nodeKilled(SharedNodePointer node) {
} }
} }
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. // Attempt to identify the sender from its address.
if (sendingNode) { 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... // now that we know the node ID, let's add these stats to the stats for that node...
_octreeSceneStatsLock.lockForWrite(); _octreeSceneStatsLock.lockForWrite();
@ -3927,7 +3927,7 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar
} }
} }
int Application::processOctreeStats(QSharedPointer<NLPacket> 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 // 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 // parse the incoming stats datas stick it in a temporary object for now, while we
@ -3941,10 +3941,10 @@ int Application::processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodeP
_octreeSceneStatsLock.lockForWrite(); _octreeSceneStatsLock.lockForWrite();
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
octreeStats = &_octreeServerSceneStats[nodeUUID]; octreeStats = &_octreeServerSceneStats[nodeUUID];
statsMessageLength = octreeStats->unpackFromPacket(*packet); statsMessageLength = octreeStats->unpackFromPacket(packet);
} else { } else {
OctreeSceneStats temp; OctreeSceneStats temp;
statsMessageLength = temp.unpackFromPacket(*packet); statsMessageLength = temp.unpackFromPacket(packet);
octreeStats = &temp; octreeStats = &temp;
} }
_octreeSceneStatsLock.unlock(); _octreeSceneStatsLock.unlock();

View file

@ -612,8 +612,8 @@ private:
StDev _idleLoopStdev; StDev _idleLoopStdev;
float _idleLoopMeasuredJitter; float _idleLoopMeasuredJitter;
int processOctreeStats(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode); int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode);
void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket); void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket);
NodeToJurisdictionMap _entityServerJurisdictions; NodeToJurisdictionMap _entityServerJurisdictions;
NodeToOctreeSceneStats _octreeServerSceneStats; NodeToOctreeSceneStats _octreeServerSceneStats;

View file

@ -28,7 +28,7 @@ OctreePacketProcessor::OctreePacketProcessor() {
} }
void OctreePacketProcessor::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) { void OctreePacketProcessor::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
queueReceivedPacket(senderNode, packet); queueReceivedPacket(packet, senderNode);
} }
void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) { void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
@ -41,8 +41,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
} }
int messageLength = packet->getSizeUsed();
Application* app = Application::getInstance(); Application* app = Application::getInstance();
bool wasStatsPacket = false; bool wasStatsPacket = false;
@ -52,60 +50,61 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // 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 // then process any remaining bytes as if it was another packet
if (octreePacketType == PacketType::OctreeStats) { if (octreePacketType == PacketType::OctreeStats) {
int statsMessageLength = app->processOctreeStats(packet, sendingNode); int statsMessageLength = app->processOctreeStats(*packet, 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 wasStatsPacket = true;
// this is testing the version and hash of the original packet int piggybackBytes = packet->getSizeUsed() - statsMessageLength;
if (!DependencyManager::get<NodeList>()->packetVersionAndHashMatch(packet)) {
return; // bail since piggyback data doesn't match our versioning if (piggybackBytes) {
} // construct a new packet from the piggybacked one
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggybackBytes]);
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggybackBytes);
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, packet->getSenderSockAddr());
packet = QSharedPointer<NLPacket>(newPacket.release());
} else { } else {
// Note... stats packets don't have sequence numbers, so we don't want to send those to trackIncomingVoxelPacket() // Note... stats packets don't have sequence numbers, so we don't want to send those to trackIncomingVoxelPacket()
return; // bail since no piggyback data return; // bail since no piggyback data
} }
} // fall through to piggyback message } // fall through to piggyback message
voxelPacketType = packetTypeForPacket(mutablePacket); PacketType::Value packetType = packet->getType();
PacketVersion packetVersion = mutablePacket[1];
PacketVersion expectedVersion = versionForPacketType(voxelPacketType);
// check version of piggyback packet against expected version // check version of piggyback packet against expected version
if (packetVersion != expectedVersion) { if (packetType != versionForPacketType(packet->getType())) {
static QMultiMap<QUuid, PacketType::Value> versionDebugSuppressMap; static QMultiMap<QUuid, PacketType::Value> versionDebugSuppressMap;
QUuid senderUUID = uuidFromPacketHeader(packet); const QUuid& senderUUID = packet->getSourceID();
if (!versionDebugSuppressMap.contains(senderUUID, voxelPacketType)) { if (!versionDebugSuppressMap.contains(senderUUID, packet->getType())) {
qDebug() << "Packet version mismatch on" << voxelPacketType << "- Sender"
<< senderUUID << "sent" << (int)packetVersion << "but" qDebug() << "Packet version mismatch on" << packetType << "- Sender"
<< (int)expectedVersion << "expected."; << senderUUID << "sent" << (int) packetType << "but"
<< (int) versionForPacketType(packetType) << "expected.";
emit packetVersionMismatch(); emit packetVersionMismatch();
versionDebugSuppressMap.insert(senderUUID, voxelPacketType); versionDebugSuppressMap.insert(senderUUID, packetType);
} }
return; // bail since piggyback version doesn't match 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: { case PacketType::EntityErase: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processEraseMessage(mutablePacket, sendingNode); app->_entities.processEraseMessage(*packet, sendingNode);
} }
} break; } break;
case PacketType::EntityData: { case PacketType::EntityData: {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
app->_entities.processDatagram(mutablePacket, sendingNode); app->_entities.processDatagram(*packet, sendingNode);
} }
} break; } break;
case PacketType::EnvironmentData: { case PacketType::EnvironmentData: {
app->_environment.parseData(*sendingNode->getActiveSocket(), mutablePacket); app->_environment.processPacket(*packet);
} break; } break;
default: { default: {

View file

@ -683,8 +683,8 @@ int EntityTreeRenderer::getBoundaryLevelAdjust() const {
} }
void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { void EntityTreeRenderer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode); static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
} }
Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) { Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) {

View file

@ -55,7 +55,7 @@ public:
EntityTree* getTree() { return static_cast<EntityTree*>(_tree); } EntityTree* getTree() { return static_cast<EntityTree*>(_tree); }
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
virtual void init(); virtual void init();
virtual void render(RenderArgs* renderArgs) override; virtual void render(RenderArgs* renderArgs) override;

View file

@ -900,11 +900,14 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
// //
// TODO: Implement support for script and visible properties. // 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) { EntityItemID& entityID, EntityItemProperties& properties) {
bool valid = false; bool valid = false;
const unsigned char* data = reinterpret_cast<const unsigned char*>(packet.getPayload());
const unsigned char* dataAt = data; const unsigned char* dataAt = data;
int bytesToRead = packet.getSizeUsed();
processedBytes = 0; 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 // the first part of the data is an octcode, this is a required element of the edit packet format, but we don't

View file

@ -179,7 +179,7 @@ public:
static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer); static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer);
static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes, static bool decodeEntityEditPacket(NLPacket& packet, int& processedBytes,
EntityItemID& entityID, EntityItemProperties& properties); EntityItemID& entityID, EntityItemProperties& properties);
bool glowLevelChanged() const { return _glowLevelChanged; } bool glowLevelChanged() const { return _glowLevelChanged; }

View file

@ -568,8 +568,8 @@ EntityItemPointer EntityTree::findEntityByEntityItemID(const EntityItemID& entit
return foundEntity; return foundEntity;
} }
int EntityTree::processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { const SharedNodePointer& senderNode) {
if (!getIsServer()) { if (!getIsServer()) {
qCDebug(entities) << "UNEXPECTED!!! processEditPacketData() should only be called on a server tree."; 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; int processedBytes = 0;
// we handle these types of "edit" packets // we handle these types of "edit" packets
switch (packetType) { switch (packet.getType()) {
case PacketType::EntityErase: { case PacketType::EntityErase: {
QByteArray dataByteArray((const char*)editData, maxLength); QByteArray dataByteArray = QByteArray::fromRawData(reinterpret_cast<const char*>(editData), maxLength);
processedBytes = processEraseMessageDetails(dataByteArray, senderNode); processedBytes = processEraseMessageDetails(dataByteArray, senderNode);
break; break;
} }
@ -598,8 +598,8 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
EntityItemID entityItemID; EntityItemID entityItemID;
EntityItemProperties properties; EntityItemProperties properties;
startDecode = usecTimestampNow(); startDecode = usecTimestampNow();
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(packet, processedBytes,
processedBytes, entityItemID, properties); entityItemID, properties);
endDecode = usecTimestampNow(); endDecode = usecTimestampNow();
// If we got a valid edit packet, then it could be a new entity or it could be an update to // 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(); startLookup = usecTimestampNow();
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID); EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
endLookup = usecTimestampNow(); endLookup = usecTimestampNow();
if (existingEntity && packetType == PacketType::EntityEdit) { if (existingEntity && packet.getType() == PacketType::EntityEdit) {
// if the EntityItem exists, then update it // if the EntityItem exists, then update it
startLogging = usecTimestampNow(); startLogging = usecTimestampNow();
if (wantEditLogging()) { if (wantEditLogging()) {
@ -623,7 +623,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
existingEntity->markAsChangedOnServer(); existingEntity->markAsChangedOnServer();
endUpdate = usecTimestampNow(); endUpdate = usecTimestampNow();
_totalUpdates++; _totalUpdates++;
} else if (packetType == PacketType::EntityAdd) { } else if (packet.getType() == PacketType::EntityAdd) {
if (senderNode->getCanRez()) { if (senderNode->getCanRez()) {
// this is a new entity... assign a new entityID // this is a new entity... assign a new entityID
properties.setCreated(properties.getLastEdited()); properties.setCreated(properties.getLastEdited());
@ -651,7 +651,7 @@ int EntityTree::processEditPacketData(PacketType::Value packetType, const unsign
} else { } else {
static QString repeatedMessage = static QString repeatedMessage =
LogHandler::getInstance().addRepeatedMessageRegex("^Add or Edit failed.*"); 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,44 +854,25 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage() // TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { int EntityTree::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
lockForWrite(); 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); packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
size_t processedBytes = numBytesPacketHeader;
dataAt += numBytesPacketHeader;
dataAt += sizeof(OCTREE_PACKET_FLAGS); uint16_t numberOfIDs = 0; // placeholder for now
processedBytes += sizeof(OCTREE_PACKET_FLAGS); packet.readPrimitive(&numberOfIDs);
dataAt += sizeof(OCTREE_PACKET_SEQUENCE); if (numberOfIDs > 0) {
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) {
QSet<EntityItemID> entityItemIDsToDelete; QSet<EntityItemID> 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"; qCDebug(entities) << "EntityTree::processEraseMessage().... bailing because not enough bytes in buffer";
break; // bail to prevent buffer overflow break; // bail to prevent buffer overflow
} }
QByteArray encodedID = dataByteArray.mid(processedBytes, NUM_BYTES_RFC4122_UUID); QUuid entityID = QUuid::fromRfc4122(packet.read(NUM_BYTES_RFC4122_UUID));
QUuid entityID = QUuid::fromRfc4122(encodedID);
dataAt += encodedID.size();
processedBytes += encodedID.size();
EntityItemID entityItemID(entityID); EntityItemID entityItemID(entityID);
entityItemIDsToDelete << entityItemID; entityItemIDsToDelete << entityItemID;
@ -904,7 +885,7 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
deleteEntities(entityItemIDsToDelete, true, true); deleteEntities(entityItemIDsToDelete, true, true);
} }
unlock(); unlock();
return processedBytes; return packet.pos();
} }
// This version skips over the header // This version skips over the header

View file

@ -66,8 +66,8 @@ public:
virtual bool canProcessVersion(PacketVersion thisVersion) const virtual bool canProcessVersion(PacketVersion thisVersion) const
{ return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; } { return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; }
virtual bool handlesEditPacketType(PacketType::Value packetType) const; virtual bool handlesEditPacketType(PacketType::Value packetType) const;
virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode); const SharedNodePointer& senderNode);
virtual bool rootElementHasData() const { return true; } virtual bool rootElementHasData() const { return true; }
@ -133,8 +133,8 @@ public:
bool& hasMore); bool& hasMore);
void forgetEntitiesDeletedBefore(quint64 sinceTime); void forgetEntitiesDeletedBefore(quint64 sinceTime);
int processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); int processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
int processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode);
EntityItemFBXService* getFBXService() const { return _fbxService; } EntityItemFBXService* getFBXService() const { return _fbxService; }
void setFBXService(EntityItemFBXService* service) { _fbxService = service; } void setFBXService(EntityItemFBXService* service) { _fbxService = service; }

View file

@ -40,6 +40,6 @@ void EntityTreeHeadlessViewer::update() {
} }
} }
void EntityTreeHeadlessViewer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { void EntityTreeHeadlessViewer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode); static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
} }

View file

@ -38,7 +38,7 @@ public:
EntityTree* getTree() { return (EntityTree*)_tree; } EntityTree* getTree() { return (EntityTree*)_tree; }
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
virtual void init(); virtual void init();

View file

@ -233,8 +233,8 @@ public:
return thisVersion == versionForPacketType(expectedDataPacketType()); } return thisVersion == versionForPacketType(expectedDataPacketType()); }
virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); } virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); }
virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; } virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; }
virtual int processEditPacketData(PacketType::Value packetType, const unsigned char* packetData, int packetLength, virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
const unsigned char* editData, int maxLength, const SharedNodePointer& sourceNode) { return 0; } const SharedNodePointer& sourceNode) { return 0; }
virtual bool recurseChildrenWithData() const { return true; } virtual bool recurseChildrenWithData() const { return true; }
virtual bool rootElementHasData() const { return false; } virtual bool rootElementHasData() const { return false; }

View file

@ -48,7 +48,7 @@ void OctreeRenderer::setTree(Octree* newTree) {
_tree = newTree; _tree = newTree;
} }
void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { void OctreeRenderer::processDatagram(NLPacket& packet, SharedNodePointer sourceNode) {
bool extraDebugging = false; bool extraDebugging = false;
if (extraDebugging) { if (extraDebugging) {
@ -61,30 +61,21 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
} }
bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); 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(); if (packet.getType() == getExpectedPacketType()) {
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) {
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails); 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. // if we are getting inbound packets, then our tree is also viewing, and we should remember that fact.
_tree->setIsViewing(true); _tree->setIsViewing(true);
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader; OCTREE_PACKET_FLAGS flags;
packet.readPrimitive(&flags);
OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt)); OCTREE_PACKET_SEQUENCE sequence;
dataAt += sizeof(OCTREE_PACKET_FLAGS); packet.readPrimitive(&sequence);
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); OCTREE_PACKET_SENT_TIME sentAt;
dataAt += sizeof(OCTREE_PACKET_SENT_TIME); packet.readPrimitive(&sentAt);
bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);
bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_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; int flightTime = arrivedAt - sentAt + clockSkew;
OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;
unsigned int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE);
if (extraDebugging) { if (extraDebugging) {
qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" 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), debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
sequence, flightTime, packetLength, dataBytes); sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable());
} }
_packetsInLastWindow++; _packetsInLastWindow++;
@ -112,41 +102,47 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
quint64 totalUncompress = 0; quint64 totalUncompress = 0;
quint64 totalReadBitsteam = 0; quint64 totalReadBitsteam = 0;
const QUuid& sourceUUID = packet.getSourceID();
int subsection = 1; int subsection = 1;
while (dataBytes > 0) {
bool error = false;
while (packet.bytesAvailable() && !error) {
if (packetIsCompressed) { if (packetIsCompressed) {
if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { if (packet.bytesAvailable() > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) {
sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt); packet.readPrimitive(&sectionLength);
dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
} else { } else {
sectionLength = 0; sectionLength = 0;
dataBytes = 0; // stop looping something is wrong error = true;
} }
} else { } else {
sectionLength = dataBytes; sectionLength = packet.bytesAvailable();
} }
if (sectionLength) { if (sectionLength) {
// ask the VoxelTree to read the bitstream into the tree // ask the VoxelTree to read the bitstream into the tree
ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL,
sourceUUID, sourceNode, false, packetVersion); sourceUUID, sourceNode, false, packet.getVersion());
quint64 startLock = usecTimestampNow(); quint64 startLock = usecTimestampNow();
// FIXME STUTTER - there may be an opportunity to bump this lock outside of the // 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 // loop to reduce the amount of locking/unlocking we're doing
_tree->lockForWrite(); _tree->lockForWrite();
quint64 startUncompress = usecTimestampNow(); quint64 startUncompress = usecTimestampNow();
OctreePacketData packetData(packetIsCompressed); OctreePacketData packetData(packetIsCompressed);
packetData.loadFinalizedContent(dataAt, sectionLength); packetData.loadFinalizedContent(reinterpret_cast<unsigned char*>(packet.getPayload() + packet.pos()),
sectionLength);
if (extraDebugging) { if (extraDebugging) {
qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" 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", " subsection:%d sectionLength:%d uncompressed:%d",
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, sequence, flightTime, packet.getSizeWithHeader(), packet.bytesAvailable(), subsection, sectionLength,
packetData.getUncompressedSize()); packetData.getUncompressedSize());
} }
if (extraDebugging) { if (extraDebugging) {
qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()..."; qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()...";
} }
@ -158,8 +154,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
} }
_tree->unlock(); _tree->unlock();
dataBytes -= sectionLength; // seek forwards in packet
dataAt += sectionLength; packet.seek(packet.pos() + sectionLength);
elementsPerPacket += args.elementsPerPacket; elementsPerPacket += args.elementsPerPacket;
entitiesPerPacket += args.entitiesPerPacket; entitiesPerPacket += args.entitiesPerPacket;

View file

@ -45,7 +45,7 @@ public:
virtual void setTree(Octree* newTree); virtual void setTree(Octree* newTree);
/// process incoming data /// 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 /// initialize and GPU/rendering related resources
virtual void init(); virtual void init();

View file

@ -747,20 +747,17 @@ const char* OctreeSceneStats::getItemValue(Item item) {
return _itemValueBuffer; return _itemValueBuffer;
} }
void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, void OctreeSceneStats::trackIncomingOctreePacket(NLPacket& packet, bool wasStatsPacket, int nodeClockSkewUsec) {
bool wasStatsPacket, int nodeClockSkewUsec) {
const bool wantExtraDebugging = false; const bool wantExtraDebugging = false;
int numBytesPacketHeader = numBytesForPacketHeader(packet); // skip past the flags
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader; packet.seek(sizeof(OCTREE_PACKET_FLAGS));
//VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt)); OCTREE_PACKET_SEQUENCE sequence;
dataAt += sizeof(OCTREE_PACKET_FLAGS); packet.readPrimitive(&sequence);
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); OCTREE_PACKET_SENT_TIME sentAt;
dataAt += sizeof(OCTREE_PACKET_SENT_TIME); packet.readPrimitive(&sentAt);
//bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); //bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);
//bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); //bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT);
@ -792,8 +789,8 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
// track packets here... // track packets here...
_incomingPacket++; _incomingPacket++;
_incomingBytes += packet.size(); _incomingBytes += packet.getSizeWithHeader();
if (!wasStatsPacket) { if (!wasStatsPacket) {
_incomingWastedBytes += (MAX_PACKET_SIZE - packet.size()); _incomingWastedBytes += (MAX_PACKET_SIZE - packet.getSizeWithHeader());
} }
} }

View file

@ -160,7 +160,7 @@ public:
quint64 getLastFullTotalBytes() const { return _lastFullTotalBytes; } quint64 getLastFullTotalBytes() const { return _lastFullTotalBytes; }
// Used in client implementations to track individual octree packets // 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; } quint32 getIncomingPackets() const { return _incomingPacket; }
quint64 getIncomingBytes() const { return _incomingBytes; } quint64 getIncomingBytes() const { return _incomingBytes; }

View file

@ -28,15 +28,6 @@
#include "SkyFromAtmosphere_vert.h" #include "SkyFromAtmosphere_vert.h"
#include "SkyFromAtmosphere_frag.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() Environment::Environment()
: _initialized(false) { : _initialized(false) {
} }
@ -53,7 +44,7 @@ void Environment::init() {
setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations); setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations);
// start off with a default-constructed environment data // start off with a default-constructed environment data
_data[HifiSockAddr()][0]; _data[QUuid()][0];
_initialized = true; _initialized = true;
} }
@ -98,7 +89,7 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra
void Environment::resetToDefault() { void Environment::resetToDefault() {
_data.clear(); _data.clear();
_data[HifiSockAddr()][0]; _data[QUuid()][0];
} }
void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) { void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) {
@ -205,33 +196,28 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
return found; return found;
} }
int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) { int Environment::processPacket(NLPacket& packet) {
// push past the packet header
int bytesRead = numBytesForPacketHeader(packet);
// push past flags, sequence, timestamp // push past flags, sequence, timestamp
bytesRead += sizeof(OCTREE_PACKET_FLAGS); packet.seek(sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
bytesRead += sizeof(OCTREE_PACKET_SEQUENCE);
bytesRead += sizeof(OCTREE_PACKET_SENT_TIME);
// get the lock for the duration of the call // get the lock for the duration of the call
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
EnvironmentData newData; EnvironmentData newData;
while (bytesRead < packet.size()) {
int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.data()) + bytesRead, while (packet.bytesAvailable() > 0) {
packet.size() - bytesRead); int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.getPayload() + packet.pos()),
packet.bytesAvailable());
packet.seek(packet.pos() + dataLength);
// update the mapping by address/ID // update the mapping by address/ID
_data[senderAddress][newData.getID()] = newData; _data[packet.getSourceID()][newData.getID()] = newData;
bytesRead += dataLength;
} }
// remove the default mapping, if any // 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) { void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) {

View file

@ -37,8 +37,7 @@ public:
EnvironmentData getClosestData(const glm::vec3& position); EnvironmentData getClosestData(const glm::vec3& position);
int processPacket(NLPacket& packet);
int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
private: private:
glm::vec3 getGravity (const glm::vec3& position); // NOTE: Deprecated glm::vec3 getGravity (const glm::vec3& position); // NOTE: Deprecated
@ -79,7 +78,7 @@ private:
typedef QHash<int, EnvironmentData> ServerData; typedef QHash<int, EnvironmentData> ServerData;
QHash<HifiSockAddr, ServerData> _data; QHash<QUuid, ServerData> _data;
EnvironmentData _overrideData; EnvironmentData _overrideData;
bool _environmentIsOverridden = false; bool _environmentIsOverridden = false;