using System.Collections.Generic; using UnityEngine; using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; namespace NeonTea.Quakeball.Net.Endpoint { public abstract class AbstractEndpoint { private Dictionary ListenThreads = new Dictionary(); public abstract void Start(string host, int port); public abstract UdpClient UdpClient { get; } public virtual void ConnectionClosed(Connection conn, ClosingReason reason) { } public void Stop() { UdpClient.Close(); foreach (Thread thread in ListenThreads.Values) { thread.Abort(); } } protected IPAddress FindAddress(string host) { IPAddress addr; try { addr = Dns.GetHostAddresses(host)[0]; } catch (ArgumentException) { addr = IPAddress.Parse(host); } return addr; } protected bool StartListen(Connection connection) { if (ListenThreads.ContainsKey(connection.uuid)) { return false; } Thread t = new Thread(ListenThread); t.Start(connection); ListenThreads.Add(connection.uuid, t); return true; } private void ListenThread(object obj) { Connection listened; try { listened = (Connection)obj; } catch (InvalidCastException) { Debug.Log($"Can not cast {obj} to a Connection"); return; } while (listened.ShouldExist) { try { Byte[] Received = UdpClient.Receive(ref listened.Endpoint); Debug.Log(Encoding.UTF8.GetString(Received)); } catch (Exception e) { Debug.Log($"Error listening to connection, closing connection: {e.ToString()}"); listened.ShouldExist = false; ConnectionClosed(listened, new ClosingReason(Reason.LISTENING_ERROR, e.ToString())); } } } } } public struct ClosingReason { public Reason Reason; public string Description; public ClosingReason(Reason reason, string description) { Reason = reason; Description = description; } } public enum Reason { LISTENING_ERROR }