Make protocol deserialize and handle packets

This commit is contained in:
Sofia 2017-11-25 15:21:06 +02:00
parent c928222199
commit 2c49aaf4ce
11 changed files with 190 additions and 31 deletions

View File

@ -55,6 +55,7 @@
<Compile Include="scripts\net\Connection.cs" /> <Compile Include="scripts\net\Connection.cs" />
<Compile Include="scripts\MainMenu.cs" /> <Compile Include="scripts\MainMenu.cs" />
<Compile Include="scripts\net\Net.cs" /> <Compile Include="scripts\net\Net.cs" />
<Compile Include="scripts\net\packethandling\packets\TextMessagePkt.cs" />
<Compile Include="scripts\net\packethandling\packets\SyncPkt.cs" /> <Compile Include="scripts\net\packethandling\packets\SyncPkt.cs" />
<Compile Include="scripts\net\packethandling\Protocol.cs" /> <Compile Include="scripts\net\packethandling\Protocol.cs" />
<Compile Include="scripts\net\packethandling\PacketBuffer.cs" /> <Compile Include="scripts\net\packethandling\PacketBuffer.cs" />

View File

@ -1,7 +1,6 @@
using Godot; using Godot;
using System; using System;
using Network; using Network;
using Network.PacketHandling;
public class MainMenu : Panel { public class MainMenu : Panel {

View File

@ -1,5 +1,6 @@
using Godot; using Godot;
using Network.PacketHandling; using Network.PacketHandling;
using Network.PacketHandling.Packets;
using System; using System;
namespace Network { namespace Network {
@ -10,6 +11,7 @@ namespace Network {
private Connection ServerConn; private Connection ServerConn;
private PacketBuffer TempBuffer; private PacketBuffer TempBuffer;
private float Timer = 0; private float Timer = 0;
public Client(PacketPeerUDP packetPeer) : base(packetPeer, false) { public Client(PacketPeerUDP packetPeer) : base(packetPeer, false) {
@ -27,6 +29,13 @@ namespace Network {
} }
public override void Process(float delta) { 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) { public override void Connected(Connection conn) {

View File

@ -19,5 +19,9 @@ namespace Network {
public bool Equals(Connection other) { public bool Equals(Connection other) {
return other.Address == Address && other.Port == Port; return other.Address == Address && other.Port == Port;
} }
public override string ToString() {
return "Connection #" + ID + " (" + Name + ")";
}
} }
} }

View File

@ -12,7 +12,7 @@ namespace Network {
private static Peer Singleton; private static Peer Singleton;
public readonly bool IsServer; public readonly bool IsServer;
private Protocol Protocol; public Protocol Protocol;
private int LastConnectionSended = -1; private int LastConnectionSended = -1;
@ -24,6 +24,7 @@ namespace Network {
public Peer(PacketPeerUDP packetPeer, bool isServer) { public Peer(PacketPeerUDP packetPeer, bool isServer) {
PacketPeer = packetPeer; PacketPeer = packetPeer;
IsServer = isServer; IsServer = isServer;
Protocol = new Protocol(this);
ConnectionList = new ConnectionList(this); ConnectionList = new ConnectionList(this);
PacketDistributor = new PacketDistributor(this, 2); PacketDistributor = new PacketDistributor(this, 2);
} }

View File

@ -1,11 +1,62 @@
 
using Godot;
using Network.PacketHandling.Packets;
using System;
using System.Collections.Generic;
using Util;
namespace Network.PacketHandling { namespace Network.PacketHandling {
public class Protocol { public class Protocol {
private static List<Type> RegisteredPacketTypes = new List<Type>();
private static int TypeCounter = 0;
private const int SYNC_PKT = 0;
private const int TEXT_MSG_PKT = 1;
private Peer Peer; private Peer Peer;
public Protocol(Peer peer) { public Protocol(Peer peer) {
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);
} }
} }

View File

@ -1,24 +1,60 @@
 
namespace Network.PacketHandling { using Godot;
public abstract class Serializable {
public bool Reliable; namespace Network.PacketHandling {
public int ID; public abstract class Serializable : Reference {
public SerializableMetadata Metadata;
public Serializable() {
Metadata = new SerializableMetadata(Protocol.GetPacketTypeIDFor(this));
}
public void Serialize(PacketBuffer packetBuffer) { public void Serialize(PacketBuffer packetBuffer) {
packetBuffer.Write(Reliable); Metadata.Serialize(packetBuffer);
packetBuffer.Write(ID);
WriteContents(packetBuffer); WriteContents(packetBuffer);
} }
public void Deserialize(PacketBuffer packetBuffer) { public void Deserialize(PacketBuffer packetBuffer) {
Reliable = packetBuffer.ReadBool(); if (!Metadata.Deserialized) {
ID = packetBuffer.ReadInt(); Metadata.Deserialize(packetBuffer);
}
ReadContents(packetBuffer); ReadContents(packetBuffer);
} }
public void DeserializeWithMetadata(SerializableMetadata metadata, PacketBuffer packetBuffer) {
Metadata = metadata;
Deserialize(packetBuffer);
}
public abstract void WriteContents(PacketBuffer packetBuffer); public abstract void WriteContents(PacketBuffer packetBuffer);
public abstract void ReadContents(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();
}
}
} }

View File

@ -3,25 +3,19 @@ namespace Network.PacketHandling.Packets {
public class SyncPkt : Serializable { public class SyncPkt : Serializable {
public int LastReliableIDReceived = -1; public int LastReliableIDReceived = -1;
public int LastUnreliableIDReceived = -1;
public int AmountOfUnreliablePackets = 0; public int AmountOfPackets = 0;
public int AmountOfReliablePackets = 0;
public override void WriteContents(PacketBuffer packetBuffer) { public override void WriteContents(PacketBuffer packetBuffer) {
packetBuffer.Write(LastReliableIDReceived); packetBuffer.Write(LastReliableIDReceived);
packetBuffer.Write(LastUnreliableIDReceived);
packetBuffer.Write(AmountOfUnreliablePackets); packetBuffer.Write(AmountOfPackets);
packetBuffer.Write(AmountOfReliablePackets);
} }
public override void ReadContents(PacketBuffer packetBuffer) { public override void ReadContents(PacketBuffer packetBuffer) {
LastReliableIDReceived = packetBuffer.ReadInt(); LastReliableIDReceived = packetBuffer.ReadInt();
LastUnreliableIDReceived = packetBuffer.ReadInt();
AmountOfUnreliablePackets = packetBuffer.ReadInt(); AmountOfPackets = packetBuffer.ReadInt();
AmountOfReliablePackets = packetBuffer.ReadInt();
} }
} }
} }

View File

@ -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();
}
}
}

View File

@ -13,8 +13,7 @@ namespace Network.Syncing {
private int LastUnreliableIDReceived = -1; private int LastUnreliableIDReceived = -1;
private int LastReliableIDReceived = -1; private int LastReliableIDReceived = -1;
private int LastUnreliableIDTheyReceived = -1;
private int LastReliableIDTheyReceived = -1; private int LastReliableIDTheyReceived = -1;
private float TimeSinceLastPacket = 0; private float TimeSinceLastPacket = 0;
@ -31,38 +30,89 @@ namespace Network.Syncing {
PacketBuffer Buffer = PacketBuffer.WithSignature(); PacketBuffer Buffer = PacketBuffer.WithSignature();
SyncPkt Sync = new SyncPkt(); SyncPkt Sync = new SyncPkt();
Sync.Reliable = false; Sync.Metadata.Reliable = false;
Sync.ID = UnreliableSyncID; Sync.Metadata.ID = UnreliableSyncID;
Sync.Serialize(Buffer); Sync.LastReliableIDReceived = LastReliableIDReceived;
// Add Queues // 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); Peer.SendBuffer(Buffer, Connection);
// Clear unreliables-queue
UnreliableQueue.Clear();
} }
public void ReceiveBuffer(PacketBuffer packetBuffer) { public void ReceiveBuffer(PacketBuffer packetBuffer) {
SyncPkt Sync = new SyncPkt(); SyncPkt Sync = new SyncPkt();
Sync.Deserialize(packetBuffer); Sync.Deserialize(packetBuffer);
GD.print("Received sync-" + Sync.ID); GD.print("Received sync-" + Sync.Metadata.ID);
LastReliableIDTheyReceived = Sync.LastReliableIDReceived;
RemoveRedundantReliables();
// Read Queues // Read Queues
int AmountOfPackets = Sync.AmountOfPackets;
List<Serializable> Packets = new List<Serializable>();
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) { public void AddReliable(Serializable serializable, int ReliableID) {
serializable.Reliable = true; serializable.Metadata.Reliable = true;
serializable.ID = ReliableID; serializable.Metadata.ID = ReliableID;
ReliableQueue.Add(serializable); ReliableQueue.Add(serializable);
} }
public void AddUnreliable(Serializable serializable, int UnreliableID) { public void AddUnreliable(Serializable serializable, int UnreliableID) {
serializable.Reliable = false; serializable.Metadata.Reliable = false;
serializable.ID = UnreliableID; serializable.Metadata.ID = UnreliableID;
UnreliableQueue.Add(serializable); UnreliableQueue.Add(serializable);
} }
private void RemoveRedundantReliables() {
ReliableQueue.FindAll(Packet => Packet.Metadata.ID > LastReliableIDTheyReceived);
}
} }
} }

View File

@ -28,7 +28,6 @@ namespace Network.Syncing {
TimeSinceLastSync = 0; TimeSinceLastSync = 0;
foreach (ConnectionHandler Handler in HandlerList) { foreach (ConnectionHandler Handler in HandlerList) {
GD.print("Sending to " + Handler.Connection.Name);
Handler.SerializeAndSendQueues(UnreliableIDCounter++); Handler.SerializeAndSendQueues(UnreliableIDCounter++);
} }
} }