diff --git a/Intersect.Network/Intersect.Network.csproj b/Intersect.Network/Intersect.Network.csproj index 8e0f40ee86..9ea420d796 100644 --- a/Intersect.Network/Intersect.Network.csproj +++ b/Intersect.Network/Intersect.Network.csproj @@ -26,7 +26,6 @@ - diff --git a/Intersect.Network/Lidgren/LidgrenBuffer.cs b/Intersect.Network/Lidgren/LidgrenBuffer.cs deleted file mode 100644 index b472dd51e9..0000000000 --- a/Intersect.Network/Lidgren/LidgrenBuffer.cs +++ /dev/null @@ -1,788 +0,0 @@ -using System.Text; - -using Intersect.Memory; - -using Lidgren.Network; - -namespace Intersect.Network.Lidgren; - - -public partial class LidgrenBuffer : IBuffer -{ - - public LidgrenBuffer(NetBuffer buffer) - { - Buffer = buffer; - } - - public NetBuffer Buffer { get; } - - public void Dispose() - { - } - - public long Length => Buffer?.LengthBytes ?? -1; - - public long Position => Buffer?.PositionInBytes ?? -1; - - public long Remaining => Length - Position; - - public byte[] ToBytes() - { - return Buffer?.ReadBytes((int)Length); - } - - public bool Has(long bytes) - { - return bytes <= Remaining; - } - - public bool Read(out bool value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadBoolean(); - - return true; - } - catch (Exception) - { - value = default(bool); - - return false; - } - } - - public bool Read(out byte value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadByte(); - - return true; - } - catch (Exception) - { - value = default(byte); - - return false; - } - } - - public bool Read(out byte[] value) - { - if (Read(out int count)) - { - return Read(out value, count); - } - - value = default(byte[]); - - return false; - } - - public bool Read(out byte[] value, long count) - { - value = new byte[count]; - - return count < 1 || Read(ref value, 0, count); - } - - public bool Read(ref byte[] value, long offset, long count) - { - try - { - // ReSharper disable once PossibleNullReferenceException - Buffer.ReadBytes(value, (int) offset, (int) count); - - return true; - } - catch (Exception) - { - return false; - } - } - - public bool Read(out char value) - { - if (Has(sizeof(char)) && Read(out var bytes, sizeof(char))) - { - value = BitConverter.ToChar(bytes, 0); - - return true; - } - - value = default(char); - - return false; - } - - public bool Read(out decimal value) - { - value = default(decimal); - - var bits = new int[4]; - if (!Read(out bits[0])) - { - return false; - } - - if (!Read(out bits[1])) - { - return false; - } - - if (!Read(out bits[2])) - { - return false; - } - - if (!Read(out bits[3])) - { - return false; - } - - value = new decimal(bits); - - return true; - } - - public bool Read(out double value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadDouble(); - - return true; - } - catch (Exception) - { - value = default(double); - - return false; - } - } - - public bool Read(out float value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadFloat(); - - return true; - } - catch (Exception) - { - value = default(float); - - return false; - } - } - - public bool Read(out int value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadInt32(); - - return true; - } - catch (Exception) - { - value = default(int); - - return false; - } - } - - public bool Read(out long value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadInt64(); - - return true; - } - catch (Exception) - { - value = default(long); - - return false; - } - } - - public bool Read(out sbyte value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadSByte(); - - return true; - } - catch (Exception) - { - value = default(sbyte); - - return false; - } - } - - public bool Read(out short value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadInt16(); - - return true; - } - catch (Exception) - { - value = default(short); - - return false; - } - } - - public bool Read(out string value) - { - return Read(out value, Encoding.UTF8); - } - - public bool Read(out string value, Encoding encoding, bool nullTerminated = false) - { - if (encoding == null) - { - throw new ArgumentNullException(); - } - - int length; - if (nullTerminated) - { - var position = Buffer?.PositionInBytes ?? int.MaxValue; - var buffer = Buffer?.PeekDataBuffer() ?? Array.Empty(); - while (Buffer?.LengthBytes - position > 0) - { - if (buffer[position] == 0) - { - break; - } - - position++; - } - - length = Buffer?.LengthBytes - Buffer?.PositionInBytes ?? -1; - } - else if (!Read(out length)) - { - value = default(string); - - return false; - } - - switch (length) - { - case 0: - value = ""; - - break; - - case -1: - value = null; - - break; - - default: - value = Read(out var bytes, length) ? encoding.GetString(bytes, 0, length) : null; - - break; - } - - return true; - } - - public bool Read(out uint value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadUInt32(); - - return true; - } - catch (Exception) - { - value = default(uint); - - return false; - } - } - - public bool Read(out ulong value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadUInt64(); - - return true; - } - catch (Exception) - { - value = default(ulong); - - return false; - } - } - - public bool Read(out ushort value) - { - try - { - // ReSharper disable once PossibleNullReferenceException - value = Buffer.ReadUInt16(); - - return true; - } - catch (Exception) - { - value = default(ushort); - - return false; - } - } - - public bool ReadBool() - { - if (Read(out bool value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public bool ReadBoolean() - { - if (Read(out bool value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public byte ReadByte() - { - if (Read(out byte value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public byte ReadUInt8() - { - if (Read(out byte value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public byte[] ReadBytes() - { - if (Read(out byte[] value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public byte[] ReadBytes(long count) - { - if (Read(out var value, count)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public byte[] ReadBytes(ref byte[] bytes, long offset, long count) - { - if (Read(ref bytes, offset, count)) - { - return bytes; - } - - throw new OutOfMemoryException(); - } - - public char ReadChar() - { - if (Read(out char value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public char ReadCharacter() - { - if (Read(out char value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public decimal ReadDecimal() - { - if (Read(out decimal value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public double ReadDouble() - { - if (Read(out double value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public float ReadFloat() - { - if (Read(out float value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public float ReadSingle() - { - if (Read(out float value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public int ReadInt() - { - if (Read(out int value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public int ReadInt32() - { - if (Read(out int value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public int ReadInteger() - { - if (Read(out int value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public long ReadInt64() - { - if (Read(out long value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public long ReadLong() - { - if (Read(out long value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public sbyte ReadInt8() - { - if (Read(out sbyte value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public sbyte ReadSByte() - { - if (Read(out sbyte value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public short ReadInt16() - { - if (Read(out short value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public short ReadShort() - { - if (Read(out short value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public string ReadString() - { - if (Read(out string value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public string ReadString(Encoding encoding, bool nullTerminated = false) - { - if (Read(out var value, encoding, nullTerminated)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public uint ReadUInt() - { - if (Read(out uint value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public uint ReadUInt32() - { - if (Read(out uint value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public uint ReadUnsignedInteger() - { - if (Read(out uint value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public ulong ReadULong() - { - if (Read(out ulong value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public ulong ReadUInt64() - { - if (Read(out ulong value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public ushort ReadUInt16() - { - if (Read(out ushort value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public ushort ReadUShort() - { - if (Read(out ushort value)) - { - return value; - } - - throw new OutOfMemoryException(); - } - - public void Write(bool value) - { - Buffer?.Write(value); - } - - public void Write(byte value) - { - Buffer?.Write(value); - } - - public void Write(byte[] value) - { - Write(value?.Length ?? 0); - Write(value, value?.Length ?? 0); - } - - public void Write(byte[] value, long count) - { - Write(value, 0, count); - } - - public void Write(byte[] value, long offset, long count) - { - Buffer?.Write(value, (int) offset, (int) count); - } - - public void Write(char value) - { - Buffer?.Write(BitConverter.GetBytes(value)); - } - - public void Write(decimal value) - { - var bits = decimal.GetBits(value); - Write(bits[0]); - Write(bits[1]); - Write(bits[2]); - Write(bits[3]); - } - - public void Write(double value) - { - Buffer?.Write(value); - } - - public void Write(float value) - { - Buffer?.Write(value); - } - - public void Write(int value) - { - Buffer?.Write(value); - } - - public void Write(long value) - { - Buffer?.Write(value); - } - - public void Write(sbyte value) - { - Buffer?.Write(value); - } - - public void Write(short value) - { - Buffer?.Write(value); - } - - public void Write(string value) - { - Write(value, Encoding.UTF8); - } - - public void Write(string value, Encoding encoding, bool nullTerminated = false) - { - if (encoding == null) - { - throw new ArgumentNullException(); - } - - if (!nullTerminated) - { - Write(value?.Length ?? -1); - } - - if (value == null) - { - return; - } - - if (value.Length < 1) - { - return; - } - - var bytes = encoding.GetBytes(value); - Write(bytes, bytes.Length); - } - - public void Write(uint value) - { - Buffer?.Write(value); - } - - public void Write(ulong value) - { - Buffer?.Write(value); - } - - public void Write(ushort value) - { - Buffer?.Write(value); - } - -} diff --git a/Intersect.Network/Lidgren/LidgrenConnection.cs b/Intersect.Network/Lidgren/LidgrenConnection.cs deleted file mode 100644 index 4ce630fa3d..0000000000 --- a/Intersect.Network/Lidgren/LidgrenConnection.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System.Security.Cryptography; - -using Intersect.Logging; -using Intersect.Network.Packets; -using Intersect.Utilities; - -using Lidgren.Network; -using Lidgren.Network.Encryption; - -namespace Intersect.Network.Lidgren; - - -public sealed partial class LidgrenConnection : AbstractConnection -{ - - private byte[] mAesKey; - - private byte[] mHandshakeSecret; - - private byte[] mRsaSecret; - - public LidgrenConnection(INetwork network, NetConnection connection, byte[] aesKey, RSAParameters rsaParameters) - : this(network, Guid.NewGuid(), connection, aesKey) - { - CreateRsa(rsaParameters); - } - - public LidgrenConnection(INetwork network, Guid guid, NetConnection netConnection, byte[] aesKey) : base(guid) - { - Network = network; - NetConnection = netConnection ?? throw new ArgumentNullException(); - mAesKey = aesKey ?? throw new ArgumentNullException(); - - CreateAes(); - } - - public LidgrenConnection( - INetwork network, - Guid guid, - NetConnection netConnection, - byte[] handshakeSecret, - RSAParameters rsaParameters - ) : base(guid) - { - Network = network; - NetConnection = netConnection; - mHandshakeSecret = handshakeSecret; - CreateRsa(rsaParameters); - } - - public INetwork Network { get; } - - public NetConnection NetConnection { get; } - - public RSACryptoServiceProvider Rsa { get; private set; } - - public NetEncryption Aes { get; private set; } - - public override string Ip => NetConnection?.RemoteEndPoint?.Address?.ToString(); - - public override int Port => NetConnection?.RemoteEndPoint?.Port ?? -1; - - private void CreateRsa(RSAParameters rsaParameters) - { - Rsa = new RSACryptoServiceProvider(); - Rsa.ImportParameters(rsaParameters); - } - - private void CreateAes() - { - if (NetConnection == null) - { - throw new ArgumentNullException(); - } - - if (mAesKey == null) - { - throw new ArgumentNullException(); - } - - Aes = new NetAesGcmEncryption(NetConnection.Peer, mAesKey); - } - - public bool HandleApproval(ApprovalPacket approval) - { - if (approval == null) - { - throw new ArgumentNullException(); - } - - if (approval.HandshakeSecret == null) - { - throw new ArgumentNullException(); - } - - if (approval.AesKey == null) - { - throw new ArgumentNullException(); - } - - if (mHandshakeSecret == null) - { - throw new ArgumentNullException(); - } - - if (!mHandshakeSecret.SequenceEqual(approval.HandshakeSecret)) - { - Log.Error("Bad handshake secret received from server."); - - return false; - } - - mAesKey = approval.AesKey; - - CreateAes(); - - Timing.Global.Synchronize(approval.UTC, approval.Offset); - Log.Debug($"approval Time={approval.Adjusted / TimeSpan.TicksPerMillisecond} Offset={approval.Offset / TimeSpan.TicksPerMillisecond} Real={approval.UTC / TimeSpan.TicksPerMillisecond}"); - Log.Debug($"local Time={Timing.Global.Milliseconds} Offset={Timing.Global.MillisecondsOffset} Real={Timing.Global.MillisecondsUtc}"); - Log.Debug($"real delta={(Timing.Global.TicksUtc - approval.UTC) / TimeSpan.TicksPerMillisecond}"); - Log.Debug($"this.Statistics.Ping={this.Statistics.Ping} NCPing={(long)Math.Ceiling(NetConnection.AverageRoundtripTime * 1000)}"); - - return true; - } - - public override void Dispose() - { - base.Dispose(); - NetConnection?.Disconnect(NetworkStatus.Quitting.ToString()); - } - - public override bool Send(IPacket packet, TransmissionMode mode = TransmissionMode.All) - { - return Network?.Send(this, packet, mode) ?? false; - } - - public override void Disconnect(string message = default) - { - NetConnection?.Disconnect(message); - } -} diff --git a/Intersect.Network/Lidgren/LidgrenInterface.cs b/Intersect.Network/Lidgren/LidgrenInterface.cs deleted file mode 100644 index 5768d7f63b..0000000000 --- a/Intersect.Network/Lidgren/LidgrenInterface.cs +++ /dev/null @@ -1,946 +0,0 @@ -using System.Diagnostics; -using System.Net; -using System.Security.Cryptography; - -using Intersect.Logging; -using Intersect.Memory; -using Intersect.Network.Events; -using Intersect.Network.Packets; -using Intersect.Utilities; - -using Lidgren.Network; - -namespace Intersect.Network.Lidgren; - - -public sealed partial class LidgrenInterface : INetworkLayerInterface -{ - - private static readonly IConnection[] EmptyConnections = { }; - - private readonly IDictionary mGuidLookup; - - private readonly INetwork mNetwork; - - private readonly NetPeer mPeer; - - private readonly NetPeerConfiguration mPeerConfiguration; - - private readonly RandomNumberGenerator mRng; - - private readonly RSACryptoServiceProvider mRsa; - - public LidgrenInterface(INetwork network, Type peerType, RSAParameters rsaParameters) - { - if (peerType == null) - { - throw new ArgumentNullException(nameof(peerType)); - } - - mNetwork = network ?? throw new ArgumentNullException(nameof(network)); - - var configuration = mNetwork.Configuration; - if (configuration == null) - { - throw new ArgumentNullException(nameof(mNetwork.Configuration)); - } - - mRng = new RNGCryptoServiceProvider(); - - mRsa = new RSACryptoServiceProvider(); - mRsa.ImportParameters(rsaParameters); - mPeerConfiguration = new NetPeerConfiguration( - $"{VersionHelper.ExecutableVersion} {VersionHelper.LibraryVersion} {SharedConstants.VersionName}" - ) - { - AcceptIncomingConnections = configuration.IsServer - }; - - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.Receipt); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.UnconnectedData); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.ConnectionLatencyUpdated); - - if (configuration.IsServer) - { - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.DiscoveryRequest); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.ConnectionApproval); - mPeerConfiguration.AcceptIncomingConnections = true; - mPeerConfiguration.MaximumConnections = configuration.MaximumConnections; - - //mPeerConfiguration.LocalAddress = DnsUtils.Resolve(config.Host); - //mPeerConfiguration.EnableUPnP = true; - mPeerConfiguration.Port = configuration.Port; - } - - if (Debugger.IsAttached) - { - mPeerConfiguration.ConnectionTimeout = 60; - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.VerboseDebugMessage); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.DebugMessage); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.ErrorMessage); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.WarningMessage); - mPeerConfiguration.EnableMessageType(NetIncomingMessageType.Error); - } - else - { - mPeerConfiguration.ConnectionTimeout = 15; - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.VerboseDebugMessage); - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage); - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.ErrorMessage); - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.WarningMessage); - mPeerConfiguration.DisableMessageType(NetIncomingMessageType.Error); - } - - mPeerConfiguration.PingInterval = 2.5f; - mPeerConfiguration.UseMessageRecycling = true; - mPeerConfiguration.AutoExpandMTU = true; - - var constructorInfo = peerType.GetConstructor(new[] {typeof(NetPeerConfiguration)}); - if (constructorInfo == null) - { - throw new ArgumentNullException(nameof(constructorInfo)); - } - - var constructedPeer = constructorInfo.Invoke(new object[] {mPeerConfiguration}) as NetPeer; - mPeer = constructedPeer ?? throw new ArgumentNullException(nameof(constructedPeer)); - - mGuidLookup = new Dictionary(); - - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - - mPeer?.RegisterReceivedCallback( - peer => - { - lock (mPeer) - { - if (OnPacketAvailable == null) - { - Log.Debug("Unhandled inbound Lidgren message."); - Log.Diagnostic($"Unhandled message: {TryHandleInboundMessage()}"); - - return; - } - - OnPacketAvailable(this); - } - } - ); - } - - public HandleConnectionEvent OnConnected { get; set; } - - public HandleConnectionEvent OnConnectionApproved { get; set; } - - public HandleConnectionEvent OnConnectionDenied { get; set; } - - public HandleConnectionRequest OnConnectionRequested { get; set; } - - public HandleConnectionEvent OnDisconnected { get; set; } - - public HandlePacketAvailable OnPacketAvailable { get; set; } - - public HandleUnconnectedMessage OnUnconnectedMessage { get; set; } - - private bool IsDisposing { get; set; } - - public bool IsDisposed { get; private set; } - - public bool SendUnconnectedPacket(IPEndPoint target, ReadOnlySpan data) - { - throw new NotImplementedException(); - } - - public bool SendUnconnectedPacket(IPEndPoint target, UnconnectedPacket packet) - { - throw new NotImplementedException(); - } - - public void Start() - { - if (mNetwork.Configuration.IsServer) - { - Log.Pretty.Info($"Listening on {mPeerConfiguration.LocalAddress}:{mPeerConfiguration.Port}."); - mPeer.Start(); - - return; - } - - if (!Connect()) - { - Log.Error("Failed to make the initial connection attempt."); - } - } - - public bool Connect() - { - if (mNetwork.Configuration.IsServer) - { - throw new InvalidOperationException("Server interfaces cannot use Connect()."); - } - - Log.Info($"Connecting to {mNetwork.Configuration.Host}:{mNetwork.Configuration.Port}..."); - - var handshakeSecret = new byte[32]; - mRng.GetNonZeroBytes(handshakeSecret); - - var connectionRsa = new RSACryptoServiceProvider(2048); - var hailParameters = connectionRsa.ExportParameters(false); - var hail = new HailPacket(mRsa, handshakeSecret, SharedConstants.VersionData, hailParameters); - hail.Encrypt(); - - var hailMessage = mPeer.CreateMessage(hail.Data.Length); - if (hailMessage == null) - { - throw new InvalidOperationException(); - } - - hailMessage.Data = hail.Data; - hailMessage.LengthBytes = hail.Data.Length; - - if (mPeer.Status == NetPeerStatus.NotRunning) - { - mPeer.Start(); - } - - var connection = mPeer.Connect(mNetwork.Configuration.Host, mNetwork.Configuration.Port, hailMessage); - var server = new LidgrenConnection( - mNetwork, Guid.Empty, connection, handshakeSecret, connectionRsa.ExportParameters(true) - ); - - if (mNetwork.AddConnection(server)) - { - return true; - } - - Log.Error("Failed to add connection to list."); - connection?.Disconnect("client_error"); - - return false; - } - - protected IConnection FindConnection(NetConnection netConnection) - { - var lidgrenId = netConnection?.RemoteUniqueIdentifier ?? -1; - Debug.Assert(mGuidLookup != null, "mGuidLookup != null"); - if (!mGuidLookup.TryGetValue(lidgrenId, out var guid)) - { - return default; - } - - return mNetwork.FindConnection(guid); - } - - event HandleConnectionEvent? INetworkLayerInterface.OnConnected - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandleConnectionEvent? INetworkLayerInterface.OnConnectionApproved - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandleConnectionEvent? INetworkLayerInterface.OnConnectionDenied - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandleConnectionRequest? INetworkLayerInterface.OnConnectionRequested - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandleConnectionEvent? INetworkLayerInterface.OnDisconnected - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandlePacketAvailable? INetworkLayerInterface.OnPacketAvailable - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - event HandleUnconnectedMessage? INetworkLayerInterface.OnUnconnectedMessage - { - add => throw new NotImplementedException(); - remove => throw new NotImplementedException(); - } - - public bool TryGetInboundBuffer(out IBuffer buffer, out IConnection connection) - { - buffer = default; - connection = default; - - var message = TryHandleInboundMessage(); - if (message == null) - { - return true; - } - - connection = FindConnection(message.SenderConnection); - if (connection == null) - { - //Log.Error($"Received message from an unregistered endpoint."); - mPeer.Recycle(message); - - return false; - } - - if (connection != null) - { - var lidgrenConnection = connection as LidgrenConnection; - if (lidgrenConnection?.Aes == null) - { - Log.Error("No provider to decrypt data with."); - - return false; - } - - if (!lidgrenConnection.Aes.Decrypt(message)) - { - Log.Error($"Error decrypting inbound Lidgren message [Connection:{connection.Guid}]."); - - return false; - } - } - else - { - //Log.Warn($"Received message from an unregistered endpoint."); - } - - buffer = new LidgrenBuffer(message); - - return true; - } - - public void ReleaseInboundBuffer(IBuffer buffer) - { - var message = (buffer as LidgrenBuffer)?.Buffer as NetIncomingMessage; - mPeer?.Recycle(message); - } - - public bool SendPacket( - IPacket packet, - IConnection connection = null, - TransmissionMode transmissionMode = TransmissionMode.All - ) - { - if (connection == null) - { - return SendPacket(packet, EmptyConnections, transmissionMode); - } - - if (!(connection is LidgrenConnection lidgrenConnection)) - { - Log.Diagnostic("Tried to send to a non-Lidgren connection."); - - return false; - } - - var deliveryMethod = TranslateTransmissionMode(transmissionMode); - if (mPeer == null) - { - throw new ArgumentNullException(nameof(mPeer)); - } - - if (packet == null) - { - Log.Diagnostic("Tried to send a null packet."); - - return false; - } - - var message = mPeer.CreateMessage(); - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - message.Data = packet.Data; - message.LengthBytes = message.Data.Length; - - SendMessage(message, lidgrenConnection, NetDeliveryMethod.ReliableOrdered); - - return true; - } - - public bool SendPacket( - IPacket packet, - ICollection connections, - TransmissionMode transmissionMode = TransmissionMode.All - ) - { - var deliveryMethod = TranslateTransmissionMode(transmissionMode); - if (mPeer == null) - { - throw new ArgumentNullException(nameof(mPeer)); - } - - if (packet == null) - { - Log.Diagnostic("Tried to send a null packet."); - - return false; - } - - var message = mPeer.CreateMessage(); - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - message.Data = packet.Data; - message.LengthBytes = message.Data.Length; - - if (connections == null || connections.Count(connection => connection != null) < 1) - { - connections = mNetwork?.FindConnections(); - } - - var lidgrenConnections = connections?.OfType().ToList(); - if (lidgrenConnections?.Count > 0) - { - var firstConnection = lidgrenConnections.First(); - - lidgrenConnections.ForEach( - lidgrenConnection => - { - if (lidgrenConnection == null) - { - return; - } - - if (firstConnection == lidgrenConnection) - { - return; - } - - if (message.Data == null) - { - throw new ArgumentNullException(nameof(message.Data)); - } - - //var messageClone = mPeer.CreateMessage(message.Data.Length); - //if (messageClone == null) - //{ - // throw new ArgumentNullException(nameof(messageClone)); - //} - - //Buffer.BlockCopy(message.Data, 0, messageClone.Data, 0, message.Data.Length); - //messageClone.LengthBytes = message.LengthBytes; - SendMessage(message, lidgrenConnection, deliveryMethod); - } - ); - - SendMessage(message, lidgrenConnections.First(), deliveryMethod); - } - else - { - Log.Diagnostic("No lidgren connections, skipping..."); - } - - return true; - } - - public void Stop(string reason = "stopping") - { - Disconnect(reason); - } - - public void Disconnect(IConnection connection, string message) - { - Disconnect(new[] {connection}, message); - } - - public void Disconnect(ICollection connections, string message) - { - if (connections == null) - { - return; - } - - foreach (var connection in connections) - { - (connection as LidgrenConnection)?.NetConnection?.Disconnect(message); - (connection as LidgrenConnection)?.NetConnection?.Peer.FlushSendQueue(); - (connection as LidgrenConnection)?.Dispose(); - } - } - - public void Dispose() - { - if (IsDisposed) - { - throw new ObjectDisposedException(nameof(LidgrenInterface)); - } - - if (IsDisposing) - { - return; - } - - IsDisposing = true; - - switch (mPeer.Status) - { - case NetPeerStatus.NotRunning: - case NetPeerStatus.ShutdownRequested: - break; - - case NetPeerStatus.Running: - case NetPeerStatus.Starting: - mPeer.Shutdown(@"Terminating."); - - break; - - default: - throw new ArgumentOutOfRangeException(nameof(mPeer.Status)); - } - - IsDisposed = true; - IsDisposing = false; - } - - private NetIncomingMessage TryHandleInboundMessage() - { - Debug.Assert(mPeer != null, "mPeer != null"); - - if (!mPeer.ReadMessage(out var message)) - { - return null; - } - - var senderConnection = message.SenderConnection; - var lidgrenId = senderConnection?.RemoteUniqueIdentifier ?? -1; - var lidgrenIdHex = BitConverter.ToString(BitConverter.GetBytes(lidgrenId)); - - switch (message.MessageType) - { - case NetIncomingMessageType.Data: - - //Log.Diagnostic($"{message.MessageType}: {message}"); - return message; - - case NetIncomingMessageType.StatusChanged: - Debug.Assert(mGuidLookup != null, "mGuidLookup != null"); - Debug.Assert(mNetwork != null, "mNetwork != null"); - - switch (senderConnection?.Status ?? NetConnectionStatus.None) - { - case NetConnectionStatus.None: - case NetConnectionStatus.InitiatedConnect: - case NetConnectionStatus.ReceivedInitiation: - case NetConnectionStatus.RespondedAwaitingApproval: - case NetConnectionStatus.RespondedConnect: - Log.Diagnostic($"{message.MessageType}: {message} [{senderConnection?.Status}]"); - - break; - - case NetConnectionStatus.Disconnecting: - Log.Debug($"{message.MessageType}: {message} [{senderConnection?.Status}]"); - - break; - - case NetConnectionStatus.Connected: - { - LidgrenConnection intersectConnection; - if (!mNetwork.Configuration.IsServer) - { - intersectConnection = mNetwork.FindConnection(Guid.Empty); - if (intersectConnection == null) - { - Log.Error("Bad state, no connection found."); - mNetwork.Disconnect("client_connection_missing"); - senderConnection?.Disconnect("client_connection_missing"); - - break; - } - - FireHandler( - OnConnectionApproved, nameof(OnConnectionApproved), this, new ConnectionEventArgs - { - NetworkStatus = NetworkStatus.Connecting, - Connection = intersectConnection - } - ); - - Debug.Assert(senderConnection != null, "connection != null"); - var approvalPacketData = senderConnection.RemoteHailMessage.Data; - var approval = MessagePacker.Instance.Deserialize(approvalPacketData) as ApprovalPacket; - - if (!(approval?.Decrypt(intersectConnection.Rsa) ?? false)) - { - Log.Error("Unable to read approval message, disconnecting."); - mNetwork.Disconnect("client_error"); - senderConnection.Disconnect("client_error"); - - break; - } - - if (!intersectConnection.HandleApproval(approval)) - { - mNetwork.Disconnect(NetworkStatus.HandshakeFailure.ToString()); - senderConnection.Disconnect(NetworkStatus.HandshakeFailure.ToString()); - - break; - } - - if (!(mNetwork is ClientNetwork clientNetwork)) - { - throw new InvalidOperationException(); - } - - clientNetwork.AssignId(approval.Guid); - - Debug.Assert(mGuidLookup != null, "mGuidLookup != null"); - mGuidLookup.Add(senderConnection.RemoteUniqueIdentifier, Guid.Empty); - } - else - { - Log.Diagnostic($"{message.MessageType}: {message} [{senderConnection?.Status}]"); - if (!mGuidLookup.TryGetValue(lidgrenId, out var guid)) - { - Log.Error($"Unknown client connected ({lidgrenIdHex})."); - senderConnection?.Disconnect("server_unknown_client"); - - break; - } - - intersectConnection = mNetwork.FindConnection(guid); - } - - if (OnConnected != null) - { - intersectConnection?.HandleConnected(); - } - - FireHandler( - OnConnected, nameof(OnConnected), this, new ConnectionEventArgs - { - NetworkStatus = NetworkStatus.Online, - Connection = intersectConnection - } - ); - } - - break; - - case NetConnectionStatus.Disconnected: - { - Debug.Assert(senderConnection != null, "connection != null"); - Log.Debug($"{message.MessageType}: {message} [{senderConnection.Status}]"); - var result = (NetConnectionStatus) message.ReadByte(); - var reason = message.ReadString(); - - NetworkStatus networkStatus; - try - { - networkStatus = reason switch - { - //Lidgren won't accept a connection with a bad version and sends this message back so we need to manually handle it - "Wrong application identifier!" => NetworkStatus.VersionMismatch, - "Connection timed out" => NetworkStatus.Quitting, - "Failed to establish connection - no response from remote host" => NetworkStatus.Offline, - "closing" => NetworkStatus.Offline, - _ => (NetworkStatus)Enum.Parse(typeof(NetworkStatus), reason ?? "", true) - }; - } - catch (Exception exception) - { - Log.Diagnostic(exception); - networkStatus = NetworkStatus.Unknown; - } - - HandleConnectionEvent disconnectHandler; - string disconnectHandlerName; - switch (networkStatus) - { - case NetworkStatus.HandshakeFailure: - case NetworkStatus.ServerFull: - case NetworkStatus.VersionMismatch: - case NetworkStatus.Failed: - disconnectHandler = OnConnectionDenied; - disconnectHandlerName = nameof(OnConnectionDenied); - Log.Diagnostic($"Disconnecting because of {networkStatus} ({reason})"); - break; - - case NetworkStatus.Connecting: - case NetworkStatus.Online: - case NetworkStatus.Offline: - case NetworkStatus.Quitting: - case NetworkStatus.Unknown: - disconnectHandler = OnDisconnected; - disconnectHandlerName = nameof(OnDisconnected); - - break; - - default: - throw new ArgumentOutOfRangeException(); - } - - if (!mGuidLookup.TryGetValue(lidgrenId, out var guid)) - { - Log.Debug($"Unknown client disconnected ({lidgrenIdHex})."); - FireHandler( - disconnectHandler, disconnectHandlerName, this, - new ConnectionEventArgs {NetworkStatus = networkStatus} - ); - - break; - } - - var client = mNetwork.FindConnection(guid); - if (client != null) - { - client.HandleDisconnected(); - - FireHandler( - disconnectHandler, disconnectHandlerName, this, - new ConnectionEventArgs {Connection = client, NetworkStatus = NetworkStatus.Offline} - ); - - mNetwork.RemoveConnection(client); - } - - mGuidLookup.Remove(senderConnection.RemoteUniqueIdentifier); - } - - break; - - default: - throw new ArgumentOutOfRangeException(); - } - - break; - - case NetIncomingMessageType.UnconnectedData: - UnconnectedMessageSender sender = new(this, message.SenderEndPoint, mPeer); - OnUnconnectedMessage?.Invoke(sender, new LidgrenBuffer(message)); - Log.Diagnostic($"Net Incoming Message: {message.MessageType}: {message}"); - - break; - - case NetIncomingMessageType.ConnectionApproval: - { - try - { - var hail = MessagePacker.Instance.Deserialize(message.Data) as HailPacket; - if (!(hail?.Decrypt(mRsa) ?? false)) - { - Log.Warn($"Failed to read hail, denying connection [{lidgrenIdHex}]."); - senderConnection?.Deny(NetworkStatus.HandshakeFailure.ToString()); - - break; - } - - Debug.Assert(SharedConstants.VersionData != null, "SharedConstants.VERSION_DATA != null"); - Debug.Assert(hail.VersionData != null, "hail.VersionData != null"); - if (!SharedConstants.VersionData.SequenceEqual(hail.VersionData)) - { - Log.Error($"Bad version detected, denying connection [{lidgrenIdHex}]."); - senderConnection?.Deny(NetworkStatus.VersionMismatch.ToString()); - - break; - } - - Log.Debug($"hail Time={hail.Adjusted / TimeSpan.TicksPerMillisecond} Offset={hail.Offset / TimeSpan.TicksPerMillisecond} Real={hail.UTC / TimeSpan.TicksPerMillisecond}"); - Log.Debug($"local Time={Timing.Global.Milliseconds} Offset={(long)Timing.Global.MillisecondsOffset} Real={Timing.Global.MillisecondsUtc}"); - Log.Debug($"real delta={(Timing.Global.TicksUtc - hail.UTC) / TimeSpan.TicksPerMillisecond}"); - Log.Debug($"NCPing={(long)Math.Ceiling(senderConnection.AverageRoundtripTime * 1000)}"); - - // Check if we've got more connections than we're allowed to handle! - if (mNetwork.ConnectionCount >= Options.Instance.MaxClientConnections) - { - Log.Info($"Connection limit reached, denying connection [{lidgrenIdHex}]."); - senderConnection?.Deny(NetworkStatus.ServerFull.ToString()); - break; - } - - if (OnConnectionApproved == null) - { - Log.Error($"No handlers for OnConnectionApproved, denying connection [{lidgrenIdHex}]."); - senderConnection?.Deny(NetworkStatus.Failed.ToString()); - - break; - } - - /* Approving connection from here-on. */ - var aesKey = new byte[32]; - mRng?.GetNonZeroBytes(aesKey); - var client = new LidgrenConnection(mNetwork, senderConnection, aesKey, hail.RsaParameters); - - if (!OnConnectionRequested(this, client)) - { - Log.Warn($"Connection blocked due to ban or ip filter!"); - senderConnection?.Deny(NetworkStatus.Failed.ToString()); - - break; - } - - Debug.Assert(mNetwork != null, "mNetwork != null"); - if (!mNetwork.AddConnection(client)) - { - Log.Error($"Failed to add the connection."); - senderConnection?.Deny(NetworkStatus.Failed.ToString()); - - break; - } - - Debug.Assert(mGuidLookup != null, "mGuidLookup != null"); - Debug.Assert(senderConnection != null, "connection != null"); - mGuidLookup.Add(senderConnection.RemoteUniqueIdentifier, client.Guid); - - Debug.Assert(mPeer != null, "mPeer != null"); - var approval = new ApprovalPacket(client.Rsa, hail.HandshakeSecret, aesKey, client.Guid); - approval.Encrypt(); - - var approvalMessage = mPeer.CreateMessage(approval.Data.Length); - if (approvalMessage == null) - { - throw new InvalidOperationException(); - } - - approvalMessage.Data = approval.Data; - approvalMessage.LengthBytes = approvalMessage.Data.Length; - senderConnection.Approve(approvalMessage); - - OnConnectionApproved( - this, new ConnectionEventArgs {Connection = client, NetworkStatus = NetworkStatus.Online} - ); - } - catch - { - senderConnection?.Deny(NetworkStatus.Failed.ToString()); - } - - break; - } - - case NetIncomingMessageType.VerboseDebugMessage: - Log.Diagnostic($"Net Incoming Message: {message.MessageType}: {message.ReadString()}"); - - break; - - case NetIncomingMessageType.DebugMessage: - Log.Debug($"Net Incoming Message: {message.MessageType}: {message.ReadString()}"); - - break; - - case NetIncomingMessageType.WarningMessage: - Log.Warn($"Net Incoming Message: {message.MessageType}: {message.ReadString()}"); - - break; - - case NetIncomingMessageType.ErrorMessage: - case NetIncomingMessageType.Error: - Log.Error($"Net Incoming Message: {message.MessageType}: {message.ReadString()}"); - - break; - - case NetIncomingMessageType.Receipt: - Log.Info($"Net Incoming Message: {message.MessageType}: {message.ReadString()}"); - - break; - - case NetIncomingMessageType.DiscoveryRequest: - case NetIncomingMessageType.DiscoveryResponse: - case NetIncomingMessageType.NatIntroductionSuccess: - Log.Diagnostic($"Net Incoming Message: {message.MessageType}: {message}"); - break; - - case NetIncomingMessageType.ConnectionLatencyUpdated: - { - Log.Diagnostic($"Net Incoming Message: {message.MessageType}: {message}"); - var rtt = message.ReadFloat(); - var connection = FindConnection(senderConnection); - if (connection != null) - { - connection.Statistics.Ping = (long)Math.Ceiling(senderConnection.AverageRoundtripTime * 1000); - } - break; - } - - default: - throw new ArgumentOutOfRangeException(); - } - - return null; - } - - private bool FireHandler( - HandleConnectionEvent handler, - string name, - INetworkLayerInterface sender, - ConnectionEventArgs connectionEventArgs - ) - { - handler?.Invoke(sender, connectionEventArgs); - - if (handler == null) - { - Log.Error($"No handlers for '{name}'."); - } - - return handler != null; - } - - private void SendMessage( - NetOutgoingMessage message, - LidgrenConnection connection, - NetDeliveryMethod deliveryMethod, - int sequenceChannel = 0 - ) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - if (connection == null) - { - throw new ArgumentNullException(nameof(connection)); - } - - if (connection.NetConnection == null) - { - throw new ArgumentNullException(nameof(connection.NetConnection)); - } - - lock (connection.Aes) - { - message.Encrypt(connection.Aes); - } - connection.NetConnection.SendMessage(message, deliveryMethod, sequenceChannel); - } - - private static NetDeliveryMethod TranslateTransmissionMode(TransmissionMode transmissionMode) - { - switch (transmissionMode) - { - case TransmissionMode.Any: - return NetDeliveryMethod.Unreliable; - - case TransmissionMode.Latest: - return NetDeliveryMethod.ReliableSequenced; - - // ReSharper disable once RedundantCaseLabel - case TransmissionMode.All: - default: - return NetDeliveryMethod.ReliableOrdered; - } - } - - internal bool Disconnect(string message) - { - mPeer.Connections?.ForEach(connection => connection?.Disconnect(message)); - - return true; - } - -} diff --git a/Intersect.Server/Networking/Helpers/NetDebug.cs b/Intersect.Server/Networking/Helpers/NetDebug.cs index b0d1f0091e..2b22abf69b 100644 --- a/Intersect.Server/Networking/Helpers/NetDebug.cs +++ b/Intersect.Server/Networking/Helpers/NetDebug.cs @@ -1,20 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Net; -using System.Net.Http; +using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; -using System.Threading.Tasks; - -using Intersect.Logging; using Intersect.Server.Core; using Intersect.Server.Localization; -using Lidgren.Network; - using Newtonsoft.Json; namespace Intersect.Server.Networking.Helpers @@ -53,46 +43,46 @@ public static void GenerateDebugFile() sb.AppendLine("Internal IP: " + localIP); sb.AppendLine("Server Port: " + Options.ServerPort); sb.AppendLine(); - var canConnectVia127 = CheckServerPlayerCount("127.0.0.1", Options.ServerPort) > -1; - sb.AppendLine( - "Server Status (connecting to self via localhost: 127.0.0.1:" + - Options.ServerPort + - "): " + - (canConnectVia127 ? "Online" : "Offline") - ); - - var canConnectViaInternalIp = CheckServerPlayerCount(localIP, Options.ServerPort) > -1; - sb.AppendLine( - "Server Status (connecting to self via internal ip: " + - localIP + - ":" + - Options.ServerPort + - "): " + - (canConnectViaInternalIp ? "Online" : "Offline") - ); - - if (Options.UPnP && !string.IsNullOrEmpty(UpnP.GetExternalIp())) - { - var canConnectViaRouterIp = CheckServerPlayerCount(UpnP.GetExternalIp(), Options.ServerPort) > -1; - sb.AppendLine( - "Server Status (connecting to self via router ip (from UPnP): " + - UpnP.GetExternalIp() + - ":" + - Options.ServerPort + - "): " + - (canConnectViaRouterIp ? "Online" : "Offline") - ); - } - - var canConnectViaExternalIp = CheckServerPlayerCount(externalIp, Options.ServerPort) > -1; - sb.AppendLine( - "Server Status (connecting to self via external ip (from AGD): " + - externalIp + - ":" + - Options.ServerPort + - "): " + - (canConnectViaExternalIp ? "Online" : "Offline") - ); + // var canConnectVia127 = CheckServerPlayerCount("127.0.0.1", Options.ServerPort) > -1; + // sb.AppendLine( + // "Server Status (connecting to self via localhost: 127.0.0.1:" + + // Options.ServerPort + + // "): " + + // (canConnectVia127 ? "Online" : "Offline") + // ); + + // var canConnectViaInternalIp = CheckServerPlayerCount(localIP, Options.ServerPort) > -1; + // sb.AppendLine( + // "Server Status (connecting to self via internal ip: " + + // localIP + + // ":" + + // Options.ServerPort + + // "): " + + // (canConnectViaInternalIp ? "Online" : "Offline") + // ); + + // if (Options.UPnP && !string.IsNullOrEmpty(UpnP.GetExternalIp())) + // { + // var canConnectViaRouterIp = CheckServerPlayerCount(UpnP.GetExternalIp(), Options.ServerPort) > -1; + // sb.AppendLine( + // "Server Status (connecting to self via router ip (from UPnP): " + + // UpnP.GetExternalIp() + + // ":" + + // Options.ServerPort + + // "): " + + // (canConnectViaRouterIp ? "Online" : "Offline") + // ); + // } + + // var canConnectViaExternalIp = CheckServerPlayerCount(externalIp, Options.ServerPort) > -1; + // sb.AppendLine( + // "Server Status (connecting to self via external ip (from AGD): " + + // externalIp + + // ":" + + // Options.ServerPort + + // "): " + + // (canConnectViaExternalIp ? "Online" : "Offline") + // ); sb.AppendLine($"Server Status (as seen by AGD): {serverAccessible}"); sb.AppendLine(); @@ -172,58 +162,58 @@ public static IEnumerable GetTraceRoute(string hostname) } } - private static int CheckServerPlayerCount(string ip, int port) - { - var players = -1; - if (string.IsNullOrEmpty(ip)) - { - return -1; - } - - var config = new NetPeerConfiguration("AGD_CanYouSeeMee"); - var client = new NetClient(config); - try - { - config.EnableMessageType(NetIncomingMessageType.UnconnectedData); - client.Start(); - var msg = client.CreateMessage(); - msg.Write("status"); - - var receiver = new IPEndPoint(NetUtility.Resolve(ip), port); - - client.SendUnconnectedMessage(msg, receiver); - - NetIncomingMessage incomingmsg; - var watch = new Stopwatch(); - watch.Start(); - while (watch.ElapsedMilliseconds < 1250) - { - while ((incomingmsg = client.ReadMessage()) != null) - { - switch (incomingmsg.MessageType) - { - case NetIncomingMessageType.UnconnectedData: - players = incomingmsg.ReadVariableInt32(); - - return players; - } - - client.Recycle(incomingmsg); - } - } - } - catch (Exception exception) - { - Log.Warn(exception); - } - finally - { - client.Shutdown("bye"); - client = null; - } - - return -1; - } + // private static int CheckServerPlayerCount(string ip, int port) + // { + // var players = -1; + // if (string.IsNullOrEmpty(ip)) + // { + // return -1; + // } + // + // var config = new NetPeerConfiguration("AGD_CanYouSeeMee"); + // var client = new NetClient(config); + // try + // { + // config.EnableMessageType(NetIncomingMessageType.UnconnectedData); + // client.Start(); + // var msg = client.CreateMessage(); + // msg.Write("status"); + // + // var receiver = new IPEndPoint(NetUtility.Resolve(ip), port); + // + // client.SendUnconnectedMessage(msg, receiver); + // + // NetIncomingMessage incomingmsg; + // var watch = new Stopwatch(); + // watch.Start(); + // while (watch.ElapsedMilliseconds < 1250) + // { + // while ((incomingmsg = client.ReadMessage()) != null) + // { + // switch (incomingmsg.MessageType) + // { + // case NetIncomingMessageType.UnconnectedData: + // players = incomingmsg.ReadVariableInt32(); + // + // return players; + // } + // + // client.Recycle(incomingmsg); + // } + // } + // } + // catch (Exception exception) + // { + // Log.Warn(exception); + // } + // finally + // { + // client.Shutdown("bye"); + // client = null; + // } + // + // return -1; + // } } diff --git a/Intersect.Server/Networking/Lidgren/ServerNetwork.Lidgren.cs b/Intersect.Server/Networking/Lidgren/ServerNetwork.Lidgren.cs deleted file mode 100644 index 4b5a6e93ed..0000000000 --- a/Intersect.Server/Networking/Lidgren/ServerNetwork.Lidgren.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System.Collections.Concurrent; -using System.Net; -using System.Security.Cryptography; -using Amib.Threading; -using Intersect.Core; -using Intersect.Logging; -using Intersect.Memory; -using Intersect.Network; -using Intersect.Network.Events; -using Intersect.Network.Lidgren; -using Intersect.Server.Core; -using Lidgren.Network; - -namespace Intersect.Server.Networking.Lidgren -{ - - // TODO: Migrate to a proper service - internal partial class ServerNetwork : AbstractNetwork, IServer - { - /// - /// This is our smart thread pool which we use to handle packet processing and packet sending. - /// Min/Max Number of Threads and Idle Timeouts are set via server config. - /// - public static SmartThreadPool Pool = new SmartThreadPool( - new STPStartInfo() - { - ThreadPoolName = "NetworkPool", - IdleTimeout = 20000, - MinWorkerThreads = Options.Instance.Processing.MinNetworkThreads, - MaxWorkerThreads = Options.Instance.Processing.MaxNetworkThreads - } - ); - - internal ServerNetwork( - IServerContext context, - IApplicationContext applicationContext, - NetworkConfiguration configuration, - RSAParameters rsaParameters - ) : base( - applicationContext, configuration - ) - { - Context = context ?? throw new ArgumentNullException(nameof(context)); - - Id = Guid.NewGuid(); - - var networkLayerInterface = new LidgrenInterface(this, typeof(NetServer), rsaParameters); - networkLayerInterface.OnConnected += HandleInterfaceOnConnected; - networkLayerInterface.OnConnectionApproved += HandleInterfaceOnConnectonApproved; - networkLayerInterface.OnDisconnected += HandleInterfaceOnDisconnected; - networkLayerInterface.OnUnconnectedMessage += HandleOnUnconnectedMessage; - networkLayerInterface.OnConnectionRequested += HandleConnectionRequested; - AddNetworkLayerInterface(networkLayerInterface); - } - - private IServerContext Context { get; } - - public override bool IsConnected => Connections.Any(); - - public override event HandleConnectionEvent OnConnected; - public override event HandleConnectionEvent OnConnectionApproved; - public override event HandleConnectionEvent OnConnectionDenied; - public override event HandleConnectionRequest OnConnectionRequested; - public override event HandleConnectionEvent OnDisconnected; - public override event HandlePacketAvailable OnPacketAvailable; - public override event HandleUnconnectedMessage OnUnconnectedMessage; - - public override void Close() => Disconnect("closing"); - - public bool Listen() - { - StartInterfaces(); - - return true; - } - - protected virtual void HandleInterfaceOnConnected( - INetworkLayerInterface sender, - ConnectionEventArgs connectionEventArgs - ) - { - Log.Info($"Connected [{connectionEventArgs.Connection?.Guid}]."); - var client =Client.CreateBeta4Client(Context, this, connectionEventArgs.Connection); - PacketSender.SendPing(client); - OnConnected?.Invoke(sender, connectionEventArgs); - } - - protected virtual void HandleInterfaceOnConnectonApproved( - INetworkLayerInterface sender, - ConnectionEventArgs connectionEventArgs - ) - { - Log.Info($"Connection approved [{connectionEventArgs.Connection?.Guid}]."); - OnConnectionApproved?.Invoke(sender, connectionEventArgs); - } - - protected virtual void HandleInterfaceOnDisconnected( - INetworkLayerInterface sender, - ConnectionEventArgs connectionEventArgs - ) - { - Log.Info($"Disconnected [{connectionEventArgs.Connection?.Guid}]."); - Client.RemoveBeta4Client(connectionEventArgs.Connection); - OnDisconnected?.Invoke(sender, connectionEventArgs); - } - - protected virtual void HandleOnUnconnectedMessage(UnconnectedMessageSender sender, IBuffer message) - { - try - { - var packetType = message.ReadString(); - switch (packetType) - { - case "status": - // TODO: Response buffers - // var response = peer.CreateMessage(); - // response.WriteVariableInt32(Player.OnlineCount); - // peer.SendUnconnectedMessage(response, message.SenderEndPoint); - break; - } - } -#if DIAGNOSTIC - catch (Exception exception) -#endif - catch - { -#if DIAGNOSTIC - Log.Diagnostic(exception); -#else - // ignored -#endif - } - } - - protected virtual bool HandleConnectionRequested(INetworkLayerInterface sender, IConnection connection) - { - if (string.IsNullOrEmpty(connection?.Ip)) - { - return false; - } - - return true; - } - - protected override bool SendUnconnected(IPEndPoint endPoint, UnconnectedPacket packet) - { - throw new NotImplementedException(); - } - - public override bool Send(IPacket packet, TransmissionMode mode = TransmissionMode.All) - { - return Send(Connections, packet, mode); - } - - public override bool Send(IConnection connection, IPacket packet, TransmissionMode mode = TransmissionMode.All) - { - return Send(new[] {connection}, packet, mode); - } - - public override bool Send(ICollection connections, IPacket packet, TransmissionMode mode = TransmissionMode.All) - { - SendPacket(packet, connections, mode); - - return true; - } - - protected override IDictionary CreateDictionaryLegacy() - { - return new ConcurrentDictionary(); - } - } -}