using Godot; using Network.PacketHandling; using Network.Syncing; using System.Threading; using Thread = System.Threading.Thread; namespace Network { public abstract class Peer : Object { private static PacketPeerUDP PacketPeer; private static Peer Singleton; public readonly bool IsServer; private Protocol Protocol; private int LastConnectionSended = -1; private Thread ListenerThread; public ConnectionList ConnectionList; public PacketDistributor PacketDistributor; public Peer(PacketPeerUDP packetPeer, bool isServer) { PacketPeer = packetPeer; IsServer = isServer; ConnectionList = new ConnectionList(this); PacketDistributor = new PacketDistributor(this, 2); } public void Update(float delta) { PacketDistributor.Update(delta); Process(delta); } public abstract void Initialize(string address, int port); public abstract void Process(float delta); public abstract void Connected(Connection conn); public void SendBuffer(PacketBuffer packetBuffer, Connection to) { if (LastConnectionSended != to.ID) { PacketPeer.SetDestAddress(to.Address, to.Port); LastConnectionSended = to.ID; } PacketPeer.PutPacket(packetBuffer.ByteBuffer); } 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); if (PB.Length > PacketBuffer.SignatureBytes.Length) { bool Confirmed = true; foreach (byte B in PacketBuffer.SignatureBytes) { if (PB.Read() != B) { // Ignore packet, confirmation bytes don't match up. Confirmed = false; break; } } if (Confirmed) { Connection conn = new Connection(Address, Port); Singleton.ConnectionList.AddConnection(conn); Singleton.PacketDistributor.AddHandler(conn); Singleton.PacketDistributor.HandleRawPacket(PB, Singleton.ConnectionList.GetOriginal(conn)); } } } } } }