//Process incoming packet public override bool ProcessPacket(NetPacket packet) { if (packet.Property == PacketProperty.Ack) { ProcessAck(packet); return(false); } int seq = packet.Sequence; if (seq >= NetConstants.MaxSequence) { NetDebug.Write("[RR]Bad sequence"); return(false); } int relate = NetUtils.RelativeSequenceNumber(seq, _remoteWindowStart); int relateSeq = NetUtils.RelativeSequenceNumber(seq, _remoteSequence); if (relateSeq > _windowSize) { NetDebug.Write("[RR]Bad sequence"); return(false); } //Drop bad packets if (relate < 0) { //Too old packet doesn't ack NetDebug.Write("[RR]ReliableInOrder too old"); return(false); } if (relate >= _windowSize * 2) { //Some very new packet NetDebug.Write("[RR]ReliableInOrder too new"); return(false); } //If very new - move window int ackIdx; int ackByte; int ackBit; lock (_outgoingAcks) { if (relate >= _windowSize) { //New window position int newWindowStart = (_remoteWindowStart + relate - _windowSize + 1) % NetConstants.MaxSequence; _outgoingAcks.Sequence = (ushort)newWindowStart; //Clean old data while (_remoteWindowStart != newWindowStart) { ackIdx = _remoteWindowStart % _windowSize; ackByte = NetConstants.ChanneledHeaderSize + ackIdx / BitsInByte; ackBit = ackIdx % BitsInByte; _outgoingAcks.RawData[ackByte] &= (byte)~(1 << ackBit); _remoteWindowStart = (_remoteWindowStart + 1) % NetConstants.MaxSequence; } } //Final stage - process valid packet //trigger acks send _mustSendAcks = true; ackIdx = seq % _windowSize; ackByte = NetConstants.ChanneledHeaderSize + ackIdx / BitsInByte; ackBit = ackIdx % BitsInByte; if ((_outgoingAcks.RawData[ackByte] & (1 << ackBit)) != 0) { NetDebug.Write("[RR]ReliableInOrder duplicate"); return(false); } //save ack _outgoingAcks.RawData[ackByte] |= (byte)(1 << ackBit); } AddToPeerChannelSendQueue(); //detailed check if (seq == _remoteSequence) { NetDebug.Write("[RR]ReliableInOrder packet succes"); Peer.AddReliablePacket(_deliveryMethod, packet); _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; if (_ordered) { NetPacket p; while ((p = _receivedPackets[_remoteSequence % _windowSize]) != null) { //process holden packet _receivedPackets[_remoteSequence % _windowSize] = null; Peer.AddReliablePacket(_deliveryMethod, p); _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; } } else { while (_earlyReceived[_remoteSequence % _windowSize]) { //process early packet _earlyReceived[_remoteSequence % _windowSize] = false; _remoteSequence = (_remoteSequence + 1) % NetConstants.MaxSequence; } } return(true); } //holden packet if (_ordered) { _receivedPackets[ackIdx] = packet; } else { _earlyReceived[ackIdx] = true; Peer.AddReliablePacket(_deliveryMethod, packet); } return(true); }