using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; public class Client { //public ConnectionMethod connection; public UdpClient udpClient; public string ipAddress; public int port; public byte networkId; public static Client GetClient(string ipAddress, int port) { foreach (Client c in clients) { if (c.ipAddress == ipAddress && c.port == port) return c; } return null; } static public List clients = new List(); public static Client NewClient() { Client client = new(); clients.Add(client); client.networkId = 0; return client; } public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { Client client = NewClient(); client.ipAddress = null; client.port = port; client.udpClient = udpClient; return client; } } public class IMessage { public IMessage() { } public IMessage(byte[] data) { Deserialize(data); } public virtual byte[] Serialize() { return null; } public virtual void Deserialize(byte[] data) { } public static void SendMsg(Client client, byte[] data) { if (client.ipAddress != null) client.udpClient.Send(data, data.Length, client.ipAddress, client.port); else ;//Debug.Log("Unknown client"); } } #region Client class ClientMsg : IMessage { public const byte length = 2; public byte clientId; public ClientMsg(byte[] data) : base(data) { } public override void Deserialize(byte[] data) { base.Deserialize(data); uint ix = 0; clientId = data[ix++]; } protected async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != ClientMsg.length) { //Debug.LogWarning($"Client msg size invalid: {packetSize}"); return false; } byte[] buffer = new byte[packetSize - 1]; // without msgId int byteCount = dataStream.Read(buffer, 0, packetSize - 1); while (byteCount < packetSize - 1) { // not all bytes have been read, wait and try again await Task.Delay(1); byteCount += dataStream.Read(buffer, byteCount, packetSize - 1 - byteCount); } ClientMsg msg = new(buffer); if (client.networkId == 0) { client.networkId = (byte)(Client.clients.Count); NetworkIdMsg.Send(client); //if (string.IsNullOrEmpty(sceneUrl) == false) //SendModelUrl(client, sceneUrl); } else if (msg.clientId == 0) { NetworkIdMsg.Send(client); //if (string.IsNullOrEmpty(sceneUrl) == false) //SendModelUrl(client, sceneUrl); } return true; } } #endregion Client #region Network Id class NetworkIdMsg : IMessage { public const byte Id = 0xA1; public const byte length = 2; public static void Send(Client client) { byte[] data = new byte[NetworkIdMsg.length]; data[0] = NetworkIdMsg.Id; data[1] = client.networkId; SendMsg(client, data); } } #endregion Network Id