mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 18:50:36 +02:00
repairs to octree packet receiving in interface
This commit is contained in:
parent
264f39fa59
commit
d990420565
18 changed files with 179 additions and 218 deletions
|
@ -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.
|
||||
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<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
|
||||
|
||||
// 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();
|
||||
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();
|
||||
|
|
|
@ -612,8 +612,8 @@ private:
|
|||
StDev _idleLoopStdev;
|
||||
float _idleLoopMeasuredJitter;
|
||||
|
||||
int processOctreeStats(QSharedPointer<NLPacket> 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;
|
||||
|
|
|
@ -28,7 +28,7 @@ OctreePacketProcessor::OctreePacketProcessor() {
|
|||
}
|
||||
|
||||
void OctreePacketProcessor::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode) {
|
||||
queueReceivedPacket(senderNode, packet);
|
||||
queueReceivedPacket(packet, senderNode);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
int messageLength = packet->getSizeUsed();
|
||||
|
||||
Application* app = Application::getInstance();
|
||||
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
|
||||
// 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<NodeList>()->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<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 {
|
||||
// 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<QUuid, PacketType::Value> 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<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
app->_entities.processEraseMessage(mutablePacket, sendingNode);
|
||||
app->_entities.processEraseMessage(*packet, sendingNode);
|
||||
}
|
||||
} break;
|
||||
|
||||
case PacketType::EntityData: {
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->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: {
|
||||
|
|
|
@ -683,8 +683,8 @@ int EntityTreeRenderer::getBoundaryLevelAdjust() const {
|
|||
}
|
||||
|
||||
|
||||
void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode);
|
||||
void EntityTreeRenderer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
|
||||
}
|
||||
|
||||
Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) {
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
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 render(RenderArgs* renderArgs) override;
|
||||
|
|
|
@ -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<const unsigned char*>(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
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
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);
|
||||
|
||||
bool glowLevelChanged() const { return _glowLevelChanged; }
|
||||
|
|
|
@ -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<const char*>(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,44 +854,25 @@ 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);
|
||||
uint16_t numberOfIDs = 0; // placeholder for now
|
||||
packet.readPrimitive(&numberOfIDs);
|
||||
|
||||
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) {
|
||||
if (numberOfIDs > 0) {
|
||||
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";
|
||||
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
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -40,6 +40,6 @@ void EntityTreeHeadlessViewer::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeHeadlessViewer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode);
|
||||
void EntityTreeHeadlessViewer::processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode) {
|
||||
static_cast<EntityTree*>(_tree)->processEraseMessage(packet, sourceNode);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -233,8 +233,8 @@ public:
|
|||
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; }
|
||||
|
|
|
@ -48,7 +48,7 @@ void OctreeRenderer::setTree(Octree* 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<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader;
|
||||
OCTREE_PACKET_FLAGS flags;
|
||||
packet.readPrimitive(&flags);
|
||||
|
||||
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_SEQUENCE sequence;
|
||||
packet.readPrimitive(&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++;
|
||||
|
@ -112,41 +102,47 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar
|
|||
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);
|
||||
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<unsigned char*>(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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||
// skip past the flags
|
||||
packet.seek(sizeof(OCTREE_PACKET_FLAGS));
|
||||
|
||||
//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_SEQUENCE sequence;
|
||||
packet.readPrimitive(&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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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,7 +89,7 @@ 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) {
|
||||
|
@ -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<const unsigned char*>(packet.data()) + bytesRead,
|
||||
packet.size() - bytesRead);
|
||||
|
||||
while (packet.bytesAvailable() > 0) {
|
||||
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
|
||||
_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) {
|
||||
|
|
|
@ -37,8 +37,7 @@ public:
|
|||
|
||||
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
|
||||
|
@ -79,7 +78,7 @@ private:
|
|||
|
||||
typedef QHash<int, EnvironmentData> ServerData;
|
||||
|
||||
QHash<HifiSockAddr, ServerData> _data;
|
||||
QHash<QUuid, ServerData> _data;
|
||||
EnvironmentData _overrideData;
|
||||
bool _environmentIsOverridden = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue