Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Source/ACE.Common/Cryptography/Hash32.cs
Original file line number Diff line number Diff line change
@@ -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<byte> 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;
Expand Down
21 changes: 9 additions & 12 deletions Source/ACE.Server/Network/ClientPacketFragment.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Buffers;
using System;
using System.IO;

using ACE.Common.Cryptography;
Expand All @@ -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<byte>.Shared.Rent(PacketFragmentHeader.HeaderSize);
Span<byte> 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<byte>.Shared.Return(buffer);
}
return fragmentChecksum;
}
}
}
1 change: 0 additions & 1 deletion Source/ACE.Server/Network/NetworkSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using ACE.Server.Network.Packets;

using log4net;
using log4net.Util;

namespace ACE.Server.Network
{
Expand Down
4 changes: 2 additions & 2 deletions Source/ACE.Server/Network/PacketFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
35 changes: 12 additions & 23 deletions Source/ACE.Server/Network/PacketFragmentHeader.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Buffers.Binary;
using System.IO;

using ACE.Common.Cryptography;
Expand All @@ -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; }
Expand Down Expand Up @@ -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<byte> buffer, int offset = 0)
{
Pack(buffer, ref offset);
}

public void Pack(byte[] buffer, ref int offset)
public void Pack(Span<byte> buffer, ref int offset)
Copy link
Contributor

@FlaggAC FlaggAC Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would double check to make sure the ref int offset doesn't reference the value on the heap (it's probably fine)

{
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;
}

/// <summary>
Expand Down
60 changes: 17 additions & 43 deletions Source/ACE.Server/Network/PacketHeader.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.IO;

using ACE.Common.Cryptography;
Expand All @@ -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; }
Expand Down Expand Up @@ -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<byte> 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<byte>.Shared.Rent(HeaderSize);
Span<byte> 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<byte>.Shared.Return(buffer);
}
return checksum;
}

public bool HasFlag(PacketHeaderFlags flags) { return (flags & Flags) != 0; }
Expand Down
2 changes: 1 addition & 1 deletion Source/ACE.Server/Network/ServerPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary>
/// Make sure you call InitializeDataWriter() before you use this
Expand Down