using Mirror.SimpleWeb; using Newtonsoft.Json; using System; using System.IO; using System.Net; using System.Security.Authentication; namespace Mirror { public class SimpleWebTransport : Transport { public const string NormalScheme = "ws"; public const string SecureScheme = "wss"; public int maxMessageSize = 16 * 1024; public int handshakeMaxSize = 3000; public bool noDelay = true; public int sendTimeout = 5000; public int receiveTimeout = 20000; public int serverMaxMessagesPerTick = 10000; public int clientMaxMessagesPerTick = 1000; public bool batchSend = true; public bool waitBeforeSend = false; public bool clientUseWss; public bool sslEnabled; public string sslCertJson = "./cert.json"; public SslProtocols sslProtocols = SslProtocols.Tls12; Log.Levels _logLevels = Log.Levels.none; /// /// Gets _logLevels field /// Sets _logLevels and Log.level fields /// public Log.Levels LogLevels { get => _logLevels; set { _logLevels = value; Log.level = _logLevels; } } void OnValidate() { if (maxMessageSize > ushort.MaxValue) { Console.WriteLine($"max supported value for maxMessageSize is {ushort.MaxValue}"); maxMessageSize = ushort.MaxValue; } Log.level = _logLevels; } SimpleWebServer server; TcpConfig TcpConfig => new TcpConfig(noDelay, sendTimeout, receiveTimeout); public override bool Available() { return true; } public override int GetMaxPacketSize(int channelId = 0) { return maxMessageSize; } void Awake() { Log.level = _logLevels; SWTConfig conf = new SWTConfig(); if (!File.Exists("SWTConfig.json")) { File.WriteAllText("SWTConfig.json", JsonConvert.SerializeObject(conf, Formatting.Indented)); } else { conf = JsonConvert.DeserializeObject(File.ReadAllText("SWTConfig.json")); } maxMessageSize = conf.maxMessageSize; handshakeMaxSize = conf.handshakeMaxSize; noDelay = conf.noDelay; sendTimeout = conf.sendTimeout; receiveTimeout = conf.receiveTimeout; serverMaxMessagesPerTick = conf.serverMaxMessagesPerTick; waitBeforeSend = conf.waitBeforeSend; clientUseWss = conf.clientUseWss; sslEnabled = conf.sslEnabled; sslCertJson = conf.sslCertJson; sslProtocols = conf.sslProtocols; } public override void Shutdown() { server?.Stop(); server = null; } #region Client string GetClientScheme() => (sslEnabled || clientUseWss) ? SecureScheme : NormalScheme; string GetServerScheme() => sslEnabled ? SecureScheme : NormalScheme; public override bool ClientConnected() { // not null and not NotConnected (we want to return true if connecting or disconnecting) return false; } public override void ClientConnect(string hostname) { } public override void ClientDisconnect() { } public override void ClientSend(int channelId, ArraySegment segment) { } #endregion #region Server public override bool ServerActive() { return server != null && server.Active; } public override void ServerStart(ushort requestedPort) { if (ServerActive()) { Console.WriteLine("SimpleWebServer Already Started"); } SslConfig config = SslConfigLoader.Load(this); server = new SimpleWebServer(serverMaxMessagesPerTick, TcpConfig, maxMessageSize, handshakeMaxSize, config); server.onConnect += OnServerConnected.Invoke; server.onDisconnect += OnServerDisconnected.Invoke; server.onData += (int connId, ArraySegment data) => OnServerDataReceived.Invoke(connId, data, 0); server.onError += OnServerError.Invoke; SendLoopConfig.batchSend = batchSend || waitBeforeSend; SendLoopConfig.sleepBeforeSend = waitBeforeSend; server.Start(requestedPort); } public override void ServerStop() { if (!ServerActive()) { Console.WriteLine("SimpleWebServer Not Active"); } server.Stop(); server = null; } public override bool ServerDisconnect(int connectionId) { if (!ServerActive()) { Console.WriteLine("SimpleWebServer Not Active"); return false; } return server.KickClient(connectionId); } public override void ServerSend(int connectionId, int channelId, ArraySegment segment) { if (!ServerActive()) { Console.WriteLine("SimpleWebServer Not Active"); return; } if (segment.Count > maxMessageSize) { Console.WriteLine("Message greater than max size"); return; } if (segment.Count == 0) { Console.WriteLine("Message count was zero"); return; } server.SendOne(connectionId, segment); return; } public override string ServerGetClientAddress(int connectionId) { return server.GetClientAddress(connectionId); } public override Uri ServerUri() { UriBuilder builder = new UriBuilder { Scheme = GetServerScheme(), Host = Dns.GetHostName() }; return builder.Uri; } public void Update() { server?.ProcessMessageQueue(); } #endregion } }