diff --git a/Source/ACE.Common/Cryptography/Hash32.cs b/Source/ACE.Common/Cryptography/Hash32.cs index b538747c09..6d91ee6d3d 100644 --- a/Source/ACE.Common/Cryptography/Hash32.cs +++ b/Source/ACE.Common/Cryptography/Hash32.cs @@ -1,15 +1,16 @@ using System; +using System.Buffers.Binary; namespace ACE.Common.Cryptography { public static class Hash32 { - public static uint Calculate(byte[] data, int length) + public static uint Calculate(Span data, int length) { uint checksum = (uint)length << 16; for (int i = 0; i < length && i + 4 <= length; i += 4) - checksum += BitConverter.ToUInt32(data, i); + checksum += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(i)); int shift = 3; int j = (length / 4) * 4; diff --git a/Source/ACE.Server/Network/ClientPacketFragment.cs b/Source/ACE.Server/Network/ClientPacketFragment.cs index 7ed33f2511..503aee0911 100644 --- a/Source/ACE.Server/Network/ClientPacketFragment.cs +++ b/Source/ACE.Server/Network/ClientPacketFragment.cs @@ -1,4 +1,4 @@ -using System.Buffers; +using System; using System.IO; using ACE.Common.Cryptography; @@ -10,30 +10,27 @@ public class ClientPacketFragment : PacketFragment public bool Unpack(BinaryReader payload) { Header.Unpack(payload); + if (Header.Size - PacketFragmentHeader.HeaderSize < 0) return false; + if (Header.Size > 464) return false; + Data = payload.ReadBytes(Header.Size - PacketFragmentHeader.HeaderSize); + return true; } public uint CalculateHash32() { - byte[] buffer = ArrayPool.Shared.Rent(PacketFragmentHeader.HeaderSize); + Span buffer = stackalloc byte[PacketFragmentHeader.HeaderSize]; - try - { - Header.Pack(buffer); + Header.Pack(buffer); - uint fragmentChecksum = Hash32.Calculate(buffer, buffer.Length) + Hash32.Calculate(Data, Data.Length); + uint fragmentChecksum = Hash32.Calculate(buffer, buffer.Length) + Hash32.Calculate(Data, Data.Length); - return fragmentChecksum; - } - finally - { - ArrayPool.Shared.Return(buffer); - } + return fragmentChecksum; } } } diff --git a/Source/ACE.Server/Network/NetworkSession.cs b/Source/ACE.Server/Network/NetworkSession.cs index 42c2ac0ee5..415ca6319f 100644 --- a/Source/ACE.Server/Network/NetworkSession.cs +++ b/Source/ACE.Server/Network/NetworkSession.cs @@ -19,7 +19,6 @@ using ACE.Server.Network.Packets; using log4net; -using log4net.Util; namespace ACE.Server.Network { diff --git a/Source/ACE.Server/Network/PacketFragment.cs b/Source/ACE.Server/Network/PacketFragment.cs index 55fe0d446a..2aa0ae47df 100644 --- a/Source/ACE.Server/Network/PacketFragment.cs +++ b/Source/ACE.Server/Network/PacketFragment.cs @@ -3,8 +3,8 @@ namespace ACE.Server.Network { public abstract class PacketFragment { - public static int MaxFragementSize { get; } = 464; // Packet.MaxPacketSize - PacketHeader.HeaderSize - public static int MaxFragmentDataSize { get; } = 448; // Packet.MaxPacketSize - PacketHeader.HeaderSize - PacketFragmentHeader.HeaderSize + public const int MaxFragementSize = 464; // Packet.MaxPacketSize - PacketHeader.HeaderSize + public const int MaxFragmentDataSize = 448; // Packet.MaxPacketSize - PacketHeader.HeaderSize - PacketFragmentHeader.HeaderSize public PacketFragmentHeader Header { get; } = new PacketFragmentHeader(); public byte[] Data { get; protected set; } diff --git a/Source/ACE.Server/Network/PacketFragmentHeader.cs b/Source/ACE.Server/Network/PacketFragmentHeader.cs index 3a709aa699..dde678a288 100644 --- a/Source/ACE.Server/Network/PacketFragmentHeader.cs +++ b/Source/ACE.Server/Network/PacketFragmentHeader.cs @@ -1,3 +1,5 @@ +using System; +using System.Buffers.Binary; using System.IO; using ACE.Common.Cryptography; @@ -6,7 +8,7 @@ namespace ACE.Server.Network { public class PacketFragmentHeader { - public static int HeaderSize { get; } = 16; + public const int HeaderSize = 16; public uint Sequence { get; set; } public uint Id { get; set; } @@ -35,34 +37,21 @@ public void Unpack(byte[] buffer, int offset = 0) Queue = (ushort)(buffer[offset++] | (buffer[offset++] << 8)); } - public void Pack(byte[] buffer, int offset = 0) + public void Pack(Span buffer, int offset = 0) { Pack(buffer, ref offset); } - public void Pack(byte[] buffer, ref int offset) + public void Pack(Span buffer, ref int offset) { - buffer[offset++] = (byte)Sequence; - buffer[offset++] = (byte)(Sequence >> 8); - buffer[offset++] = (byte)(Sequence >> 16); - buffer[offset++] = (byte)(Sequence >> 24); + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), Sequence); + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 4), Id); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 8), Count); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 10), Size); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 12), Index); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 14), Queue); - buffer[offset++] = (byte)Id; - buffer[offset++] = (byte)(Id >> 8); - buffer[offset++] = (byte)(Id >> 16); - buffer[offset++] = (byte)(Id >> 24); - - buffer[offset++] = (byte)Count; - buffer[offset++] = (byte)(Count >> 8); - - buffer[offset++] = (byte)Size; - buffer[offset++] = (byte)(Size >> 8); - - buffer[offset++] = (byte)Index; - buffer[offset++] = (byte)(Index >> 8); - - buffer[offset++] = (byte)Queue; - buffer[offset++] = (byte)(Queue >> 8); + offset += 16; } /// diff --git a/Source/ACE.Server/Network/PacketHeader.cs b/Source/ACE.Server/Network/PacketHeader.cs index 563b7fec2f..82da1e9045 100644 --- a/Source/ACE.Server/Network/PacketHeader.cs +++ b/Source/ACE.Server/Network/PacketHeader.cs @@ -1,5 +1,5 @@ using System; -using System.Buffers; +using System.Buffers.Binary; using System.IO; using ACE.Common.Cryptography; @@ -8,7 +8,7 @@ namespace ACE.Server.Network { public class PacketHeader { - public static int HeaderSize { get; } = 20; + public const int HeaderSize = 20; public uint Sequence { get; set; } public PacketHeaderFlags Flags { get; set; } @@ -41,56 +41,30 @@ public void Unpack(byte[] buffer, int offset = 0) Iteration = (ushort)(buffer[offset++] | (buffer[offset++] << 8)); } - public void Pack(byte[] buffer, int offset = 0) + public void Pack(Span buffer, int offset = 0) { - buffer[offset++] = (byte)Sequence; - buffer[offset++] = (byte)(Sequence >> 8); - buffer[offset++] = (byte)(Sequence >> 16); - buffer[offset++] = (byte)(Sequence >> 24); - - buffer[offset++] = (byte)Flags; - buffer[offset++] = (byte)((int)Flags >> 8); - buffer[offset++] = (byte)((int)Flags >> 16); - buffer[offset++] = (byte)((int)Flags >> 24); - - buffer[offset++] = (byte)Checksum; - buffer[offset++] = (byte)(Checksum >> 8); - buffer[offset++] = (byte)(Checksum >> 16); - buffer[offset++] = (byte)(Checksum >> 24); - - buffer[offset++] = (byte)Id; - buffer[offset++] = (byte)(Id >> 8); - - buffer[offset++] = (byte)Time; - buffer[offset++] = (byte)(Time >> 8); - - buffer[offset++] = (byte)Size; - buffer[offset++] = (byte)(Size >> 8); - - buffer[offset++] = (byte)Iteration; - buffer[offset++] = (byte)(Iteration >> 8); + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), Sequence); + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 4), (uint)Flags); + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 8), Checksum); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 12), Id); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 14), Time); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 16), Size); + BinaryPrimitives.WriteUInt16LittleEndian(buffer.Slice(offset + 18), Iteration); } public uint CalculateHash32() { - byte[] buffer = ArrayPool.Shared.Rent(HeaderSize); + Span buffer = stackalloc byte[HeaderSize]; - try - { - uint original = Checksum; - Checksum = 0xBADD70DD; + uint original = Checksum; + Checksum = 0xBADD70DD; - Pack(buffer); + Pack(buffer); - var checksum = Hash32.Calculate(buffer, HeaderSize); - Checksum = original; + var checksum = Hash32.Calculate(buffer, HeaderSize); + Checksum = original; - return checksum; - } - finally - { - ArrayPool.Shared.Return(buffer); - } + return checksum; } public bool HasFlag(PacketHeaderFlags flags) { return (flags & Flags) != 0; } diff --git a/Source/ACE.Server/Network/ServerPacket.cs b/Source/ACE.Server/Network/ServerPacket.cs index 0989bc0ea5..54adc8ac57 100644 --- a/Source/ACE.Server/Network/ServerPacket.cs +++ b/Source/ACE.Server/Network/ServerPacket.cs @@ -8,7 +8,7 @@ namespace ACE.Server.Network public class ServerPacket : Packet { // TODO: I don't know why this value is 464. The reasoning and math needs to be documented here. - public static int MaxPacketSize { get; } = 464; + public const int MaxPacketSize = 464; /// /// Make sure you call InitializeDataWriter() before you use this