4
4
using System . Threading . Tasks ;
5
5
using Unity . Networking . Transport ;
6
6
using Unity . Networking . Transport . Relay ;
7
- #if ENABLE_RELAY_SERVICE
8
- using Unity . Services . Relay ;
9
- using Unity . Services . Relay . Allocations ;
10
- using Unity . Services . Relay . Models ;
11
- using Unity . Services . Core ;
12
- #endif
13
7
14
8
using MLAPI . Transports . Tasks ;
15
9
using UnityEngine ;
@@ -42,14 +36,11 @@ private enum State
42
36
[ SerializeField ] private int m_MessageBufferSize = MaximumMessageLength ;
43
37
[ SerializeField ] private string m_ServerAddress = "127.0.0.1" ;
44
38
[ SerializeField ] private ushort m_ServerPort = 7777 ;
45
- [ SerializeField ] private int m_RelayMaxPlayers = 10 ;
46
- [ SerializeField ] private string m_RelayServer = "https://relay-allocations.cloud.unity3d.com" ;
47
39
48
40
private State m_State = State . Disconnected ;
49
41
private NetworkDriver m_Driver ;
50
42
private List < INetworkParameter > m_NetworkParameters ;
51
43
private byte [ ] m_MessageBuffer ;
52
- private string m_RelayJoinCode ;
53
44
private ulong m_ServerClientId ;
54
45
55
46
private NetworkPipeline m_UnreliableSequencedPipeline ;
@@ -58,16 +49,20 @@ private enum State
58
49
59
50
public override ulong ServerClientId => m_ServerClientId ;
60
51
61
- public string RelayJoinCode => m_RelayJoinCode ;
62
-
63
52
public ProtocolType Protocol => m_ProtocolType ;
64
53
54
+ private RelayServerData m_RelayServerData ;
55
+
65
56
private void InitDriver ( )
66
57
{
67
58
if ( m_NetworkParameters . Count > 0 )
59
+ {
68
60
m_Driver = NetworkDriver . Create ( m_NetworkParameters . ToArray ( ) ) ;
61
+ }
69
62
else
63
+ {
70
64
m_Driver = NetworkDriver . Create ( ) ;
65
+ }
71
66
72
67
m_UnreliableSequencedPipeline = m_Driver . CreatePipeline ( typeof ( UnreliableSequencedPipelineStage ) ) ;
73
68
m_ReliableSequencedPipeline = m_Driver . CreatePipeline ( typeof ( ReliableSequencedPipelineStage ) ) ;
@@ -79,39 +74,8 @@ private void InitDriver()
79
74
private void DisposeDriver ( )
80
75
{
81
76
if ( m_Driver . IsCreated )
82
- m_Driver . Dispose ( ) ;
83
- }
84
-
85
- private static RelayAllocationId ConvertFromAllocationIdBytes ( byte [ ] allocationIdBytes )
86
- {
87
- unsafe
88
77
{
89
- fixed ( byte * ptr = allocationIdBytes )
90
- {
91
- return RelayAllocationId . FromBytePointer ( ptr , allocationIdBytes . Length ) ;
92
- }
93
- }
94
- }
95
-
96
- private static RelayHMACKey ConvertFromHMAC ( byte [ ] hmac )
97
- {
98
- unsafe
99
- {
100
- fixed ( byte * ptr = hmac )
101
- {
102
- return RelayHMACKey . FromBytePointer ( ptr , RelayHMACKey . k_Length ) ;
103
- }
104
- }
105
- }
106
-
107
- private static RelayConnectionData ConvertConnectionData ( byte [ ] connectionData )
108
- {
109
- unsafe
110
- {
111
- fixed ( byte * ptr = connectionData )
112
- {
113
- return RelayConnectionData . FromBytePointer ( ptr , RelayConnectionData . k_Length ) ;
114
- }
78
+ m_Driver . Dispose ( ) ;
115
79
}
116
80
}
117
81
@@ -134,7 +98,9 @@ private NetworkPipeline SelectSendPipeline(NetworkChannel channel, int size)
134
98
case NetworkDelivery . ReliableFragmentedSequenced :
135
99
// No need to send on the fragmented pipeline if data is smaller than MTU.
136
100
if ( size < NetworkParameterConstants . MTU )
101
+ {
137
102
return m_ReliableSequencedPipeline ;
103
+ }
138
104
139
105
return m_ReliableSequencedFragmentedPipeline ;
140
106
@@ -150,43 +116,17 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
150
116
151
117
if ( m_ProtocolType == ProtocolType . RelayUnityTransport )
152
118
{
153
- #if ! ENABLE_RELAY_SERVICE
154
- Debug . LogError ( "You must have Relay SDK installed via the UDash in order to use the relay transport" ) ;
155
- yield return null ;
156
- #else
157
- var joinTask = RelayService . AllocationsApiClient . JoinRelayAsync ( new JoinRelayRequest ( new JoinRequest ( m_RelayJoinCode ) ) ) ;
158
-
159
- while ( ! joinTask . IsCompleted )
160
- yield return null ;
161
-
162
- if ( joinTask . IsFaulted )
119
+ //This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
120
+ //reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
121
+ if ( m_RelayServerData . Equals ( default ( RelayServerData ) ) )
163
122
{
164
- Debug . LogError ( "Join Relay request failed " ) ;
123
+ Debug . LogError ( "You must call SetRelayServerData() at least once before calling StartRelayServer. " ) ;
165
124
task . IsDone = true ;
166
125
task . Success = false ;
167
126
yield break ;
168
127
}
169
128
170
- var allocation = joinTask . Result . Result . Data . Allocation ;
171
-
172
- serverEndpoint = NetworkEndPoint . Parse ( allocation . RelayServer . IpV4 , ( ushort ) allocation . RelayServer . Port ) ;
173
-
174
- var allocationId = ConvertFromAllocationIdBytes ( allocation . AllocationIdBytes ) ;
175
-
176
- var connectionData = ConvertConnectionData ( allocation . ConnectionData ) ;
177
- var hostConnectionData = ConvertConnectionData ( allocation . HostConnectionData ) ;
178
- var key = ConvertFromHMAC ( allocation . Key ) ;
179
-
180
- Debug . Log ( $ "client: { allocation . ConnectionData [ 0 ] } { allocation . ConnectionData [ 1 ] } ") ;
181
- Debug . Log ( $ "host: { allocation . HostConnectionData [ 0 ] } { allocation . HostConnectionData [ 1 ] } ") ;
182
-
183
- Debug . Log ( $ "client: { allocation . AllocationId } ") ;
184
-
185
- var relayServerData = new RelayServerData ( ref serverEndpoint , 0 , ref allocationId , ref connectionData , ref hostConnectionData , ref key ) ;
186
- relayServerData . ComputeNewNonce ( ) ;
187
-
188
- m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = relayServerData } ) ;
189
- #endif
129
+ m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = m_RelayServerData } ) ;
190
130
}
191
131
else
192
132
{
@@ -223,8 +163,6 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
223
163
{
224
164
Debug . LogError ( "Client failed to connect to server" ) ;
225
165
}
226
-
227
-
228
166
}
229
167
230
168
task . IsDone = true ;
@@ -256,69 +194,82 @@ private IEnumerator ServerBindAndListen(SocketTask task, NetworkEndPoint endPoin
256
194
{
257
195
Debug . LogError ( "Server failed to listen" ) ;
258
196
}
259
-
260
-
261
197
}
262
198
263
199
task . IsDone = true ;
264
200
}
265
201
266
-
267
- private IEnumerator StartRelayServer ( SocketTask task )
202
+ private static RelayAllocationId ConvertFromAllocationIdBytes ( byte [ ] allocationIdBytes )
268
203
{
269
- #if ! ENABLE_RELAY_SERVICE
270
- Debug . LogError ( "You must have Relay SDK installed via the UDash in order to use the relay transport" ) ;
271
- yield return null ;
272
- #else
273
- var allocationTask = RelayService . AllocationsApiClient . CreateAllocationAsync ( new CreateAllocationRequest ( new AllocationRequest ( m_RelayMaxPlayers ) ) ) ;
274
-
275
- while ( ! allocationTask . IsCompleted )
204
+ unsafe
276
205
{
277
- yield return null ;
206
+ fixed ( byte * ptr = allocationIdBytes )
207
+ {
208
+ return RelayAllocationId . FromBytePointer ( ptr , allocationIdBytes . Length ) ;
209
+ }
278
210
}
211
+ }
279
212
280
- if ( allocationTask . IsFaulted )
213
+ private static RelayHMACKey ConvertFromHMAC ( byte [ ] hmac )
214
+ {
215
+ unsafe
281
216
{
282
- Debug . LogError ( "Create allocation request failed" ) ;
283
- task . IsDone = true ;
284
- task . Success = false ;
285
- yield break ;
217
+ fixed ( byte * ptr = hmac )
218
+ {
219
+ return RelayHMACKey . FromBytePointer ( ptr , RelayHMACKey . k_Length ) ;
220
+ }
286
221
}
222
+ }
287
223
288
- var allocation = allocationTask . Result . Result . Data . Allocation ;
289
-
290
- var joinCodeTask = RelayService . AllocationsApiClient . CreateJoincodeAsync ( new CreateJoincodeRequest ( new JoinCodeRequest ( allocation . AllocationId ) ) ) ;
224
+ private static RelayConnectionData ConvertConnectionData ( byte [ ] connectionData )
225
+ {
226
+ unsafe
227
+ {
228
+ fixed ( byte * ptr = connectionData )
229
+ {
230
+ return RelayConnectionData . FromBytePointer ( ptr , RelayConnectionData . k_Length ) ;
231
+ }
232
+ }
233
+ }
291
234
292
- while ( ! joinCodeTask . IsCompleted )
235
+ public void SetRelayServerData ( string ipv4address , ushort port , byte [ ] allocationIdBytes , byte [ ] keyBytes , byte [ ] connectionDataBytes , byte [ ] hostConnectionDataBytes = null )
236
+ {
237
+ RelayConnectionData hostConnectionData ;
238
+
239
+ var serverEndpoint = NetworkEndPoint . Parse ( ipv4address , port ) ;
240
+ var allocationId = ConvertFromAllocationIdBytes ( allocationIdBytes ) ;
241
+ var key = ConvertFromHMAC ( keyBytes ) ;
242
+ var connectionData = ConvertConnectionData ( connectionDataBytes ) ;
243
+
244
+ if ( hostConnectionDataBytes != null )
245
+ {
246
+ hostConnectionData = ConvertConnectionData ( hostConnectionDataBytes ) ;
247
+ }
248
+ else
293
249
{
294
- yield return null ;
250
+ hostConnectionData = connectionData ;
295
251
}
252
+ m_RelayServerData = new RelayServerData ( ref serverEndpoint , 0 , ref allocationId , ref connectionData , ref hostConnectionData , ref key ) ;
253
+ m_RelayServerData . ComputeNewNonce ( ) ;
254
+ }
296
255
297
- if ( joinCodeTask . IsFaulted )
256
+ private IEnumerator StartRelayServer ( SocketTask task )
257
+ {
258
+ //This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
259
+ //reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
260
+ if ( m_RelayServerData . Equals ( default ( RelayServerData ) ) )
298
261
{
299
- Debug . LogError ( "Create join code request failed " ) ;
262
+ Debug . LogError ( "You must call SetRelayServerData() at least once before calling StartRelayServer. " ) ;
300
263
task . IsDone = true ;
301
264
task . Success = false ;
302
265
yield break ;
303
266
}
267
+ else
268
+ {
269
+ m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = m_RelayServerData } ) ;
304
270
305
- m_RelayJoinCode = joinCodeTask . Result . Result . Data . JoinCode ;
306
-
307
- var serverEndpoint = NetworkEndPoint . Parse ( allocation . RelayServer . IpV4 , ( ushort ) allocation . RelayServer . Port ) ;
308
- // Debug.Log($"Relay Server endpoint: {allocation.RelayServer.IpV4}:{(ushort)allocation.RelayServer.Port}");
309
-
310
- var allocationId = ConvertFromAllocationIdBytes ( allocation . AllocationIdBytes ) ;
311
- var connectionData = ConvertConnectionData ( allocation . ConnectionData ) ;
312
- var key = ConvertFromHMAC ( allocation . Key ) ;
313
-
314
-
315
- var relayServerData = new RelayServerData ( ref serverEndpoint , 0 , ref allocationId , ref connectionData , ref connectionData , ref key ) ;
316
- relayServerData . ComputeNewNonce ( ) ;
317
-
318
- m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = relayServerData } ) ;
319
-
320
- yield return ServerBindAndListen ( task , NetworkEndPoint . AnyIpv4 ) ;
321
- #endif
271
+ yield return ServerBindAndListen ( task , NetworkEndPoint . AnyIpv4 ) ;
272
+ }
322
273
}
323
274
324
275
private bool AcceptConnection ( )
@@ -396,8 +347,15 @@ private void Update()
396
347
if ( m_Driver . IsCreated )
397
348
{
398
349
m_Driver . ScheduleUpdate ( ) . Complete ( ) ;
399
- while ( AcceptConnection ( ) && m_Driver . IsCreated ) ;
400
- while ( ProcessEvent ( ) && m_Driver . IsCreated ) ;
350
+ while ( AcceptConnection ( ) && m_Driver . IsCreated )
351
+ {
352
+ ;
353
+ }
354
+
355
+ while ( ProcessEvent ( ) && m_Driver . IsCreated )
356
+ {
357
+ ;
358
+ }
401
359
}
402
360
403
361
}
@@ -417,14 +375,6 @@ private static unsafe NetworkConnection ParseClientId(ulong mlapiConnectionId)
417
375
return * ( NetworkConnection * ) & mlapiConnectionId ;
418
376
}
419
377
420
- public void SetRelayJoinCode ( string value )
421
- {
422
- if ( m_State == State . Disconnected )
423
- {
424
- m_RelayJoinCode = value ;
425
- }
426
- }
427
-
428
378
public override void DisconnectLocalClient ( )
429
379
{
430
380
Debug . Assert ( m_State == State . Connected , "DisconnectLocalClient should be called on a connected client" ) ;
@@ -462,20 +412,13 @@ public override void Init()
462
412
463
413
m_NetworkParameters = new List < INetworkParameter > ( ) ;
464
414
465
-
466
415
// If we want to be able to actually handle messages MaximumMessageLength bytes in
467
416
// size, we need to allow a bit more than that in FragmentationUtility since this needs
468
417
// to account for headers and such. 128 bytes is plenty enough for such overhead.
469
418
var maxFragmentationCapacity = MaximumMessageLength + 128 ;
470
419
m_NetworkParameters . Add ( new FragmentationUtility . Parameters ( ) { PayloadCapacity = maxFragmentationCapacity } ) ;
471
420
472
421
m_MessageBuffer = new byte [ m_MessageBufferSize ] ;
473
- #if ENABLE_RELAY_SERVICE
474
- if ( m_ProtocolType == ProtocolType . RelayUnityTransport ) {
475
- Unity . Services . Relay . RelayService . Configuration . BasePath = m_RelayServer ;
476
- UnityServices . Initialize ( ) ;
477
- }
478
- #endif
479
422
}
480
423
481
424
public override NetworkEvent PollEvent ( out ulong clientId , out NetworkChannel networkChannel , out ArraySegment < byte > payload , out float receiveTime )
@@ -510,7 +453,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
510
453
}
511
454
512
455
if ( m_Driver . EndSend ( writer ) == size )
456
+ {
513
457
return ;
458
+ }
514
459
}
515
460
516
461
Debug . LogError ( "Error sending the message" ) ;
@@ -519,7 +464,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
519
464
public override SocketTasks StartClient ( )
520
465
{
521
466
if ( m_Driver . IsCreated )
467
+ {
522
468
return SocketTask . Fault . AsTasks ( ) ;
469
+ }
523
470
524
471
var task = SocketTask . Working ;
525
472
StartCoroutine ( ClientBindAndConnect ( task ) ) ;
@@ -529,7 +476,9 @@ public override SocketTasks StartClient()
529
476
public override SocketTasks StartServer ( )
530
477
{
531
478
if ( m_Driver . IsCreated )
479
+ {
532
480
return SocketTask . Fault . AsTasks ( ) ;
481
+ }
533
482
534
483
var task = SocketTask . Working ;
535
484
switch ( m_ProtocolType )
0 commit comments