mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: Unity LLAPI transport meets the recycle bin. (#2484)
This commit is contained in:
parent
adabbdc552
commit
798a4cab33
@ -37,7 +37,8 @@ public static void AddDefineSymbols()
|
|||||||
"MIRROR_26_0_OR_NEWER",
|
"MIRROR_26_0_OR_NEWER",
|
||||||
"MIRROR_27_0_OR_NEWER",
|
"MIRROR_27_0_OR_NEWER",
|
||||||
"MIRROR_28_0_OR_NEWER",
|
"MIRROR_28_0_OR_NEWER",
|
||||||
"MIRROR_29_0_OR_NEWER"
|
"MIRROR_29_0_OR_NEWER",
|
||||||
|
"MIRROR_30_0_OR_NEWER"
|
||||||
};
|
};
|
||||||
|
|
||||||
// only touch PlayerSettings if we actually modified it.
|
// only touch PlayerSettings if we actually modified it.
|
||||||
|
@ -1,384 +0,0 @@
|
|||||||
// Coburn: LLAPI is not available on UWP. There are a lot of compile directives here that we're checking against.
|
|
||||||
// Checking all of them may be overkill, but it's better to cover all the possible UWP directives. Sourced from
|
|
||||||
// https://docs.unity3d.com/Manual/PlatformDependentCompilation.html
|
|
||||||
// TODO: Check if LLAPI is supported on Xbox One?
|
|
||||||
|
|
||||||
// LLAPITransport wraps UNET's LLAPI for use as a HLAPI TransportLayer, only if you're not on a UWP platform.
|
|
||||||
#if !(UNITY_WSA || UNITY_WSA_10_0 || UNITY_WINRT || UNITY_WINRT_10_0 || NETFX_CORE)
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Net;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Networking;
|
|
||||||
using UnityEngine.Networking.Types;
|
|
||||||
|
|
||||||
namespace Mirror
|
|
||||||
{
|
|
||||||
[Obsolete("LLAPI is obsolete and will be removed from future versions of Unity")]
|
|
||||||
public class LLAPITransport : Transport
|
|
||||||
{
|
|
||||||
public const string Scheme = "unet";
|
|
||||||
|
|
||||||
public ushort port = 7777;
|
|
||||||
|
|
||||||
[Tooltip("Enable for WebGL games. Can only do either WebSockets or regular Sockets, not both (yet).")]
|
|
||||||
public bool useWebsockets;
|
|
||||||
|
|
||||||
// settings copied from uMMORPG configuration for best results
|
|
||||||
public ConnectionConfig connectionConfig = new ConnectionConfig
|
|
||||||
{
|
|
||||||
PacketSize = 1500,
|
|
||||||
FragmentSize = 500,
|
|
||||||
ResendTimeout = 1200,
|
|
||||||
DisconnectTimeout = 6000,
|
|
||||||
ConnectTimeout = 6000,
|
|
||||||
MinUpdateTimeout = 1,
|
|
||||||
PingTimeout = 2000,
|
|
||||||
ReducedPingTimeout = 100,
|
|
||||||
AllCostTimeout = 20,
|
|
||||||
NetworkDropThreshold = 80,
|
|
||||||
OverflowDropThreshold = 80,
|
|
||||||
MaxConnectionAttempt = 10,
|
|
||||||
AckDelay = 33,
|
|
||||||
SendDelay = 10,
|
|
||||||
MaxCombinedReliableMessageSize = 100,
|
|
||||||
MaxCombinedReliableMessageCount = 10,
|
|
||||||
MaxSentMessageQueueSize = 512,
|
|
||||||
AcksType = ConnectionAcksType.Acks128,
|
|
||||||
InitialBandwidth = 0,
|
|
||||||
BandwidthPeakFactor = 2,
|
|
||||||
WebSocketReceiveBufferMaxSize = 0,
|
|
||||||
UdpSocketReceiveBufferMaxSize = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// settings copied from uMMORPG configuration for best results
|
|
||||||
public GlobalConfig globalConfig = new GlobalConfig
|
|
||||||
{
|
|
||||||
ReactorModel = ReactorModel.SelectReactor,
|
|
||||||
ThreadAwakeTimeout = 1,
|
|
||||||
ReactorMaximumSentMessages = 4096,
|
|
||||||
ReactorMaximumReceivedMessages = 4096,
|
|
||||||
MaxPacketSize = 2000,
|
|
||||||
MaxHosts = 16,
|
|
||||||
ThreadPoolSize = 3,
|
|
||||||
MinTimerTimeout = 1,
|
|
||||||
MaxTimerTimeout = 12000
|
|
||||||
};
|
|
||||||
|
|
||||||
// always use first channel
|
|
||||||
readonly int channelId;
|
|
||||||
byte error;
|
|
||||||
|
|
||||||
int clientId = -1;
|
|
||||||
int clientConnectionId = -1;
|
|
||||||
readonly byte[] clientReceiveBuffer = new byte[4096];
|
|
||||||
byte[] clientSendBuffer;
|
|
||||||
|
|
||||||
int serverHostId = -1;
|
|
||||||
readonly byte[] serverReceiveBuffer = new byte[4096];
|
|
||||||
byte[] serverSendBuffer;
|
|
||||||
|
|
||||||
void OnValidate()
|
|
||||||
{
|
|
||||||
// add connectionconfig channels if none
|
|
||||||
if (connectionConfig.Channels.Count == 0)
|
|
||||||
{
|
|
||||||
// channel 0 is reliable fragmented sequenced
|
|
||||||
connectionConfig.AddChannel(QosType.ReliableFragmentedSequenced);
|
|
||||||
// channel 1 is unreliable
|
|
||||||
connectionConfig.AddChannel(QosType.Unreliable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Awake()
|
|
||||||
{
|
|
||||||
NetworkTransport.Init(globalConfig);
|
|
||||||
Debug.Log("LLAPITransport initialized!");
|
|
||||||
|
|
||||||
// initialize send buffers
|
|
||||||
clientSendBuffer = new byte[globalConfig.MaxPacketSize];
|
|
||||||
serverSendBuffer = new byte[globalConfig.MaxPacketSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Available()
|
|
||||||
{
|
|
||||||
// LLAPI runs on all platforms, including webgl
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region client
|
|
||||||
public override bool ClientConnected()
|
|
||||||
{
|
|
||||||
return clientConnectionId != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ClientConnect(string address, int port)
|
|
||||||
{
|
|
||||||
// LLAPI can't handle 'localhost'
|
|
||||||
if (address.ToLower() == "localhost") address = "127.0.0.1";
|
|
||||||
|
|
||||||
HostTopology hostTopology = new HostTopology(connectionConfig, 1);
|
|
||||||
|
|
||||||
// important:
|
|
||||||
// AddHost(topology) doesn't work in WebGL.
|
|
||||||
// AddHost(topology, port) works in standalone and webgl if port=0
|
|
||||||
clientId = NetworkTransport.AddHost(hostTopology, 0);
|
|
||||||
|
|
||||||
clientConnectionId = NetworkTransport.Connect(clientId, address, port, 0, out error);
|
|
||||||
NetworkError networkError = (NetworkError)error;
|
|
||||||
if (networkError != NetworkError.Ok)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("NetworkTransport.Connect failed: clientId=" + clientId + " address= " + address + " port=" + port + " error=" + error);
|
|
||||||
clientConnectionId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ClientConnect(string address)
|
|
||||||
{
|
|
||||||
ClientConnect(address, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ClientConnect(Uri uri)
|
|
||||||
{
|
|
||||||
if (uri.Scheme != Scheme)
|
|
||||||
throw new ArgumentException($"Invalid url {uri}, use {Scheme}://host:port instead", nameof(uri));
|
|
||||||
|
|
||||||
int serverPort = uri.IsDefaultPort ? port : uri.Port;
|
|
||||||
|
|
||||||
ClientConnect(uri.Host, serverPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ClientSend(int channelId, ArraySegment<byte> segment)
|
|
||||||
{
|
|
||||||
// Send buffer is copied internally, so we can get rid of segment
|
|
||||||
// immediately after returning and it still works.
|
|
||||||
// -> BUT segment has an offset, Send doesn't. we need to manually
|
|
||||||
// copy it into a 0-offset array
|
|
||||||
if (segment.Count <= clientSendBuffer.Length)
|
|
||||||
{
|
|
||||||
Array.Copy(segment.Array, segment.Offset, clientSendBuffer, 0, segment.Count);
|
|
||||||
NetworkTransport.Send(clientId, clientConnectionId, channelId, clientSendBuffer, segment.Count, out error);
|
|
||||||
}
|
|
||||||
else Debug.LogError("LLAPI.ClientSend: buffer( " + clientSendBuffer.Length + ") too small for: " + segment.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ProcessClientMessage()
|
|
||||||
{
|
|
||||||
if (clientId == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
NetworkEventType networkEvent = NetworkTransport.ReceiveFromHost(clientId, out int connectionId, out int channel, clientReceiveBuffer, clientReceiveBuffer.Length, out int receivedSize, out error);
|
|
||||||
|
|
||||||
// note: 'error' is used for extra information, e.g. the reason for
|
|
||||||
// a disconnect. we don't necessarily have to throw an error if
|
|
||||||
// error != 0. but let's log it for easier debugging.
|
|
||||||
//
|
|
||||||
// DO NOT return after error != 0. otherwise Disconnect won't be
|
|
||||||
// registered.
|
|
||||||
NetworkError networkError = (NetworkError)error;
|
|
||||||
if (networkError != NetworkError.Ok)
|
|
||||||
{
|
|
||||||
string message = "NetworkTransport.Receive failed: hostid=" + clientId + " connId=" + connectionId + " channelId=" + channel + " error=" + networkError;
|
|
||||||
OnClientError.Invoke(new Exception(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// raise events
|
|
||||||
switch (networkEvent)
|
|
||||||
{
|
|
||||||
case NetworkEventType.ConnectEvent:
|
|
||||||
OnClientConnected.Invoke();
|
|
||||||
break;
|
|
||||||
case NetworkEventType.DataEvent:
|
|
||||||
ArraySegment<byte> data = new ArraySegment<byte>(clientReceiveBuffer, 0, receivedSize);
|
|
||||||
OnClientDataReceived.Invoke(data, channel);
|
|
||||||
break;
|
|
||||||
case NetworkEventType.DisconnectEvent:
|
|
||||||
OnClientDisconnected.Invoke();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ClientGetAddress()
|
|
||||||
{
|
|
||||||
NetworkTransport.GetConnectionInfo(serverHostId, clientId, out string address, out int port, out NetworkID networkId, out NodeID node, out error);
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ClientDisconnect()
|
|
||||||
{
|
|
||||||
if (clientId != -1)
|
|
||||||
{
|
|
||||||
NetworkTransport.RemoveHost(clientId);
|
|
||||||
clientId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region server
|
|
||||||
|
|
||||||
// right now this just returns the first available uri,
|
|
||||||
// should we return the list of all available uri?
|
|
||||||
public override Uri ServerUri()
|
|
||||||
{
|
|
||||||
UriBuilder builder = new UriBuilder();
|
|
||||||
builder.Scheme = Scheme;
|
|
||||||
builder.Host = Dns.GetHostName();
|
|
||||||
builder.Port = port;
|
|
||||||
return builder.Uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ServerActive()
|
|
||||||
{
|
|
||||||
return serverHostId != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ServerStart()
|
|
||||||
{
|
|
||||||
if (useWebsockets)
|
|
||||||
{
|
|
||||||
HostTopology topology = new HostTopology(connectionConfig, ushort.MaxValue - 1);
|
|
||||||
serverHostId = NetworkTransport.AddWebsocketHost(topology, port);
|
|
||||||
//Debug.Log("LLAPITransport.ServerStartWebsockets port=" + port + " max=" + maxConnections + " hostid=" + serverHostId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HostTopology topology = new HostTopology(connectionConfig, ushort.MaxValue - 1);
|
|
||||||
serverHostId = NetworkTransport.AddHost(topology, port);
|
|
||||||
//Debug.Log("LLAPITransport.ServerStart port=" + port + " max=" + maxConnections + " hostid=" + serverHostId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment)
|
|
||||||
{
|
|
||||||
// Send buffer is copied internally, so we can get rid of segment
|
|
||||||
// immediately after returning and it still works.
|
|
||||||
// -> BUT segment has an offset, Send doesn't. we need to manually
|
|
||||||
// copy it into a 0-offset array
|
|
||||||
if (segment.Count <= serverSendBuffer.Length)
|
|
||||||
{
|
|
||||||
// copy to 0-offset
|
|
||||||
Array.Copy(segment.Array, segment.Offset, serverSendBuffer, 0, segment.Count);
|
|
||||||
|
|
||||||
// send
|
|
||||||
NetworkTransport.Send(serverHostId, connectionId, channelId, serverSendBuffer, segment.Count, out error);
|
|
||||||
}
|
|
||||||
else Debug.LogError("LLAPI.ServerSend: buffer( " + serverSendBuffer.Length + ") too small for: " + segment.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ProcessServerMessage()
|
|
||||||
{
|
|
||||||
if (serverHostId == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
NetworkEventType networkEvent = NetworkTransport.ReceiveFromHost(serverHostId, out int connectionId, out int channel, serverReceiveBuffer, serverReceiveBuffer.Length, out int receivedSize, out error);
|
|
||||||
|
|
||||||
// note: 'error' is used for extra information, e.g. the reason for
|
|
||||||
// a disconnect. we don't necessarily have to throw an error if
|
|
||||||
// error != 0. but let's log it for easier debugging.
|
|
||||||
//
|
|
||||||
// DO NOT return after error != 0. otherwise Disconnect won't be
|
|
||||||
// registered.
|
|
||||||
NetworkError networkError = (NetworkError)error;
|
|
||||||
if (networkError != NetworkError.Ok)
|
|
||||||
{
|
|
||||||
string message = "NetworkTransport.Receive failed: hostid=" + serverHostId + " connId=" + connectionId + " channelId=" + channel + " error=" + networkError;
|
|
||||||
|
|
||||||
// TODO write a TransportException or better
|
|
||||||
OnServerError.Invoke(connectionId, new Exception(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
// LLAPI client sends keep alive messages (75-6C-6C) on channel=110.
|
|
||||||
// ignore all messages that aren't for our selected channel.
|
|
||||||
/*if (channel != channelId)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
switch (networkEvent)
|
|
||||||
{
|
|
||||||
case NetworkEventType.ConnectEvent:
|
|
||||||
OnServerConnected.Invoke(connectionId);
|
|
||||||
break;
|
|
||||||
case NetworkEventType.DataEvent:
|
|
||||||
ArraySegment<byte> data = new ArraySegment<byte>(serverReceiveBuffer, 0, receivedSize);
|
|
||||||
OnServerDataReceived.Invoke(connectionId, data, channel);
|
|
||||||
break;
|
|
||||||
case NetworkEventType.DisconnectEvent:
|
|
||||||
OnServerDisconnected.Invoke(connectionId);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// nothing or a message we don't recognize
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ServerDisconnect(int connectionId)
|
|
||||||
{
|
|
||||||
return NetworkTransport.Disconnect(serverHostId, connectionId, out error);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ServerGetClientAddress(int connectionId)
|
|
||||||
{
|
|
||||||
NetworkTransport.GetConnectionInfo(serverHostId, connectionId, out string address, out int port, out NetworkID networkId, out NodeID node, out error);
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ServerStop()
|
|
||||||
{
|
|
||||||
NetworkTransport.RemoveHost(serverHostId);
|
|
||||||
serverHostId = -1;
|
|
||||||
Debug.Log("LLAPITransport.ServerStop");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region common
|
|
||||||
// IMPORTANT: set script execution order to >1000 to call Transport's
|
|
||||||
// LateUpdate after all others. Fixes race condition where
|
|
||||||
// e.g. in uSurvival Transport would apply Cmds before
|
|
||||||
// ShoulderRotation.LateUpdate, resulting in projectile
|
|
||||||
// spawns at the point before shoulder rotation.
|
|
||||||
public void LateUpdate()
|
|
||||||
{
|
|
||||||
// process all messages
|
|
||||||
while (ProcessClientMessage()) { }
|
|
||||||
while (ProcessServerMessage()) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
NetworkTransport.Shutdown();
|
|
||||||
serverHostId = -1;
|
|
||||||
clientConnectionId = -1;
|
|
||||||
Debug.Log("LLAPITransport.Shutdown");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetMaxPacketSize(int channelId)
|
|
||||||
{
|
|
||||||
return globalConfig.MaxPacketSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
if (ServerActive())
|
|
||||||
{
|
|
||||||
return "LLAPI Server port: " + port;
|
|
||||||
}
|
|
||||||
else if (ClientConnected())
|
|
||||||
{
|
|
||||||
string ip = ClientGetAddress();
|
|
||||||
return "LLAPI Client ip: " + ip + " port: " + port;
|
|
||||||
}
|
|
||||||
return "LLAPI (inactive/disconnected)";
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d333dcc8c7bd34f35896f5a9b4c9e759
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 1001
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -506,7 +506,7 @@ PlayerSettings:
|
|||||||
webGLLinkerTarget: 1
|
webGLLinkerTarget: 1
|
||||||
webGLThreadsSupport: 0
|
webGLThreadsSupport: 0
|
||||||
scriptingDefineSymbols:
|
scriptingDefineSymbols:
|
||||||
1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER;MIRROR_14_0_OR_NEWER;MIRROR_15_0_OR_NEWER;MIRROR_16_0_OR_NEWER;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER
|
1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER;MIRROR_14_0_OR_NEWER;MIRROR_15_0_OR_NEWER;MIRROR_16_0_OR_NEWER;MIRROR_17_0_OR_NEWER;MIRROR_18_0_OR_NEWER;MIRROR_24_0_OR_NEWER;MIRROR_26_0_OR_NEWER;MIRROR_27_0_OR_NEWER;MIRROR_28_0_OR_NEWER;MIRROR_29_0_OR_NEWER;MIRROR_30_0_OR_NEWER
|
||||||
platformArchitecture: {}
|
platformArchitecture: {}
|
||||||
scriptingBackend: {}
|
scriptingBackend: {}
|
||||||
il2cppCompilerConfiguration: {}
|
il2cppCompilerConfiguration: {}
|
||||||
|
Loading…
Reference in New Issue
Block a user