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; } } } }