77using Unity . Entities ;
88using Unity . NetCode ;
99using Unity . Netcode . Transports . UTP ;
10+ using UnityEngine ;
1011
1112namespace Unity . Netcode . Unified
1213{
1314 [ BurstCompile ]
15+ internal unsafe struct FixedBytes1280
16+ {
17+ public fixed byte Buffer [ 1280 ] ;
18+ public int Length ;
19+
20+ // Returns a direct pointer to the data in the buffer.
21+ // Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
22+ // Note that the buffer MUST outlive the returned pointer, as it is an alias.
23+ public static byte * GetUnsafePtr ( in FixedBytes1280 data )
24+ {
25+ fixed ( byte * buffer = data . Buffer )
26+ {
27+ return buffer ;
28+ }
29+ }
30+
31+ // Returns a native array that is an alias of the existing data without copying it
32+ // Implemented as a static with an in-parameter to avoid the buffer being copied while keeping its memory allocation fixed/non-heap
33+ // Note that the buffer MUST outlive the returned array, as it is an alias.
34+ public static NativeArray < byte > ToNativeArray ( in FixedBytes1280 data )
35+ {
36+ var array = NativeArrayUnsafeUtility . ConvertExistingDataToNativeArray < byte > ( GetUnsafePtr ( data ) , data . Length , Allocator . None ) ;
37+ #if ENABLE_UNITY_COLLECTIONS_CHECKS
38+ var safety = CollectionHelper . CreateSafetyHandle ( Allocator . None ) ;
39+ NativeArrayUnsafeUtility . SetAtomicSafetyHandle ( ref array , safety ) ;
40+ #endif
41+ return array ;
42+ }
43+ }
44+
45+ [ BurstCompile ]
1446 internal struct TransportRpc : IOutOfBandRpcCommand , IRpcCommandSerializer < TransportRpc >
1547 {
16- public FixedList4096Bytes < byte > Buffer ;
48+ public FixedBytes1280 Buffer ;
1749 public ulong Order ;
1850
1951 public unsafe void Serialize ( ref DataStreamWriter writer , in RpcSerializerState state , in TransportRpc data )
2052 {
2153 writer . WriteULong ( data . Order ) ;
2254 writer . WriteInt ( data . Buffer . Length ) ;
23- var span = new Span < byte > ( data . Buffer . GetUnsafePtr ( ) , data . Buffer . Length ) ;
55+ var span = new Span < byte > ( FixedBytes1280 . GetUnsafePtr ( data . Buffer ) , data . Buffer . Length ) ;
2456 writer . WriteBytes ( span ) ;
2557 }
2658
2759 public unsafe void Deserialize ( ref DataStreamReader reader , in RpcDeserializerState state , ref TransportRpc data )
2860 {
2961 data . Order = reader . ReadULong ( ) ;
3062 var length = reader . ReadInt ( ) ;
31- data . Buffer = new FixedList4096Bytes < byte > ( )
63+ data . Buffer = new FixedBytes1280
3264 {
3365 Length = length
3466 } ;
35- var span = new Span < byte > ( data . Buffer . GetUnsafePtr ( ) , length ) ;
67+
68+ var span = new Span < byte > ( FixedBytes1280 . GetUnsafePtr ( data . Buffer ) , length ) ;
3669 reader . ReadBytes ( span ) ;
3770 }
3871
@@ -81,7 +114,6 @@ public void OnUpdate(ref SystemState state)
81114 }
82115 }
83116
84-
85117 internal partial class UnifiedNetcodeUpdateSystem : SystemBase
86118 {
87119 public UnifiedNetcodeTransport Transport ;
@@ -96,11 +128,11 @@ public void Disconnect(Connection connection)
96128 protected override void OnUpdate ( )
97129 {
98130 using var commandBuffer = new EntityCommandBuffer ( Allocator . Temp ) ;
99- foreach ( var ( request , rpc , entity ) in SystemAPI . Query < RefRO < ReceiveRpcCommandRequest > , RefRW < TransportRpc > > ( ) . WithEntityAccess ( ) )
131+ foreach ( var ( request , rpc , entity ) in SystemAPI . Query < RefRO < ReceiveRpcCommandRequest > , RefRO < TransportRpc > > ( ) . WithEntityAccess ( ) )
100132 {
101133 var connectionId = SystemAPI . GetComponent < NetworkId > ( request . ValueRO . SourceConnection ) . Value ;
102134
103- var buffer = rpc . ValueRW . Buffer ;
135+ var buffer = rpc . ValueRO . Buffer ;
104136 try
105137 {
106138 Transport . DispatchMessage ( connectionId , buffer , rpc . ValueRO . Order ) ;
@@ -124,7 +156,7 @@ protected override void OnUpdate()
124156
125157 internal class UnifiedNetcodeTransport : NetworkTransport
126158 {
127- private const int k_MaxPacketSize = 1300 ;
159+ private const int k_MaxPacketSize = 1280 ;
128160
129161 private int m_ServerClientId = - 1 ;
130162 public override ulong ServerClientId => ( ulong ) m_ServerClientId ;
@@ -140,27 +172,34 @@ private class ConnectionInfo
140172 public Connection Connection ;
141173 public ulong LastSent ;
142174 public ulong LastReceived ;
143- public Dictionary < ulong , FixedList4096Bytes < byte > > DeferredMessages ;
175+ public Dictionary < ulong , FixedBytes1280 > DeferredMessages ;
144176 }
145177
146178 private Dictionary < int , ConnectionInfo > m_Connections ;
147179
148- internal void DispatchMessage ( int connectionId , FixedList4096Bytes < byte > buffer , ulong order )
180+ internal void DispatchMessage ( int connectionId , in FixedBytes1280 buffer , ulong order )
149181 {
150182 var connectionInfo = m_Connections [ connectionId ] ;
151183
184+ if ( order <= connectionInfo . LastReceived )
185+ {
186+ Debug . LogWarning ( "Received duplicate message, ignoring." ) ;
187+ return ;
188+ }
189+
152190 if ( order != connectionInfo . LastReceived + 1 )
153191 {
154192 if ( connectionInfo . DeferredMessages == null )
155193 {
156- connectionInfo . DeferredMessages = new Dictionary < ulong , FixedList4096Bytes < byte > > ( ) ;
194+ connectionInfo . DeferredMessages = new Dictionary < ulong , FixedBytes1280 > ( ) ;
157195 }
158196
159197 connectionInfo . DeferredMessages [ order ] = buffer ;
160198 return ;
161199 }
162200
163- var reader = new DataStreamReader ( buffer . ToNativeArray ( Allocator . Temp ) ) ;
201+ using var arr = FixedBytes1280 . ToNativeArray ( buffer ) ;
202+ var reader = new DataStreamReader ( arr ) ;
164203 if ( connectionInfo . ReceiveQueue == null )
165204 {
166205 connectionInfo . ReceiveQueue = new BatchedReceiveQueue ( reader ) ;
@@ -176,7 +215,7 @@ internal void DispatchMessage(int connectionId, FixedList4096Bytes<byte> buffer,
176215 var next = order + 1 ;
177216 while ( connectionInfo . DeferredMessages . Remove ( next , out var nextBuffer ) )
178217 {
179- reader = new DataStreamReader ( nextBuffer . ToNativeArray ( Allocator . Temp ) ) ;
218+ reader = new DataStreamReader ( FixedBytes1280 . ToNativeArray ( nextBuffer ) ) ;
180219 connectionInfo . ReceiveQueue . PushReader ( reader ) ;
181220 connectionInfo . LastReceived = next ;
182221 ++ next ;
@@ -205,10 +244,10 @@ public override unsafe void Send(ulong clientId, ArraySegment<byte> payload, Net
205244 {
206245 var rpc = new TransportRpc
207246 {
208- Buffer = new FixedList4096Bytes < byte > ( ) ,
247+ Buffer = new FixedBytes1280 ( ) ,
209248 } ;
210249
211- var writer = new DataStreamWriter ( rpc . Buffer . GetUnsafePtr ( ) , k_MaxPacketSize ) ;
250+ var writer = new DataStreamWriter ( FixedBytes1280 . GetUnsafePtr ( rpc . Buffer ) , k_MaxPacketSize ) ;
212251
213252 var amount = connectionInfo . SendQueue . FillWriterWithBytes ( ref writer , k_MaxPacketSize ) ;
214253 rpc . Buffer . Length = amount ;
0 commit comments