Exemplo n.º 1
0
        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();
            }
        }
Exemplo n.º 2
0
        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);
        }