Support entity properties > 1 MTU
I am not familiar with this part of the code at all. This is a highly experimental and possibly dangerous change. But...it seems to work (in my basic tests)!
There are two parts to this change:
Client -> Server Communication (EntityEditLarge)
Clients communicate edits via EntityEditPacketSender::queueEditEntityMessage, which calls EntityItemProperties::encodeEntityEditPacket. This gets called multiple times, packing all the changed properties into multiple individual packets. If the first property in a new packet doesn't fit (reported via firstDidntFitProperty), we know it's too big, and we instead search for a large enough buffer and send an EntityEditLarge packet list.
Server -> Client Communication (EntityDataLarge)
The server is a little more complicated. It is constantly trying to send multiple entities to multiple clients as things change. OctreeSendThread::traverseTreeAndSendContents builds up _packetData in EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload and sends it as EntityData packets. Now, if the first property we encounter doesn't fit (_numEntities == 0 && firstDidntFitProperty was set), we again search for a large enough buffer and send a EntityData packet list...a little circuitiously through handlePacketListSend.
Notes:
- EntityDataLarge packets are compressed later in the process, which means we can detect that we need a packet list based on the uncompressed size, but then end up fitting everything in one packet after compression. We don't currently do anything special to handle this, so some of our large packets can actually end up quite small. EntityEditLarge packets are not compressed (maybe they should be?).
- This isn't a protocol change! I used some unused packet types in PacketHeaders.h, so theoretically old clients/servers will simply ignore these new packet types. Alternatively, this could theoretically be done with the same old packet types and a protocol change, but it seems helpful to be able to keep track of these new packets separately.
- This specifically handles packets to and from the entity server. It does not handle avatar entity packets (which go through the avatar server) or any other packets that break when they get too big (avatar joints).
I just tested the PR, and when starting game in tutorial world it segfaults in libraries/entities/src/EntityItem.cpp line 391.
Here's the backtrace and local variables:
It's possible that this affects serverless worlds only
The crash seems to happen every time for me when launching interface in Tutorial.
thank you, I’ll take a look! looks like it’s specific to when you have an avatar entity attached
@ksuprynowicz should be fixed!
The crash is fixed now :) It seems that there's another problem though. I started a server and client on this version, and large part of the entities on that copy of Overte Hub were missing. I will do more teating tomorrow.
@ksuprynowicz interesting - are there even any entities in the domain that hit the packet limit? if there are none I'm surprised, as the code should operate as before.
if there are any, I did encounter a similar issue at one point during testing, but I thought I had fixed it. it related to the sequence number and the changes in OctreeSendThread.cpp. when we send a large packet, we rewrite the sequence number of the normal size packet that we have at the time to bump it. but now that we're sending a mix of normal packets and packet lists, I don't totally understand if the sequence numbers are able to handle it.
Here's a screenshot of the same place in master branch and in PR 830:
Master branch:
PR 830: