2017-11-22 19:39:24 +01:00
|
|
|
using Godot;
|
|
|
|
using Network.PacketHandling;
|
2017-11-25 11:26:55 +01:00
|
|
|
using Network.Syncing;
|
2017-11-22 19:39:24 +01:00
|
|
|
using System.Threading;
|
2017-11-25 12:34:17 +01:00
|
|
|
using Util;
|
2017-11-22 19:39:24 +01:00
|
|
|
using Thread = System.Threading.Thread;
|
|
|
|
|
|
|
|
namespace Network {
|
|
|
|
public abstract class Peer : Object {
|
|
|
|
|
2017-11-25 15:23:55 +01:00
|
|
|
public const float TIMEOUT = 4f; // 4 seconds
|
|
|
|
|
2017-11-22 19:39:24 +01:00
|
|
|
private static PacketPeerUDP PacketPeer;
|
|
|
|
private static Peer Singleton;
|
2017-11-25 11:26:55 +01:00
|
|
|
public readonly bool IsServer;
|
|
|
|
|
2017-11-25 14:21:06 +01:00
|
|
|
public Protocol Protocol;
|
2017-11-25 11:26:55 +01:00
|
|
|
|
2017-11-22 19:39:24 +01:00
|
|
|
private int LastConnectionSended = -1;
|
2017-11-25 11:26:55 +01:00
|
|
|
|
2017-11-22 19:39:24 +01:00
|
|
|
private Thread ListenerThread;
|
|
|
|
|
2017-11-22 21:56:43 +01:00
|
|
|
public ConnectionList ConnectionList;
|
2017-11-25 11:26:55 +01:00
|
|
|
public PacketDistributor PacketDistributor;
|
2017-11-22 19:39:24 +01:00
|
|
|
|
2017-11-25 11:26:55 +01:00
|
|
|
public Peer(PacketPeerUDP packetPeer, bool isServer) {
|
2017-11-22 19:39:24 +01:00
|
|
|
PacketPeer = packetPeer;
|
2017-11-25 11:26:55 +01:00
|
|
|
IsServer = isServer;
|
2017-11-25 14:21:06 +01:00
|
|
|
Protocol = new Protocol(this);
|
2017-11-22 21:56:43 +01:00
|
|
|
ConnectionList = new ConnectionList(this);
|
2017-11-25 15:23:55 +01:00
|
|
|
PacketDistributor = new PacketDistributor(this, 0.5f);
|
2017-11-25 11:26:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Update(float delta) {
|
|
|
|
PacketDistributor.Update(delta);
|
|
|
|
Process(delta);
|
2017-11-22 19:39:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public abstract void Initialize(string address, int port);
|
2017-11-25 11:26:55 +01:00
|
|
|
public abstract void Process(float delta);
|
2017-11-22 19:39:24 +01:00
|
|
|
public abstract void Connected(Connection conn);
|
2017-11-25 15:23:55 +01:00
|
|
|
public abstract void Disconnected(Connection conn);
|
2017-11-22 19:39:24 +01:00
|
|
|
|
|
|
|
public void SendBuffer(PacketBuffer packetBuffer, Connection to) {
|
|
|
|
if (LastConnectionSended != to.ID) {
|
|
|
|
PacketPeer.SetDestAddress(to.Address, to.Port);
|
|
|
|
LastConnectionSended = to.ID;
|
|
|
|
}
|
|
|
|
PacketPeer.PutPacket(packetBuffer.ByteBuffer);
|
2017-11-25 15:23:55 +01:00
|
|
|
GD.print("Sent PacketBuffer with size " + packetBuffer.ByteBuffer.Length + " bytes.");
|
2017-11-22 19:39:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool StartListening(int port, string address = "*") {
|
|
|
|
if (PacketPeer.IsListening() || ListenerThread != null) {
|
|
|
|
GD.printerr("The Peer is already listening or the thread is active!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Singleton = this;
|
|
|
|
PacketPeer.Listen(port, address);
|
|
|
|
ThreadStart ChildRef = new ThreadStart(ListenerThreadMethod);
|
|
|
|
ListenerThread = new Thread(ChildRef);
|
|
|
|
ListenerThread.Start();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void ListenerThreadMethod() {
|
|
|
|
GD.print("Started Listener Thread.");
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
PacketPeer.Wait();
|
|
|
|
byte[] Buffer = PacketPeer.GetPacket();
|
|
|
|
string Address = PacketPeer.GetPacketIp();
|
|
|
|
int Port = PacketPeer.GetPacketPort();
|
|
|
|
|
|
|
|
PacketBuffer PB = PacketBuffer.FromByteBuffer(Buffer);
|
2017-11-25 11:26:55 +01:00
|
|
|
|
|
|
|
if (PB.Length > PacketBuffer.SignatureBytes.Length) {
|
2017-11-22 19:39:24 +01:00
|
|
|
bool Confirmed = true;
|
2017-11-25 11:26:55 +01:00
|
|
|
foreach (byte B in PacketBuffer.SignatureBytes) {
|
2017-11-22 19:39:24 +01:00
|
|
|
if (PB.Read() != B) {
|
|
|
|
// Ignore packet, confirmation bytes don't match up.
|
|
|
|
Confirmed = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-11-25 11:26:55 +01:00
|
|
|
|
2017-11-22 19:39:24 +01:00
|
|
|
if (Confirmed) {
|
2017-11-25 12:34:17 +01:00
|
|
|
Optional<Connection> Conn = Singleton.ConnectionList.GetOriginal(Address, Port);
|
|
|
|
if (Conn.isEmpty) {
|
|
|
|
Conn = new Connection(Address, Port);
|
|
|
|
Singleton.ConnectionList.AddConnection(Conn);
|
|
|
|
Singleton.PacketDistributor.AddHandler(Conn);
|
|
|
|
}
|
|
|
|
Singleton.PacketDistributor.HandleRawPacket(PB, Singleton.ConnectionList.GetOriginal(Conn));
|
2017-11-22 19:39:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-25 15:23:55 +01:00
|
|
|
|
|
|
|
public void Disconnect(Connection conn, DisconnectReason reason) {
|
|
|
|
GD.print(conn + " disconnected. Reason:");
|
|
|
|
switch (reason) {
|
|
|
|
case DisconnectReason.TIMEOUT: {
|
|
|
|
GD.print("TIMEOUT");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
GD.print("Unknown.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ConnectionList.RemoveConnection(conn);
|
|
|
|
PacketDistributor.RemoveHandler(conn);
|
|
|
|
}
|
2017-11-22 19:39:24 +01:00
|
|
|
}
|
|
|
|
}
|