quakeball/Assets/Scripts/Net/Endpoint/Endpoint.cs

80 lines
2.4 KiB
C#

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<uint, Thread> ListenThreads = new Dictionary<uint, Thread>();
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
}