diff --git a/Lidgren.Network/NetConnection.Reliability.cs b/Lidgren.Network/NetConnection.Reliability.cs index 3ffd783..036f3da 100644 --- a/Lidgren.Network/NetConnection.Reliability.cs +++ b/Lidgren.Network/NetConnection.Reliability.cs @@ -233,7 +233,7 @@ namespace Lidgren.Network } } - private void ExpectedReliableSequenceArrived(int reliableSlot) + private void ExpectedReliableSequenceArrived(int reliableSlot, bool isFragment) { NetBitVector received = m_reliableReceived[reliableSlot]; @@ -275,8 +275,11 @@ namespace Lidgren.Network // Found withheld message due for delivery m_owner.LogVerbose("Releasing withheld message " + wm); - // AcceptMessage - m_owner.ReleaseMessage(wm); + //Console.WriteLine("Releasing withheld message " + wm); + + // Accept, unless a fragment + if (wm.m_fragmentationInfo == null) + m_owner.ReleaseMessage(wm); foundWithheld = true; withheldList.Remove(wm); @@ -290,7 +293,13 @@ namespace Lidgren.Network } } if (!foundWithheld) - throw new NetException("Failed to find withheld message!"); + { + // probably a fragment; we don't withhold those - advance anyway + //Console.WriteLine("Withheld #" + nextExpected + " not found; probably a fragment!"); + //received[(nextExpected + (NetConstants.NumSequenceNumbers / 2)) % NetConstants.NumSequenceNumbers] = false; // reset for next pass + //nextExpected = (nextExpected + 1) % NetConstants.NumSequenceNumbers; + throw new NetException("Withheld message not found!"); + } } } diff --git a/Lidgren.Network/NetConnection.cs b/Lidgren.Network/NetConnection.cs index 447e216..59b09ec 100644 --- a/Lidgren.Network/NetConnection.cs +++ b/Lidgren.Network/NetConnection.cs @@ -233,7 +233,7 @@ namespace Lidgren.Network ptr = msg.Encode(now, buffer, ptr, this); numIncludedMessages++; - + // room to piggyback some acks? if (m_acknowledgesToSend.Count > 0) { @@ -339,7 +339,7 @@ namespace Lidgren.Network // Expected sequence number AcceptMessage(mtp, isFragment, channelSequenceNumber, ptr, payloadLengthBits); - ExpectedReliableSequenceArrived(reliableSlot); + ExpectedReliableSequenceArrived(reliableSlot, isFragment); return; } @@ -404,7 +404,7 @@ namespace Lidgren.Network im.m_senderEndpoint = m_remoteEndpoint; m_owner.LogVerbose("Withholding " + im + " (waiting for " + m_nextExpectedReliableSequence[reliableSlot] + ")"); - + wmList.Add(im); return; @@ -498,7 +498,10 @@ namespace Lidgren.Network Buffer.BlockCopy(m_owner.m_receiveBuffer, ptr, im.m_data, offset, payloadLength); - im.m_bitLength = (8 * (offset + payloadLength)); + // only enlarge message length if this is latest fragment received + int newBitLength = (8 * (offset + payloadLength)); + if (newBitLength > im.m_bitLength) + im.m_bitLength = newBitLength; info.Received[nr] = true; info.TotalReceived++; @@ -567,7 +570,7 @@ namespace Lidgren.Network throw new NetException("Message has already been sent!"); NetException.Assert(sequenceChannel >= 0 && sequenceChannel < NetConstants.NetChannelsPerDeliveryMethod, "Sequence channel must be between 0 and NetConstants.NetChannelsPerDeliveryMethod (" + NetConstants.NetChannelsPerDeliveryMethod + ")"); - + msg.m_type = (NetMessageType)((int)method + sequenceChannel); EnqueueOutgoingMessage(msg); } @@ -602,7 +605,7 @@ namespace Lidgren.Network int numFragments = (msgLen + mtu - 1) / mtu; - for(int i=0;i 127 ? 2 * 8 : 1 * 8) + (bytes.Length * 8)); + + // determine number of bytes to store length + int lenBytesNeeded = 1; + uint num1 = (uint)bytes.Length; + while (num1 >= 0x80) + { + num1 = num1 >> 7; + lenBytesNeeded++; + } + InternalEnsureBufferSize(m_bitLength + ((bytes.Length + lenBytesNeeded) * 8)); + WriteVariableUInt32((uint)bytes.Length); Write(bytes); } diff --git a/Lidgren.Network/NetPeer.Internal.cs b/Lidgren.Network/NetPeer.Internal.cs index 36dde25..9c592d5 100644 --- a/Lidgren.Network/NetPeer.Internal.cs +++ b/Lidgren.Network/NetPeer.Internal.cs @@ -49,6 +49,8 @@ namespace Lidgren.Network { NetException.Assert(msg.m_status != NetIncomingMessageReleaseStatus.ReleasedToApplication, "Message released to application twice!"); + NetException.Assert(msg.m_fragmentationInfo == null, "Fragment released to application!"); + msg.m_status = NetIncomingMessageReleaseStatus.ReleasedToApplication; m_releasedIncomingMessages.Enqueue(msg); if (m_messageReceivedEvent != null)