-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support entity properties > 1 MTU #830
base: master
Are you sure you want to change the base?
Conversation
EntityPropertyList targetProperty = firstDidntFitProperty; | ||
unsigned int bufferMultiplier = 2; | ||
int32_t numEntitiesOffset; | ||
while (true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appendEntityData
still doesn't report how much it overran the buffer by, so we have to do this loop to search for the right size. this seems dangerous (since there's no upper limit) and slow (since we could know the exact right size after the first attempt). we should definitely fix the latter issue in a followup, but I'm not sure how bad the lack of an upper limit really is.
@@ -119,15 +121,29 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, | |||
requestedProperties -= PROP_PRIVATE_USER_DATA; | |||
} | |||
|
|||
while (encodeResult == OctreeElement::PARTIAL) { | |||
encodeResult = EntityItemProperties::encodeEntityEditPacket(type, entityItemID, propertiesCopy, bufferOut, requestedProperties, didntFitProperties); | |||
while (encodeResult == OctreeElement::PARTIAL && !requestedProperties.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weirdly, entity adds from client -> server already used packet lists, but have an arbitrary 10 * MTU limit (see MAX_ADD_DATA_SIZE above). so Entities.addEntity with an extremely large property (or several big properties) could still fail.
NLPacketList::NLPacketList(const NLPacketList& other) : PacketList(other) { | ||
// Update _packets | ||
for (auto& packet : _packets) { | ||
packet = NLPacket::fromBase(std::move(packet)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a copy constructor so this move is wrong, but I couldn't get it to work otherwise...(because of the const if I remember correctly)
63ff8a3
to
2b55dbf
Compare
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 :) |
@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. |
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: