44using Unity . Burst ;
55using Unity . Burst . Intrinsics ;
66using Unity . Collections ;
7+ using Unity . Collections . LowLevel . Unsafe ;
78using Unity . Entities ;
89using Unity . NetCode ;
910using Unity . Netcode . Transports . UTP ;
11+ using UnityEngine ;
1012
1113namespace Unity . Netcode . Unified
1214{
1315 [ BurstCompile ]
16+ internal unsafe struct FixedBytes1280
17+ {
18+ public fixed byte Buffer [ 1280 ] ;
19+ public int Length ;
20+
21+ // Returns a direct pointer to the data in the buffer.
22+ // Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
23+ // Note that the buffer MUST outlive the returned pointer, as it is an alias.
24+ public static byte * GetUnsafePtr ( in FixedBytes1280 data )
25+ {
26+ fixed ( byte * buffer = data . Buffer )
27+ {
28+ return buffer ;
29+ }
30+ }
31+
32+ // Returns a native array that is an alias of the existing data without copying it
33+ // Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
34+ // Note that the buffer MUST outlive the returned array, as it is an alias.
35+ public static NativeArray < byte > ToNativeArray ( in FixedBytes1280 data )
36+ {
37+ var array = NativeArrayUnsafeUtility . ConvertExistingDataToNativeArray < byte > ( GetUnsafePtr ( data ) , data . Length , Allocator . None ) ;
38+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
39+ var safety = CollectionHelper . CreateSafetyHandle ( Allocator . None ) ;
40+ NativeArrayUnsafeUtility . SetAtomicSafetyHandle ( ref array , safety ) ;
41+ #endif
42+ return array ;
43+ }
44+ }
45+
46+ [ BurstCompile ]
1447 internal struct TransportRpc : IOutOfBandRpcCommand , IRpcCommandSerializer < TransportRpc >
1548 {
16- public FixedList4096Bytes < byte > Buffer ;
49+ public FixedBytes1280 Buffer ;
1750 public ulong Order ;
1851
1952 public unsafe void Serialize ( ref DataStreamWriter writer , in RpcSerializerState state , in TransportRpc data )
2053 {
2154 writer . WriteULong ( data . Order ) ;
2255 writer . WriteInt ( data . Buffer . Length ) ;
23- var span = new Span < byte > ( data . Buffer . GetUnsafePtr ( ) , data . Buffer . Length ) ;
56+ var span = new Span < byte > ( FixedBytes1280 . GetUnsafePtr ( data . Buffer ) , data . Buffer . Length ) ;
2457 writer . WriteBytes ( span ) ;
2558 }
2659
2760 public unsafe void Deserialize ( ref DataStreamReader reader , in RpcDeserializerState state , ref TransportRpc data )
2861 {
2962 data . Order = reader . ReadULong ( ) ;
3063 var length = reader . ReadInt ( ) ;
31- data . Buffer = new FixedList4096Bytes < byte > ( )
64+ data . Buffer = new FixedBytes1280
3265 {
3366 Length = length
3467 } ;
35- var span = new Span < byte > ( data . Buffer . GetUnsafePtr ( ) , length ) ;
68+
69+ var span = new Span < byte > ( FixedBytes1280 . GetUnsafePtr ( data . Buffer ) , length ) ;
3670 reader . ReadBytes ( span ) ;
3771 }
3872
@@ -81,7 +115,6 @@ public void OnUpdate(ref SystemState state)
81115 }
82116 }
83117
84-
85118 internal partial class UnifiedNetcodeUpdateSystem : SystemBase
86119 {
87120 public UnifiedNetcodeTransport Transport ;
@@ -96,11 +129,11 @@ public void Disconnect(Connection connection)
96129 protected override void OnUpdate ( )
97130 {
98131 using var commandBuffer = new EntityCommandBuffer ( Allocator . Temp ) ;
99- foreach ( var ( request , rpc , entity ) in SystemAPI . Query < RefRO < ReceiveRpcCommandRequest > , RefRW < TransportRpc > > ( ) . WithEntityAccess ( ) )
132+ foreach ( var ( request , rpc , entity ) in SystemAPI . Query < RefRO < ReceiveRpcCommandRequest > , RefRO < TransportRpc > > ( ) . WithEntityAccess ( ) )
100133 {
101134 var connectionId = SystemAPI . GetComponent < NetworkId > ( request . ValueRO . SourceConnection ) . Value ;
102135
103- var buffer = rpc . ValueRW . Buffer ;
136+ var buffer = rpc . ValueRO . Buffer ;
104137 try
105138 {
106139 Transport . DispatchMessage ( connectionId , buffer , rpc . ValueRO . Order ) ;
@@ -124,7 +157,7 @@ protected override void OnUpdate()
124157
125158 internal class UnifiedNetcodeTransport : NetworkTransport
126159 {
127- private const int k_MaxPacketSize = 1300 ;
160+ private const int k_MaxPacketSize = 1280 ;
128161
129162 private int m_ServerClientId = - 1 ;
130163 public override ulong ServerClientId => ( ulong ) m_ServerClientId ;
@@ -140,27 +173,34 @@ private class ConnectionInfo
140173 public Connection Connection ;
141174 public ulong LastSent ;
142175 public ulong LastReceived ;
143- public Dictionary < ulong , FixedList4096Bytes < byte > > DeferredMessages ;
176+ public Dictionary < ulong , FixedBytes1280 > DeferredMessages ;
144177 }
145178
146179 private Dictionary < int , ConnectionInfo > m_Connections ;
147180
148- internal void DispatchMessage ( int connectionId , FixedList4096Bytes < byte > buffer , ulong order )
181+ internal void DispatchMessage ( int connectionId , in FixedBytes1280 buffer , ulong order )
149182 {
150183 var connectionInfo = m_Connections [ connectionId ] ;
151184
185+ if ( order <= connectionInfo . LastReceived )
186+ {
187+ Debug . LogWarning ( "Received duplicate message, ignoring." ) ;
188+ return ;
189+ }
190+
152191 if ( order != connectionInfo . LastReceived + 1 )
153192 {
154193 if ( connectionInfo . DeferredMessages == null )
155194 {
156- connectionInfo . DeferredMessages = new Dictionary < ulong , FixedList4096Bytes < byte > > ( ) ;
195+ connectionInfo . DeferredMessages = new Dictionary < ulong , FixedBytes1280 > ( ) ;
157196 }
158197
159198 connectionInfo . DeferredMessages [ order ] = buffer ;
160199 return ;
161200 }
162201
163- var reader = new DataStreamReader ( buffer . ToNativeArray ( Allocator . Temp ) ) ;
202+ using var arr = FixedBytes1280 . ToNativeArray ( buffer ) ;
203+ var reader = new DataStreamReader ( arr ) ;
164204 if ( connectionInfo . ReceiveQueue == null )
165205 {
166206 connectionInfo . ReceiveQueue = new BatchedReceiveQueue ( reader ) ;
@@ -176,7 +216,7 @@ internal void DispatchMessage(int connectionId, FixedList4096Bytes<byte> buffer,
176216 var next = order + 1 ;
177217 while ( connectionInfo . DeferredMessages . Remove ( next , out var nextBuffer ) )
178218 {
179- reader = new DataStreamReader ( nextBuffer . ToNativeArray ( Allocator . Temp ) ) ;
219+ reader = new DataStreamReader ( FixedBytes1280 . ToNativeArray ( nextBuffer ) ) ;
180220 connectionInfo . ReceiveQueue . PushReader ( reader ) ;
181221 connectionInfo . LastReceived = next ;
182222 ++ next ;
@@ -205,10 +245,10 @@ public override unsafe void Send(ulong clientId, ArraySegment<byte> payload, Net
205245 {
206246 var rpc = new TransportRpc
207247 {
208- Buffer = new FixedList4096Bytes < byte > ( ) ,
248+ Buffer = new FixedBytes1280 ( ) ,
209249 } ;
210250
211- var writer = new DataStreamWriter ( rpc . Buffer . GetUnsafePtr ( ) , k_MaxPacketSize ) ;
251+ var writer = new DataStreamWriter ( FixedBytes1280 . GetUnsafePtr ( rpc . Buffer ) , k_MaxPacketSize ) ;
212252
213253 var amount = connectionInfo . SendQueue . FillWriterWithBytes ( ref writer , k_MaxPacketSize ) ;
214254 rpc . Buffer . Length = amount ;
0 commit comments