Exemplo n.º 1
0
 protected override void HandleConnectionDisconnected(NetConnection connection, string reason, bool connectionLost)
 {
     NetLogger.Log("Client disconnected: {0}", reason);
     newConnectionsLost.Enqueue(new LostConnection(connection, reason, connectionLost));
 }
        void AddRecentPing(int ping)
        {
            // Add the new ping
            recentPings[avgPingI++] = ping;

            // If we've reached the end of one ping collection
            if (avgPingI == recentPings.Length)
            {
                // Average the pings we collected
                AverageRecentPings();
                avgPingI = 0;

                // If we are calculating the base ping as well, set it
                if (baseAvgPing == -1)
                {
                    if (NetLogger.LogFlowControl)
                    {
                        NetLogger.LogVerbose("[FlowControl] Base Ping for {0} set to {1}", EndPoint, lastAvgPing);
                    }
                    baseAvgPing = lastAvgPing;
                }
                else if (NetTime.Now - sendRateSwitchCooldown >= 0)
                {
                    // If the ping increased too much, drop the send rate
                    if (lastAvgPing - baseAvgPing > 80)
                    {
                        sendRateDropped = true;
                        if (!config.DontApplyPingControl)
                        {
                            if (!NetLogger.IgnoreSendRateChanges)
                            {
                                NetLogger.LogWarning("[FlowControl] Dropped send rate for {0}", EndPoint);
                            }
                            chunkSendDelay = droppedSendRate[0];
                            PacketSendRate = droppedSendRate[1];
                        }
                        sendRateSwitchCooldown = NetTime.Now + sendRateSwitchCooldownDelay;
                    }
                    // If the ping returned to normal, try increasing the send rate
                    else if (sendRateDropped && lastAvgPing - baseAvgPing < 80)
                    {
                        sendRateDropped = false;
                        if (!config.DontApplyPingControl)
                        {
                            if (!NetLogger.IgnoreSendRateChanges)
                            {
                                NetLogger.Log("[FlowControl] Send rate set to normal for {0}", EndPoint);
                            }
                            chunkSendDelay = normalSendRate[0];
                            PacketSendRate = normalSendRate[1];
                        }
                        sendRateSwitchCooldown = NetTime.Now + sendRateSwitchCooldownDelay;
                    }
                    // If the average ping dropped, see if we can lower the base ping
                    else if (!sendRateDropped && lastAvgPing - baseAvgPing < -20)
                    {
                        if (NetLogger.LogFlowControl)
                        {
                            NetLogger.LogVerbose("[FlowControl] Attempting to increase base ping for {0}...", EndPoint);
                        }
                        RecalculateBasePing();
                    }
                }
            }
        }
        void Heartbeat()
        {
            if (socket.Available >= NetOutboundPacket.PacketHeaderSize)
            {
                try
                {
                    // Read the packet
                    PacketState state = new PacketState(ReceiveEndPoint, new byte[READ_BUFFER_SIZE]);
                    //socket.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None,
                    //    ref state.Sender, PacketReceived, state);

                    //NetLogger.LogImportant("Awaiting data from {0}...", state.Sender);
                    state.BytesReceived = socket.ReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.Sender);
                    //byte[] data = socket.Receive(ref state.Sender);
                    //state.Buffer = data;

                    //NetLogger.LogVerbose("Got {0} byte packet from {1}", br, state.Sender);

                    if (!config.SimulatePacketLoss || packetLossRandom.NextDouble() <= 1f - config.SimulatedPacketLossChance)
                    {
                        if (config.SimulateLatency)
                        {
                            delayedReceivedPackets.Enqueue(new DelayedInboundPacket(state, NetTime.Now + config.SimulatedLatencyAmount));
                        }
                        else
                        {
                            PacketReceived(state);
                        }
                    }
                }
                catch (SocketException e)
                {
                    if (e.SocketErrorCode != SocketError.ConnectionReset)
                    {
                        NetLogger.LogError("SocketErrorCode: {0}", e.SocketErrorCode.ToString());
                        NetLogger.LogError(e);
                    }
                }
            }

            if (delayedReceivedPackets.Count > 0)
            {
                DelayedInboundPacket delayedPacket;
                while (delayedReceivedPackets.Count > 0 && delayedReceivedPackets.TryPeek(out delayedPacket))
                {
                    if (delayedPacket.QueueAfter > NetTime.Now)
                    {
                        break;
                    }

                    if (delayedReceivedPackets.TryDequeue(out delayedPacket))
                    {
                        PacketReceived(delayedPacket.Packet);
                    }
                }
            }

            foreach (NetConnection conn in Connections.Values)
            {
                // Attempt to run the connections heartbeat
                if (!conn.Heartbeat(NetTime.Now))
                {
                    NetLogger.Log("Connection {0} timed out!", conn);
                    // The heartbeat failed which means the connection timed out
                    conn.Disconnect("Lost Connection", true);
                }
            }

            foreach (TrackedConnection conn in trackedConnections.Values)
            {
                if (conn.IsFlooding())
                {
                    int ignoreTime;
                    if (lastIgnoreLengths.TryGetValue(conn.EndPoint, out ignoreTime))
                    {
                        ignoreTime *= 2;
                    }
                    else
                    {
                        ignoreTime = 10000;
                    }

                    AddIgnoredConnection(conn.EndPoint,
                                         string.Format("Sent {0} invalid packets in the last second, {1} total.",
                                                       conn.PacketsFrom, conn.Accumulator),
                                         ignoreTime);
                }
                else if (NetTime.Now >= conn.StopTrackingAt && conn.PacketsFrom == 0)
                {
                    TrackedConnection temp;
                    if (trackedConnections.TryRemove(conn.EndPoint, out temp))
                    {
                        NetLogger.Log("[WATCH] No longer watching {0} for excessive invalid packets", conn.EndPoint);
                    }
                }
            }

            foreach (IgnoredConnection conn in ignoredConnections.Values)
            {
                if (NetTime.Now >= conn.AcknowledgeAt)
                {
                    IgnoredConnection temp;
                    if (ignoredConnections.TryRemove(conn.EndPoint, out temp))
                    {
                        NetLogger.Log("[IGNORE] No longer ignoring {0}...", conn.EndPoint);
                        lastIgnoreLengths[conn.EndPoint] = conn.IgnoreTime;
                    }
                }
            }
        }