From: Forest Date: Sun, 22 Jul 2018 19:40:53 +0000 (-0700) Subject: Some very specific and excessive testing, and a few touchups in places X-Git-Tag: 1.0.0~83 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=5c0d773cdc401ed566ace15470124eaf34710099;p=rhonda%2Fimpostor.hazel.git Some very specific and excessive testing, and a few touchups in places --- diff --git a/Hazel.UnitTests/Hazel.UnitTests.csproj b/Hazel.UnitTests/Hazel.UnitTests.csproj index 4cd3d36..0cd7986 100644 --- a/Hazel.UnitTests/Hazel.UnitTests.csproj +++ b/Hazel.UnitTests/Hazel.UnitTests.csproj @@ -8,7 +8,7 @@ Properties Hazel.UnitTests Hazel.UnitTests - v3.5 + v4.5 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -27,6 +27,7 @@ prompt 4 false + false pdbonly @@ -35,6 +36,7 @@ TRACE prompt 4 + false diff --git a/Hazel.UnitTests/MessageReaderTests.cs b/Hazel.UnitTests/MessageReaderTests.cs index 80f54eb..152da54 100644 --- a/Hazel.UnitTests/MessageReaderTests.cs +++ b/Hazel.UnitTests/MessageReaderTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Hazel.UnitTests @@ -58,6 +59,7 @@ namespace Hazel.UnitTests msg.StartMessage(1); msg.Write(Test1); msg.Write(Test2); + msg.Write(string.Empty); msg.EndMessage(); Assert.AreEqual(msg.Length, msg.Position); @@ -66,6 +68,7 @@ namespace Hazel.UnitTests Assert.AreEqual(Test1, reader.ReadString()); Assert.AreEqual(Test2, reader.ReadString()); + Assert.AreEqual(string.Empty, reader.ReadString()); } @@ -97,6 +100,9 @@ namespace Hazel.UnitTests msg.StartMessage(2); msg.Write("HO"); msg.EndMessage(); + msg.StartMessage(2); + msg.Write("NO"); + msg.EndMessage(); msg.EndMessage(); Assert.AreEqual(msg.Length, msg.Position); @@ -104,10 +110,104 @@ namespace Hazel.UnitTests MessageReader reader = MessageReader.Get(msg.Buffer, 0); Assert.AreEqual(1, reader.Tag); Assert.AreEqual(65534, reader.ReadInt32()); // Content + var sub = reader.ReadMessage(); + Assert.AreEqual(3, sub.Length); Assert.AreEqual(2, sub.Tag); Assert.AreEqual("HO", sub.ReadString()); + sub = reader.ReadMessage(); + Assert.AreEqual(3, sub.Length); + Assert.AreEqual(2, sub.Tag); + Assert.AreEqual("NO", sub.ReadString()); + } + + [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"; + 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()); + + while (msg.Position < msg.Length) + { + var sub = msg.ReadMessage(); + + 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) + { + uint childId = sub.ReadPackedUInt32(); + var childReader = sub.ReadMessage(); + if (childId == 6736) + { + 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}"); + } + else + { + Console.WriteLine($"Child {childId} has data ({childReader.Tag}) len={childReader.Length}"); + } + } + } + else + { + 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}"); + } } [TestMethod] diff --git a/Hazel.UnitTests/MessageWriterTests.cs b/Hazel.UnitTests/MessageWriterTests.cs index 571808a..b72e0da 100644 --- a/Hazel.UnitTests/MessageWriterTests.cs +++ b/Hazel.UnitTests/MessageWriterTests.cs @@ -57,6 +57,7 @@ namespace Hazel.UnitTests var msg = new MessageWriter(2048); msg.Write(Test1); msg.Write(Test2); + msg.Write(string.Empty); Assert.AreEqual(msg.Length, msg.Position); @@ -65,6 +66,7 @@ namespace Hazel.UnitTests { Assert.AreEqual(Test1, reader.ReadString()); Assert.AreEqual(Test2, reader.ReadString()); + Assert.AreEqual(string.Empty, reader.ReadString()); } } @@ -85,6 +87,55 @@ namespace Hazel.UnitTests } } + [TestMethod] + public void WritePackedUint() + { + var msg = new MessageWriter(2048); + msg.StartMessage(0); + msg.WritePacked(8u); + msg.WritePacked(250u); + msg.WritePacked(68000u); + msg.EndMessage(); + + Assert.AreEqual(3 + 1 + 2 + 3, msg.Position); + Assert.AreEqual(msg.Length, msg.Position); + + MessageReader reader = MessageReader.Get(msg.Buffer, 0); + + Assert.AreEqual(8u, reader.ReadPackedUInt32()); + Assert.AreEqual(250u, reader.ReadPackedUInt32()); + Assert.AreEqual(68000u, reader.ReadPackedUInt32()); + } + + + [TestMethod] + public void WritePackedInt() + { + var msg = new MessageWriter(2048); + msg.StartMessage(0); + msg.WritePacked(8); + msg.WritePacked(250); + msg.WritePacked(68000); + msg.WritePacked(-68000); + msg.WritePacked(-250); + msg.WritePacked(-8); + msg.EndMessage(); + + Assert.AreEqual(3 + 1 + 2 + 3 + 5 + 5 + 5, msg.Position); + Assert.AreEqual(msg.Length, msg.Position); + + MessageReader reader = MessageReader.Get(msg.Buffer, 0); + + Assert.AreEqual(8, reader.ReadPackedInt32()); + Assert.AreEqual(250, reader.ReadPackedInt32()); + Assert.AreEqual(68000, reader.ReadPackedInt32()); + + + Assert.AreEqual(-68000, reader.ReadPackedInt32()); + Assert.AreEqual(-250, reader.ReadPackedInt32()); + Assert.AreEqual(-8, reader.ReadPackedInt32()); + } + [TestMethod] public void WritesMessageLength() { diff --git a/Hazel/Hazel.csproj b/Hazel/Hazel.csproj index 236a7b1..7f33975 100644 --- a/Hazel/Hazel.csproj +++ b/Hazel/Hazel.csproj @@ -9,7 +9,7 @@ Properties Hazel Hazel - v3.5 + v4.5 512 @@ -24,6 +24,7 @@ true + false pdbonly @@ -35,6 +36,7 @@ true + false true diff --git a/Hazel/MessageReader.cs b/Hazel/MessageReader.cs index 9287023..1cea852 100644 --- a/Hazel/MessageReader.cs +++ b/Hazel/MessageReader.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Text; namespace Hazel @@ -8,20 +9,35 @@ namespace Hazel { private static readonly ObjectPool objectPool = new ObjectPool(() => new MessageReader()); - private byte[] Buffer; + public byte[] Buffer; public byte Tag; - public int End; - public int Position; + public int Length; + public int Offset { get; private set; } + public int Position + { + get { return this._position; } + set + { + this._position = value; + this.readHead = this._position + Offset; + } + } + + private int _position; + + private int readHead; + public static MessageReader Get(byte[] buffer, int offset, int length) { var output = objectPool.GetObject(); output.Buffer = buffer; - output.Position = offset; - output.End = length + offset; + output.Offset = offset; + output.Position = 0; + output.Length = length; output.Tag = output.ReadByte(); - + return output; } @@ -29,67 +45,72 @@ namespace Hazel { var output = objectPool.GetObject(); output.Buffer = buffer; - output.Position = offset; - output.End = output.ReadUInt16() + offset; + output.Offset = offset; + output.Position = 0; + + output.Length = output.ReadUInt16(); output.Tag = output.ReadByte(); + output.Offset += 3; + output.Position = 0; + return output; } /// public MessageReader ReadMessage() { - var output = MessageReader.Get(this.Buffer, this.Position); - this.Position += output.End; + var output = MessageReader.Get(this.Buffer, this.readHead); + this.Position += output.Length + 3; return output; } /// public void Recycle() { - this.Position = this.End = 0; + this.Position = this.Length = 0; objectPool.PutObject(this); } #region Read Methods public bool ReadBoolean() { - byte val = this.Buffer[this.Position++]; + byte val = this.FastByte(); return val != 0; } public sbyte ReadSByte() { - return (sbyte)this.Buffer[this.Position++]; + return (sbyte)this.FastByte(); } public byte ReadByte() { - return this.Buffer[this.Position++]; + return this.FastByte(); } public ushort ReadUInt16() { - ushort output = - (ushort)(this.Buffer[Position++] - | this.Buffer[Position++] << 8); + ushort output = + (ushort)(this.FastByte() + | this.FastByte() << 8); return output; } public short ReadInt16() { short output = - (short)(this.Buffer[Position++] - | this.Buffer[Position++] << 8); + (short)(this.FastByte() + | this.FastByte() << 8); return output; } public int ReadInt32() { - int output = this.Buffer[Position++] - | this.Buffer[Position++] << 8 - | this.Buffer[Position++] << 16 - | this.Buffer[Position++] << 24; + int output = this.FastByte() + | this.FastByte() << 8 + | this.FastByte() << 16 + | this.FastByte() << 24; return output; } @@ -97,7 +118,7 @@ namespace Hazel public unsafe float ReadSingle() { float output = 0; - fixed (byte* bufPtr = &this.Buffer[this.Position]) + fixed (byte* bufPtr = &this.Buffer[this.readHead]) { byte* outPtr = (byte*)&output; @@ -114,7 +135,7 @@ namespace Hazel public string ReadString() { int len = this.ReadPackedInt32(); - string output = UTF8Encoding.UTF8.GetString(this.Buffer, this.Position, len); + string output = UTF8Encoding.UTF8.GetString(this.Buffer, this.readHead, len); this.Position += len; return output; @@ -129,7 +150,7 @@ namespace Hazel public byte[] ReadBytes(int length) { byte[] output = new byte[length]; - Array.Copy(this.Buffer, this.Position, output, 0, output.Length); + Array.Copy(this.Buffer, this.readHead, output, 0, output.Length); this.Position += output.Length; return output; } @@ -168,6 +189,13 @@ namespace Hazel } #endregion + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private byte FastByte() + { + this._position++; + return this.Buffer[this.readHead++]; + } + public unsafe static bool IsLittleEndian() { byte b; diff --git a/Hazel/MessageWriter.cs b/Hazel/MessageWriter.cs index 7f38860..adee5a5 100644 --- a/Hazel/MessageWriter.cs +++ b/Hazel/MessageWriter.cs @@ -165,6 +165,12 @@ namespace Hazel this.Write(bytes); } + public void WriteBytesAndSize(byte[] bytes, int length) + { + this.WritePacked((uint)length); + this.Write(bytes, length); + } + public void Write(byte[] bytes) { Array.Copy(bytes, 0, this.Buffer, this.Position, bytes.Length); @@ -172,6 +178,13 @@ namespace Hazel if (this.Position > this.Length) this.Length = this.Position; } + public void Write(byte[] bytes, int length) + { + Array.Copy(bytes, 0, this.Buffer, this.Position, length); + this.Position += length; + if (this.Position > this.Length) this.Length = this.Position; + } + /// public void WritePacked(int value) { diff --git a/Hazel/Udp/UdpConnection.Reliable.cs b/Hazel/Udp/UdpConnection.Reliable.cs index b407ed5..829ca33 100644 --- a/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Hazel/Udp/UdpConnection.Reliable.cs @@ -345,9 +345,7 @@ namespace Hazel.Udp else { //See if we're missing it, else this packet is a duplicate as so we return false - if (reliableDataPacketsMissing.Contains(id)) - reliableDataPacketsMissing.Remove(id); - else + if (!reliableDataPacketsMissing.Remove(id)) return false; } } @@ -367,10 +365,9 @@ namespace Hazel.Udp lock (reliableDataPacketsSent) { //Dispose of timer and remove from dictionary - if (reliableDataPacketsSent.ContainsKey(id)) - { - Packet packet = reliableDataPacketsSent[id]; - + Packet packet; + if (reliableDataPacketsSent.TryGetValue(id, out packet)) + { packet.Acknowledged = true; if (packet.AckCallback != null)