fishbait/ServerProject-DONT-IMPORT-INTO-UNITY/MultiCompiled/Telepathy/TelepathyTransport.cs
2021-04-07 01:10:52 -05:00

195 lines
7.7 KiB
C#

// wraps Telepathy for use as HLAPI TransportLayer
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
// Replaced by Kcp November 2020
namespace Mirror
{
public class TelepathyTransport : Transport
{
// scheme used by this transport
// "tcp4" means tcp with 4 bytes header, network byte order
public const string Scheme = "tcp4";
public bool NoDelay = true;
public int SendTimeout = 5000;
public int ReceiveTimeout = 30000;
public int serverMaxMessageSize = 16 * 1024;
public int serverMaxReceivesPerTick = 10000;
public int serverSendQueueLimitPerConnection = 10000;
public int serverReceiveQueueLimitPerConnection = 10000;
public int clientMaxMessageSize = 16 * 1024;
public int clientMaxReceivesPerTick = 1000;
public int clientSendQueueLimit = 10000;
public int clientReceiveQueueLimit = 10000;
Telepathy.Client client;
Telepathy.Server server;
// scene change message needs to halt message processing immediately
// Telepathy.Tick() has a enabledCheck parameter that we can use, but
// let's only allocate it once.
Func<bool> enabledCheck;
void Awake()
{
TelepathyConfig conf = new TelepathyConfig();
if (!File.Exists("TelepathyConfig.json"))
{
File.WriteAllText("TelepathyConfig.json", JsonConvert.SerializeObject(conf, Formatting.Indented));
}
else
{
conf = JsonConvert.DeserializeObject<TelepathyConfig>(File.ReadAllText("TelepathyConfig.json"));
}
NoDelay = conf.NoDelay;
SendTimeout = conf.SendTimeout;
ReceiveTimeout = conf.ReceiveTimeout;
serverMaxMessageSize = conf.serverMaxMessageSize;
serverMaxReceivesPerTick = conf.serverMaxReceivesPerTick;
serverSendQueueLimitPerConnection = conf.serverSendQueueLimitPerConnection;
serverReceiveQueueLimitPerConnection = conf.serverReceiveQueueLimitPerConnection;
// create client & server
client = new Telepathy.Client(clientMaxMessageSize);
server = new Telepathy.Server(serverMaxMessageSize);
// tell Telepathy to use Unity's Debug.Log
Telepathy.Log.Info = Console.WriteLine;
Telepathy.Log.Warning = Console.WriteLine;
Telepathy.Log.Error = Console.WriteLine;
// client hooks
// other systems hook into transport events in OnCreate or
// OnStartRunning in no particular order. the only way to avoid
// race conditions where telepathy uses OnConnected before another
// system's hook (e.g. statistics OnData) was added is to wrap
// them all in a lambda and always call the latest hook.
// (= lazy call)
client.OnConnected = () => OnClientConnected.Invoke();
client.OnData = (segment) => OnClientDataReceived.Invoke(segment, 0);
client.OnDisconnected = () => OnClientDisconnected.Invoke();
// client configuration
client.NoDelay = NoDelay;
client.SendTimeout = SendTimeout;
client.ReceiveTimeout = ReceiveTimeout;
client.SendQueueLimit = clientSendQueueLimit;
client.ReceiveQueueLimit = clientReceiveQueueLimit;
// server hooks
// other systems hook into transport events in OnCreate or
// OnStartRunning in no particular order. the only way to avoid
// race conditions where telepathy uses OnConnected before another
// system's hook (e.g. statistics OnData) was added is to wrap
// them all in a lambda and always call the latest hook.
// (= lazy call)
server.OnConnected = (connectionId) => OnServerConnected.Invoke(connectionId);
server.OnData = (connectionId, segment) => OnServerDataReceived.Invoke(connectionId, segment, 0);
server.OnDisconnected = (connectionId) => OnServerDisconnected.Invoke(connectionId);
// server configuration
server.NoDelay = NoDelay;
server.SendTimeout = SendTimeout;
server.ReceiveTimeout = ReceiveTimeout;
server.SendQueueLimit = serverSendQueueLimitPerConnection;
server.ReceiveQueueLimit = serverReceiveQueueLimitPerConnection;
// allocate enabled check only once
enabledCheck = () => true;
Console.WriteLine("TelepathyTransport initialized!");
}
public override bool Available()
{
// C#'s built in TCP sockets run everywhere except on WebGL
return true;
}
// client
public override bool ClientConnected() => client.Connected;
public override void ClientConnect(string address) { }
public override void ClientConnect(Uri uri) { }
public override void ClientSend(int channelId, ArraySegment<byte> segment) => client.Send(segment);
public override void ClientDisconnect() => client.Disconnect();
// messages should always be processed in early update
// server
public override Uri ServerUri()
{
UriBuilder builder = new UriBuilder();
builder.Scheme = Scheme;
builder.Host = Dns.GetHostName();
return builder.Uri;
}
public override bool ServerActive() => server.Active;
public override void ServerStart(ushort requestedPort) => server.Start(requestedPort);
public override void ServerSend(int connectionId, int channelId, ArraySegment<byte> segment) => server.Send(connectionId, segment);
public override bool ServerDisconnect(int connectionId) => server.Disconnect(connectionId);
public override string ServerGetClientAddress(int connectionId)
{
try
{
return server.GetClientAddress(connectionId);
}
catch (SocketException)
{
// using server.listener.LocalEndpoint causes an Exception
// in UWP + Unity 2019:
// Exception thrown at 0x00007FF9755DA388 in UWF.exe:
// Microsoft C++ exception: Il2CppExceptionWrapper at memory
// location 0x000000E15A0FCDD0. SocketException: An address
// incompatible with the requested protocol was used at
// System.Net.Sockets.Socket.get_LocalEndPoint ()
// so let's at least catch it and recover
return "unknown";
}
}
public override void ServerStop() => server.Stop();
// messages should always be processed in early update
public void Update()
{
// note: we need to check enabled in case we set it to false
// when LateUpdate already started.
// (https://github.com/vis2k/Mirror/pull/379)
// process a maximum amount of server messages per tick
// IMPORTANT: check .enabled to stop processing immediately after a
// scene change message arrives!
server.Tick(serverMaxReceivesPerTick, enabledCheck);
}
// common
public override void Shutdown()
{
Console.WriteLine("TelepathyTransport Shutdown()");
client.Disconnect();
server.Stop();
}
public override int GetMaxPacketSize(int channelId)
{
return serverMaxMessageSize;
}
public override string ToString()
{
return "Telepathy";
}
}
}