using FishNet.Managing; using FishNet.Managing.Timing; using System; using UnityEngine; namespace FishNet.Connection { /// /// A container for a connected client used to perform actions on and gather information for the declared client. /// public partial class NetworkConnection : IEquatable { #pragma warning disable CS0414 #region Private. /// /// Last tick this connection sent a ping. /// private uint _lastPingTick; /// /// Number of times client has excessively sent a ping. /// private float _excessivePingCount; /// /// Ticks expected between each ping. /// private uint _requiredPingTicks; #endregion #region Const. /// /// Number of times a ping may occur excessively before server will punish connection. /// private const byte EXCESSIVE_PING_LIMIT = 10; #endregion #pragma warning restore CS0414 /// /// Initializes for ping. /// private void InitializePing() { //Give the client some room for error. float requiredInterval = (NetworkManager.TimeManager.PingInterval * 0.85f); //Round down so required ticks is lower. _requiredPingTicks = NetworkManager.TimeManager.TimeToTicks(requiredInterval, TickRounding.RoundDown); } /// /// Resets PingPong values. /// private void ResetPingPong() { _excessivePingCount = 0; _lastPingTick = 0; } /// /// Called when a ping is received from this connection. Returns if can respond to ping. /// /// True to respond to ping, false to kick connection. internal bool CanPingPong() { /* Only check ping conditions in build. Editors are prone to pausing which can * improperly kick clients. */ #if UNITY_EDITOR return true; #else TimeManager tm = (NetworkManager == null) ? InstanceFinder.TimeManager : NetworkManager.TimeManager; //Server FPS is running low, timing isn't reliable enough to kick clients. if (tm.LowFrameRate) return true; uint currentTick = tm.Tick; uint difference = (currentTick - _lastPingTick); _lastPingTick = currentTick; //Ping sent too quickly. if (difference < _requiredPingTicks) { _excessivePingCount += 1f; //Ping limit hit. if (_excessivePingCount >= EXCESSIVE_PING_LIMIT) { NetworkManager.LogWarning($"Kicked connectionId {ClientId} for excessive pings."); Disconnect(true); } //Return to not send pong back. return false; } //Ping isnt too fast. else { _excessivePingCount = UnityEngine.Mathf.Max(0f, _excessivePingCount - 0.5f); return true; } #endif } } }