Skip to content

Commit 766d690

Browse files
andrews-unityShadauxCatnetcode-ci-service
authored
fix: increases maximum message size to int.MaxValue (#1384) (#1462)
* fix: increases maximum message size to int.MaxValue * Changelog entry * - Fixed tools tests - Fixed incorrect reporting of message size for Named and Unnamed message, not taking packing into account - Fixed OnBeforeMessageRecieved() and OnAfterMessageReceived() being called twice for messages that are deferred when received * Moved changelog entry to Unreleased * Reverted unrelated change. * Standards... Co-authored-by: Jaedyn Draper <[email protected]> Co-authored-by: Unity Netcode CI <[email protected]>
1 parent 2ad7ccb commit 766d690

15 files changed

+142
-108
lines changed

com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConstants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ namespace Unity.Netcode
55
/// </summary>
66
internal static class NetworkConstants
77
{
8-
internal const string PROTOCOL_VERSION = "14.0.0";
8+
internal const string PROTOCOL_VERSION = "15.0.0";
99
}
1010
}

com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ internal void __sendServerRpc(FastBufferWriter writer, uint rpcMethodId, ServerR
8282
SystemOwner = NetworkManager,
8383
// header information isn't valid since it's not a real message.
8484
// Passing false to canDefer prevents it being accessed.
85-
Header = new MessageHeader()
85+
Header = new MessageHeader(),
86+
SerializedHeaderSize = 0,
8687
};
8788
message.Handle(tempBuffer, context, NetworkManager, NetworkManager.ServerClientId, false);
8889
rpcMessageSize = tempBuffer.Length;
@@ -188,7 +189,8 @@ internal unsafe void __sendClientRpc(FastBufferWriter writer, uint rpcMethodId,
188189
SystemOwner = NetworkManager,
189190
// header information isn't valid since it's not a real message.
190191
// Passing false to canDefer prevents it being accessed.
191-
Header = new MessageHeader()
192+
Header = new MessageHeader(),
193+
SerializedHeaderSize = 0,
192194
};
193195
message.Handle(tempBuffer, context, NetworkManager, NetworkManager.ServerClientId, false);
194196
messageSize = tempBuffer.Length;

com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal CustomMessagingManager(NetworkManager networkManager)
2828
/// </summary>
2929
public event UnnamedMessageDelegate OnUnnamedMessage;
3030

31-
internal void InvokeUnnamedMessage(ulong clientId, FastBufferReader reader)
31+
internal void InvokeUnnamedMessage(ulong clientId, FastBufferReader reader, int serializedHeaderSize)
3232
{
3333
if (OnUnnamedMessage != null)
3434
{
@@ -40,7 +40,7 @@ internal void InvokeUnnamedMessage(ulong clientId, FastBufferReader reader)
4040
((UnnamedMessageDelegate)handler).Invoke(clientId, reader);
4141
}
4242
}
43-
m_NetworkManager.NetworkMetrics.TrackUnnamedMessageReceived(clientId, reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
43+
m_NetworkManager.NetworkMetrics.TrackUnnamedMessageReceived(clientId, reader.Length + serializedHeaderSize);
4444
}
4545

4646
/// <summary>
@@ -115,9 +115,9 @@ public void SendUnnamedMessage(ulong clientId, FastBufferWriter messageBuffer, N
115115
private Dictionary<ulong, string> m_MessageHandlerNameLookup32 = new Dictionary<ulong, string>();
116116
private Dictionary<ulong, string> m_MessageHandlerNameLookup64 = new Dictionary<ulong, string>();
117117

118-
internal void InvokeNamedMessage(ulong hash, ulong sender, FastBufferReader reader)
118+
internal void InvokeNamedMessage(ulong hash, ulong sender, FastBufferReader reader, int serializedHeaderSize)
119119
{
120-
var bytesCount = reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>();
120+
var bytesCount = reader.Length + serializedHeaderSize;
121121

122122
if (m_NetworkManager == null)
123123
{

com.unity.netcode.gameobjects/Runtime/Messaging/MessageHeader.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ internal struct MessageHeader
1111
/// unchanged - if new messages are added or messages are removed, MessageType assignments may be
1212
/// calculated differently.
1313
/// </summary>
14-
public byte MessageType;
14+
public uint MessageType;
1515

1616
/// <summary>
1717
/// The total size of the message, NOT including the header.
18+
/// Stored as a uint to avoid zig-zag encoding, but capped at int.MaxValue.
1819
/// </summary>
19-
public ushort MessageSize;
20+
public uint MessageSize;
2021
}
2122
}

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/NamedMessage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public static void Receive(FastBufferReader reader, in NetworkContext context)
1616
var message = new NamedMessage();
1717
reader.ReadValueSafe(out message.Hash);
1818

19-
((NetworkManager)context.SystemOwner).CustomMessagingManager.InvokeNamedMessage(message.Hash, context.SenderId, reader);
19+
((NetworkManager)context.SystemOwner).CustomMessagingManager.InvokeNamedMessage(message.Hash, context.SenderId, reader, context.SerializedHeaderSize);
2020
}
2121
}
2222
}

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/UnnamedMessage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public unsafe void Serialize(FastBufferWriter writer)
1111

1212
public static void Receive(FastBufferReader reader, in NetworkContext context)
1313
{
14-
((NetworkManager)context.SystemOwner).CustomMessagingManager.InvokeUnnamedMessage(context.SenderId, reader);
14+
((NetworkManager)context.SystemOwner).CustomMessagingManager.InvokeUnnamedMessage(context.SenderId, reader, context.SerializedHeaderSize);
1515
}
1616
}
1717
}

com.unity.netcode.gameobjects/Runtime/Messaging/MessagingSystem.cs

Lines changed: 77 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ private struct ReceiveQueueItem
2323
public MessageHeader Header;
2424
public ulong SenderId;
2525
public float Timestamp;
26+
public int MessageHeaderSerializedSize;
2627
}
2728

2829
private struct SendQueueItem
@@ -46,27 +47,27 @@ public SendQueueItem(NetworkDelivery delivery, int writerSize, Allocator writerA
4647
private MessageHandler[] m_MessageHandlers = new MessageHandler[255];
4748
private Type[] m_ReverseTypeMap = new Type[255];
4849

49-
private Dictionary<Type, byte> m_MessageTypes = new Dictionary<Type, byte>();
50+
private Dictionary<Type, uint> m_MessageTypes = new Dictionary<Type, uint>();
5051
private Dictionary<ulong, NativeList<SendQueueItem>> m_SendQueues = new Dictionary<ulong, NativeList<SendQueueItem>>();
5152

5253
private List<INetworkHooks> m_Hooks = new List<INetworkHooks>();
5354

54-
private byte m_HighMessageType;
55+
private uint m_HighMessageType;
5556
private object m_Owner;
5657
private IMessageSender m_MessageSender;
5758
private bool m_Disposed;
5859

5960
internal Type[] MessageTypes => m_ReverseTypeMap;
6061
internal MessageHandler[] MessageHandlers => m_MessageHandlers;
61-
internal int MessageHandlerCount => m_HighMessageType;
62+
internal uint MessageHandlerCount => m_HighMessageType;
6263

63-
internal byte GetMessageType(Type t)
64+
internal uint GetMessageType(Type t)
6465
{
6566
return m_MessageTypes[t];
6667
}
6768

6869
public const int NON_FRAGMENTED_MESSAGE_MAX_SIZE = 1300;
69-
public const int FRAGMENTED_MESSAGE_MAX_SIZE = 64000;
70+
public const int FRAGMENTED_MESSAGE_MAX_SIZE = int.MaxValue;
7071

7172
internal struct MessageWithHandler
7273
{
@@ -165,14 +166,23 @@ internal void HandleIncomingData(ulong clientId, ArraySegment<byte> data, float
165166

166167
for (var messageIdx = 0; messageIdx < batchHeader.BatchSize; ++messageIdx)
167168
{
168-
if (!batchReader.TryBeginRead(sizeof(MessageHeader)))
169+
170+
var messageHeader = new MessageHeader();
171+
var position = batchReader.Position;
172+
try
173+
{
174+
ByteUnpacker.ReadValueBitPacked(batchReader, out messageHeader.MessageType);
175+
ByteUnpacker.ReadValueBitPacked(batchReader, out messageHeader.MessageSize);
176+
}
177+
catch (OverflowException)
169178
{
170179
NetworkLog.LogWarning("Received a batch that didn't have enough data for all of its batches, ending early!");
171-
return;
180+
throw;
172181
}
173-
batchReader.ReadValue(out MessageHeader messageHeader);
174182

175-
if (!batchReader.TryBeginRead(messageHeader.MessageSize))
183+
var receivedHeaderSize = batchReader.Position - position;
184+
185+
if (!batchReader.TryBeginRead((int)messageHeader.MessageSize))
176186
{
177187
NetworkLog.LogWarning("Received a message that claimed a size larger than the packet, ending early!");
178188
return;
@@ -185,9 +195,10 @@ internal void HandleIncomingData(ulong clientId, ArraySegment<byte> data, float
185195
// Copy the data for this message into a new FastBufferReader that owns that memory.
186196
// We can't guarantee the memory in the ArraySegment stays valid because we don't own it,
187197
// so we must move it to memory we do own.
188-
Reader = new FastBufferReader(batchReader.GetUnsafePtrAtCurrentPosition(), Allocator.TempJob, messageHeader.MessageSize)
198+
Reader = new FastBufferReader(batchReader.GetUnsafePtrAtCurrentPosition(), Allocator.TempJob, (int)messageHeader.MessageSize),
199+
MessageHeaderSerializedSize = receivedHeaderSize,
189200
});
190-
batchReader.Seek(batchReader.Position + messageHeader.MessageSize);
201+
batchReader.Seek(batchReader.Position + (int)messageHeader.MessageSize);
191202
}
192203
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
193204
{
@@ -210,7 +221,7 @@ private bool CanReceive(ulong clientId, Type messageType)
210221
return true;
211222
}
212223

213-
public void HandleMessage(in MessageHeader header, FastBufferReader reader, ulong senderId, float timestamp)
224+
public void HandleMessage(in MessageHeader header, FastBufferReader reader, ulong senderId, float timestamp, int serializedHeaderSize)
214225
{
215226
if (header.MessageType >= m_HighMessageType)
216227
{
@@ -223,8 +234,10 @@ public void HandleMessage(in MessageHeader header, FastBufferReader reader, ulon
223234
SystemOwner = m_Owner,
224235
SenderId = senderId,
225236
Timestamp = timestamp,
226-
Header = header
237+
Header = header,
238+
SerializedHeaderSize = serializedHeaderSize,
227239
};
240+
228241
var type = m_ReverseTypeMap[header.MessageType];
229242
if (!CanReceive(senderId, type))
230243
{
@@ -236,6 +249,7 @@ public void HandleMessage(in MessageHeader header, FastBufferReader reader, ulon
236249
{
237250
m_Hooks[hookIdx].OnBeforeReceiveMessage(senderId, type, reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
238251
}
252+
239253
var handler = m_MessageHandlers[header.MessageType];
240254
using (reader)
241255
{
@@ -265,7 +279,7 @@ internal unsafe void ProcessIncomingMessageQueue()
265279
{
266280
// Avoid copies...
267281
ref var item = ref m_IncomingMessageQueue.GetUnsafeList()->ElementAt(index);
268-
HandleMessage(item.Header, item.Reader, item.SenderId, item.Timestamp);
282+
HandleMessage(item.Header, item.Reader, item.SenderId, item.Timestamp, item.MessageHeaderSerializedSize);
269283
if (m_Disposed)
270284
{
271285
return;
@@ -328,64 +342,68 @@ internal unsafe int SendMessage<TMessageType, TClientIdListType>(in TMessageType
328342
}
329343

330344
var maxSize = delivery == NetworkDelivery.ReliableFragmentedSequenced ? FRAGMENTED_MESSAGE_MAX_SIZE : NON_FRAGMENTED_MESSAGE_MAX_SIZE;
331-
var tmpSerializer = new FastBufferWriter(NON_FRAGMENTED_MESSAGE_MAX_SIZE - FastBufferWriter.GetWriteSize<MessageHeader>(), Allocator.Temp, maxSize - FastBufferWriter.GetWriteSize<MessageHeader>());
332-
using (tmpSerializer)
345+
346+
using var tmpSerializer = new FastBufferWriter(NON_FRAGMENTED_MESSAGE_MAX_SIZE - FastBufferWriter.GetWriteSize<MessageHeader>(), Allocator.Temp, maxSize - FastBufferWriter.GetWriteSize<MessageHeader>());
347+
348+
message.Serialize(tmpSerializer);
349+
350+
using var headerSerializer = new FastBufferWriter(FastBufferWriter.GetWriteSize<MessageHeader>(), Allocator.Temp);
351+
352+
var header = new MessageHeader
333353
{
334-
message.Serialize(tmpSerializer);
354+
MessageSize = (ushort)tmpSerializer.Length,
355+
MessageType = m_MessageTypes[typeof(TMessageType)],
356+
};
357+
BytePacker.WriteValueBitPacked(headerSerializer, header.MessageType);
358+
BytePacker.WriteValueBitPacked(headerSerializer, header.MessageSize);
335359

336-
for (var i = 0; i < clientIds.Count; ++i)
337-
{
338-
var clientId = clientIds[i];
360+
for (var i = 0; i < clientIds.Count; ++i)
361+
{
362+
var clientId = clientIds[i];
339363

340-
if (!CanSend(clientId, typeof(TMessageType), delivery))
341-
{
342-
continue;
343-
}
364+
if (!CanSend(clientId, typeof(TMessageType), delivery))
365+
{
366+
continue;
367+
}
344368

345-
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
346-
{
347-
m_Hooks[hookIdx].OnBeforeSendMessage(clientId, typeof(TMessageType), delivery);
348-
}
369+
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
370+
{
371+
m_Hooks[hookIdx].OnBeforeSendMessage(clientId, typeof(TMessageType), delivery);
372+
}
349373

350-
var sendQueueItem = m_SendQueues[clientId];
351-
if (sendQueueItem.Length == 0)
374+
var sendQueueItem = m_SendQueues[clientId];
375+
if (sendQueueItem.Length == 0)
376+
{
377+
sendQueueItem.Add(new SendQueueItem(delivery, NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.TempJob,
378+
maxSize));
379+
sendQueueItem.GetUnsafeList()->ElementAt(0).Writer.Seek(sizeof(BatchHeader));
380+
}
381+
else
382+
{
383+
ref var lastQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
384+
if (lastQueueItem.NetworkDelivery != delivery ||
385+
lastQueueItem.Writer.MaxCapacity - lastQueueItem.Writer.Position
386+
< tmpSerializer.Length + headerSerializer.Length)
352387
{
353388
sendQueueItem.Add(new SendQueueItem(delivery, NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.TempJob,
354389
maxSize));
355-
sendQueueItem.GetUnsafeList()->ElementAt(0).Writer.Seek(sizeof(BatchHeader));
356-
}
357-
else
358-
{
359-
ref var lastQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
360-
if (lastQueueItem.NetworkDelivery != delivery ||
361-
lastQueueItem.Writer.MaxCapacity - lastQueueItem.Writer.Position
362-
< tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>())
363-
{
364-
sendQueueItem.Add(new SendQueueItem(delivery, NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.TempJob,
365-
maxSize));
366-
sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1).Writer.Seek(sizeof(BatchHeader));
367-
}
390+
sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1).Writer.Seek(sizeof(BatchHeader));
368391
}
392+
}
369393

370-
ref var writeQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
371-
writeQueueItem.Writer.TryBeginWrite(tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
372-
var header = new MessageHeader
373-
{
374-
MessageSize = (ushort)tmpSerializer.Length,
375-
MessageType = m_MessageTypes[typeof(TMessageType)],
376-
};
394+
ref var writeQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
395+
writeQueueItem.Writer.TryBeginWrite(tmpSerializer.Length + headerSerializer.Length);
377396

378-
writeQueueItem.Writer.WriteValue(header);
379-
writeQueueItem.Writer.WriteBytes(tmpSerializer.GetUnsafePtr(), tmpSerializer.Length);
380-
writeQueueItem.BatchHeader.BatchSize++;
381-
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
382-
{
383-
m_Hooks[hookIdx].OnAfterSendMessage(clientId, typeof(TMessageType), delivery, tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
384-
}
397+
writeQueueItem.Writer.WriteBytes(headerSerializer.GetUnsafePtr(), headerSerializer.Length);
398+
writeQueueItem.Writer.WriteBytes(tmpSerializer.GetUnsafePtr(), tmpSerializer.Length);
399+
writeQueueItem.BatchHeader.BatchSize++;
400+
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
401+
{
402+
m_Hooks[hookIdx].OnAfterSendMessage(clientId, typeof(TMessageType), delivery, tmpSerializer.Length + headerSerializer.Length);
385403
}
386-
387-
return tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>();
388404
}
405+
406+
return tmpSerializer.Length + headerSerializer.Length;
389407
}
390408

391409
private struct PointerListWrapper<T> : IReadOnlyList<T>

com.unity.netcode.gameobjects/Runtime/Messaging/NetworkContext.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,10 @@ internal ref struct NetworkContext
2525
/// The header data that was sent with the message
2626
/// </summary>
2727
public MessageHeader Header;
28+
29+
/// <summary>
30+
/// The actual serialized size of the header when packed into the buffer
31+
/// </summary>
32+
public int SerializedHeaderSize;
2833
}
2934
}

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ private struct TriggerData
2727
public MessageHeader Header;
2828
public ulong SenderId;
2929
public float Timestamp;
30+
public int SerializedHeaderSize;
3031
}
3132
private struct TriggerInfo
3233
{
@@ -117,7 +118,8 @@ internal unsafe void TriggerOnSpawn(ulong networkObjectId, FastBufferReader read
117118
Reader = new FastBufferReader(reader.GetUnsafePtr(), Allocator.Persistent, reader.Length),
118119
Header = context.Header,
119120
Timestamp = context.Timestamp,
120-
SenderId = context.SenderId
121+
SenderId = context.SenderId,
122+
SerializedHeaderSize = context.SerializedHeaderSize
121123
});
122124
}
123125

@@ -501,7 +503,7 @@ private void SpawnNetworkObjectLocallyCommon(NetworkObject networkObject, ulong
501503
foreach (var trigger in triggerInfo.TriggerData)
502504
{
503505
// Reader will be disposed within HandleMessage
504-
NetworkManager.MessagingSystem.HandleMessage(trigger.Header, trigger.Reader, trigger.SenderId, trigger.Timestamp);
506+
NetworkManager.MessagingSystem.HandleMessage(trigger.Header, trigger.Reader, trigger.SenderId, trigger.Timestamp, trigger.SerializedHeaderSize);
505507
}
506508

507509
triggerInfo.TriggerData.Dispose();

0 commit comments

Comments
 (0)