From: Forest Date: Wed, 25 Jul 2018 18:23:18 +0000 (-0700) Subject: I don't really know, but I'm in a pretty happy place with Hazel now X-Git-Tag: 1.0.0~82 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=ab23930f276ede938e2aabc3d6a2a0f237dea195;p=rhonda%2Fimpostor.hazel.git I don't really know, but I'm in a pretty happy place with Hazel now --- diff --git a/Hazel.UnitTests/MessageReaderTests.cs b/Hazel.UnitTests/MessageReaderTests.cs index 152da54..4e507d7 100644 --- a/Hazel.UnitTests/MessageReaderTests.cs +++ b/Hazel.UnitTests/MessageReaderTests.cs @@ -125,88 +125,63 @@ namespace Hazel.UnitTests [TestMethod] public void TestMessage() { - string test = "5 32 0 0 0 22 0 4 4 2 3 208 52 4 0 1 0 0 0 2 209 52 0 0 1 210 52 0 0 1 40 0 2 208 52 4 36 0 0 128 63 0 0 128 63 0 0 192 63 0 0 112 65 1 0 0 0 1 0 0 0 2 0 0 0 1 0 0 0 1 0 0 0 22 0 4 4 2 3 211 52 4 0 1 0 0 0 2 212 52 0 0 1 213 52 0 0 1 40 0 2 211 52 4 36 0 0 128 63 0 0 128 63 0 0 192 63 0 0 112 65 1 0 0 0 1 0 0 0 2 0 0 0 1 0 0 0 1 0 0 0"; + string test = "5 32 0 0 0 5 0 5 255 255 255 255 15 2 0 2 2 2 9 0 1 4 110 123 233 131 255 127 255 127"; byte[] testValues = test.Replace("-", "").Split(' ').Select(b => byte.Parse(b)).ToArray(); - - - MessageWriter dataWriter = new MessageWriter(1024); - dataWriter.Write((byte)5); - dataWriter.Write(32); - dataWriter.StartMessage(4); // Start spawn - dataWriter.WritePacked(4); // Spawn Id = Player - dataWriter.WritePacked(2); // Owner Id - dataWriter.WritePacked(3); // Number children - - dataWriter.Write((byte)208); // NetId (packed) - dataWriter.Write((byte)52); // NetId (packed) - - dataWriter.StartMessage(1); // Start data - dataWriter.Write(""); // Name - dataWriter.Write((byte)0); // Color - dataWriter.Write((byte)0); // Important Flags - dataWriter.Write((byte)2); // Player Id - dataWriter.EndMessage(); - - dataWriter.Write((byte)209); // NetId (packed) - dataWriter.Write((byte)52); // NetId (packed) - - dataWriter.StartMessage(1); // Start data (None) - dataWriter.EndMessage(); - - dataWriter.Write((byte)210); // NetId (packed) - dataWriter.Write((byte)52); // NetId (packed) - - dataWriter.StartMessage(1); // Start data (None) - dataWriter.EndMessage(); - - dataWriter.EndMessage(); - - Console.WriteLine($"{string.Join(" ", dataWriter.Buffer.Take(dataWriter.Length))}"); - Console.WriteLine($"{string.Join(" ", testValues.Take(dataWriter.Length))}"); - - Assert.AreEqual(22 + 4 + 1 + 3, dataWriter.Length); - - MessageReader msg = MessageReader.Get(testValues, 0, testValues.Length); - Assert.AreEqual(5, msg.Tag); - Assert.AreEqual(32, msg.ReadInt32()); + msg.ReadInt32(); + msg.ReadByte(); while (msg.Position < msg.Length) { var sub = msg.ReadMessage(); - + Console.WriteLine($"Position: {msg.Position}/{msg.Length}"); + if (sub.Tag == 4) // Spawn { uint spawnId = sub.ReadPackedUInt32(); - int ownerId = sub.ReadPackedInt32(); - int numChild = sub.ReadPackedInt32(); - Console.WriteLine($"Spawning {spawnId} for {ownerId} with {numChild} children"); - for (int i = 0; i < numChild; ++i) + if (spawnId == 4) { - uint childId = sub.ReadPackedUInt32(); - var childReader = sub.ReadMessage(); - if (childId == 6736) + int ownerId = sub.ReadPackedInt32(); + int numChild = sub.ReadPackedInt32(); + Console.WriteLine($"Spawning {spawnId} for {ownerId} with {numChild} children"); + for (int i = 0; i < numChild; ++i) { - string name = childReader.ReadString(); - byte color = childReader.ReadByte(); - byte flags = childReader.ReadByte(); - uint playerId = childReader.ReadByte(); - Console.WriteLine($"Child {childId} has name='{name}' {color} {flags} {playerId}"); + uint childId = sub.ReadPackedUInt32(); + var childReader = sub.ReadMessage(); + Console.WriteLine($"Child {childId} has data ({childReader.Tag}) len={childReader.Length}"); } - else + } + else if (spawnId == 3) + { + int ownerId = sub.ReadPackedInt32(); + int numChild = sub.ReadPackedInt32(); + Console.WriteLine($"Spawning {spawnId} for {ownerId} with {numChild} children"); + for (int i = 0; i < numChild; ++i) { - Console.WriteLine($"Child {childId} has data ({childReader.Tag}) len={childReader.Length}"); + uint childId = sub.ReadPackedUInt32(); + var childReader = sub.ReadMessage(); + + var gameGuid = new Guid(childReader.ReadBytesAndSize()); + var numPlayers = childReader.ReadByte(); + Console.WriteLine($"Child {childId} has data: {gameGuid} NumPlayers= {numPlayers}"); + Console.WriteLine($"Remainder Data = {string.Join(" ", childReader.ReadBytes(childReader.Length - childReader.Position))}"); + } } + else + { + sub.Position = 0; + Console.WriteLine($"Tag: {sub.Tag}\tLength: {sub.Length}\tData = {string.Join(" ", sub.ReadBytes(sub.Length).Select(s => s.ToString()).ToArray())}"); + } } else { + sub.Position = 0; Console.WriteLine($"Tag: {sub.Tag}\tLength: {sub.Length}\tData = {string.Join(" ", sub.ReadBytes(sub.Length).Select(s => s.ToString()).ToArray())}"); } - Console.WriteLine($"Position: {msg.Position}/{msg.Length}"); } } @@ -215,5 +190,14 @@ namespace Hazel.UnitTests { Assert.IsTrue(MessageWriter.IsLittleEndian()); } + + [TestMethod] + public void Test() + { + sbyte s = -1; + Assert.AreEqual(255, (byte)s); + byte b = 255; + Assert.AreEqual(-1, (sbyte)b); + } } } \ No newline at end of file diff --git a/Hazel/Connection.cs b/Hazel/Connection.cs index 0f12223..5b59197 100644 --- a/Hazel/Connection.cs +++ b/Hazel/Connection.cs @@ -236,10 +236,10 @@ namespace Hazel /// received. The bytes and the send option that the message was sent with should be passed in to give to the /// subscribers. /// - protected void InvokeDataReceived(byte[] bytes, SendOption sendOption) + protected void InvokeDataReceived(byte[] bytes, SendOption sendOption, ushort reliableId) { DataReceivedEventArgs args = DataReceivedEventArgs.GetObject(); - args.Set(bytes, sendOption); + args.Set(bytes, sendOption, reliableId); //Make a copy to avoid race condition between null check and invocation EventHandler handler = DataReceived; diff --git a/Hazel/DataReceivedEventArgs.cs b/Hazel/DataReceivedEventArgs.cs index ef86cf9..ffdcce0 100644 --- a/Hazel/DataReceivedEventArgs.cs +++ b/Hazel/DataReceivedEventArgs.cs @@ -42,6 +42,8 @@ namespace Hazel /// public SendOption SendOption { get; private set; } + public ushort ReliableId { get; private set; } + /// /// Private constructor for object pool. /// @@ -55,10 +57,11 @@ namespace Hazel /// /// The bytes received. /// The send option used to send the data. - internal void Set(byte[] bytes, SendOption sendOption) + internal void Set(byte[] bytes, SendOption sendOption, ushort reliableId) { this.Bytes = bytes; this.SendOption = sendOption; + this.ReliableId = reliableId; } /// diff --git a/Hazel/Udp/UdpClientConnection.cs b/Hazel/Udp/UdpClientConnection.cs index 56b9688..89f408c 100644 --- a/Hazel/Udp/UdpClientConnection.cs +++ b/Hazel/Udp/UdpClientConnection.cs @@ -53,6 +53,11 @@ namespace Hazel.Udp } } + ~UdpClientConnection() + { + this.Dispose(false); + } + /// protected override void WriteBytesToConnection(byte[] bytes, int length) { @@ -67,10 +72,10 @@ namespace Hazel.Udp try { socket.BeginSendTo( - bytes, - 0, - length, - SocketFlags.None, + bytes, + 0, + length, + SocketFlags.None, RemoteEndPoint, delegate (IAsyncResult result) { @@ -87,7 +92,7 @@ namespace Hazel.Udp { HandleDisconnect(new HazelException("Could not send data as a SocketException occured.", e)); } - }, + }, null ); } @@ -210,7 +215,7 @@ namespace Hazel.Udp //Copy data to new array byte[] bytes = new byte[bytesReceived]; Buffer.BlockCopy(dataBuffer, 0, bytes, 0, bytesReceived); - + //Begin receiving again try { @@ -269,8 +274,13 @@ namespace Hazel.Udp //Dispose of the socket lock (stateLock) State = ConnectionState.NotConnected; + } + if (socket != null) + { socket.Close(); + socket.Dispose(); + socket = null; } base.Dispose(disposing); diff --git a/Hazel/Udp/UdpConnection.Fragmented.cs b/Hazel/Udp/UdpConnection.Fragmented.cs index 8de05ba..bf3b49d 100644 --- a/Hazel/Udp/UdpConnection.Fragmented.cs +++ b/Hazel/Udp/UdpConnection.Fragmented.cs @@ -96,7 +96,8 @@ namespace Hazel.Udp void FragmentedStartMessageReceive(byte[] buffer) { //Send to reliable code to send the acknowledgement - if (!ProcessReliableReceive(buffer, 5)) + ushort reliableId; + if (!ProcessReliableReceive(buffer, 5, out reliableId)) return; ushort id = (ushort)((buffer[1] << 8) + buffer[2]); @@ -125,7 +126,8 @@ namespace Hazel.Udp void FragmentedMessageReceive(byte[] buffer) { //Send to reliable code to send the acknowledgement - if (!ProcessReliableReceive(buffer, 5)) + ushort reliableId; + if (!ProcessReliableReceive(buffer, 5, out reliableId)) return; ushort id = (ushort)((buffer[1] << 8) + buffer[2]); @@ -163,7 +165,7 @@ namespace Hazel.Udp ptr += fragment.data.Length - fragment.offset; } - InvokeDataReceived(completeData, SendOption.FragmentedReliable); + InvokeDataReceived(completeData, SendOption.FragmentedReliable, 0); } /// diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index 829ca33..5b8758d 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -219,7 +219,7 @@ namespace Hazel.Udp Trace.WriteLine("Resend."); }, - resendTimeout > 0 ? resendTimeout : (AveragePingMs != 0 ? (int)AveragePingMs * 2 : 200), + resendTimeout > 0 ? resendTimeout : (AveragePingMs != 0 ? (int)AveragePingMs * 4 : 200), ackCallback ); @@ -272,8 +272,9 @@ namespace Hazel.Udp /// The buffer received. void ReliableMessageReceive(byte[] buffer) { - if (ProcessReliableReceive(buffer, 1)) - InvokeDataReceived(SendOption.Reliable, buffer, 3); + ushort id; + if (ProcessReliableReceive(buffer, 1, out id)) + InvokeDataReceived(SendOption.Reliable, buffer, 3, id); Statistics.LogReliableReceive(buffer.Length - 3, buffer.Length); } @@ -284,10 +285,10 @@ namespace Hazel.Udp /// The buffer containing the data. /// The offset of the reliable header. /// Whether the packet was a new packet or not. - bool ProcessReliableReceive(byte[] bytes, int offset) + bool ProcessReliableReceive(byte[] bytes, int offset, out ushort id) { //Get the ID form the packet - ushort id = (ushort)((bytes[offset] << 8) + bytes[offset + 1]); + id = (ushort)((bytes[offset] << 8) + bytes[offset + 1]); //Send an acknowledgement SendAck(bytes[offset], bytes[offset + 1]); @@ -334,7 +335,9 @@ namespace Hazel.Udp { //Mark items between the most recent receive and the id received as missing for (ushort i = (ushort)(reliableReceiveLast + 1); i < id; i++) + { reliableDataPacketsMissing.Add(i); + } //Update the most recently received reliableReceiveLast = id; @@ -346,7 +349,9 @@ namespace Hazel.Udp { //See if we're missing it, else this packet is a duplicate as so we return false if (!reliableDataPacketsMissing.Remove(id)) + { return false; + } } } diff --git a/Hazel/Udp/UdpConnection.cs b/Hazel/Udp/UdpConnection.cs index 4329fdf..f705bff 100644 --- a/Hazel/Udp/UdpConnection.cs +++ b/Hazel/Udp/UdpConnection.cs @@ -179,7 +179,8 @@ namespace Hazel.Udp //We need to acknowledge hello messages but dont want to invoke any events! case (byte)UdpSendOption.Hello: - ProcessReliableReceive(buffer, 1); + ushort id; + ProcessReliableReceive(buffer, 1, out id); Statistics.LogHelloReceive(buffer.Length); break; @@ -198,7 +199,7 @@ namespace Hazel.Udp //Treat everything else as unreliable default: - InvokeDataReceived(SendOption.None, buffer, 1); + InvokeDataReceived(SendOption.None, buffer, 1, 0); Statistics.LogUnreliableReceive(buffer.Length - 1, buffer.Length); break; } @@ -243,12 +244,12 @@ namespace Hazel.Udp /// The send option the message was received with. /// The buffer received. /// The offset of data in the buffer. - void InvokeDataReceived(SendOption sendOption, byte[] buffer, int dataOffset) + void InvokeDataReceived(SendOption sendOption, byte[] buffer, int dataOffset, ushort reliableId) { byte[] dataBytes = new byte[buffer.Length - dataOffset]; Buffer.BlockCopy(buffer, dataOffset, dataBytes, 0, dataBytes.Length); - InvokeDataReceived(dataBytes, sendOption); + InvokeDataReceived(dataBytes, sendOption, reliableId); } /// diff --git a/Hazel/Udp/UdpConnectionListener.cs b/Hazel/Udp/UdpConnectionListener.cs index 22bdbbc..e1cacd6 100644 --- a/Hazel/Udp/UdpConnectionListener.cs +++ b/Hazel/Udp/UdpConnectionListener.cs @@ -63,6 +63,11 @@ namespace Hazel.Udp } } + ~UdpConnectionListener() + { + this.Dispose(false); + } + /// public override void Start() { @@ -224,8 +229,12 @@ namespace Hazel.Udp /// protected override void Dispose(bool disposing) { - if (disposing) + if (listener != null) + { listener.Close(); + this.listener.Dispose(); + this.listener = null; + } base.Dispose(disposing); }