using Godot; using Network.PacketHandling; using System.Threading; using Thread = System.Threading.Thread; namespace Network { public abstract class Peer : Object { private static PacketPeerUDP PacketPeer; private static Peer Singleton; private int LastConnectionSended = -1; private Thread ListenerThread; private static byte[] ConfirmationBytes = { 0b10011010, 0b11010011 }; public ConnectionList ConnectionList = new ConnectionList(); public Peer(PacketPeerUDP packetPeer) { PacketPeer = packetPeer; } public abstract void Initialize(string address, int port); public abstract void Update(float delta); public abstract void ReceivePacket(PacketBuffer packetBuffer, Connection connection); 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); GD.print("Putting stuff to " + to.Address + ":" + to.Port); } 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; } public static PacketBuffer NewPacketBuffer() { PacketBuffer PB = new PacketBuffer(); foreach (byte B in ConfirmationBytes) { PB.Write(B); } return PB; } 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 > ConfirmationBytes.Length) { bool Confirmed = true; foreach (byte B in ConfirmationBytes) { 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.ReceivePacket(PB, Singleton.ConnectionList.GetOriginal(conn)); } } } } } }