diff --git a/Source/ACE.Server/Network/ClientMessage.cs b/Source/ACE.Server/Network/ClientMessage.cs index 13dfba8282..c7f4be3afe 100644 --- a/Source/ACE.Server/Network/ClientMessage.cs +++ b/Source/ACE.Server/Network/ClientMessage.cs @@ -4,12 +4,13 @@ namespace ACE.Server.Network { public class ClientMessage { - public BinaryReader Payload { get; } - public MemoryStream Data { get; } + public BinaryReader Payload { get; } + public uint Opcode { get; } + /// stream must be at least 4 bytes in length remaining to read public ClientMessage(MemoryStream stream) { Data = stream; @@ -17,6 +18,7 @@ public ClientMessage(MemoryStream stream) Opcode = Payload.ReadUInt32(); } + /// data must be at least 4 bytes in length public ClientMessage(byte[] data) { Data = new MemoryStream(data); diff --git a/Source/ACE.Server/Network/MessageBuffer.cs b/Source/ACE.Server/Network/MessageBuffer.cs index 1ba5d7be4f..4d12b52fad 100644 --- a/Source/ACE.Server/Network/MessageBuffer.cs +++ b/Source/ACE.Server/Network/MessageBuffer.cs @@ -30,16 +30,25 @@ public void AddFragment(ClientPacketFragment fragment) } } - public ClientMessage GetMessage() + /// + /// This will return null if not enough data exists to create a valid ClientMessage (4 bytes minimum are required) + /// + public ClientMessage TryGetMessage() { fragments.Sort(delegate (ClientPacketFragment x, ClientPacketFragment y) { return x.Header.Index - y.Header.Index; }); + MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); foreach (ClientPacketFragment fragment in fragments) { writer.Write(fragment.Data); } + stream.Seek(0, SeekOrigin.Begin); + + if (stream.Length < 4) // ClientMessage must be a minimum of 4 bytes in length + return null; + return new ClientMessage(stream); } } diff --git a/Source/ACE.Server/Network/NetworkSession.cs b/Source/ACE.Server/Network/NetworkSession.cs index dc3a811e70..f7119bf1fe 100644 --- a/Source/ACE.Server/Network/NetworkSession.cs +++ b/Source/ACE.Server/Network/NetworkSession.cs @@ -475,7 +475,7 @@ private void ProcessFragment(ClientPacketFragment fragment) { // The buffer is complete, so we can go ahead and handle packetLog.DebugFormat("[{0}] Buffer {1} is complete", session.LoggingIdentifier, buffer.Sequence); - message = buffer.GetMessage(); + message = buffer.TryGetMessage(); MessageBuffer removed = null; partialFragments.TryRemove(fragment.Header.Sequence, out removed); } @@ -495,7 +495,9 @@ private void ProcessFragment(ClientPacketFragment fragment) { // Packet is not split, proceed with handling it. packetLog.DebugFormat("[{0}] Fragment {1} is not split", session.LoggingIdentifier, fragment.Header.Sequence); - message = new ClientMessage(fragment.Data); + + if (fragment.Data.Length >= 4) // ClientMessage must be a minimum of 4 bytes in length + message = new ClientMessage(fragment.Data); } // If message is not null, we have a complete message to handle