Shorten Channel Enums (#2644)

Co-authored-by: MrGadget1024 <chris@clevertech.net>
This commit is contained in:
MrGadget 2021-03-15 23:46:10 -04:00 committed by vis2k
parent 254a0b929d
commit 53dad15e04
18 changed files with 287 additions and 182 deletions

View File

@ -212,7 +212,7 @@ bool NeedsTeleport()
} }
// local authority client sends sync message to server for broadcasting // local authority client sends sync message to server for broadcasting
[Command(channel = Channels.DefaultUnreliable)] [Command(channel = Channels.Unreliable)]
void CmdClientToServerSync(Vector3 position, uint packedRotation, Vector3 scale) void CmdClientToServerSync(Vector3 position, uint packedRotation, Vector3 scale)
{ {
// Ignore messages from client if not in client authority mode // Ignore messages from client if not in client authority mode
@ -229,7 +229,7 @@ void CmdClientToServerSync(Vector3 position, uint packedRotation, Vector3 scale)
RpcMove(position, packedRotation, scale); RpcMove(position, packedRotation, scale);
} }
[ClientRpc(channel = Channels.DefaultUnreliable)] [ClientRpc(channel = Channels.Unreliable)]
void RpcMove(Vector3 position, uint packedRotation, Vector3 scale) void RpcMove(Vector3 position, uint packedRotation, Vector3 scale)
{ {
if (hasAuthority && excludeOwnerUpdate) return; if (hasAuthority && excludeOwnerUpdate) return;
@ -456,7 +456,7 @@ void DoTeleport(Vector3 newLocalPosition, Quaternion newLocalRotation)
lastRotation = newLocalRotation; lastRotation = newLocalRotation;
} }
[ClientRpc(channel = Channels.DefaultUnreliable)] [ClientRpc(channel = Channels.Unreliable)]
void RpcTeleport(Vector3 newPosition, uint newPackedRotation, bool isClientAuthority) void RpcTeleport(Vector3 newPosition, uint newPackedRotation, bool isClientAuthority)
{ {
DoTeleport(newPosition, Compression.DecompressQuaternion(newPackedRotation)); DoTeleport(newPosition, Compression.DecompressQuaternion(newPackedRotation));
@ -470,7 +470,7 @@ void RpcTeleport(Vector3 newPosition, uint newPackedRotation, bool isClientAutho
/// This RPC will be invoked on server after client finishes overriding the position. /// This RPC will be invoked on server after client finishes overriding the position.
/// </summary> /// </summary>
/// <param name="initialAuthority"></param> /// <param name="initialAuthority"></param>
[Command(channel = Channels.DefaultUnreliable)] [Command(channel = Channels.Unreliable)]
void CmdTeleportFinished() void CmdTeleportFinished()
{ {
if (clientAuthorityBeforeTeleport) if (clientAuthorityBeforeTeleport)

View File

@ -20,7 +20,7 @@ public class SyncVarAttribute : PropertyAttribute
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public class CommandAttribute : Attribute public class CommandAttribute : Attribute
{ {
public int channel = Channels.DefaultReliable; public int channel = Channels.Reliable;
public bool requiresAuthority = true; public bool requiresAuthority = true;
} }
@ -30,7 +30,7 @@ public class CommandAttribute : Attribute
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public class ClientRpcAttribute : Attribute public class ClientRpcAttribute : Attribute
{ {
public int channel = Channels.DefaultReliable; public int channel = Channels.Reliable;
public bool includeOwner = true; public bool includeOwner = true;
} }
@ -40,7 +40,7 @@ public class ClientRpcAttribute : Attribute
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public class TargetRpcAttribute : Attribute public class TargetRpcAttribute : Attribute
{ {
public int channel = Channels.DefaultReliable; public int channel = Channels.Reliable;
} }
/// <summary> /// <summary>

View File

@ -14,7 +14,7 @@ public LocalConnectionToClient() : base(LocalConnectionId, false, 0) {}
public override string address => "localhost"; public override string address => "localhost";
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable) internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
{ {
// get a writer to copy the message into since the segment is only // get a writer to copy the message into since the segment is only
// valid until returning. // valid until returning.
@ -63,7 +63,7 @@ internal class LocalConnectionToServer : NetworkConnectionToServer
internal void QueueConnectedEvent() => connectedEventPending = true; internal void QueueConnectedEvent() => connectedEventPending = true;
internal void QueueDisconnectedEvent() => disconnectedEventPending = true; internal void QueueDisconnectedEvent() => disconnectedEventPending = true;
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable) internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
{ {
if (segment.Count == 0) if (segment.Count == 0)
{ {
@ -91,7 +91,7 @@ internal void Update()
PooledNetworkWriter writer = queue.Dequeue(); PooledNetworkWriter writer = queue.Dequeue();
ArraySegment<byte> segment = writer.ToArraySegment(); ArraySegment<byte> segment = writer.ToArraySegment();
//Debug.Log("Dequeue " + BitConverter.ToString(segment.Array, segment.Offset, segment.Count)); //Debug.Log("Dequeue " + BitConverter.ToString(segment.Array, segment.Offset, segment.Count));
TransportReceive(segment, Channels.DefaultReliable); TransportReceive(segment, Channels.Reliable);
NetworkWriterPool.Recycle(writer); NetworkWriterPool.Recycle(writer);
} }

View File

@ -290,7 +290,7 @@ static void OnDisconnected()
// send //////////////////////////////////////////////////////////////// // send ////////////////////////////////////////////////////////////////
/// <summary>Send a NetworkMessage to the server over the given channel.</summary> /// <summary>Send a NetworkMessage to the server over the given channel.</summary>
public static void Send<T>(T message, int channelId = Channels.DefaultReliable) public static void Send<T>(T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
if (connection != null) if (connection != null)

View File

@ -72,7 +72,7 @@ internal void SetHandlers(Dictionary<int, NetworkMessageDelegate> handlers)
} }
/// <summary>Send a NetworkMessage to this connection over the given channel.</summary> /// <summary>Send a NetworkMessage to this connection over the given channel.</summary>
public void Send<T>(T msg, int channelId = Channels.DefaultReliable) public void Send<T>(T msg, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
@ -110,7 +110,7 @@ protected static bool ValidatePacketSize(ArraySegment<byte> segment, int channel
// internal because no one except Mirror should send bytes directly to // internal because no one except Mirror should send bytes directly to
// the client. they would be detected as a message. send messages instead. // the client. they would be detected as a message. send messages instead.
internal abstract void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable); internal abstract void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable);
public override string ToString() => $"connection({connectionId})"; public override string ToString() => $"connection({connectionId})";

View File

@ -122,7 +122,7 @@ internal void SendBatch(int channelId, Batch batch)
batch.lastSendTime = NetworkTime.time; batch.lastSendTime = NetworkTime.time;
} }
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable) internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
{ {
//Debug.Log("ConnectionSend " + this + " bytes:" + BitConverter.ToString(segment.Array, segment.Offset, segment.Count)); //Debug.Log("ConnectionSend " + this + " bytes:" + BitConverter.ToString(segment.Array, segment.Offset, segment.Count));

View File

@ -6,7 +6,7 @@ public class NetworkConnectionToServer : NetworkConnection
{ {
public override string address => ""; public override string address => "";
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable) internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
{ {
// Debug.Log("ConnectionSend " + this + " bytes:" + BitConverter.ToString(segment.Array, segment.Offset, segment.Count)); // Debug.Log("ConnectionSend " + this + " bytes:" + BitConverter.ToString(segment.Array, segment.Offset, segment.Count));

View File

@ -225,7 +225,7 @@ public static bool NoExternalConnections()
// send //////////////////////////////////////////////////////////////// // send ////////////////////////////////////////////////////////////////
/// <summary>Send a message to all clients, even those that haven't joined the world yet (non ready)</summary> /// <summary>Send a message to all clients, even those that haven't joined the world yet (non ready)</summary>
public static void SendToAll<T>(T message, int channelId = Channels.DefaultReliable, bool sendToReadyOnly = false) public static void SendToAll<T>(T message, int channelId = Channels.Reliable, bool sendToReadyOnly = false)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
if (!active) if (!active)
@ -260,7 +260,7 @@ public static void SendToAll<T>(T message, int channelId = Channels.DefaultRelia
/// <summary>Send a message to all clients which have joined the world (are ready).</summary> /// <summary>Send a message to all clients which have joined the world (are ready).</summary>
// TODO put rpcs into NetworkServer.Update WorldState packet, then finally remove SendToReady! // TODO put rpcs into NetworkServer.Update WorldState packet, then finally remove SendToReady!
public static void SendToReady<T>(T message, int channelId = Channels.DefaultReliable) public static void SendToReady<T>(T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
if (!active) if (!active)
@ -274,7 +274,7 @@ public static void SendToReady<T>(T message, int channelId = Channels.DefaultRel
/// <summary>Send a message to only clients which are ready with option to include the owner of the object identity</summary> /// <summary>Send a message to only clients which are ready with option to include the owner of the object identity</summary>
// TODO put rpcs into NetworkServer.Update WorldState packet, then finally remove SendToReady! // TODO put rpcs into NetworkServer.Update WorldState packet, then finally remove SendToReady!
public static void SendToReady<T>(NetworkIdentity identity, T message, bool includeOwner = true, int channelId = Channels.DefaultReliable) public static void SendToReady<T>(NetworkIdentity identity, T message, bool includeOwner = true, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
// Debug.Log("Server.SendToReady msgType:" + typeof(T)); // Debug.Log("Server.SendToReady msgType:" + typeof(T));
@ -312,7 +312,7 @@ public static void SendToReady<T>(NetworkIdentity identity, T message, int chann
// this is like SendToReady - but it doesn't check the ready flag on the connection. // this is like SendToReady - but it doesn't check the ready flag on the connection.
// this is used for ObjectDestroy messages. // this is used for ObjectDestroy messages.
static void SendToObservers<T>(NetworkIdentity identity, T message, int channelId = Channels.DefaultReliable) static void SendToObservers<T>(NetworkIdentity identity, T message, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
// Debug.Log("Server.SendToObservers id:" + typeof(T)); // Debug.Log("Server.SendToObservers id:" + typeof(T));
@ -336,7 +336,7 @@ static void SendToObservers<T>(NetworkIdentity identity, T message, int channelI
/// <summary>Send this message to the player only</summary> /// <summary>Send this message to the player only</summary>
[Obsolete("Use identity.connectionToClient.Send() instead! Previously Mirror needed this function internally, but not anymore.")] [Obsolete("Use identity.connectionToClient.Send() instead! Previously Mirror needed this function internally, but not anymore.")]
public static void SendToClientOfPlayer<T>(NetworkIdentity identity, T msg, int channelId = Channels.DefaultReliable) public static void SendToClientOfPlayer<T>(NetworkIdentity identity, T msg, int channelId = Channels.Reliable)
where T : struct, NetworkMessage where T : struct, NetworkMessage
{ {
if (identity != null) if (identity != null)

View File

@ -47,7 +47,7 @@ internal static void UpdateClient()
if (Time.time - lastPingTime >= PingFrequency) if (Time.time - lastPingTime >= PingFrequency)
{ {
NetworkPingMessage pingMessage = new NetworkPingMessage(LocalTime()); NetworkPingMessage pingMessage = new NetworkPingMessage(LocalTime());
NetworkClient.Send(pingMessage, Channels.DefaultUnreliable); NetworkClient.Send(pingMessage, Channels.Unreliable);
lastPingTime = Time.time; lastPingTime = Time.time;
} }
} }
@ -63,7 +63,7 @@ internal static void OnServerPing(NetworkConnection conn, NetworkPingMessage mes
clientTime = message.clientTime, clientTime = message.clientTime,
serverTime = LocalTime() serverTime = LocalTime()
}; };
conn.Send(pongMessage, Channels.DefaultUnreliable); conn.Send(pongMessage, Channels.Unreliable);
} }
// Executed at the client when we receive a Pong message // Executed at the client when we receive a Pong message

View File

@ -57,14 +57,14 @@ void Awake()
// client // client
client = new KcpClient( client = new KcpClient(
() => OnClientConnected.Invoke(), () => OnClientConnected.Invoke(),
(message) => OnClientDataReceived.Invoke(message, Channels.DefaultReliable), (message) => OnClientDataReceived.Invoke(message, Channels.Reliable),
() => OnClientDisconnected.Invoke() () => OnClientDisconnected.Invoke()
); );
// server // server
server = new KcpServer( server = new KcpServer(
(connectionId) => OnServerConnected.Invoke(connectionId), (connectionId) => OnServerConnected.Invoke(connectionId),
(connectionId, message) => OnServerDataReceived.Invoke(connectionId, message, Channels.DefaultReliable), (connectionId, message) => OnServerDataReceived.Invoke(connectionId, message, Channels.Reliable),
(connectionId) => OnServerDisconnected.Invoke(connectionId), (connectionId) => OnServerDisconnected.Invoke(connectionId),
NoDelay, NoDelay,
Interval, Interval,
@ -97,7 +97,7 @@ public override void ClientSend(int channelId, ArraySegment<byte> segment)
// default to reliable just to be sure. // default to reliable just to be sure.
switch (channelId) switch (channelId)
{ {
case Channels.DefaultUnreliable: case Channels.Unreliable:
client.Send(segment, KcpChannel.Unreliable); client.Send(segment, KcpChannel.Unreliable);
break; break;
default: default:
@ -156,7 +156,7 @@ public override void ServerSend(int connectionId, int channelId, ArraySegment<by
// default to reliable just to be sure. // default to reliable just to be sure.
switch (channelId) switch (channelId)
{ {
case Channels.DefaultUnreliable: case Channels.Unreliable:
server.Send(connectionId, segment, KcpChannel.Unreliable); server.Send(connectionId, segment, KcpChannel.Unreliable);
break; break;
default: default:
@ -187,14 +187,14 @@ public override void ServerEarlyUpdate()
public override void Shutdown() {} public override void Shutdown() {}
// max message size // max message size
public override int GetMaxPacketSize(int channelId = Channels.DefaultReliable) public override int GetMaxPacketSize(int channelId = Channels.Reliable)
{ {
// switch to kcp channel. // switch to kcp channel.
// unreliable or reliable. // unreliable or reliable.
// default to reliable just to be sure. // default to reliable just to be sure.
switch (channelId) switch (channelId)
{ {
case Channels.DefaultUnreliable: case Channels.Unreliable:
return KcpConnection.UnreliableMaxMessageSize; return KcpConnection.UnreliableMaxMessageSize;
default: default:
return KcpConnection.ReliableMaxMessageSize; return KcpConnection.ReliableMaxMessageSize;

View File

@ -12,7 +12,7 @@ struct QueuedMessage
{ {
public int connectionId; public int connectionId;
public byte[] bytes; public byte[] bytes;
public float timeToSend; public float time;
} }
[HelpURL("https://mirror-networking.gitbook.io/docs/transports/latency-simulaton-transport")] [HelpURL("https://mirror-networking.gitbook.io/docs/transports/latency-simulaton-transport")]
@ -24,19 +24,15 @@ public class LatencySimulation : Transport
[Header("Reliable Messages")] [Header("Reliable Messages")]
[Tooltip("Reliable latency in seconds")] [Tooltip("Reliable latency in seconds")]
public float reliableLatency = 0; public float reliableLatency = 0;
[Tooltip("Simulate latency spikes with % of latency for % of messages.")]
[Range(0, 1)] public float reliableLatencySpikes;
// note: packet loss over reliable manifests itself in latency. // note: packet loss over reliable manifests itself in latency.
// don't need (and can't add) a loss option here. // don't need (and can't add) a loss option here.
// note: reliable is ordered by definition. no need to scramble. // note: reliable is ordered by definition. no need to scramble.
[Header("Unreliable Messages")] [Header("Unreliable Messages")]
[Tooltip("Unreliable latency in seconds")]
public float unreliableLatency = 0;
[Tooltip("Simulate latency spikes with % of latency for % of messages.")]
[Range(0, 1)] public float unreliableLatencySpikes;
[Tooltip("Packet loss in %")] [Tooltip("Packet loss in %")]
[Range(0, 1)] public float unreliableLoss; [Range(0, 1)] public float unreliableLoss;
[Tooltip("Unreliable latency in seconds")]
public float unreliableLatency = 0;
[Tooltip("Scramble unreliable messages, just like over the real network. Mirror unreliable is unordered.")] [Tooltip("Scramble unreliable messages, just like over the real network. Mirror unreliable is unordered.")]
public bool unreliableScramble; public bool unreliableScramble;
@ -64,19 +60,6 @@ public void Awake()
void OnEnable() { wrap.enabled = true; } void OnEnable() { wrap.enabled = true; }
void OnDisable() { wrap.enabled = false; } void OnDisable() { wrap.enabled = false; }
// helper function to simulate latency & spike with spike probability
float SimulateLatency(float latency, float spikesPercent)
{
// will this one spike?
bool spike = random.NextDouble() < spikesPercent;
// if it spiked, add spike latency by percent of original latency
float add = spike ? latency * spikesPercent : 0;
// return latency + spike
return latency + add;
}
// helper function to simulate a send with latency/loss/scramble // helper function to simulate a send with latency/loss/scramble
void SimulateSend(int connectionId, int channelId, ArraySegment<byte> segment, List<QueuedMessage> reliableQueue, List<QueuedMessage> unreliableQueue) void SimulateSend(int connectionId, int channelId, ArraySegment<byte> segment, List<QueuedMessage> reliableQueue, List<QueuedMessage> unreliableQueue)
{ {
@ -84,34 +67,30 @@ void SimulateSend(int connectionId, int channelId, ArraySegment<byte> segment, L
// (allocates for now. it's only for testing anyway.) // (allocates for now. it's only for testing anyway.)
byte[] bytes = new byte[segment.Count]; byte[] bytes = new byte[segment.Count];
Buffer.BlockCopy(segment.Array, segment.Offset, bytes, 0, segment.Count); Buffer.BlockCopy(segment.Array, segment.Offset, bytes, 0, segment.Count);
// enqueue message. send after latency interval. // enqueue message. send after latency interval.
QueuedMessage message = new QueuedMessage QueuedMessage message = new QueuedMessage
{ {
connectionId = connectionId, connectionId = connectionId,
bytes = bytes bytes = bytes,
time = Time.time
}; };
switch (channelId) switch (channelId)
{ {
case Channels.DefaultReliable: case Channels.Reliable:
// simulate latency & spikes // simulate latency
message.timeToSend = Time.time + SimulateLatency(reliableLatency, reliableLatencySpikes);
reliableQueue.Add(message); reliableQueue.Add(message);
break; break;
case Channels.DefaultUnreliable: case Channels.Unreliable:
// simulate packet loss // simulate packet loss
bool drop = random.NextDouble() < unreliableLoss; bool drop = random.NextDouble() < unreliableLoss;
if (!drop) if (!drop)
{ {
// simulate scramble (Random.Next is < max, so +1) // simulate scramble (Random.Next is < max, so +1)
// note that list entries are NOT ordered by time anymore
// after inserting randomly.
int last = unreliableQueue.Count; int last = unreliableQueue.Count;
int index = unreliableScramble ? random.Next(0, last + 1) : last; int index = unreliableScramble ? random.Next(0, last + 1) : last;
// simulate latency & spikes // simulate latency
message.timeToSend = Time.time + SimulateLatency(unreliableLatency, unreliableLatencySpikes);
unreliableQueue.Insert(index, message); unreliableQueue.Insert(index, message);
} }
break; break;
@ -184,32 +163,34 @@ public override void ServerStop()
public override void ServerEarlyUpdate() => wrap.ServerEarlyUpdate(); public override void ServerEarlyUpdate() => wrap.ServerEarlyUpdate();
public override void ClientLateUpdate() public override void ClientLateUpdate()
{ {
// flush reliable messages that are ready to be sent // flush reliable messages after latency
// => list isn't ordered (due to scramble). need to iterate all. while (reliableClientToServer.Count > 0)
for (int i = 0; i < reliableClientToServer.Count; ++i)
{ {
QueuedMessage message = reliableClientToServer[i]; // check the first message time
if (Time.time >= message.timeToSend) QueuedMessage message = reliableClientToServer[0];
if (message.time + reliableLatency <= Time.time)
{ {
// send and remove // send and eat
wrap.ClientSend(Channels.DefaultReliable, new ArraySegment<byte>(message.bytes)); wrap.ClientSend(Channels.Reliable, new ArraySegment<byte>(message.bytes));
reliableClientToServer.RemoveAt(i); reliableClientToServer.RemoveAt(0);
--i;
} }
// not enough time elapsed yet
break;
} }
// flush unrelabe messages that are ready to be sent // flush unreliable messages after latency
// => list isn't ordered (due to scramble). need to iterate all. while (unreliableClientToServer.Count > 0)
for (int i = 0; i < unreliableClientToServer.Count; ++i)
{ {
QueuedMessage message = unreliableClientToServer[i]; // check the first message time
if (Time.time >= message.timeToSend) QueuedMessage message = unreliableClientToServer[0];
if (message.time + unreliableLatency <= Time.time)
{ {
// send and remove // send and eat
wrap.ClientSend(Channels.DefaultUnreliable, new ArraySegment<byte>(message.bytes)); wrap.ClientSend(Channels.Unreliable, new ArraySegment<byte>(message.bytes));
unreliableClientToServer.RemoveAt(i); unreliableClientToServer.RemoveAt(0);
--i;
} }
// not enough time elapsed yet
break;
} }
// update wrapped transport too // update wrapped transport too
@ -217,32 +198,34 @@ public override void ClientLateUpdate()
} }
public override void ServerLateUpdate() public override void ServerLateUpdate()
{ {
// flush reliable messages that are ready to be sent // flush reliable messages after latency
// => list isn't ordered (due to scramble). need to iterate all. while (reliableServerToClient.Count > 0)
for (int i = 0; i < reliableServerToClient.Count; ++i)
{ {
QueuedMessage message = reliableServerToClient[i]; // check the first message time
if (Time.time >= message.timeToSend) QueuedMessage message = reliableServerToClient[0];
if (message.time + reliableLatency <= Time.time)
{ {
// send and remove // send and eat
wrap.ServerSend(message.connectionId, Channels.DefaultReliable, new ArraySegment<byte>(message.bytes)); wrap.ServerSend(message.connectionId, Channels.Reliable, new ArraySegment<byte>(message.bytes));
reliableServerToClient.RemoveAt(i); reliableServerToClient.RemoveAt(0);
--i;
} }
// not enough time elapsed yet
break;
} }
// flush unrelabe messages that are ready to be sent // flush unreliable messages after latency
// => list isn't ordered (due to scramble). need to iterate all. while (unreliableServerToClient.Count > 0)
for (int i = 0; i < unreliableServerToClient.Count; ++i)
{ {
QueuedMessage message = unreliableServerToClient[i]; // check the first message time
if (Time.time >= message.timeToSend) QueuedMessage message = unreliableServerToClient[0];
if (message.time + unreliableLatency <= Time.time)
{ {
// send and remove // send and eat
wrap.ServerSend(message.connectionId, Channels.DefaultUnreliable, new ArraySegment<byte>(message.bytes)); wrap.ServerSend(message.connectionId, Channels.Unreliable, new ArraySegment<byte>(message.bytes));
unreliableServerToClient.RemoveAt(i); unreliableServerToClient.RemoveAt(0);
--i;
} }
// not enough time elapsed yet
break;
} }
// update wrapped transport too // update wrapped transport too

View File

@ -150,7 +150,7 @@ public override void ClientConnect(string hostname)
// there should be no more messages after disconnect // there should be no more messages after disconnect
client = null; client = null;
}; };
client.onData += (ArraySegment<byte> data) => OnClientDataReceived.Invoke(data, Channels.DefaultReliable); client.onData += (ArraySegment<byte> data) => OnClientDataReceived.Invoke(data, Channels.Reliable);
client.onError += (Exception e) => client.onError += (Exception e) =>
{ {
OnClientError.Invoke(e); OnClientError.Invoke(e);
@ -214,7 +214,7 @@ public override void ServerStart()
server.onConnect += OnServerConnected.Invoke; server.onConnect += OnServerConnected.Invoke;
server.onDisconnect += OnServerDisconnected.Invoke; server.onDisconnect += OnServerDisconnected.Invoke;
server.onData += (int connId, ArraySegment<byte> data) => OnServerDataReceived.Invoke(connId, data, Channels.DefaultReliable); server.onData += (int connId, ArraySegment<byte> data) => OnServerDataReceived.Invoke(connId, data, Channels.Reliable);
server.onError += OnServerError.Invoke; server.onError += OnServerError.Invoke;
SendLoopConfig.batchSend = batchSend || waitBeforeSend; SendLoopConfig.batchSend = batchSend || waitBeforeSend;

View File

@ -80,7 +80,7 @@ void Awake()
// them all in a lambda and always call the latest hook. // them all in a lambda and always call the latest hook.
// (= lazy call) // (= lazy call)
client.OnConnected = () => OnClientConnected.Invoke(); client.OnConnected = () => OnClientConnected.Invoke();
client.OnData = (segment) => OnClientDataReceived.Invoke(segment, Channels.DefaultReliable); client.OnData = (segment) => OnClientDataReceived.Invoke(segment, Channels.Reliable);
client.OnDisconnected = () => OnClientDisconnected.Invoke(); client.OnDisconnected = () => OnClientDisconnected.Invoke();
// client configuration // client configuration
@ -98,7 +98,7 @@ void Awake()
// them all in a lambda and always call the latest hook. // them all in a lambda and always call the latest hook.
// (= lazy call) // (= lazy call)
server.OnConnected = (connectionId) => OnServerConnected.Invoke(connectionId); server.OnConnected = (connectionId) => OnServerConnected.Invoke(connectionId);
server.OnData = (connectionId, segment) => OnServerDataReceived.Invoke(connectionId, segment, Channels.DefaultReliable); server.OnData = (connectionId, segment) => OnServerDataReceived.Invoke(connectionId, segment, Channels.Reliable);
server.OnDisconnected = (connectionId) => OnServerDisconnected.Invoke(connectionId); server.OnDisconnected = (connectionId) => OnServerDisconnected.Invoke(connectionId);
// server configuration // server configuration

View File

@ -1,46 +1,99 @@
// Transport Rules
//
// All transports should follow these rules so that they work correctly with mirror:
// * When Monobehaviour is disabled the Transport should not invoke callbacks
// * Callbacks should be invoked on main thread. It is best to do this from LateUpdate
// * Callbacks can be invoked after ServerStop or ClientDisconnect has been called
// * ServerStop or ClientDisconnect can be called by mirror multiple times
// * Available should check the platform and 32 vs 64 bit if the transport only works on some of them
// * GetMaxPacketSize should return size even if transport is not running
// * Default channel should be reliable Channels.DefaultReliable
using System; using System;
using UnityEngine; using UnityEngine;
namespace Mirror namespace Mirror
{ {
/// <summary>Abstract transport layer component</summary> /// <summary>
/// Abstract transport layer component
/// </summary>
/// <remarks>
/// <h2>
/// Transport Rules
/// </h2>
/// <list type="bullet">
/// <listheader><description>
/// All transports should follow these rules so that they work correctly with mirror
/// </description></listheader>
/// <item><description>
/// When Monobehaviour is disabled the Transport should not invoke callbacks
/// </description></item>
/// <item><description>
/// Callbacks should be invoked on main thread. It is best to do this from LateUpdate
/// </description></item>
/// <item><description>
/// Callbacks can be invoked after <see cref="ServerStop"/> or <see cref="ClientDisconnect"/> as been called
/// </description></item>
/// <item><description>
/// <see cref="ServerStop"/> or <see cref="ClientDisconnect"/> can be called by mirror multiple times
/// </description></item>
/// <item><description>
/// <see cref="Available"/> should check the platform and 32 vs 64 bit if the transport only works on some of them
/// </description></item>
/// <item><description>
/// <see cref="GetMaxPacketSize"/> should return size even if transport is not running
/// </description></item>
/// <item><description>
/// Default channel should be reliable <see cref="Channels.Reliable"/>
/// </description></item>
/// </list>
/// </remarks>
public abstract class Transport : MonoBehaviour public abstract class Transport : MonoBehaviour
{ {
/// <summary>The current transport used by Mirror.</summary> /// <summary>
/// The current transport used by Mirror.
/// </summary>
public static Transport activeTransport; public static Transport activeTransport;
/// <summary>Transport available on this platform? Some aren't available on all platforms.</summary> /// <summary>
/// Is this transport available in the current platform?
/// <para>Some transports might only be available in mobile</para>
/// <para>Many will not work in webgl</para>
/// <para>Example usage: return Application.platform == RuntimePlatform.WebGLPlayer</para>
/// </summary>
/// <returns>True if this transport works in the current platform</returns>
public abstract bool Available(); public abstract bool Available();
/// <summary>Notify subscribers when this client establish a successful connection to the server</summary> #region Client
/// <summary>
/// Notify subscribers when this client establish a successful connection to the server
/// <para>callback()</para>
/// </summary>
public Action OnClientConnected = () => Debug.LogWarning("OnClientConnected called with no handler"); public Action OnClientConnected = () => Debug.LogWarning("OnClientConnected called with no handler");
/// <summary>Notify subscribers when this client receive data from the server</summary> /// <summary>
/// Notify subscribers when this client receive data from the server
/// <para>callback(ArraySegment&lt;byte&gt; data, int channel)</para>
/// </summary>
public Action<ArraySegment<byte>, int> OnClientDataReceived = (data, channel) => Debug.LogWarning("OnClientDataReceived called with no handler"); public Action<ArraySegment<byte>, int> OnClientDataReceived = (data, channel) => Debug.LogWarning("OnClientDataReceived called with no handler");
/// <summary>Notify subscribers when this client encounters an error communicating with the server</summary> /// <summary>
/// Notify subscribers when this client encounters an error communicating with the server
/// <para>callback(Exception e)</para>
/// </summary>
public Action<Exception> OnClientError = (error) => Debug.LogWarning("OnClientError called with no handler"); public Action<Exception> OnClientError = (error) => Debug.LogWarning("OnClientError called with no handler");
/// <summary>Notify subscribers when this client disconnects from the server</summary> /// <summary>
/// Notify subscribers when this client disconnects from the server
/// <para>callback()</para>
/// </summary>
public Action OnClientDisconnected = () => Debug.LogWarning("OnClientDisconnected called with no handler"); public Action OnClientDisconnected = () => Debug.LogWarning("OnClientDisconnected called with no handler");
/// <summary>Determines if we are currently connected to the server</summary> /// <summary>
/// Determines if we are currently connected to the server
/// </summary>
/// <returns>True if a connection has been established to the server</returns>
public abstract bool ClientConnected(); public abstract bool ClientConnected();
/// <summary>Establish a connection to a server</summary> /// <summary>
/// Establish a connection to a server
/// </summary>
/// <param name="address">The IP address or FQDN of the server we are trying to connect to</param>
public abstract void ClientConnect(string address); public abstract void ClientConnect(string address);
/// <summary>Establish a connection to a server</summary> /// <summary>
/// Establish a connection to a server
/// </summary>
/// <param name="uri">The address of the server we are trying to connect to</param>
public virtual void ClientConnect(Uri uri) public virtual void ClientConnect(Uri uri)
{ {
// By default, to keep backwards compatibility, just connect to the host // By default, to keep backwards compatibility, just connect to the host
@ -48,60 +101,120 @@ public virtual void ClientConnect(Uri uri)
ClientConnect(uri.Host); ClientConnect(uri.Host);
} }
/// <summary>Send data to the server over a given channel</summary> /// <summary>
/// Send data to the server
/// </summary>
/// <param name="channelId">The channel to use. 0 is the default channel,
/// but some transports might want to provide unreliable, encrypted, compressed, or any other feature
/// as new channels</param>
/// <param name="segment">The data to send to the server. Will be recycled after returning, so either use it directly or copy it internally. This allows for allocation-free sends!</param>
public abstract void ClientSend(int channelId, ArraySegment<byte> segment); public abstract void ClientSend(int channelId, ArraySegment<byte> segment);
/// <summary>Disconnect this client from the server</summary> /// <summary>
/// Disconnect this client from the server
/// </summary>
public abstract void ClientDisconnect(); public abstract void ClientDisconnect();
/// <summary>Get the address of this server. Useful for network discovery</summary> #endregion
#region Server
/// <summary>
/// Retrieves the address of this server.
/// Useful for network discovery
/// </summary>
/// <returns>the url at which this server can be reached</returns>
public abstract Uri ServerUri(); public abstract Uri ServerUri();
/// <summary>Notify subscribers when a client connects to this server</summary> /// <summary>
/// Notify subscribers when a client connects to this server
/// <para>callback(int connId)</para>
/// </summary>
public Action<int> OnServerConnected = (connId) => Debug.LogWarning("OnServerConnected called with no handler"); public Action<int> OnServerConnected = (connId) => Debug.LogWarning("OnServerConnected called with no handler");
/// <summary>Notify subscribers when this server receives data from the client</summary> /// <summary>
/// Notify subscribers when this server receives data from the client
/// <para>callback(int connId, ArraySegment&lt;byte&gt; data, int channel)</para>
/// </summary>
public Action<int, ArraySegment<byte>, int> OnServerDataReceived = (connId, data, channel) => Debug.LogWarning("OnServerDataReceived called with no handler"); public Action<int, ArraySegment<byte>, int> OnServerDataReceived = (connId, data, channel) => Debug.LogWarning("OnServerDataReceived called with no handler");
/// <summary>Notify subscribers when this server has some problem communicating with the client</summary> /// <summary>
/// Notify subscribers when this server has some problem communicating with the client
/// <para>callback(int connId, Exception e)</para>
/// </summary>
public Action<int, Exception> OnServerError = (connId, error) => Debug.LogWarning("OnServerError called with no handler"); public Action<int, Exception> OnServerError = (connId, error) => Debug.LogWarning("OnServerError called with no handler");
/// <summary>Notify subscribers when a client disconnects from this server</summary> /// <summary>
/// Notify subscribers when a client disconnects from this server
/// <para>callback(int connId)</para>
/// </summary>
public Action<int> OnServerDisconnected = (connId) => Debug.LogWarning("OnServerDisconnected called with no handler"); public Action<int> OnServerDisconnected = (connId) => Debug.LogWarning("OnServerDisconnected called with no handler");
/// <summary>Determines if the server is up and running</summary> /// <summary>
/// Determines if the server is up and running
/// </summary>
/// <returns>true if the transport is ready for connections from clients</returns>
public abstract bool ServerActive(); public abstract bool ServerActive();
/// <summary>Start listening for clients</summary> /// <summary>
/// Start listening for clients
/// </summary>
public abstract void ServerStart(); public abstract void ServerStart();
/// <summary>Send data to the client with connectionId over the given channel.</summary> /// <summary>
/// Send data to a client.
/// </summary>
/// <param name="connectionId">The client connection id to send the data to</param>
/// <param name="channelId">The channel to be used. Transports can use channels to implement
/// other features such as unreliable, encryption, compression, etc...</param>
/// <param name="data"></param>
public abstract void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment); public abstract void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment);
/// <summary>Disconnect a client from this server. Useful to kick people out.</summary> /// <summary>
/// Disconnect a client from this server. Useful to kick people out.
/// </summary>
/// <param name="connectionId">the id of the client to disconnect</param>
/// <returns>true if the client was kicked</returns>
public abstract bool ServerDisconnect(int connectionId); public abstract bool ServerDisconnect(int connectionId);
/// <summary>Get the client address, useful for IP bans etc.</summary> /// <summary>
/// Get the client address
/// </summary>
/// <param name="connectionId">id of the client</param>
/// <returns>address of the client</returns>
public abstract string ServerGetClientAddress(int connectionId); public abstract string ServerGetClientAddress(int connectionId);
/// <summary>Stop listening for clients and disconnect all existing clients</summary> /// <summary>
/// Stop listening for clients and disconnect all existing clients
/// </summary>
public abstract void ServerStop(); public abstract void ServerStop();
/// <summary>The maximum packet size for a given channel.</summary> #endregion
// Unreliable transports usually can only deliver small packets.
// Reliable fragmented channels can usually deliver large ones.
//
// GetMaxPacketSize needs to return a value at all times. Even if the
// Transport isn't running, or isn't Available(). This is because
// Fallback and Multiplex transports need to find the smallest possible
// packet size at runtime.
public abstract int GetMaxPacketSize(int channelId = Channels.DefaultReliable);
/// <summary>The maximum batch(!) size for a given channel.</summary> /// <summary>
// Uses GetMaxPacketSize by default. /// The maximum packet size for a given channel. Unreliable transports
// Some transports like kcp support large max packet sizes which should /// usually can only deliver small packets. Reliable fragmented channels
// not be used for batching all the time because they end up being too /// can usually deliver large ones.
// slow (head of line blocking etc.). ///
/// GetMaxPacketSize needs to return a value at all times. Even if the
/// Transport isn't running, or isn't Available(). This is because
/// Fallback and Multiplex transports need to find the smallest possible
/// packet size at runtime.
/// </summary>
/// <param name="channelId">channel id</param>
/// <returns>the size in bytes that can be sent via the provided channel</returns>
public abstract int GetMaxPacketSize(int channelId = Channels.Reliable);
/// <summary>
/// The maximum batch(!) size for a given channel.
/// Uses GetMaxPacketSize by default.
/// Some transports like kcp support large max packet sizes which should
/// not be used for batching all the time because they end up being too
/// slow (head of line blocking etc.).
/// </summary>
/// <param name="channelId">channel id</param>
/// <returns>the size in bytes that should be batched via the provided channel</returns>
public virtual int GetMaxBatchSize(int channelId) => public virtual int GetMaxBatchSize(int channelId) =>
GetMaxPacketSize(channelId); GetMaxPacketSize(channelId);
@ -122,12 +235,14 @@ public void Update() {}
public void LateUpdate() {} public void LateUpdate() {}
#pragma warning restore UNT0001 // Empty Unity message #pragma warning restore UNT0001 // Empty Unity message
// NetworkLoop NetworkEarly/LateUpdate were added for a proper network /// <summary>
// update order. the goal is to: /// NetworkLoop NetworkEarly/LateUpdate were added for a proper network
// process_incoming() /// update order. the goal is to:
// update_world() /// process_incoming()
// process_outgoing() /// update_world()
// in order to avoid unnecessary latency and data races. /// process_outgoing()
/// in order to avoid unnecessary latency and data races.
/// </summary>
// => split into client and server parts so that we can cleanly call // => split into client and server parts so that we can cleanly call
// them from NetworkClient/Server // them from NetworkClient/Server
// => VIRTUAL for now so we can take our time to convert transports // => VIRTUAL for now so we can take our time to convert transports
@ -137,13 +252,15 @@ public virtual void ServerEarlyUpdate() {}
public virtual void ClientLateUpdate() {} public virtual void ClientLateUpdate() {}
public virtual void ServerLateUpdate() {} public virtual void ServerLateUpdate() {}
/// <summary>Shut down the transport, both as client and server</summary> /// <summary>
/// Shut down the transport, both as client and server
/// </summary>
public abstract void Shutdown(); public abstract void Shutdown();
// called when quitting the application by closing the window / pressing /// <summary>
// stop in the editor. /// called when quitting the application by closing the window / pressing stop in the editor
// virtual so that inheriting classes' OnApplicationQuit() can call /// <para>virtual so that inheriting classes' OnApplicationQuit() can call base.OnApplicationQuit() too</para>
// base.OnApplicationQuit() too</para> /// </summary>
public virtual void OnApplicationQuit() public virtual void OnApplicationQuit()
{ {
// stop transport (e.g. to shut down threads) // stop transport (e.g. to shut down threads)

View File

@ -38,8 +38,13 @@ public enum Version
// add custom channels anymore. // add custom channels anymore.
public static class Channels public static class Channels
{ {
public const int DefaultReliable = 0; public const int Reliable = 0; // ordered
public const int DefaultUnreliable = 1; public const int Unreliable = 1; // unordered
[Obsolete("Use Channels.Reliable instead")]
public const int DefaultReliable = Reliable;
[Obsolete("Use Channels.Unreliable instead")]
public const int DefaultUnreliable = Unreliable;
} }
// -- helpers for float conversion without allocations -- // -- helpers for float conversion without allocations --

View File

@ -39,7 +39,7 @@ public void TearDown()
public void SendEmptyBatch() public void SendEmptyBatch()
{ {
// empty batch - nothing should be sent // empty batch - nothing should be sent
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(0)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(0));
} }
@ -47,7 +47,7 @@ public void SendEmptyBatch()
public void SendAlmostMaxBatchSizedMessageBatch() public void SendAlmostMaxBatchSizedMessageBatch()
{ {
// create a message < max batch size // create a message < max batch size
int max = transport.GetMaxBatchSize(Channels.DefaultReliable); int max = transport.GetMaxBatchSize(Channels.Reliable);
byte[] message = new byte[max-1]; byte[] message = new byte[max-1];
// add to batch queue // add to batch queue
@ -56,7 +56,7 @@ public void SendAlmostMaxBatchSizedMessageBatch()
batch.messages.Enqueue(writer); batch.messages.Enqueue(writer);
// send batch - client should receive that exact message // send batch - client should receive that exact message
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(1)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(1));
Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length)); Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length));
} }
@ -65,7 +65,7 @@ public void SendAlmostMaxBatchSizedMessageBatch()
public void SendMaxBatchSizedMessageBatch() public void SendMaxBatchSizedMessageBatch()
{ {
// create a message == max batch size // create a message == max batch size
int max = transport.GetMaxBatchSize(Channels.DefaultReliable); int max = transport.GetMaxBatchSize(Channels.Reliable);
byte[] message = new byte[max]; byte[] message = new byte[max];
// add to batch queue // add to batch queue
@ -74,7 +74,7 @@ public void SendMaxBatchSizedMessageBatch()
batch.messages.Enqueue(writer); batch.messages.Enqueue(writer);
// send batch - client should receive that exact message // send batch - client should receive that exact message
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(1)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(1));
Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length)); Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length));
} }
@ -97,7 +97,7 @@ public void SendTwoSmallMessagesBatch()
batch.messages.Enqueue(writerB); batch.messages.Enqueue(writerB);
// send batch - client should receive one message that contains A, B // send batch - client should receive one message that contains A, B
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(1)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(1));
MemoryTransport.Message msg = transport.clientIncoming.Dequeue(); MemoryTransport.Message msg = transport.clientIncoming.Dequeue();
Assert.That(msg.data.Length, Is.EqualTo(4)); Assert.That(msg.data.Length, Is.EqualTo(4));
@ -111,7 +111,7 @@ public void SendTwoSmallMessagesBatch()
public void SendAlmostMaxBatchSizedAndSmallMessageBatch() public void SendAlmostMaxBatchSizedAndSmallMessageBatch()
{ {
// create a message < max batch size // create a message < max batch size
int max = transport.GetMaxBatchSize(Channels.DefaultReliable); int max = transport.GetMaxBatchSize(Channels.Reliable);
byte[] almost = new byte[max-1]; byte[] almost = new byte[max-1];
// create small message // create small message
@ -129,7 +129,7 @@ public void SendAlmostMaxBatchSizedAndSmallMessageBatch()
// send batch - should send the first one and then the second one // send batch - should send the first one and then the second one
// because both together would've been > max // because both together would've been > max
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(2)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(2));
Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(almost.Length)); Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(almost.Length));
Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(small.Length)); Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(small.Length));
@ -142,8 +142,8 @@ public void SendAlmostMaxBatchSizedAndSmallMessageBatch()
[Test] [Test]
public void SendLargerMaxBatchSizedMessageBatch() public void SendLargerMaxBatchSizedMessageBatch()
{ {
int maxBatch = transport.GetMaxBatchSize(Channels.DefaultReliable); int maxBatch = transport.GetMaxBatchSize(Channels.Reliable);
int maxPacket = transport.GetMaxPacketSize(Channels.DefaultReliable); int maxPacket = transport.GetMaxPacketSize(Channels.Reliable);
// we can only tested if transport max batch < max message // we can only tested if transport max batch < max message
Assert.That(maxBatch < maxPacket, Is.True); Assert.That(maxBatch < maxPacket, Is.True);
@ -157,7 +157,7 @@ public void SendLargerMaxBatchSizedMessageBatch()
batch.messages.Enqueue(writer); batch.messages.Enqueue(writer);
// send batch - client should receive that exact message // send batch - client should receive that exact message
connection.SendBatch(Channels.DefaultReliable, batch); connection.SendBatch(Channels.Reliable, batch);
Assert.That(transport.clientIncoming.Count, Is.EqualTo(1)); Assert.That(transport.clientIncoming.Count, Is.EqualTo(1));
Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length)); Assert.That(transport.clientIncoming.Dequeue().data.Length, Is.EqualTo(message.Length));
} }

View File

@ -21,11 +21,11 @@ public void CommandAttributeTest()
{ {
CommandAttribute attrib = new CommandAttribute(); CommandAttribute attrib = new CommandAttribute();
Assert.That(attrib.channel == Channels.DefaultReliable); Assert.That(attrib.channel == Channels.Reliable);
attrib.channel = Channels.DefaultUnreliable; attrib.channel = Channels.Unreliable;
Assert.That(attrib.channel == Channels.DefaultUnreliable); Assert.That(attrib.channel == Channels.Unreliable);
} }
[Test] [Test]
@ -33,11 +33,11 @@ public void ClientRPCAttributeTest()
{ {
ClientRpcAttribute attrib = new ClientRpcAttribute(); ClientRpcAttribute attrib = new ClientRpcAttribute();
Assert.That(attrib.channel == Channels.DefaultReliable); Assert.That(attrib.channel == Channels.Reliable);
attrib.channel = Channels.DefaultUnreliable; attrib.channel = Channels.Unreliable;
Assert.That(attrib.channel == Channels.DefaultUnreliable); Assert.That(attrib.channel == Channels.Unreliable);
} }
[Test] [Test]
@ -45,9 +45,9 @@ public void TargetRPCAttributeTest()
{ {
TargetRpcAttribute attrib = new TargetRpcAttribute(); TargetRpcAttribute attrib = new TargetRpcAttribute();
Assert.That(attrib.channel == Channels.DefaultReliable); Assert.That(attrib.channel == Channels.Reliable);
attrib.channel = Channels.DefaultUnreliable; attrib.channel = Channels.Unreliable;
Assert.That(attrib.channel == 1); Assert.That(attrib.channel == 1);
} }

View File

@ -44,9 +44,9 @@ public void TestAvailable(bool available)
} }
[Test] [Test]
[TestCase(Channels.DefaultReliable, 4000)] [TestCase(Channels.Reliable, 4000)]
[TestCase(Channels.DefaultReliable, 2000)] [TestCase(Channels.Reliable, 2000)]
[TestCase(Channels.DefaultUnreliable, 4000)] [TestCase(Channels.Unreliable, 4000)]
public void TestGetMaxPacketSize(int channel, int packageSize) public void TestGetMaxPacketSize(int channel, int packageSize)
{ {
inner.GetMaxPacketSize(Arg.Any<int>()).Returns(packageSize); inner.GetMaxPacketSize(Arg.Any<int>()).Returns(packageSize);
@ -97,8 +97,8 @@ public void TestClientDisconnect()
} }
[Test] [Test]
[TestCase(Channels.DefaultReliable)] [TestCase(Channels.Reliable)]
[TestCase(Channels.DefaultUnreliable)] [TestCase(Channels.Unreliable)]
public void TestClientSend(int channel) public void TestClientSend(int channel)
{ {
byte[] array = new byte[10]; byte[] array = new byte[10];