using UnityEngine; using System.Net; using System; using System.Net.Sockets; using System.Threading; using NeonTea.Quakeball.TeaNet.Packets; namespace NeonTea.Quakeball.TeaNet.Peers { /// Manager for the thread that listens from the given endpoint. Initiated with public class ListenerThread { private IPEndPoint EndPoint; private Thread Thread; private Peer Peer; public Connection LastSentConnection; private static int[] CONN_LOST_CODES = new int[] { 10054, 10051 }; /// The amount of bytes received since the last clear interval from Peer public int BytesReceived; /// The amount of bytes received since the last clear interval from Peer public int MessagesReceived; public ListenerThread(Peer peer, IPEndPoint endpoint) { EndPoint = endpoint; Peer = peer; } public bool Start() { if (Thread != null) { return false; } Thread t = new Thread(new ThreadStart(ListenThreadMethod)); t.Start(); Thread = t; return true; } public bool Stop() { if (Thread == null) { return false; } Thread.Abort(); return true; } private void ListenThreadMethod() { try { while (Thread.CurrentThread.IsAlive) { if (Peer.UdpClient.Available > 0) { IPEndPoint Listened = new IPEndPoint(EndPoint.Address, EndPoint.Port); ByteBuffer Buffer = new ByteBuffer(); try { Buffer = new ByteBuffer(Peer.UdpClient.Receive(ref Listened)); } catch (SocketException e) { if (Array.Exists(CONN_LOST_CODES, x => x == e.ErrorCode)) { if (LastSentConnection != null) { LastSentConnection.Status = ConnectionStatus.Lost; Peer.MessageListener.Err($"Connection lost to {LastSentConnection.Endpoint}: {e.ToString()}"); } } else { Peer.MessageListener.Err($"Listener error: {e.ToString()}"); } } if (Buffer.ReadFingerprint(Peer.Fingerprint)) { Peer.ConnectionManager.Handle(Listened, Buffer); BytesReceived += Buffer.Size; MessagesReceived++; } } } } catch (ThreadAbortException) { Peer.MessageListener.Message("Listener Thread stopped"); } } } }