Initial Commit

This commit is contained in:
Sebastian Cabrera 2021-08-02 05:44:37 -04:00
parent 53eb92e9af
commit 270ab7d11f
15341 changed files with 700234 additions and 0 deletions

View file

@ -0,0 +1,8 @@
namespace MLAPI.Transports.UNET
{
public static class ProfilerConstants
{
public const string NumberOfTransportSends = nameof(NumberOfTransportSends);
public const string NumberOfTransportSendQueues = nameof(NumberOfTransportSendQueues);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5bc85b7565054d6295b7847967cdbd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,442 @@
#pragma warning disable 618
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Net;
using UnityEngine;
using UnityEngine.Networking;
namespace MLAPI.Transports.UNET
{
public static class RelayTransport
{
private enum MessageType
{
StartServer,
ConnectToServer,
Data,
ClientDisconnect,
AddressReport
}
private static byte s_DefaultChannelId;
private static int s_RelayConnectionId;
private static bool s_IsClient = false;
private static string s_Address;
private static ushort s_Port;
private static List<ChannelQOS> s_Channels = new List<ChannelQOS>();
public static bool Enabled { get; set; } = true;
public static string RelayAddress { get; set; } = "127.0.0.1";
public static ushort RelayPort { get; set; } = 8888;
public static event Action<IPEndPoint> OnRemoteEndpointReported;
public static int Connect(int hostId, string serverAddress, int serverPort, int exceptionConnectionId, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.Connect(hostId, serverAddress, serverPort, exceptionConnectionId, out error);
s_IsClient = true;
s_Address = serverAddress;
s_Port = (ushort)serverPort;
s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error); // Requests connection
return s_RelayConnectionId;
}
public static int ConnectWithSimulator(int hostId, string serverAddress, int serverPort, int exceptionConnectionId, out byte error, ConnectionSimulatorConfig conf)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.ConnectWithSimulator(hostId, serverAddress, serverPort, exceptionConnectionId, out error, conf);
s_IsClient = true;
s_Address = serverAddress;
s_Port = (ushort)serverPort;
s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.ConnectWithSimulator(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error, conf); // Requests connection
return s_RelayConnectionId;
}
public static int ConnectEndPoint(int hostId, EndPoint endPoint, int exceptionConnectionId, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.ConnectEndPoint(hostId, endPoint, exceptionConnectionId, out error);
s_IsClient = true;
s_Address = ((IPEndPoint)endPoint).Address.ToString();
s_Port = (ushort)((IPEndPoint)endPoint).Port;
s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error); // Requests connection
return s_RelayConnectionId;
}
private static void SetChannelsFromTopology(HostTopology topology) => s_Channels = topology.DefaultConfig.Channels;
public static int AddHost(HostTopology topology, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHost(topology, 0, null);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHost(topology, 0, null);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHost(HostTopology topology, int port, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHost(topology, port);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHost(topology, port);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHost(HostTopology topology, int port, string ip, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHost(topology, port, ip);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHost(topology, port, ip);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHostWithSimulator(HostTopology topology, int minTimeout, int maxTimeout, int port, string ip, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port, ip);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHostWithSimulator(HostTopology topology, int minTimeout, int maxTimeout, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHostWithSimulator(HostTopology topology, int minTimeout, int maxTimeout, int port, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port);
s_IsClient = !createServer;
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddWebsocketHost(HostTopology topology, int port, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddWebsocketHost(topology, port);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddWebsocketHost(topology, port);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddWebsocketHost(HostTopology topology, int port, string ip, bool createServer)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.AddWebsocketHost(topology, port, ip);
s_IsClient = !createServer;
s_DefaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = UnityEngine.Networking.NetworkTransport.AddWebsocketHost(topology, port, ip);
if (createServer) s_RelayConnectionId = UnityEngine.Networking.NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
private static readonly byte[] disconnectBuffer = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, (byte)MessageType.ClientDisconnect };
public static bool Disconnect(int hostId, int connectionId, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.Disconnect(hostId, connectionId, out error);
if (!s_IsClient)
{
for (byte i = 0; i < sizeof(ulong); i++) disconnectBuffer[i] = ((byte)((ulong)connectionId >> (i * 8)));
return UnityEngine.Networking.NetworkTransport.Send(hostId, s_RelayConnectionId, s_DefaultChannelId, disconnectBuffer, 9, out error);
}
return UnityEngine.Networking.NetworkTransport.Disconnect(hostId, connectionId, out error);
}
public static bool Send(int hostId, int connectionId, int channelId, byte[] buffer, int size, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.Send(hostId, connectionId, channelId, buffer, size, out error);
++size;
if (!s_IsClient)
{
size += 8;
int connectionIdOffset = size - 9;
for (byte i = 0; i < sizeof(ulong); i++) buffer[connectionIdOffset + i] = ((byte)((ulong)connectionId >> (i * 8)));
}
buffer[size - 1] = (byte)MessageType.Data;
return UnityEngine.Networking.NetworkTransport.Send(hostId, s_RelayConnectionId, channelId, buffer, size, out error);
}
public static bool QueueMessageForSending(int hostId, int connectionId, int channelId, byte[] buffer, int size, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.QueueMessageForSending(hostId, connectionId, channelId, buffer, size, out error);
++size;
if (!s_IsClient)
{
size += 8;
int connectionIdOffset = size - 9;
for (byte i = 0; i < sizeof(ulong); i++) buffer[connectionIdOffset + i] = ((byte)((ulong)connectionId >> (i * 8)));
}
buffer[size - 1] = (byte)MessageType.Data;
return UnityEngine.Networking.NetworkTransport.QueueMessageForSending(hostId, s_RelayConnectionId, channelId, buffer, size, out error);
}
public static bool SendQueuedMessages(int hostId, int connectionId, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.SendQueuedMessages(hostId, connectionId, out error);
return UnityEngine.Networking.NetworkTransport.SendQueuedMessages(hostId, s_RelayConnectionId, out error);
}
public static NetworkEventType ReceiveFromHost(int hostId, out int connectionId, out int channelId, byte[] buffer, int bufferSize, out int receivedSize, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.ReceiveFromHost(hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
var eventType = UnityEngine.Networking.NetworkTransport.ReceiveFromHost(hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
return BaseReceive(eventType, hostId, ref connectionId, ref channelId, buffer, bufferSize, ref receivedSize, ref error);
}
public static NetworkEventType Receive(out int hostId, out int connectionId, out int channelId, byte[] buffer, int bufferSize, out int receivedSize, out byte error)
{
if (!Enabled) return UnityEngine.Networking.NetworkTransport.Receive(out hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
var eventType = UnityEngine.Networking.NetworkTransport.Receive(out hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
return BaseReceive(eventType, hostId, ref connectionId, ref channelId, buffer, bufferSize, ref receivedSize, ref error);
}
private static NetworkEventType BaseReceive(NetworkEventType netEvent, int hostId, ref int connectionId, ref int channelId, byte[] buffer, int bufferSize, ref int receivedSize, ref byte error)
{
switch (netEvent)
{
case NetworkEventType.DataEvent:
{
var messageType = (MessageType)buffer[receivedSize - 1];
switch (messageType)
{
case MessageType.AddressReport:
{
byte[] addressBytes = new byte[16];
for (int i = 0; i < addressBytes.Length; i++)
{
addressBytes[i] = buffer[i];
}
ushort remotePort = (ushort)(((ushort)buffer[16]) |
((ushort)buffer[17] << 8));
var remoteEndPoint = new IPEndPoint(new IPAddress(addressBytes), remotePort);
OnRemoteEndpointReported?.Invoke(remoteEndPoint);
break;
}
case MessageType.ConnectToServer: // Connection approved
{
if (!s_IsClient)
{
ulong _connectionId = (((ulong)buffer[receivedSize - 9]) |
((ulong)buffer[receivedSize - 8] << 8) |
((ulong)buffer[receivedSize - 7] << 16) |
((ulong)buffer[receivedSize - 6] << 24) |
((ulong)buffer[receivedSize - 5] << 32) |
((ulong)buffer[receivedSize - 4] << 40) |
((ulong)buffer[receivedSize - 3] << 48) |
((ulong)buffer[receivedSize - 2] << 56));
connectionId = (int)_connectionId;
}
return NetworkEventType.ConnectEvent;
}
case MessageType.Data:
{
// Implicitly remove header
if (s_IsClient) --receivedSize;
else
{
receivedSize -= 9;
ulong _connectionId = (((ulong)buffer[receivedSize]) |
((ulong)buffer[receivedSize + 1] << 8) |
((ulong)buffer[receivedSize + 2] << 16) |
((ulong)buffer[receivedSize + 3] << 24) |
((ulong)buffer[receivedSize + 4] << 32) |
((ulong)buffer[receivedSize + 5] << 40) |
((ulong)buffer[receivedSize + 6] << 48) |
((ulong)buffer[receivedSize + 7] << 56));
connectionId = (int)_connectionId;
}
return NetworkEventType.DataEvent;
}
case MessageType.ClientDisconnect:
{
ulong _connectionId = (((ulong)buffer[0]) |
((ulong)buffer[1] << 8) |
((ulong)buffer[2] << 16) |
((ulong)buffer[3] << 24) |
((ulong)buffer[4] << 32) |
((ulong)buffer[5] << 40) |
((ulong)buffer[6] << 48) |
((ulong)buffer[7] << 56));
connectionId = (int)_connectionId;
return NetworkEventType.DisconnectEvent;
}
}
}
break;
case NetworkEventType.ConnectEvent:
{
if (s_IsClient)
{
//Connect via relay
byte[] ipv6AddressBuffer;
var ipAddress = IPAddress.Parse(s_Address);
if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
ipv6AddressBuffer = ipAddress.GetAddressBytes();
}
else if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
byte[] ipv4Address = ipAddress.GetAddressBytes();
ipv6AddressBuffer = new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, ipv4Address[0], ipv4Address[1], ipv4Address[2], ipv4Address[3] };
}
else
{
// TODO: Throw wrong type
ipv6AddressBuffer = null;
}
// TODO: Throw if address is not 16 bytes. It should always be
for (int i = 0; i < ipv6AddressBuffer.Length; i++) buffer[i] = ipv6AddressBuffer[i];
for (byte i = 0; i < sizeof(ushort); i++) buffer[16 + i] = ((byte)(s_Port >> (i * 8)));
buffer[16 + 2] = (byte)MessageType.ConnectToServer;
UnityEngine.Networking.NetworkTransport.Send(hostId, connectionId, s_DefaultChannelId, buffer, 16 + 2 + 1, out error);
}
else
{
//Register us as a server
buffer[0] = (byte)MessageType.StartServer;
UnityEngine.Networking.NetworkTransport.Send(hostId, connectionId, s_DefaultChannelId, buffer, 1, out error);
}
return NetworkEventType.Nothing; // Connect event is ignored
}
case NetworkEventType.DisconnectEvent:
{
if ((NetworkError)error == NetworkError.CRCMismatch) Debug.LogError("[MLAPI.Relay] The MLAPI Relay detected a CRC mismatch. This could be due to the maxClients or other connectionConfig settings not being the same");
return NetworkEventType.DisconnectEvent;
}
}
return netEvent;
}
}
public class InvalidConfigException : SystemException
{
public InvalidConfigException() { }
public InvalidConfigException(string issue) : base(issue) { }
}
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
#pragma warning restore 618

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11544f78e46198d4cb39bfb970a357aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,22 @@
using System;
using UnityEngine.Networking;
namespace MLAPI.Transports
{
/// <summary>
/// A transport channel used by the MLAPI
/// </summary>
[Serializable]
public class UNetChannel
{
/// <summary>
/// The name of the channel
/// </summary>
public NetworkChannel Id;
/// <summary>
/// The type of channel
/// </summary>
public QosType Type;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e864534da30ef604992c0ed33c75d3c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,475 @@
#pragma warning disable 618
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using MLAPI.Exceptions;
using MLAPI.Logging;
using MLAPI.Profiling;
using MLAPI.Transports.Tasks;
using UnityEngine.Networking;
namespace MLAPI.Transports.UNET
{
public class UNetTransport : NetworkTransport, ITransportProfilerData
{
public enum SendMode
{
Immediately,
Queued
}
private static ProfilingDataStore s_TransportProfilerData = new ProfilingDataStore();
public static bool ProfilerEnabled;
// Inspector / settings
public int MessageBufferSize = 1024 * 5;
public int MaxConnections = 100;
public int MaxSentMessageQueueSize = 128;
public string ConnectAddress = "127.0.0.1";
public int ConnectPort = 7777;
public int ServerListenPort = 7777;
public int ServerWebsocketListenPort = 8887;
public bool SupportWebsocket = false;
// user-definable channels. To add your own channel, do something of the form:
// #define MY_CHANNEL 0
// ...
// transport.Channels.Add(
// new UNetChannel()
// {
// Id = Channel.ChannelUnused + MY_CHANNEL, <<-- must offset from reserved channel offset in MLAPI SDK
// Type = QosType.Unreliable
// }
// );
public List<UNetChannel> Channels = new List<UNetChannel>();
// Relay
public bool UseMLAPIRelay = false;
public string MLAPIRelayAddress = "184.72.104.138";
public int MLAPIRelayPort = 8888;
public SendMode MessageSendMode = SendMode.Immediately;
// Runtime / state
private byte[] m_MessageBuffer;
private WeakReference m_TemporaryBufferReference;
// Lookup / translation
private readonly Dictionary<NetworkChannel, int> m_ChannelNameToId = new Dictionary<NetworkChannel, int>();
private readonly Dictionary<int, NetworkChannel> m_ChannelIdToName = new Dictionary<int, NetworkChannel>();
private int m_ServerConnectionId;
private int m_ServerHostId;
private SocketTask m_ConnectTask;
public override ulong ServerClientId => GetMLAPIClientId(0, 0, true);
protected void LateUpdate()
{
if (UnityEngine.Networking.NetworkTransport.IsStarted && MessageSendMode == SendMode.Queued)
{
if (NetworkManager.Singleton.IsServer)
{
for (int i = 0; i < NetworkManager.Singleton.ConnectedClientsList.Count; i++)
{
SendQueued(NetworkManager.Singleton.ConnectedClientsList[i].ClientId);
}
}
else
{
SendQueued(NetworkManager.Singleton.LocalClientId);
}
}
}
public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChannel networkChannel)
{
if (ProfilerEnabled)
{
s_TransportProfilerData.Increment(ProfilerConstants.NumberOfTransportSends);
}
GetUNetConnectionDetails(clientId, out byte hostId, out ushort connectionId);
int channelId = 0;
if (m_ChannelNameToId.ContainsKey(networkChannel))
{
channelId = m_ChannelNameToId[networkChannel];
}
else
{
channelId = m_ChannelNameToId[NetworkChannel.Internal];
}
byte[] buffer;
if (data.Offset > 0)
{
// UNET cant handle this, do a copy
if (m_MessageBuffer.Length >= data.Count)
{
buffer = m_MessageBuffer;
}
else
{
object bufferRef = null;
if (m_TemporaryBufferReference != null && ((bufferRef = m_TemporaryBufferReference.Target) != null) && ((byte[])bufferRef).Length >= data.Count)
{
buffer = (byte[])bufferRef;
}
else
{
buffer = new byte[data.Count];
m_TemporaryBufferReference = new WeakReference(buffer);
}
}
Buffer.BlockCopy(data.Array, data.Offset, buffer, 0, data.Count);
}
else
{
buffer = data.Array;
}
if (MessageSendMode == SendMode.Queued)
{
RelayTransport.QueueMessageForSending(hostId, connectionId, channelId, buffer, data.Count, out byte error);
}
else
{
RelayTransport.Send(hostId, connectionId, channelId, buffer, data.Count, out byte error);
}
}
public void SendQueued(ulong clientId)
{
if (ProfilerEnabled)
{
s_TransportProfilerData.Increment(ProfilerConstants.NumberOfTransportSendQueues);
}
GetUNetConnectionDetails(clientId, out byte hostId, out ushort connectionId);
RelayTransport.SendQueuedMessages(hostId, connectionId, out byte error);
}
public override NetworkEvent PollEvent(out ulong clientId, out NetworkChannel networkChannel, out ArraySegment<byte> payload, out float receiveTime)
{
var eventType = RelayTransport.Receive(out int hostId, out int connectionId, out int channelId, m_MessageBuffer, m_MessageBuffer.Length, out int receivedSize, out byte error);
clientId = GetMLAPIClientId((byte)hostId, (ushort)connectionId, false);
receiveTime = UnityEngine.Time.realtimeSinceStartup;
var networkError = (NetworkError)error;
if (networkError == NetworkError.MessageToLong)
{
byte[] tempBuffer;
if (m_TemporaryBufferReference != null && m_TemporaryBufferReference.IsAlive && ((byte[])m_TemporaryBufferReference.Target).Length >= receivedSize)
{
tempBuffer = (byte[])m_TemporaryBufferReference.Target;
}
else
{
tempBuffer = new byte[receivedSize];
m_TemporaryBufferReference = new WeakReference(tempBuffer);
}
eventType = RelayTransport.Receive(out hostId, out connectionId, out channelId, tempBuffer, tempBuffer.Length, out receivedSize, out error);
payload = new ArraySegment<byte>(tempBuffer, 0, receivedSize);
}
else
{
payload = new ArraySegment<byte>(m_MessageBuffer, 0, receivedSize);
}
if (m_ChannelIdToName.ContainsKey(channelId))
{
networkChannel = m_ChannelIdToName[channelId];
}
else
{
networkChannel = NetworkChannel.Internal;
}
if (m_ConnectTask != null && hostId == m_ServerHostId && connectionId == m_ServerConnectionId)
{
if (eventType == NetworkEventType.ConnectEvent)
{
// We just got a response to our connect request.
m_ConnectTask.Message = null;
m_ConnectTask.SocketError = networkError == NetworkError.Ok ? System.Net.Sockets.SocketError.Success : System.Net.Sockets.SocketError.SocketError;
m_ConnectTask.State = null;
m_ConnectTask.Success = networkError == NetworkError.Ok;
m_ConnectTask.TransportCode = (byte)networkError;
m_ConnectTask.TransportException = null;
m_ConnectTask.IsDone = true;
m_ConnectTask = null;
}
else if (eventType == NetworkEventType.DisconnectEvent)
{
// We just got a response to our connect request.
m_ConnectTask.Message = null;
m_ConnectTask.SocketError = System.Net.Sockets.SocketError.SocketError;
m_ConnectTask.State = null;
m_ConnectTask.Success = false;
m_ConnectTask.TransportCode = (byte)networkError;
m_ConnectTask.TransportException = null;
m_ConnectTask.IsDone = true;
m_ConnectTask = null;
}
}
if (networkError == NetworkError.Timeout)
{
// In UNET. Timeouts are not disconnects. We have to translate that here.
eventType = NetworkEventType.DisconnectEvent;
}
// Translate NetworkEventType to NetEventType
switch (eventType)
{
case NetworkEventType.DataEvent:
return NetworkEvent.Data;
case NetworkEventType.ConnectEvent:
return NetworkEvent.Connect;
case NetworkEventType.DisconnectEvent:
return NetworkEvent.Disconnect;
case NetworkEventType.Nothing:
return NetworkEvent.Nothing;
case NetworkEventType.BroadcastEvent:
return NetworkEvent.Nothing;
}
return NetworkEvent.Nothing;
}
public override SocketTasks StartClient()
{
var socketTask = SocketTask.Working;
m_ServerHostId = RelayTransport.AddHost(new HostTopology(GetConfig(), 1), false);
m_ServerConnectionId = RelayTransport.Connect(m_ServerHostId, ConnectAddress, ConnectPort, 0, out byte error);
var connectError = (NetworkError)error;
switch (connectError)
{
case NetworkError.Ok:
socketTask.Success = true;
socketTask.TransportCode = error;
socketTask.SocketError = System.Net.Sockets.SocketError.Success;
socketTask.IsDone = false;
// We want to continue to wait for the successful connect
m_ConnectTask = socketTask;
break;
default:
socketTask.Success = false;
socketTask.TransportCode = error;
socketTask.SocketError = System.Net.Sockets.SocketError.SocketError;
socketTask.IsDone = true;
break;
}
return socketTask.AsTasks();
}
public override SocketTasks StartServer()
{
var topology = new HostTopology(GetConfig(), MaxConnections);
if (SupportWebsocket)
{
if (!UseMLAPIRelay)
{
int websocketHostId = UnityEngine.Networking.NetworkTransport.AddWebsocketHost(topology, ServerWebsocketListenPort);
}
else
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error) NetworkLog.LogError("Cannot create websocket host when using MLAPI relay");
}
}
int normalHostId = RelayTransport.AddHost(topology, ServerListenPort, true);
return SocketTask.Done.AsTasks();
}
public override void DisconnectRemoteClient(ulong clientId)
{
GetUNetConnectionDetails(clientId, out byte hostId, out ushort connectionId);
RelayTransport.Disconnect((int)hostId, (int)connectionId, out byte error);
}
public override void DisconnectLocalClient()
{
RelayTransport.Disconnect(m_ServerHostId, m_ServerConnectionId, out byte error);
}
public override ulong GetCurrentRtt(ulong clientId)
{
GetUNetConnectionDetails(clientId, out byte hostId, out ushort connectionId);
if (UseMLAPIRelay)
{
return 0;
}
else
{
return (ulong)UnityEngine.Networking.NetworkTransport.GetCurrentRTT((int)hostId, (int)connectionId, out byte error);
}
}
public override void Shutdown()
{
m_ChannelIdToName.Clear();
m_ChannelNameToId.Clear();
UnityEngine.Networking.NetworkTransport.Shutdown();
}
public override void Init()
{
UpdateRelay();
m_MessageBuffer = new byte[MessageBufferSize];
s_TransportProfilerData.Clear();
UnityEngine.Networking.NetworkTransport.Init();
}
public ulong GetMLAPIClientId(byte hostId, ushort connectionId, bool isServer)
{
if (isServer)
{
return 0;
}
else
{
return ((ulong)connectionId | (ulong)hostId << 16) + 1;
}
}
public void GetUNetConnectionDetails(ulong clientId, out byte hostId, out ushort connectionId)
{
if (clientId == 0)
{
hostId = (byte)m_ServerHostId;
connectionId = (ushort)m_ServerConnectionId;
}
else
{
hostId = (byte)((clientId - 1) >> 16);
connectionId = (ushort)((clientId - 1));
}
}
public ConnectionConfig GetConfig()
{
var connectionConfig = new ConnectionConfig();
// MLAPI built-in channels
for (int i = 0; i < MLAPI_CHANNELS.Length; i++)
{
int channelId = AddMLAPIChannel(MLAPI_CHANNELS[i].Delivery, connectionConfig);
m_ChannelIdToName.Add(channelId, MLAPI_CHANNELS[i].Channel);
m_ChannelNameToId.Add(MLAPI_CHANNELS[i].Channel, channelId);
}
// Custom user-added channels
for (int i = 0; i < Channels.Count; i++)
{
int channelId = AddUNETChannel(Channels[i].Type, connectionConfig);
if (m_ChannelNameToId.ContainsKey(Channels[i].Id))
{
throw new InvalidChannelException($"Channel {channelId} already exists");
}
m_ChannelIdToName.Add(channelId, Channels[i].Id);
m_ChannelNameToId.Add(Channels[i].Id, channelId);
}
connectionConfig.MaxSentMessageQueueSize = (ushort)MaxSentMessageQueueSize;
return connectionConfig;
}
public int AddMLAPIChannel(NetworkDelivery type, ConnectionConfig config)
{
switch (type)
{
case NetworkDelivery.Unreliable:
return config.AddChannel(QosType.Unreliable);
case NetworkDelivery.Reliable:
return config.AddChannel(QosType.Reliable);
case NetworkDelivery.ReliableSequenced:
return config.AddChannel(QosType.ReliableSequenced);
case NetworkDelivery.ReliableFragmentedSequenced:
return config.AddChannel(QosType.ReliableFragmentedSequenced);
case NetworkDelivery.UnreliableSequenced:
return config.AddChannel(QosType.UnreliableSequenced);
}
return 0;
}
public int AddUNETChannel(QosType type, ConnectionConfig config)
{
switch (type)
{
case QosType.Unreliable:
return config.AddChannel(QosType.Unreliable);
case QosType.UnreliableFragmented:
return config.AddChannel(QosType.UnreliableFragmented);
case QosType.UnreliableSequenced:
return config.AddChannel(QosType.UnreliableSequenced);
case QosType.Reliable:
return config.AddChannel(QosType.Reliable);
case QosType.ReliableFragmented:
return config.AddChannel(QosType.ReliableFragmented);
case QosType.ReliableSequenced:
return config.AddChannel(QosType.ReliableSequenced);
case QosType.StateUpdate:
return config.AddChannel(QosType.StateUpdate);
case QosType.ReliableStateUpdate:
return config.AddChannel(QosType.ReliableStateUpdate);
case QosType.AllCostDelivery:
return config.AddChannel(QosType.AllCostDelivery);
case QosType.UnreliableFragmentedSequenced:
return config.AddChannel(QosType.UnreliableFragmentedSequenced);
case QosType.ReliableFragmentedSequenced:
return config.AddChannel(QosType.ReliableFragmentedSequenced);
}
return 0;
}
private void UpdateRelay()
{
RelayTransport.Enabled = UseMLAPIRelay;
RelayTransport.RelayAddress = MLAPIRelayAddress;
RelayTransport.RelayPort = (ushort)MLAPIRelayPort;
}
public void BeginNewTick()
{
s_TransportProfilerData.Clear();
}
public IReadOnlyDictionary<string, int> GetTransportProfilerData()
{
return s_TransportProfilerData.GetReadonly();
}
}
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
#pragma warning restore 618

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b84c2d8dfe509a34fb59e2b81f8e1319
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: