From 2c49aaf4ce8b16c8598bea1d63e9e4140efd6974 Mon Sep 17 00:00:00 2001 From: teascade Date: Sat, 25 Nov 2017 15:21:06 +0200 Subject: [PATCH] Make protocol deserialize and handle packets --- TicTacToe.csproj | 1 + scripts/MainMenu.cs | 1 - scripts/net/Client.cs | 9 +++ scripts/net/Connection.cs | 4 ++ scripts/net/Peer.cs | 3 +- scripts/net/packethandling/Protocol.cs | 51 +++++++++++++ scripts/net/packethandling/Serializable.cs | 52 +++++++++++--- scripts/net/packethandling/packets/SyncPkt.cs | 12 +--- .../packethandling/packets/TextMessagePkt.cs | 15 ++++ scripts/net/syncing/ConnectionHandler.cs | 72 ++++++++++++++++--- scripts/net/syncing/PacketDistributor.cs | 1 - 11 files changed, 190 insertions(+), 31 deletions(-) create mode 100644 scripts/net/packethandling/packets/TextMessagePkt.cs diff --git a/TicTacToe.csproj b/TicTacToe.csproj index 3fbe39f..70aceb9 100644 --- a/TicTacToe.csproj +++ b/TicTacToe.csproj @@ -55,6 +55,7 @@ + diff --git a/scripts/MainMenu.cs b/scripts/MainMenu.cs index 1aa173b..cfd5487 100644 --- a/scripts/MainMenu.cs +++ b/scripts/MainMenu.cs @@ -1,7 +1,6 @@ using Godot; using System; using Network; -using Network.PacketHandling; public class MainMenu : Panel { diff --git a/scripts/net/Client.cs b/scripts/net/Client.cs index 62bf8aa..584b374 100644 --- a/scripts/net/Client.cs +++ b/scripts/net/Client.cs @@ -1,5 +1,6 @@ using Godot; using Network.PacketHandling; +using Network.PacketHandling.Packets; using System; namespace Network { @@ -10,6 +11,7 @@ namespace Network { private Connection ServerConn; private PacketBuffer TempBuffer; + private float Timer = 0; public Client(PacketPeerUDP packetPeer) : base(packetPeer, false) { @@ -27,6 +29,13 @@ namespace Network { } public override void Process(float delta) { + Timer += delta; + if (Timer > 10) { + Timer = 0; + TextMessagePkt Pkt = new TextMessagePkt(); + Pkt.Text = "Hello, Server!"; + PacketDistributor.AddReliableForAll(Pkt); + } } public override void Connected(Connection conn) { diff --git a/scripts/net/Connection.cs b/scripts/net/Connection.cs index eb6848e..a112a60 100644 --- a/scripts/net/Connection.cs +++ b/scripts/net/Connection.cs @@ -19,5 +19,9 @@ namespace Network { public bool Equals(Connection other) { return other.Address == Address && other.Port == Port; } + + public override string ToString() { + return "Connection #" + ID + " (" + Name + ")"; + } } } \ No newline at end of file diff --git a/scripts/net/Peer.cs b/scripts/net/Peer.cs index 4a783c6..d71e80e 100644 --- a/scripts/net/Peer.cs +++ b/scripts/net/Peer.cs @@ -12,7 +12,7 @@ namespace Network { private static Peer Singleton; public readonly bool IsServer; - private Protocol Protocol; + public Protocol Protocol; private int LastConnectionSended = -1; @@ -24,6 +24,7 @@ namespace Network { public Peer(PacketPeerUDP packetPeer, bool isServer) { PacketPeer = packetPeer; IsServer = isServer; + Protocol = new Protocol(this); ConnectionList = new ConnectionList(this); PacketDistributor = new PacketDistributor(this, 2); } diff --git a/scripts/net/packethandling/Protocol.cs b/scripts/net/packethandling/Protocol.cs index ddd44ed..e4db81d 100644 --- a/scripts/net/packethandling/Protocol.cs +++ b/scripts/net/packethandling/Protocol.cs @@ -1,11 +1,62 @@  +using Godot; +using Network.PacketHandling.Packets; +using System; +using System.Collections.Generic; +using Util; + namespace Network.PacketHandling { public class Protocol { + private static List RegisteredPacketTypes = new List(); + private static int TypeCounter = 0; + + private const int SYNC_PKT = 0; + private const int TEXT_MSG_PKT = 1; + private Peer Peer; public Protocol(Peer peer) { Peer = peer; + + RegisterPacketType(SYNC_PKT, typeof(SyncPkt)); + RegisterPacketType(TEXT_MSG_PKT, typeof(TextMessagePkt)); + } + + public static int GetPacketTypeIDFor(Serializable serializable) { + for (int i = 0; i < RegisteredPacketTypes.Count; i++) { + if (RegisteredPacketTypes[i] == serializable.GetType()) { + return i; + } + } + throw new InvalidOperationException("The serializable is not a registered packet type."); + } + + public Serializable DeserializePacket(PacketBuffer packetBuffer, SerializableMetadata metadata) { + switch (metadata.PacketType) { + case SYNC_PKT: { + var SyncPkt = new SyncPkt(); + SyncPkt.DeserializeWithMetadata(metadata, packetBuffer); + return SyncPkt; + } + case TEXT_MSG_PKT: { + var TextMessagePkt = new TextMessagePkt(); + TextMessagePkt.DeserializeWithMetadata(metadata, packetBuffer); + return TextMessagePkt; + } + } + throw new InvalidOperationException("PacketType " + metadata.PacketType + " not registered."); + } + + public void HandleSerializable(Serializable serializable) { + if (serializable.Metadata.PacketType == TEXT_MSG_PKT) { + var TMP = (TextMessagePkt) serializable; + GD.print("Received " + (TMP.Metadata.Reliable ? "Reliable" : "Unreliable") + " text message: " + TMP.Text); + } + } + + private static void RegisterPacketType(int id, Type type) { + RegisteredPacketTypes.Insert(id, type); } } diff --git a/scripts/net/packethandling/Serializable.cs b/scripts/net/packethandling/Serializable.cs index 7b25686..2f81057 100644 --- a/scripts/net/packethandling/Serializable.cs +++ b/scripts/net/packethandling/Serializable.cs @@ -1,24 +1,60 @@  -namespace Network.PacketHandling { - public abstract class Serializable { +using Godot; - public bool Reliable; - public int ID; +namespace Network.PacketHandling { + public abstract class Serializable : Reference { + + public SerializableMetadata Metadata; + + public Serializable() { + Metadata = new SerializableMetadata(Protocol.GetPacketTypeIDFor(this)); + } public void Serialize(PacketBuffer packetBuffer) { - packetBuffer.Write(Reliable); - packetBuffer.Write(ID); + Metadata.Serialize(packetBuffer); WriteContents(packetBuffer); } public void Deserialize(PacketBuffer packetBuffer) { - Reliable = packetBuffer.ReadBool(); - ID = packetBuffer.ReadInt(); + if (!Metadata.Deserialized) { + Metadata.Deserialize(packetBuffer); + } ReadContents(packetBuffer); } + public void DeserializeWithMetadata(SerializableMetadata metadata, PacketBuffer packetBuffer) { + Metadata = metadata; + Deserialize(packetBuffer); + } + public abstract void WriteContents(PacketBuffer packetBuffer); public abstract void ReadContents(PacketBuffer packetBuffer); } + + public class SerializableMetadata : Reference { + + public int PacketType; + public bool Reliable; + public int ID; + + public bool Deserialized = false; + + public SerializableMetadata(int packetType) { + PacketType = packetType; + } + + public void Serialize(PacketBuffer packetBuffer) { + packetBuffer.Write(PacketType); + packetBuffer.Write(Reliable); + packetBuffer.Write(ID); + } + + public void Deserialize(PacketBuffer packetBuffer) { + Deserialized = true; + PacketType = packetBuffer.ReadInt(); + Reliable = packetBuffer.ReadBool(); + ID = packetBuffer.ReadInt(); + } + } } diff --git a/scripts/net/packethandling/packets/SyncPkt.cs b/scripts/net/packethandling/packets/SyncPkt.cs index 3889970..7479678 100644 --- a/scripts/net/packethandling/packets/SyncPkt.cs +++ b/scripts/net/packethandling/packets/SyncPkt.cs @@ -3,25 +3,19 @@ namespace Network.PacketHandling.Packets { public class SyncPkt : Serializable { public int LastReliableIDReceived = -1; - public int LastUnreliableIDReceived = -1; - public int AmountOfUnreliablePackets = 0; - public int AmountOfReliablePackets = 0; + public int AmountOfPackets = 0; public override void WriteContents(PacketBuffer packetBuffer) { packetBuffer.Write(LastReliableIDReceived); - packetBuffer.Write(LastUnreliableIDReceived); - packetBuffer.Write(AmountOfUnreliablePackets); - packetBuffer.Write(AmountOfReliablePackets); + packetBuffer.Write(AmountOfPackets); } public override void ReadContents(PacketBuffer packetBuffer) { LastReliableIDReceived = packetBuffer.ReadInt(); - LastUnreliableIDReceived = packetBuffer.ReadInt(); - AmountOfUnreliablePackets = packetBuffer.ReadInt(); - AmountOfReliablePackets = packetBuffer.ReadInt(); + AmountOfPackets = packetBuffer.ReadInt(); } } } diff --git a/scripts/net/packethandling/packets/TextMessagePkt.cs b/scripts/net/packethandling/packets/TextMessagePkt.cs new file mode 100644 index 0000000..bff7f64 --- /dev/null +++ b/scripts/net/packethandling/packets/TextMessagePkt.cs @@ -0,0 +1,15 @@ + +namespace Network.PacketHandling.Packets { + public class TextMessagePkt : Serializable { + + public string Text = ""; + + public override void WriteContents(PacketBuffer packetBuffer) { + packetBuffer.Write(Text); + } + + public override void ReadContents(PacketBuffer packetBuffer) { + Text = packetBuffer.ReadString(); + } + } +} diff --git a/scripts/net/syncing/ConnectionHandler.cs b/scripts/net/syncing/ConnectionHandler.cs index c23137b..629a681 100644 --- a/scripts/net/syncing/ConnectionHandler.cs +++ b/scripts/net/syncing/ConnectionHandler.cs @@ -13,8 +13,7 @@ namespace Network.Syncing { private int LastUnreliableIDReceived = -1; private int LastReliableIDReceived = -1; - - private int LastUnreliableIDTheyReceived = -1; + private int LastReliableIDTheyReceived = -1; private float TimeSinceLastPacket = 0; @@ -31,38 +30,89 @@ namespace Network.Syncing { PacketBuffer Buffer = PacketBuffer.WithSignature(); SyncPkt Sync = new SyncPkt(); - Sync.Reliable = false; - Sync.ID = UnreliableSyncID; + Sync.Metadata.Reliable = false; + Sync.Metadata.ID = UnreliableSyncID; - Sync.Serialize(Buffer); + Sync.LastReliableIDReceived = LastReliableIDReceived; // Add Queues + var Unreliables = UnreliableQueue.ToArray(); + var Reliables = ReliableQueue.ToArray(); - GD.print("Sending sync-" + Sync.ID); + Sync.AmountOfPackets = Unreliables.Length + Reliables.Length; + + Sync.Serialize(Buffer); + + foreach (Serializable Unreliable in Unreliables) { + Unreliable.Serialize(Buffer); + } + foreach (Serializable Reliable in Reliables) { + Reliable.Serialize(Buffer); + } + + GD.print("Sending sync-" + Sync.Metadata.ID + " to " + Connection); Peer.SendBuffer(Buffer, Connection); + + // Clear unreliables-queue + + UnreliableQueue.Clear(); } public void ReceiveBuffer(PacketBuffer packetBuffer) { SyncPkt Sync = new SyncPkt(); Sync.Deserialize(packetBuffer); - GD.print("Received sync-" + Sync.ID); + GD.print("Received sync-" + Sync.Metadata.ID); + + LastReliableIDTheyReceived = Sync.LastReliableIDReceived; + + RemoveRedundantReliables(); // Read Queues + + int AmountOfPackets = Sync.AmountOfPackets; + + List Packets = new List(); + + for (int i = 0; i < AmountOfPackets; i++) { + var Metadata = new SerializableMetadata(0); + Metadata.Deserialize(packetBuffer); + Packets.Add(Peer.Protocol.DeserializePacket(packetBuffer, Metadata)); + } + + for (int i = 0; i < Packets.Count; i++) { + Serializable Curr = Packets[i]; + if (Curr.Metadata.Reliable) { + if (Curr.Metadata.ID <= LastReliableIDReceived) { + continue; + } + } else { + if (Curr.Metadata.ID <= LastUnreliableIDReceived) { + continue; + } + } + + Peer.Protocol.HandleSerializable(Curr); + } + } public void AddReliable(Serializable serializable, int ReliableID) { - serializable.Reliable = true; - serializable.ID = ReliableID; + serializable.Metadata.Reliable = true; + serializable.Metadata.ID = ReliableID; ReliableQueue.Add(serializable); } public void AddUnreliable(Serializable serializable, int UnreliableID) { - serializable.Reliable = false; - serializable.ID = UnreliableID; + serializable.Metadata.Reliable = false; + serializable.Metadata.ID = UnreliableID; UnreliableQueue.Add(serializable); } + private void RemoveRedundantReliables() { + ReliableQueue.FindAll(Packet => Packet.Metadata.ID > LastReliableIDTheyReceived); + } + } } diff --git a/scripts/net/syncing/PacketDistributor.cs b/scripts/net/syncing/PacketDistributor.cs index d1586af..63076af 100644 --- a/scripts/net/syncing/PacketDistributor.cs +++ b/scripts/net/syncing/PacketDistributor.cs @@ -28,7 +28,6 @@ namespace Network.Syncing { TimeSinceLastSync = 0; foreach (ConnectionHandler Handler in HandlerList) { - GD.print("Sending to " + Handler.Connection.Name); Handler.SerializeAndSendQueues(UnreliableIDCounter++); } }