mirror of
				https://github.com/DerTyp7/defrain-shooter-unity.git
				synced 2025-10-31 13:37:08 +01:00 
			
		
		
		
	CHANGED TO MIRROR
This commit is contained in:
		| @@ -0,0 +1,86 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using UnityEngine; | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     public enum ClientState | ||||
|     { | ||||
|         NotConnected = 0, | ||||
|         Connecting = 1, | ||||
|         Connected = 2, | ||||
|         Disconnecting = 3, | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// Client used to control websockets | ||||
|     /// <para>Base class used by WebSocketClientWebGl and WebSocketClientStandAlone</para> | ||||
|     /// </summary> | ||||
|     public abstract class SimpleWebClient | ||||
|     { | ||||
|         public static SimpleWebClient Create(int maxMessageSize, int maxMessagesPerTick, TcpConfig tcpConfig) | ||||
|         { | ||||
| #if UNITY_WEBGL && !UNITY_EDITOR | ||||
|             return new WebSocketClientWebGl(maxMessageSize, maxMessagesPerTick); | ||||
| #else | ||||
|             return new WebSocketClientStandAlone(maxMessageSize, maxMessagesPerTick, tcpConfig); | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|         readonly int maxMessagesPerTick; | ||||
|         protected readonly int maxMessageSize; | ||||
|         protected readonly ConcurrentQueue<Message> receiveQueue = new ConcurrentQueue<Message>(); | ||||
|         protected readonly BufferPool bufferPool; | ||||
|  | ||||
|         protected ClientState state; | ||||
|  | ||||
|         protected SimpleWebClient(int maxMessageSize, int maxMessagesPerTick) | ||||
|         { | ||||
|             this.maxMessageSize = maxMessageSize; | ||||
|             this.maxMessagesPerTick = maxMessagesPerTick; | ||||
|             bufferPool = new BufferPool(5, 20, maxMessageSize); | ||||
|         } | ||||
|  | ||||
|         public ClientState ConnectionState => state; | ||||
|  | ||||
|         public event Action onConnect; | ||||
|         public event Action onDisconnect; | ||||
|         public event Action<ArraySegment<byte>> onData; | ||||
|         public event Action<Exception> onError; | ||||
|  | ||||
|         public void ProcessMessageQueue(MonoBehaviour behaviour) | ||||
|         { | ||||
|             int processedCount = 0; | ||||
|             // check enabled every time in case behaviour was disabled after data | ||||
|             while ( | ||||
|                 behaviour.enabled && | ||||
|                 processedCount < maxMessagesPerTick && | ||||
|                 // Dequeue last | ||||
|                 receiveQueue.TryDequeue(out Message next) | ||||
|                 ) | ||||
|             { | ||||
|                 processedCount++; | ||||
|  | ||||
|                 switch (next.type) | ||||
|                 { | ||||
|                     case EventType.Connected: | ||||
|                         onConnect?.Invoke(); | ||||
|                         break; | ||||
|                     case EventType.Data: | ||||
|                         onData?.Invoke(next.data.ToSegment()); | ||||
|                         next.data.Release(); | ||||
|                         break; | ||||
|                     case EventType.Disconnected: | ||||
|                         onDisconnect?.Invoke(); | ||||
|                         break; | ||||
|                     case EventType.Error: | ||||
|                         onError?.Invoke(next.exception); | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public abstract void Connect(Uri serverAddress); | ||||
|         public abstract void Disconnect(); | ||||
|         public abstract void Send(ArraySegment<byte> segment); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 13131761a0bf5a64dadeccd700fe26e5 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,8 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: a9c19d05220a87c4cbbe4d1e422da0aa | ||||
| folderAsset: yes | ||||
| DefaultImporter: | ||||
|   externalObjects: {} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,77 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Security.Cryptography; | ||||
| using System.Text; | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Handles Handshake to the server when it first connects | ||||
|     /// <para>The client handshake does not need buffers to reduce allocations since it only happens once</para> | ||||
|     /// </summary> | ||||
|     internal class ClientHandshake | ||||
|     { | ||||
|         public bool TryHandshake(Connection conn, Uri uri) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 Stream stream = conn.stream; | ||||
|  | ||||
|                 byte[] keyBuffer = new byte[16]; | ||||
|                 using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) | ||||
|                 { | ||||
|                     rng.GetBytes(keyBuffer); | ||||
|                 } | ||||
|  | ||||
|                 string key = Convert.ToBase64String(keyBuffer); | ||||
|                 string keySum = key + Constants.HandshakeGUID; | ||||
|                 byte[] keySumBytes = Encoding.ASCII.GetBytes(keySum); | ||||
|                 Log.Verbose($"Handshake Hashing {Encoding.ASCII.GetString(keySumBytes)}"); | ||||
|  | ||||
|                 byte[] keySumHash = SHA1.Create().ComputeHash(keySumBytes); | ||||
|  | ||||
|                 string expectedResponse = Convert.ToBase64String(keySumHash); | ||||
|                 string handshake = | ||||
|                     $"GET {uri.PathAndQuery} HTTP/1.1\r\n" + | ||||
|                     $"Host: {uri.Host}:{uri.Port}\r\n" + | ||||
|                     $"Upgrade: websocket\r\n" + | ||||
|                     $"Connection: Upgrade\r\n" + | ||||
|                     $"Sec-WebSocket-Key: {key}\r\n" + | ||||
|                     $"Sec-WebSocket-Version: 13\r\n" + | ||||
|                     "\r\n"; | ||||
|                 byte[] encoded = Encoding.ASCII.GetBytes(handshake); | ||||
|                 stream.Write(encoded, 0, encoded.Length); | ||||
|  | ||||
|                 byte[] responseBuffer = new byte[1000]; | ||||
|  | ||||
|                 int? lengthOrNull = ReadHelper.SafeReadTillMatch(stream, responseBuffer, 0, responseBuffer.Length, Constants.endOfHandshake); | ||||
|  | ||||
|                 if (!lengthOrNull.HasValue) | ||||
|                 { | ||||
|                     Log.Error("Connected closed before handshake"); | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 string responseString = Encoding.ASCII.GetString(responseBuffer, 0, lengthOrNull.Value); | ||||
|  | ||||
|                 string acceptHeader = "Sec-WebSocket-Accept: "; | ||||
|                 int startIndex = responseString.IndexOf(acceptHeader) + acceptHeader.Length; | ||||
|                 int endIndex = responseString.IndexOf("\r\n", startIndex); | ||||
|                 string responseKey = responseString.Substring(startIndex, endIndex - startIndex); | ||||
|  | ||||
|                 if (responseKey != expectedResponse) | ||||
|                 { | ||||
|                     Log.Error($"Response key incorrect, Response:{responseKey} Expected:{expectedResponse}"); | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 Log.Exception(e); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 3ffdcabc9e28f764a94fc4efc82d3e8b | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,47 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Net.Security; | ||||
| using System.Net.Sockets; | ||||
| using System.Security.Cryptography.X509Certificates; | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     internal class ClientSslHelper | ||||
|     { | ||||
|         internal bool TryCreateStream(Connection conn, Uri uri) | ||||
|         { | ||||
|             NetworkStream stream = conn.client.GetStream(); | ||||
|             if (uri.Scheme != "wss") | ||||
|             { | ||||
|                 conn.stream = stream; | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 conn.stream = CreateStream(stream, uri); | ||||
|                 return true; | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 Log.Error($"Create SSLStream Failed: {e}", false); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Stream CreateStream(NetworkStream stream, Uri uri) | ||||
|         { | ||||
|             SslStream sslStream = new SslStream(stream, true, ValidateServerCertificate); | ||||
|             sslStream.AuthenticateAsClient(uri.Host); | ||||
|             return sslStream; | ||||
|         } | ||||
|  | ||||
|         static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) | ||||
|         { | ||||
|             // Do not allow this client to communicate with unauthenticated servers. | ||||
|  | ||||
|             // only accept if no errors | ||||
|             return sslPolicyErrors == SslPolicyErrors.None; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 46055a75559a79849a750f39a766db61 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,139 @@ | ||||
| using System; | ||||
| using System.Net.Sockets; | ||||
| using System.Threading; | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     public class WebSocketClientStandAlone : SimpleWebClient | ||||
|     { | ||||
|         readonly ClientSslHelper sslHelper; | ||||
|         readonly ClientHandshake handshake; | ||||
|         readonly TcpConfig tcpConfig; | ||||
|         Connection conn; | ||||
|  | ||||
|  | ||||
|         internal WebSocketClientStandAlone(int maxMessageSize, int maxMessagesPerTick, TcpConfig tcpConfig) : base(maxMessageSize, maxMessagesPerTick) | ||||
|         { | ||||
| #if UNITY_WEBGL && !UNITY_EDITOR | ||||
|             throw new NotSupportedException(); | ||||
| #else | ||||
|             sslHelper = new ClientSslHelper(); | ||||
|             handshake = new ClientHandshake(); | ||||
|             this.tcpConfig = tcpConfig; | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|         public override void Connect(Uri serverAddress) | ||||
|         { | ||||
|             state = ClientState.Connecting; | ||||
|             Thread receiveThread = new Thread(() => ConnectAndReceiveLoop(serverAddress)); | ||||
|             receiveThread.IsBackground = true; | ||||
|             receiveThread.Start(); | ||||
|         } | ||||
|  | ||||
|         void ConnectAndReceiveLoop(Uri serverAddress) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 TcpClient client = new TcpClient(); | ||||
|                 tcpConfig.ApplyTo(client); | ||||
|  | ||||
|                 // create connection object here so dispose correctly disconnects on failed connect | ||||
|                 conn = new Connection(client, AfterConnectionDisposed); | ||||
|                 conn.receiveThread = Thread.CurrentThread; | ||||
|  | ||||
|                 try | ||||
|                 { | ||||
|                     client.Connect(serverAddress.Host, serverAddress.Port); | ||||
|                 } | ||||
|                 catch (SocketException) | ||||
|                 { | ||||
|                     client.Dispose(); | ||||
|                     throw; | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 bool success = sslHelper.TryCreateStream(conn, serverAddress); | ||||
|                 if (!success) | ||||
|                 { | ||||
|                     Log.Warn("Failed to create Stream"); | ||||
|                     conn.Dispose(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 success = handshake.TryHandshake(conn, serverAddress); | ||||
|                 if (!success) | ||||
|                 { | ||||
|                     Log.Warn("Failed Handshake"); | ||||
|                     conn.Dispose(); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 Log.Info("HandShake Successful"); | ||||
|  | ||||
|                 state = ClientState.Connected; | ||||
|  | ||||
|                 receiveQueue.Enqueue(new Message(EventType.Connected)); | ||||
|  | ||||
|                 Thread sendThread = new Thread(() => | ||||
|                 { | ||||
|                     SendLoop.Config sendConfig = new SendLoop.Config( | ||||
|                         conn, | ||||
|                         bufferSize: Constants.HeaderSize + Constants.MaskSize + maxMessageSize, | ||||
|                         setMask: true); | ||||
|  | ||||
|                     SendLoop.Loop(sendConfig); | ||||
|                 }); | ||||
|  | ||||
|                 conn.sendThread = sendThread; | ||||
|                 sendThread.IsBackground = true; | ||||
|                 sendThread.Start(); | ||||
|  | ||||
|                 ReceiveLoop.Config config = new ReceiveLoop.Config(conn, | ||||
|                     maxMessageSize, | ||||
|                     false, | ||||
|                     receiveQueue, | ||||
|                     bufferPool); | ||||
|                 ReceiveLoop.Loop(config); | ||||
|             } | ||||
|             catch (ThreadInterruptedException e) { Log.InfoException(e); } | ||||
|             catch (ThreadAbortException e) { Log.InfoException(e); } | ||||
|             catch (Exception e) { Log.Exception(e); } | ||||
|             finally | ||||
|             { | ||||
|                 // close here in case connect fails | ||||
|                 conn?.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         void AfterConnectionDisposed(Connection conn) | ||||
|         { | ||||
|             state = ClientState.NotConnected; | ||||
|             // make sure Disconnected event is only called once | ||||
|             receiveQueue.Enqueue(new Message(EventType.Disconnected)); | ||||
|         } | ||||
|  | ||||
|         public override void Disconnect() | ||||
|         { | ||||
|             state = ClientState.Disconnecting; | ||||
|             Log.Info("Disconnect Called"); | ||||
|             if (conn == null) | ||||
|             { | ||||
|                 state = ClientState.NotConnected; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 conn?.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public override void Send(ArraySegment<byte> segment) | ||||
|         { | ||||
|             ArrayBuffer buffer = bufferPool.Take(segment.Count); | ||||
|             buffer.CopyFrom(segment); | ||||
|  | ||||
|             conn.sendQueue.Enqueue(buffer); | ||||
|             conn.sendPending.Set(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 05a9c87dea309e241a9185e5aa0d72ab | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,8 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 7142349d566213c4abc763afaf4d91a1 | ||||
| folderAsset: yes | ||||
| DefaultImporter: | ||||
|   externalObjects: {} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,34 @@ | ||||
| using System; | ||||
| #if UNITY_WEBGL | ||||
| using System.Runtime.InteropServices; | ||||
| #endif | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     internal static class SimpleWebJSLib | ||||
|     { | ||||
| #if UNITY_WEBGL | ||||
|         [DllImport("__Internal")] | ||||
|         internal static extern bool IsConnected(int index); | ||||
|  | ||||
| #pragma warning disable CA2101 // Specify marshaling for P/Invoke string arguments | ||||
|         [DllImport("__Internal")] | ||||
| #pragma warning restore CA2101 // Specify marshaling for P/Invoke string arguments | ||||
|         internal static extern int Connect(string address, Action<int> openCallback, Action<int> closeCallBack, Action<int, IntPtr, int> messageCallback, Action<int> errorCallback); | ||||
|  | ||||
|         [DllImport("__Internal")] | ||||
|         internal static extern void Disconnect(int index); | ||||
|  | ||||
|         [DllImport("__Internal")] | ||||
|         internal static extern bool Send(int index, byte[] array, int offset, int length); | ||||
| #else | ||||
|         internal static bool IsConnected(int index) => throw new NotSupportedException(); | ||||
|  | ||||
|         internal static int Connect(string address, Action<int> openCallback, Action<int> closeCallBack, Action<int, IntPtr, int> messageCallback, Action<int> errorCallback) => throw new NotSupportedException(); | ||||
|  | ||||
|         internal static void Disconnect(int index) => throw new NotSupportedException(); | ||||
|  | ||||
|         internal static bool Send(int index, byte[] array, int offset, int length) => throw new NotSupportedException(); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 97b96a0b65c104443977473323c2ff35 | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,99 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using AOT; | ||||
|  | ||||
| namespace Mirror.SimpleWeb | ||||
| { | ||||
|     public class WebSocketClientWebGl : SimpleWebClient | ||||
|     { | ||||
|         static readonly Dictionary<int, WebSocketClientWebGl> instances = new Dictionary<int, WebSocketClientWebGl>(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// key for instances sent between c# and js | ||||
|         /// </summary> | ||||
|         int index; | ||||
|  | ||||
|         internal WebSocketClientWebGl(int maxMessageSize, int maxMessagesPerTick) : base(maxMessageSize, maxMessagesPerTick) | ||||
|         { | ||||
| #if !UNITY_WEBGL || UNITY_EDITOR | ||||
|             throw new NotSupportedException(); | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|         public bool CheckJsConnected() => SimpleWebJSLib.IsConnected(index); | ||||
|  | ||||
|         public override void Connect(Uri serverAddress) | ||||
|         { | ||||
|             index = SimpleWebJSLib.Connect(serverAddress.ToString(), OpenCallback, CloseCallBack, MessageCallback, ErrorCallback); | ||||
|             instances.Add(index, this); | ||||
|             state = ClientState.Connecting; | ||||
|         } | ||||
|  | ||||
|         public override void Disconnect() | ||||
|         { | ||||
|             state = ClientState.Disconnecting; | ||||
|             // disconnect should cause closeCallback and OnDisconnect to be called | ||||
|             SimpleWebJSLib.Disconnect(index); | ||||
|         } | ||||
|  | ||||
|         public override void Send(ArraySegment<byte> segment) | ||||
|         { | ||||
|             if (segment.Count > maxMessageSize) | ||||
|             { | ||||
|                 Log.Error($"Cant send message with length {segment.Count} because it is over the max size of {maxMessageSize}"); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             SimpleWebJSLib.Send(index, segment.Array, 0, segment.Count); | ||||
|         } | ||||
|  | ||||
|         void onOpen() | ||||
|         { | ||||
|             receiveQueue.Enqueue(new Message(EventType.Connected)); | ||||
|             state = ClientState.Connected; | ||||
|         } | ||||
|  | ||||
|         void onClose() | ||||
|         { | ||||
|             // this code should be last in this class | ||||
|  | ||||
|             receiveQueue.Enqueue(new Message(EventType.Disconnected)); | ||||
|             state = ClientState.NotConnected; | ||||
|             instances.Remove(index); | ||||
|         } | ||||
|  | ||||
|         void onMessage(IntPtr bufferPtr, int count) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ArrayBuffer buffer = bufferPool.Take(count); | ||||
|                 buffer.CopyFrom(bufferPtr, count); | ||||
|  | ||||
|                 receiveQueue.Enqueue(new Message(buffer)); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 Log.Error($"onData {e.GetType()}: {e.Message}\n{e.StackTrace}"); | ||||
|                 receiveQueue.Enqueue(new Message(e)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         void onErr() | ||||
|         { | ||||
|             receiveQueue.Enqueue(new Message(new Exception("Javascript Websocket error"))); | ||||
|             Disconnect(); | ||||
|         } | ||||
|  | ||||
|         [MonoPInvokeCallback(typeof(Action<int>))] | ||||
|         static void OpenCallback(int index) => instances[index].onOpen(); | ||||
|  | ||||
|         [MonoPInvokeCallback(typeof(Action<int>))] | ||||
|         static void CloseCallBack(int index) => instances[index].onClose(); | ||||
|  | ||||
|         [MonoPInvokeCallback(typeof(Action<int, IntPtr, int>))] | ||||
|         static void MessageCallback(int index, IntPtr bufferPtr, int count) => instances[index].onMessage(bufferPtr, count); | ||||
|  | ||||
|         [MonoPInvokeCallback(typeof(Action<int>))] | ||||
|         static void ErrorCallback(int index) => instances[index].onErr(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 015c5b1915fd1a64cbe36444d16b2f7d | ||||
| MonoImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   defaultReferences: [] | ||||
|   executionOrder: 0 | ||||
|   icon: {instanceID: 0} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,8 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 1999985791b91b9458059e88404885a7 | ||||
| folderAsset: yes | ||||
| DefaultImporter: | ||||
|   externalObjects: {} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
| @@ -0,0 +1,105 @@ | ||||
| // this will create a global object | ||||
| const SimpleWeb = { | ||||
|     webSockets: [], | ||||
|     next: 1, | ||||
|     GetWebSocket: function (index) { | ||||
|         return SimpleWeb.webSockets[index] | ||||
|     }, | ||||
|     AddNextSocket: function (webSocket) { | ||||
|         var index = SimpleWeb.next; | ||||
|         SimpleWeb.next++; | ||||
|         SimpleWeb.webSockets[index] = webSocket; | ||||
|         return index; | ||||
|     }, | ||||
|     RemoveSocket: function (index) { | ||||
|         SimpleWeb.webSockets[index] = undefined; | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| function IsConnected(index) { | ||||
|     var webSocket = SimpleWeb.GetWebSocket(index); | ||||
|     if (webSocket) { | ||||
|         return webSocket.readyState === webSocket.OPEN; | ||||
|     } | ||||
|     else { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function Connect(addressPtr, openCallbackPtr, closeCallBackPtr, messageCallbackPtr, errorCallbackPtr) { | ||||
|     const address = Pointer_stringify(addressPtr); | ||||
|     console.log("Connecting to " + address); | ||||
|     // Create webSocket connection. | ||||
|     webSocket = new WebSocket(address); | ||||
|     webSocket.binaryType = 'arraybuffer'; | ||||
|     const index = SimpleWeb.AddNextSocket(webSocket); | ||||
|  | ||||
|     // Connection opened | ||||
|     webSocket.addEventListener('open', function (event) { | ||||
|         console.log("Connected to " + address); | ||||
|         Runtime.dynCall('vi', openCallbackPtr, [index]); | ||||
|     }); | ||||
|     webSocket.addEventListener('close', function (event) { | ||||
|         console.log("Disconnected from " + address); | ||||
|         Runtime.dynCall('vi', closeCallBackPtr, [index]); | ||||
|     }); | ||||
|  | ||||
|     // Listen for messages | ||||
|     webSocket.addEventListener('message', function (event) { | ||||
|         if (event.data instanceof ArrayBuffer) { | ||||
|             // TODO dont alloc each time | ||||
|             var array = new Uint8Array(event.data); | ||||
|             var arrayLength = array.length; | ||||
|  | ||||
|             var bufferPtr = _malloc(arrayLength); | ||||
|             var dataBuffer = new Uint8Array(HEAPU8.buffer, bufferPtr, arrayLength); | ||||
|             dataBuffer.set(array); | ||||
|  | ||||
|             Runtime.dynCall('viii', messageCallbackPtr, [index, bufferPtr, arrayLength]); | ||||
|             _free(bufferPtr); | ||||
|         } | ||||
|         else { | ||||
|             console.error("message type not supported") | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     webSocket.addEventListener('error', function (event) { | ||||
|         console.error('Socket Error', event); | ||||
|  | ||||
|         Runtime.dynCall('vi', errorCallbackPtr, [index]); | ||||
|     }); | ||||
|  | ||||
|     return index; | ||||
| } | ||||
|  | ||||
| function Disconnect(index) { | ||||
|     var webSocket = SimpleWeb.GetWebSocket(index); | ||||
|     if (webSocket) { | ||||
|         webSocket.close(1000, "Disconnect Called by Mirror"); | ||||
|     } | ||||
|  | ||||
|     SimpleWeb.RemoveSocket(index); | ||||
| } | ||||
|  | ||||
| function Send(index, arrayPtr, offset, length) { | ||||
|     var webSocket = SimpleWeb.GetWebSocket(index); | ||||
|     if (webSocket) { | ||||
|         const start = arrayPtr + offset; | ||||
|         const end = start + length; | ||||
|         const data = HEAPU8.buffer.slice(start, end); | ||||
|         webSocket.send(data); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| const SimpleWebLib = { | ||||
|     $SimpleWeb: SimpleWeb, | ||||
|     IsConnected, | ||||
|     Connect, | ||||
|     Disconnect, | ||||
|     Send | ||||
| }; | ||||
| autoAddDeps(SimpleWebLib, '$SimpleWeb'); | ||||
| mergeInto(LibraryManager.library, SimpleWebLib); | ||||
| @@ -0,0 +1,37 @@ | ||||
| fileFormatVersion: 2 | ||||
| guid: 54452a8c6d2ca9b49a8c79f81b50305c | ||||
| PluginImporter: | ||||
|   externalObjects: {} | ||||
|   serializedVersion: 2 | ||||
|   iconMap: {} | ||||
|   executionOrder: {} | ||||
|   defineConstraints: [] | ||||
|   isPreloaded: 0 | ||||
|   isOverridable: 0 | ||||
|   isExplicitlyReferenced: 0 | ||||
|   validateReferences: 1 | ||||
|   platformData: | ||||
|   - first: | ||||
|       Any:  | ||||
|     second: | ||||
|       enabled: 0 | ||||
|       settings: {} | ||||
|   - first: | ||||
|       Editor: Editor | ||||
|     second: | ||||
|       enabled: 0 | ||||
|       settings: | ||||
|         DefaultValueInitialized: true | ||||
|   - first: | ||||
|       Facebook: WebGL | ||||
|     second: | ||||
|       enabled: 1 | ||||
|       settings: {} | ||||
|   - first: | ||||
|       WebGL: WebGL | ||||
|     second: | ||||
|       enabled: 1 | ||||
|       settings: {} | ||||
|   userData:  | ||||
|   assetBundleName:  | ||||
|   assetBundleVariant:  | ||||
		Reference in New Issue
	
	Block a user
	 DerTyp187
					DerTyp187