diff --git a/Transport/LiteNetLib Transport/LiteNetLibTransport.cs b/Transport/LiteNetLib Transport/LiteNetLibTransport.cs new file mode 100644 index 0000000..6c49769 --- /dev/null +++ b/Transport/LiteNetLib Transport/LiteNetLibTransport.cs @@ -0,0 +1,184 @@ +using LiteNetLib; +using LiteNetLib.Utils; +using System.Collections.Generic; +using UnityEngine; +using System.Net; +using System.Net.Sockets; +using System; +using Netick.Unity; + +namespace Netick.Transport +{ + public class LiteNetLibTransport : NetworkTransport, INetEventListener + { + public class LNLConnection : TransportConnection + { + public LiteNetLibTransport Transport; + public NetPeer LNLPeer; + public override IEndPoint EndPoint => LNLPeer.EndPoint.ToNetickEndPoint(); + public override int Mtu => LNLPeer.Mtu; + public LNLConnection(LiteNetLibTransport transport) + { + Transport = transport; + } + public unsafe override void Send(IntPtr ptr, int length) => LNLPeer.Send(new ReadOnlySpan(ptr.ToPointer(), length), DeliveryMethod.Unreliable); + public unsafe override void SendUserData(IntPtr ptr, int length, TransportDeliveryMethod method) => LNLPeer.Send(new ReadOnlySpan(ptr.ToPointer(), length), method == TransportDeliveryMethod.Unreliable ? DeliveryMethod.Unreliable : DeliveryMethod.ReliableOrdered); + } + + private LiteNetLibTransportProvider _provider; + private NetManager _netManager; + private NetDataWriter _writer = new NetDataWriter(); + private BitBuffer _buffer; + private byte[] _connectionBytes = new byte[200]; + private int _port; + private Dictionary _clients; + private Queue _freeClients; + + public LiteNetLibTransport(LiteNetLibTransportProvider provider) + { + this._provider = provider; + } + + public override void Init() + { + _clients = new(Engine.Config.MaxPlayers); + _freeClients = new(Engine.Config.MaxPlayers); + _buffer = new BitBuffer(createChunks: false); + _netManager = new NetManager(this) { AutoRecycle = true }; + _netManager.DisconnectTimeout = (int)(_provider.DisconnectTimeout * 1000); + _netManager.ReconnectDelay = (int)(_provider.ReconnectInterval * 1000); + _netManager.MaxConnectAttempts = _provider.MaxConnectAttempts; + _netManager.UpdateTime = (int)(_provider.UpdateInterval * 1000); + + for (int i = 0; i < Engine.Config.MaxPlayers; i++) + _freeClients.Enqueue(new LNLConnection(this)); + } + + public override void PollEvents() => _netManager.PollEvents(); + public override void ForceUpdate() => _netManager.TriggerUpdate(); + + public override void Run(RunMode mode, int port) + { + _port = port; + + if (mode == RunMode.Client) + { + _netManager.UnconnectedMessagesEnabled = true; + _netManager.Start(); + } + else + { + _netManager.BroadcastReceiveEnabled = true; + _netManager.Start(port); + } + } + + public override void Shutdown() + { + _netManager.Stop(); + } + + public override void Connect(string address, int port, byte[] connectionData, int connectionDataLen) + { + if (!_netManager.IsRunning) + _netManager.Start(); + + if (connectionData == null) + _netManager.Connect(address, port, ""); + else + { + _writer. Reset(); + _writer. Put(connectionData, 0, connectionDataLen); + _netManager.Connect(address, port, _writer); + } + } + + public override void Disconnect(TransportConnection connection) + { + _netManager.DisconnectPeer(((LNLConnection)connection).LNLPeer); + } + + void INetEventListener.OnConnectionRequest(ConnectionRequest request) + { + if (_clients.Count >= Engine.Config.MaxPlayers) + { + request.Reject(); + return; + } + + int len = request.Data.AvailableBytes; + request.Data.GetBytes(_connectionBytes, 0, len); + bool accepted = NetworkPeer.OnConnectRequest(_connectionBytes, len, request.RemoteEndPoint.ToNetickEndPoint()); + + if (accepted) + request.Accept(); + else + request.Reject(); + } + + void INetEventListener.OnPeerConnected(NetPeer peer) + { + var connection = _freeClients.Dequeue(); + connection.LNLPeer = peer; + _clients. Add(peer, connection); + NetworkPeer. OnConnected(connection); + } + + void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) + { + if (!Engine.IsServer) + { + if (disconnectInfo.Reason == DisconnectReason.ConnectionRejected) + { + NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); + return; + } + + if (disconnectInfo.Reason == DisconnectReason.ConnectionFailed || disconnectInfo.Reason == DisconnectReason.Timeout) + { + NetworkPeer.OnConnectFailed(ConnectionFailedReason.Timeout); + return; + } + + if (peer == null) + { + Debug.Log($"LiteNetLib Network Error: {disconnectInfo.Reason}"); + NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); + return; + } + } + + if (peer == null) + return; + + if (_clients.ContainsKey(peer)) + { + TransportDisconnectReason reason = disconnectInfo.Reason == DisconnectReason.Timeout ? TransportDisconnectReason.Timeout : TransportDisconnectReason.Shutdown; + NetworkPeer. OnDisconnected(_clients[peer], reason); + _freeClients.Enqueue(_clients[peer]); + _clients. Remove(peer); + } + } + + unsafe void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod) + { + if (!_clients.TryGetValue(peer, out var c)) + return; + + fixed (byte* ptr = reader.RawData) + { + _buffer. SetFrom(ptr + reader.Position, reader.AvailableBytes, reader.RawData.Length); + NetworkPeer.Receive(c, _buffer); + } + } + + void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketError) + { + Debug.Log("LiteNetLib Network Error: " + socketError); + NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); + } + + void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) { } + void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) { } + } +} \ No newline at end of file diff --git a/Transport/LiteNetLib Transport/LiteNetLibTransport.cs.meta b/Transport/LiteNetLib Transport/LiteNetLibTransport.cs.meta new file mode 100644 index 0000000..bca6f99 --- /dev/null +++ b/Transport/LiteNetLib Transport/LiteNetLibTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87355d66ed32e614fb51d94a663afc31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Transport/LiteNetLib Transport/LiteNetLibTransportProvider.cs b/Transport/LiteNetLib Transport/LiteNetLibTransportProvider.cs index c0ad5db..a949c8e 100644 --- a/Transport/LiteNetLib Transport/LiteNetLibTransportProvider.cs +++ b/Transport/LiteNetLib Transport/LiteNetLibTransportProvider.cs @@ -22,177 +22,4 @@ namespace Netick.Transport public float UpdateInterval = 0.015f; public override NetworkTransport MakeTransportInstance() => new LiteNetLibTransport(this); } - - public class LiteNetLibTransport : NetworkTransport, INetEventListener - { - public class LNLConnection : TransportConnection - { - public LiteNetLibTransport Transport; - public NetPeer LNLPeer; - public override IEndPoint EndPoint => LNLPeer.EndPoint.ToNetickEndPoint(); - public override int Mtu => LNLPeer.Mtu; - public LNLConnection(LiteNetLibTransport transport) - { - Transport = transport; - } - public unsafe override void Send(IntPtr ptr, int length) => LNLPeer.Send(new ReadOnlySpan(ptr.ToPointer(), length), DeliveryMethod.Unreliable); - public unsafe override void SendUserData(IntPtr ptr, int length, TransportDeliveryMethod method) => LNLPeer.Send(new ReadOnlySpan(ptr.ToPointer(), length), method == TransportDeliveryMethod.Unreliable ? DeliveryMethod.Unreliable : DeliveryMethod.ReliableOrdered); - } - - private LiteNetLibTransportProvider _provider; - private NetManager _netManager; - private NetDataWriter _writer = new NetDataWriter(); - private BitBuffer _buffer; - private byte[] _connectionBytes = new byte[200]; - private int _port; - private Dictionary _clients; - private Queue _freeClients; - - public LiteNetLibTransport(LiteNetLibTransportProvider provider) - { - this._provider = provider; - } - - public override void Init() - { - _clients = new(Engine.Config.MaxPlayers); - _freeClients = new(Engine.Config.MaxPlayers); - _buffer = new BitBuffer(createChunks: false); - _netManager = new NetManager(this) { AutoRecycle = true }; - _netManager.DisconnectTimeout = (int)(_provider.DisconnectTimeout * 1000); - _netManager.ReconnectDelay = (int)(_provider.ReconnectInterval * 1000); - _netManager.MaxConnectAttempts = _provider.MaxConnectAttempts; - _netManager.UpdateTime = (int)(_provider.UpdateInterval * 1000); - - for (int i = 0; i < Engine.Config.MaxPlayers; i++) - _freeClients.Enqueue(new LNLConnection(this)); - } - - public override void PollEvents() => _netManager.PollEvents(); - public override void ForceUpdate() => _netManager.TriggerUpdate(); - - public override void Run(RunMode mode, int port) - { - _port = port; - - if (mode == RunMode.Client) - { - _netManager.UnconnectedMessagesEnabled = true; - _netManager.Start(); - } - else - { - _netManager.BroadcastReceiveEnabled = true; - _netManager.Start(port); - } - } - - public override void Shutdown() - { - _netManager.Stop(); - } - - public override void Connect(string address, int port, byte[] connectionData, int connectionDataLen) - { - if (!_netManager.IsRunning) - _netManager.Start(); - - if (connectionData == null) - _netManager.Connect(address, port, ""); - else - { - _writer. Reset(); - _writer. Put(connectionData, 0, connectionDataLen); - _netManager.Connect(address, port, _writer); - } - } - - public override void Disconnect(TransportConnection connection) - { - _netManager.DisconnectPeer(((LNLConnection)connection).LNLPeer); - } - - void INetEventListener.OnConnectionRequest(ConnectionRequest request) - { - if (_clients.Count >= Engine.Config.MaxPlayers) - { - request.Reject(); - return; - } - - int len = request.Data.AvailableBytes; - request.Data.GetBytes(_connectionBytes, 0, len); - bool accepted = NetworkPeer.OnConnectRequest(_connectionBytes, len, request.RemoteEndPoint.ToNetickEndPoint()); - - if (accepted) - request.Accept(); - else - request.Reject(); - } - - void INetEventListener.OnPeerConnected(NetPeer peer) - { - var connection = _freeClients.Dequeue(); - connection.LNLPeer = peer; - _clients. Add(peer, connection); - NetworkPeer. OnConnected(connection); - } - - void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) - { - if (!Engine.IsServer) - { - if (disconnectInfo.Reason == DisconnectReason.ConnectionRejected) - { - NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); - return; - } - - if (disconnectInfo.Reason == DisconnectReason.ConnectionFailed || disconnectInfo.Reason == DisconnectReason.Timeout) - { - NetworkPeer.OnConnectFailed(ConnectionFailedReason.Timeout); - return; - } - - if (peer == null) - { - Debug.Log($"LiteNetLib Network Error: {disconnectInfo.Reason}"); - NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); - return; - } - } - - if (peer == null) - return; - - if (_clients.ContainsKey(peer)) - { - TransportDisconnectReason reason = disconnectInfo.Reason == DisconnectReason.Timeout ? TransportDisconnectReason.Timeout : TransportDisconnectReason.Shutdown; - NetworkPeer. OnDisconnected(_clients[peer], reason); - _freeClients.Enqueue(_clients[peer]); - _clients. Remove(peer); - } - } - - unsafe void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod) - { - if (!_clients.TryGetValue(peer, out var c)) - return; - - fixed (byte* ptr = reader.RawData) - { - _buffer. SetFrom(ptr + reader.Position, reader.AvailableBytes, reader.RawData.Length); - NetworkPeer.Receive(c, _buffer); - } - } - - void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketError) - { - Debug.Log("LiteNetLib Network Error: " + socketError); - NetworkPeer.OnConnectFailed(ConnectionFailedReason.Refused); - } - - void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) { } - void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) { } - } } \ No newline at end of file