1
Fork 0
mirror of https://github.com/Steffo99/better-tee.git synced 2024-11-26 16:54:17 +00:00
better-tee/Assets/Packages/Mirror/Runtime/Transport/MultiplexTransport.cs
2019-09-17 17:43:32 +02:00

191 lines
6 KiB
C#

using System;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Mirror
{
// a transport that can listen to multiple underlying transport at the same time
public class MultiplexTransport : Transport
{
public Transport[] transports;
public void Awake()
{
if (transports == null || transports.Length == 0)
{
Debug.LogError("Multiplex transport requires at least 1 underlying transport");
}
InitClient();
InitServer();
}
#region Client
// clients always pick the first transport
void InitClient()
{
// wire all the base transports to my events
foreach (Transport transport in transports)
{
transport.OnClientConnected.AddListener(OnClientConnected.Invoke );
transport.OnClientDataReceived.AddListener(OnClientDataReceived.Invoke);
transport.OnClientError.AddListener(OnClientError.Invoke );
transport.OnClientDisconnected.AddListener(OnClientDisconnected.Invoke);
}
}
// The client just uses the first transport available
Transport GetAvailableTransport()
{
foreach (Transport transport in transports)
{
if (transport.Available())
{
return transport;
}
}
throw new Exception("No transport suitable for this platform");
}
public override void ClientConnect(string address)
{
GetAvailableTransport().ClientConnect(address);
}
public override bool ClientConnected()
{
return GetAvailableTransport().ClientConnected();
}
public override void ClientDisconnect()
{
GetAvailableTransport().ClientDisconnect();
}
public override bool ClientSend(int channelId, byte[] data)
{
return GetAvailableTransport().ClientSend(channelId, data);
}
public override int GetMaxPacketSize(int channelId = 0)
{
return GetAvailableTransport().GetMaxPacketSize(channelId);
}
#endregion
#region Server
// connection ids get mapped to base transports
// if we have 3 transports, then
// transport 0 will produce connection ids [0, 3, 6, 9, ...]
// transport 1 will produce connection ids [1, 4, 7, 10, ...]
// transport 2 will produce connection ids [2, 5, 8, 11, ...]
int FromBaseId(int transportId, int connectionId)
{
return connectionId * transports.Length + transportId;
}
int ToBaseId(int connectionId)
{
return connectionId / transports.Length;
}
int ToTransportId(int connectionId)
{
return connectionId % transports.Length;
}
void InitServer()
{
// wire all the base transports to my events
for (int i = 0; i < transports.Length; i++)
{
// this is required for the handlers, if I use i directly
// then all the handlers will use the last i
int locali = i;
Transport transport = transports[i];
transport.OnServerConnected.AddListener(baseConnectionId =>
{
OnServerConnected.Invoke(FromBaseId(locali, baseConnectionId));
});
transport.OnServerDataReceived.AddListener((baseConnectionId, data) =>
{
OnServerDataReceived.Invoke(FromBaseId(locali, baseConnectionId), data);
});
transport.OnServerError.AddListener((baseConnectionId, error) =>
{
OnServerError.Invoke(FromBaseId(locali, baseConnectionId), error);
});
transport.OnServerDisconnected.AddListener(baseConnectionId =>
{
OnServerDisconnected.Invoke(FromBaseId(locali, baseConnectionId));
});
}
}
public override bool ServerActive()
{
return transports.All(t => t.ServerActive());
}
public override string ServerGetClientAddress(int connectionId)
{
int baseConnectionId = ToBaseId(connectionId);
int transportId = ToTransportId(connectionId);
return transports[transportId].ServerGetClientAddress(baseConnectionId);
}
public override bool ServerDisconnect(int connectionId)
{
int baseConnectionId = ToBaseId(connectionId);
int transportId = ToTransportId(connectionId);
return transports[transportId].ServerDisconnect(baseConnectionId);
}
public override bool ServerSend(int connectionId, int channelId, byte[] data)
{
int baseConnectionId = ToBaseId(connectionId);
int transportId = ToTransportId(connectionId);
return transports[transportId].ServerSend(baseConnectionId, channelId, data);
}
public override void ServerStart()
{
foreach (Transport transport in transports)
{
transport.ServerStart();
}
}
public override void ServerStop()
{
foreach (Transport transport in transports)
{
transport.ServerStop();
}
}
#endregion
public override void Shutdown()
{
foreach (Transport transport in transports)
{
transport.Shutdown();
}
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (Transport transport in transports)
{
builder.AppendLine(transport.ToString());
}
return builder.ToString().Trim();
}
}
}