private void SendAcknowledgements(Peer peer, Buffer buffer, ref bool continueSending) { var currentAcknowledgement = peer.Acknowledgements.Begin; while (currentAcknowledgement != peer.Acknowledgements.End) { if (Protocol.Acknowledge.SIZE > buffer.BytesLeft) { continueSending = true; break; } var acknowledgement = currentAcknowledgement.Value; currentAcknowledgement = currentAcknowledgement.Next; var command = new Protocol.Acknowledge { ChannelID = acknowledgement.Command.ChannelID, ReceivedReliableSequenceNumber = acknowledgement.Command.ReliableSequenceNumber, ReceivedSentTime = (ushort)acknowledgement.SentTime, }; command.Write(buffer, Version); if (acknowledgement.Command is Protocol.Disconnect) { DispatchState(peer, PeerState.ZOMBIE); } acknowledgement.Node.Remove(); } }
private int HandleAcknowledge(Event evnt, Peer peer, Protocol.Acknowledge command) { uint receivedSentTime = command.ReceivedSentTime; receivedSentTime |= ServiceTime & 0xFFFF0000u; if ((receivedSentTime & 0x8000u) > (ServiceTime & 0x8000u)) { receivedSentTime -= 0x10000u; } if (Utils.TimeLess(ServiceTime, receivedSentTime)) { return(0); } peer.LastReceiveTime = ServiceTime; peer.EarliestTimeout = 0; uint roundTripTime = Utils.TimeDiff(ServiceTime, receivedSentTime); peer.Throttle(roundTripTime); peer.RoundTripTimeVariance -= peer.RoundTripTimeVariance / 4u; if (roundTripTime >= peer.RoundTripTime) { peer.RoundTripTime += (roundTripTime - peer.RoundTripTime) / 8u; peer.RoundTripTimeVariance += (roundTripTime - peer.RoundTripTime) / 4u; } else { peer.RoundTripTime -= (peer.RoundTripTime - roundTripTime) / 8u; peer.RoundTripTimeVariance += (peer.RoundTripTime - roundTripTime) / 4u; } if (peer.RoundTripTime < peer.LowestRoundTripTime) { peer.LowestRoundTripTime = peer.RoundTripTime; } if (peer.RoundTripTimeVariance > peer.HighestRoundTripTimeVariance) { peer.HighestRoundTripTimeVariance = peer.RoundTripTimeVariance; } if (peer.PacketThrottleEpoch == 0 || Utils.TimeDiff(ServiceTime, peer.PacketThrottleEpoch) >= peer.PacketThrottleInterval) { peer.LastRoundTripTime = peer.LowestRoundTripTime; peer.LastRoundTripTimeVariance = peer.HighestRoundTripTimeVariance; peer.LowestRoundTripTime = peer.RoundTripTime; peer.HighestRoundTripTimeVariance = peer.RoundTripTimeVariance; peer.PacketThrottleEpoch = ServiceTime; } uint receivedReliableSequenceNumber = command.ReceivedReliableSequenceNumber; var commandNumber = RemoveSentReliableCommand(peer, (ushort)receivedReliableSequenceNumber, command.ChannelID); switch (peer.State) { case PeerState.ACKNOWLEDGING_CONNECT: if (commandNumber != ProtocolCommand.VERIFY_CONNECT) { return(-1); } NotifyConnect(peer, evnt); break; case PeerState.DISCONNECTING: if (commandNumber != ProtocolCommand.DISCONNECT) { return(-1); } NotifyDisconnect(peer, evnt); break; case PeerState.DISCONNECT_LATER: if (peer.OutgoingReliableCommands.Empty && peer.OutgoingUnreliableCommands.Empty && peer.SentReliableCommands.Empty) { peer.Disconnect(peer.DisconnectData); } break; default: break; } return(0); }