internal void ToStream(NetStream stream) { stream.WriteUShort(NetMath.Pad(ObjSequence)); stream.WriteUShort(NetMath.Pad(AckSequence)); stream.WriteULong(AckHistory); stream.WriteUShort(AckTime); }
/// <summary> /// Creates a Zone using the default size and handoff ranges. /// </summary> internal NetZone(Vector3 position, int viewIdMin, int viewIdMax) { Id = NetMath.RandomUint(); ViewIdMin = viewIdMin; ViewIdMax = viewIdMax; Position = position; }
/// <summary> Detects acknowledged and lost messages. </summary> private void AckDelivered(NetHeader header) { for (int i = 0; i < sendWindow.Count; i++) { int seqDist = NetMath.SeqDistance(sendWindow[i], header.AckSequence); // This AckSequence is older than the sendWindow's, not useful: if (seqDist > 0) { break; } // AckHistory has rolled over without acking this message; Ordered reliable is broken: if (seqDist <= -64) { Connection.Disconnect(); } // If the seqDistance corresponds to a true bit in the AckHistory, message delivered/acked: else if (IsAcked(header.AckHistory, seqDist)) { MessageDelivered(i, header); i--; // Since the sendWindow count will decrease, the index needs to be adjusted. } // The seqDist is still within the send window, but if too much time has passed, assume lost: else if (NetTime.Milliseconds() - sendWindowTime[i] > 333) { MessageLost(i); } } }
/// <summary> Handles a stream based on its header/size. Determines if it should be buffered if out-of-order, /// acked and released if size is equal to header size (ack only), or delivered immediately. </summary> internal void RouteIncomingStream(NetStream strm) { var header = NetHeader.FromStream(strm); int seqDist = NetMath.SeqDistance(header.ObjSequence, LastAcceptedRemoteSequence); // If the stream is only the size of a header, it's likely a forced ack: if (strm.Length <= 120) { AckDelivered(header); strm.Release(); } else if (!RemoteSequenceValid(seqDist)) { strm.Release(); } else if (seqDist != 1) { BufferOutOfOrder(seqDist, strm, header); } else { AckReceived(header); AckDelivered(header); DeliverStream(strm); } }
/// <summary> /// Creates a Zone using the default size and handoff ranges. /// </summary> internal NetZone(Vector3 position, int viewIdMin, int viewIdMax) { Id = NetMath.RandomUint(); ViewIdMin = viewIdMin; ViewIdMax = viewIdMax; Position = position; Debug.Log("Zone Created at:" + Position); }
/// <summary> /// Creates a Zone using custom size and handoff ranges. /// </summary> internal NetZone(Vector3 position, int viewIdMin, int viewIdMax, int handoff, int handoffMin, int handoffMax, int zoneSize) { Id = NetMath.RandomUint(); ViewIdMin = viewIdMin; ViewIdMax = viewIdMax; Position = position; HandoverDistance = handoff; HandoverMinDistance = handoffMin; HandoverMaxDistance = handoffMax; ZoneSize = zoneSize; }
/// <summary> Acknowledges and updates the remote sequence. </summary> private void AckReceived(NetHeader header) { int newestDist = NetMath.SeqDistance(header.ObjSequence, NewestRemoteSequence); // If the sequence is newest, shift the buffer and apply ack bit: if (newestDist > 0) { AckHistory = (AckHistory << newestDist) | 1UL; NewestRemoteSequence = header.ObjSequence; } // Else, shift the ack bit and apply to buffer: else { AckHistory |= 1UL << -newestDist; } LastReceiveTime = NetTime.Milliseconds(); ReceivedSinceLastSend++; Received++; }
internal static NetHeader FromStream(NetStream stream) { return(new NetHeader(NetMath.Trim(stream.ReadUShort()), NetMath.Trim(stream.ReadUShort()), stream.ReadULong(), stream.ReadUShort())); }