using System; using System.Collections.Immutable; using System.Net; using System.Threading.Channels; using System.Threading.Tasks; using Lidgren.Network; using Robust.Shared.ViewVariables; namespace Robust.Shared.Network { public partial class NetManager { private sealed class NetChannel : INetChannel { private readonly NetManager _manager; private readonly NetConnection _connection; /// [ViewVariables] public long ConnectionId => _connection.RemoteUniqueIdentifier; /// [ViewVariables] public INetManager NetPeer => _manager; [ViewVariables] public string UserName => UserData.UserName; [ViewVariables] public LoginType AuthType { get; } [ViewVariables] public TimeSpan RemoteTimeOffset => TimeSpan.FromSeconds(_connection.RemoteTimeOffset); [ViewVariables] public TimeSpan RemoteTime => _manager._timing.RealTime + RemoteTimeOffset; /// [ViewVariables] public short Ping => (short) Math.Round(_connection.AverageRoundtripTime * 1000); /// [ViewVariables] public bool IsConnected => _connection.Status == NetConnectionStatus.Connected; /// public IPEndPoint RemoteEndPoint => _connection.RemoteEndPoint; /// /// Exposes the lidgren connection. /// public NetConnection Connection => _connection; [ViewVariables] public NetUserId UserId => UserData.UserId; [ViewVariables] public NetUserData UserData { get; } public bool IsHandshakeComplete { get; set; } // Only used on server, contains the encryption to use for this channel. public NetEncryption? Encryption { get; set; } [ViewVariables] public int CurrentMtu => _connection.CurrentMTU; public ChannelWriter? EncryptionChannel; public Task? EncryptionChannelTask; /// /// Creates a new instance of a NetChannel. /// /// The server this channel belongs to. /// The raw NetConnection to the remote peer. internal NetChannel(NetManager manager, NetConnection connection, NetUserData userData, LoginType loginType) { _manager = manager; _connection = connection; AuthType = loginType; UserData = userData; } /// public T CreateNetMessage() where T : NetMessage, new() { return _manager.CreateNetMessage(); } /// public void SendMessage(NetMessage message) { if (_manager.IsClient) { _manager.ClientSendMessage(message); return; } _manager.ServerSendMessage(message, this); } /// public void Disconnect(string reason) { Disconnect(reason, true); } public void Disconnect(string reason, bool sendBye) { if (_connection.Status == NetConnectionStatus.Connected) _connection.Disconnect(reason, sendBye); } public bool CanSendImmediately(NetDeliveryMethod method, int sequenceChannel) { return _connection.CanSendImmediately(method, sequenceChannel); } public override string ToString() { return $"{ConnectionId}/{UserId}"; } } } }