80 lines
2.4 KiB
C#
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
|
|||
|
}
|