Added the files for the MLAPI Relay Server

- This version of the server is modified from the other open sourced one
  on GitHub as we ignore the port when attempting to connect.
  Program.cs is modified as such
This commit is contained in:
2022-02-17 14:13:58 -06:00
parent 011ba5cba1
commit 9aa31d9cd7
285 changed files with 14612 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015, Unity Technologies
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,430 @@
using System;
using System.Collections.Generic;
using System.Net;
using UnityEngine;
using UnityEngine.Networking;
namespace MLAPI.Relay.Transports
{
public static class UnetRelayTransport
{
private enum MessageType
{
StartServer,
ConnectToServer,
Data,
ClientDisconnect,
AddressReport
}
private static byte defaultChannelId;
private static int relayConnectionId;
private static bool isClient = false;
private static string address;
private static ushort port;
private static List<ChannelQOS> 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 NetworkTransport.Connect(hostId, serverAddress, serverPort, exceptionConnectionId, out error);
isClient = true;
UnetRelayTransport.address = serverAddress;
UnetRelayTransport.port = (ushort)serverPort;
relayConnectionId = NetworkTransport.Connect(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error); // Requests connection
return relayConnectionId;
}
public static int ConnectWithSimulator(int hostId, string serverAddress, int serverPort, int exceptionConnectionId, out byte error, ConnectionSimulatorConfig conf)
{
if (!Enabled) return NetworkTransport.ConnectWithSimulator(hostId, serverAddress, serverPort, exceptionConnectionId, out error, conf);
isClient = true;
UnetRelayTransport.address = serverAddress;
UnetRelayTransport.port = (ushort)serverPort;
relayConnectionId = NetworkTransport.ConnectWithSimulator(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error, conf); // Requests connection
return relayConnectionId;
}
public static int ConnectEndPoint(int hostId, EndPoint endPoint, int exceptionConnectionId, out byte error)
{
if (!Enabled) return NetworkTransport.ConnectEndPoint(hostId, endPoint, exceptionConnectionId, out error);
isClient = true;
UnetRelayTransport.address = ((IPEndPoint)endPoint).Address.ToString();
UnetRelayTransport.port = (ushort)((IPEndPoint)endPoint).Port;
relayConnectionId = NetworkTransport.Connect(hostId, RelayAddress, RelayPort, exceptionConnectionId, out error); // Requests connection
return relayConnectionId;
}
private static void SetChannelsFromTopology(HostTopology topology) => channels = topology.DefaultConfig.Channels;
public static int AddHost(HostTopology topology, bool createServer)
{
if (!Enabled) return NetworkTransport.AddHost(topology);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHost(topology);
if (createServer) relayConnectionId = NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddHost(HostTopology topology, int port, bool createServer)
{
if (!Enabled) return NetworkTransport.AddHost(topology, port);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHost(topology, port);
if (createServer) relayConnectionId = 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 NetworkTransport.AddHost(topology, port, ip);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHost(topology, port, ip);
if (createServer) relayConnectionId = 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 NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port, ip);
if (createServer) relayConnectionId = 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 NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout);
if (createServer) relayConnectionId = 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 NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port);
isClient = !createServer;
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddHostWithSimulator(topology, minTimeout, maxTimeout, port);
if (createServer) relayConnectionId = NetworkTransport.Connect(ret, RelayAddress, RelayPort, 0, out byte b);
return ret;
}
public static int AddWebsocketHost(HostTopology topology, int port, bool createServer)
{
if (!Enabled) return NetworkTransport.AddWebsocketHost(topology, port);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddWebsocketHost(topology, port);
if (createServer) relayConnectionId = 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 NetworkTransport.AddWebsocketHost(topology, port, ip);
isClient = !createServer;
defaultChannelId = topology.DefaultConfig.AddChannel(QosType.ReliableSequenced);
SetChannelsFromTopology(topology);
int ret = NetworkTransport.AddWebsocketHost(topology, port, ip);
if (createServer) relayConnectionId = 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 NetworkTransport.Disconnect(hostId, connectionId, out error);
if (!isClient)
{
for (byte i = 0; i < sizeof(ulong); i++) disconnectBuffer[i] = ((byte)((ulong)connectionId >> (i * 8)));
return NetworkTransport.Send(hostId, relayConnectionId, defaultChannelId, disconnectBuffer, 9, out error);
}
return 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 NetworkTransport.Send(hostId, connectionId, channelId, buffer, size, out error);
++size;
if (!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 NetworkTransport.Send(hostId, 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 NetworkTransport.QueueMessageForSending(hostId, connectionId, channelId, buffer, size, out error);
++size;
if (!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 NetworkTransport.QueueMessageForSending(hostId, relayConnectionId, channelId, buffer, size, out error);
}
public static bool SendQueuedMessages(int hostId, int connectionId, out byte error)
{
if (!Enabled) return NetworkTransport.SendQueuedMessages(hostId, connectionId, out error);
return NetworkTransport.SendQueuedMessages(hostId, 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 NetworkTransport.ReceiveFromHost(hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
NetworkEventType @event = NetworkTransport.ReceiveFromHost(hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
return BaseReceive(@event, 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 NetworkTransport.Receive(out hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
NetworkEventType @event = NetworkTransport.Receive(out hostId, out connectionId, out channelId, buffer, bufferSize, out receivedSize, out error);
return BaseReceive(@event, hostId, ref connectionId, ref channelId, buffer, bufferSize, ref receivedSize, ref error);
}
private static NetworkEventType BaseReceive(NetworkEventType @event, int hostId, ref int connectionId, ref int channelId, byte[] buffer, int bufferSize, ref int receivedSize, ref byte error)
{
switch (@event)
{
case NetworkEventType.DataEvent:
{
MessageType 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));
IPEndPoint remoteEndPoint = new IPEndPoint(new IPAddress(addressBytes), remotePort);
OnRemoteEndpointReported(remoteEndPoint);
break;
}
case MessageType.ConnectToServer: // Connection approved
{
if (!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 (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 (isClient)
{
//Connect via relay
byte[] ipv6AddressBuffer;
IPAddress ipAddress = IPAddress.Parse(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)(port >> (i * 8)));
buffer[16 + 2] = (byte)MessageType.ConnectToServer;
NetworkTransport.Send(hostId, connectionId, defaultChannelId, buffer, 16 + 2 + 1, out error);
}
else
{
//Register us as a server
buffer[0] = (byte)MessageType.StartServer;
NetworkTransport.Send(hostId, connectionId, 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 @event;
}
}
public class InvalidConfigException : SystemException
{
public InvalidConfigException() { }
public InvalidConfigException(string issue) : base(issue) { }
}
}

View File

@@ -0,0 +1,53 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v2.2",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v2.2": {
"MLAPI.Relay.Transports/1.0.0": {
"dependencies": {
"UnityEditor": "0.0.0.0",
"UnityEngine": "0.0.0.0"
},
"runtime": {
"MLAPI.Relay.Transports.dll": {}
}
},
"UnityEditor/0.0.0.0": {
"runtime": {
"UnityEditor.dll": {
"assemblyVersion": "0.0.0.0",
"fileVersion": "0.0.0.0"
}
}
},
"UnityEngine/0.0.0.0": {
"runtime": {
"UnityEngine.dll": {
"assemblyVersion": "0.0.0.0",
"fileVersion": "0.0.0.0"
}
}
}
}
},
"libraries": {
"MLAPI.Relay.Transports/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"UnityEditor/0.0.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"UnityEngine/0.0.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
}
}
}

Some files were not shown because too many files have changed in this diff Show More