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,23 @@ 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
+
56
+ private static readonly RelayServerData k_DefaultRelayServerData = default ( RelayServerData ) ;
57
+ private static RelayServerData DefaultRelayServerData => k_DefaultRelayServerData ;
58
+
65
59
private void InitDriver ( )
66
60
{
67
61
if ( m_NetworkParameters . Count > 0 )
62
+ {
68
63
m_Driver = NetworkDriver . Create ( m_NetworkParameters . ToArray ( ) ) ;
64
+ }
69
65
else
66
+ {
70
67
m_Driver = NetworkDriver . Create ( ) ;
68
+ }
71
69
72
70
m_UnreliableSequencedPipeline = m_Driver . CreatePipeline ( typeof ( UnreliableSequencedPipelineStage ) ) ;
73
71
m_ReliableSequencedPipeline = m_Driver . CreatePipeline ( typeof ( ReliableSequencedPipelineStage ) ) ;
@@ -79,39 +77,8 @@ private void InitDriver()
79
77
private void DisposeDriver ( )
80
78
{
81
79
if ( m_Driver . IsCreated )
82
- m_Driver . Dispose ( ) ;
83
- }
84
-
85
- private static RelayAllocationId ConvertFromAllocationIdBytes ( byte [ ] allocationIdBytes )
86
- {
87
- unsafe
88
- {
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
80
{
111
- fixed ( byte * ptr = connectionData )
112
- {
113
- return RelayConnectionData . FromBytePointer ( ptr , RelayConnectionData . k_Length ) ;
114
- }
81
+ m_Driver . Dispose ( ) ;
115
82
}
116
83
}
117
84
@@ -134,7 +101,9 @@ private NetworkPipeline SelectSendPipeline(NetworkChannel channel, int size)
134
101
case NetworkDelivery . ReliableFragmentedSequenced :
135
102
// No need to send on the fragmented pipeline if data is smaller than MTU.
136
103
if ( size < NetworkParameterConstants . MTU )
104
+ {
137
105
return m_ReliableSequencedPipeline ;
106
+ }
138
107
139
108
return m_ReliableSequencedFragmentedPipeline ;
140
109
@@ -150,43 +119,15 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
150
119
151
120
if ( m_ProtocolType == ProtocolType . RelayUnityTransport )
152
121
{
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 )
122
+ //This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
123
+ //reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
124
+ if ( m_RelayServerData . Equals ( DefaultRelayServerData ) )
163
125
{
164
- Debug . LogError ( "Join Relay request failed" ) ;
165
- task . IsDone = true ;
166
- task . Success = false ;
126
+ Debug . LogError ( "You must set the RelayServerData property to something different from the default value before calling StartRelayServer." ) ;
167
127
yield break ;
168
128
}
169
129
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
130
+ m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = m_RelayServerData } ) ;
190
131
}
191
132
else
192
133
{
@@ -223,8 +164,6 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
223
164
{
224
165
Debug . LogError ( "Client failed to connect to server" ) ;
225
166
}
226
-
227
-
228
167
}
229
168
230
169
task . IsDone = true ;
@@ -256,69 +195,80 @@ private IEnumerator ServerBindAndListen(SocketTask task, NetworkEndPoint endPoin
256
195
{
257
196
Debug . LogError ( "Server failed to listen" ) ;
258
197
}
259
-
260
-
261
198
}
262
199
263
200
task . IsDone = true ;
264
201
}
265
202
266
-
267
- private IEnumerator StartRelayServer ( SocketTask task )
203
+ private static RelayAllocationId ConvertFromAllocationIdBytes ( byte [ ] allocationIdBytes )
268
204
{
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 )
205
+ unsafe
276
206
{
277
- yield return null ;
207
+ fixed ( byte * ptr = allocationIdBytes )
208
+ {
209
+ return RelayAllocationId . FromBytePointer ( ptr , allocationIdBytes . Length ) ;
210
+ }
278
211
}
212
+ }
279
213
280
- if ( allocationTask . IsFaulted )
214
+ private static RelayHMACKey ConvertFromHMAC ( byte [ ] hmac )
215
+ {
216
+ unsafe
281
217
{
282
- Debug . LogError ( "Create allocation request failed" ) ;
283
- task . IsDone = true ;
284
- task . Success = false ;
285
- yield break ;
218
+ fixed ( byte * ptr = hmac )
219
+ {
220
+ return RelayHMACKey . FromBytePointer ( ptr , RelayHMACKey . k_Length ) ;
221
+ }
286
222
}
223
+ }
287
224
288
- var allocation = allocationTask . Result . Result . Data . Allocation ;
289
-
290
- var joinCodeTask = RelayService . AllocationsApiClient . CreateJoincodeAsync ( new CreateJoincodeRequest ( new JoinCodeRequest ( allocation . AllocationId ) ) ) ;
225
+ private static RelayConnectionData ConvertConnectionData ( byte [ ] connectionData )
226
+ {
227
+ unsafe
228
+ {
229
+ fixed ( byte * ptr = connectionData )
230
+ {
231
+ return RelayConnectionData . FromBytePointer ( ptr , RelayConnectionData . k_Length ) ;
232
+ }
233
+ }
234
+ }
291
235
292
- while ( ! joinCodeTask . IsCompleted )
236
+ public void SetRelayServerData ( string ipv4address , ushort port , byte [ ] allocationIdBytes , byte [ ] keyBytes , byte [ ] connectionDataBytes , byte [ ] hostConnectionDataBytes = null )
237
+ {
238
+ RelayConnectionData hostConnectionData ;
239
+
240
+ var serverEndpoint = NetworkEndPoint . Parse ( ipv4address , port ) ;
241
+ var allocationId = ConvertFromAllocationIdBytes ( allocationIdBytes ) ;
242
+ var key = ConvertFromHMAC ( keyBytes ) ;
243
+ var connectionData = ConvertConnectionData ( connectionDataBytes ) ;
244
+
245
+ if ( hostConnectionDataBytes != null )
246
+ {
247
+ hostConnectionData = ConvertConnectionData ( hostConnectionDataBytes ) ;
248
+ }
249
+ else
293
250
{
294
- yield return null ;
251
+ hostConnectionData = connectionData ;
295
252
}
253
+ m_RelayServerData = new RelayServerData ( ref serverEndpoint , 0 , ref allocationId , ref connectionData , ref hostConnectionData , ref key ) ;
254
+ m_RelayServerData . ComputeNewNonce ( ) ;
255
+ }
296
256
297
- if ( joinCodeTask . IsFaulted )
257
+ private IEnumerator StartRelayServer ( SocketTask task )
258
+ {
259
+ //This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
260
+ //reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
261
+ if ( m_RelayServerData . Equals ( DefaultRelayServerData ) )
298
262
{
299
- Debug . LogError ( "Create join code request failed" ) ;
300
- task . IsDone = true ;
301
- task . Success = false ;
263
+ Debug . LogError ( "You must set the RelayServerData property to something different from the default value before calling StartRelayServer." ) ;
302
264
yield break ;
303
265
}
266
+ else
267
+ {
268
+ m_NetworkParameters . Add ( new RelayNetworkParameter { ServerData = m_RelayServerData } ) ;
304
269
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
270
+ yield return ServerBindAndListen ( task , NetworkEndPoint . AnyIpv4 ) ;
271
+ }
322
272
}
323
273
324
274
private bool AcceptConnection ( )
@@ -396,8 +346,15 @@ private void Update()
396
346
if ( m_Driver . IsCreated )
397
347
{
398
348
m_Driver . ScheduleUpdate ( ) . Complete ( ) ;
399
- while ( AcceptConnection ( ) && m_Driver . IsCreated ) ;
400
- while ( ProcessEvent ( ) && m_Driver . IsCreated ) ;
349
+ while ( AcceptConnection ( ) && m_Driver . IsCreated )
350
+ {
351
+ ;
352
+ }
353
+
354
+ while ( ProcessEvent ( ) && m_Driver . IsCreated )
355
+ {
356
+ ;
357
+ }
401
358
}
402
359
403
360
}
@@ -417,14 +374,6 @@ private static unsafe NetworkConnection ParseClientId(ulong mlapiConnectionId)
417
374
return * ( NetworkConnection * ) & mlapiConnectionId ;
418
375
}
419
376
420
- public void SetRelayJoinCode ( string value )
421
- {
422
- if ( m_State == State . Disconnected )
423
- {
424
- m_RelayJoinCode = value ;
425
- }
426
- }
427
-
428
377
public override void DisconnectLocalClient ( )
429
378
{
430
379
Debug . Assert ( m_State == State . Connected , "DisconnectLocalClient should be called on a connected client" ) ;
@@ -462,20 +411,13 @@ public override void Init()
462
411
463
412
m_NetworkParameters = new List < INetworkParameter > ( ) ;
464
413
465
-
466
414
// If we want to be able to actually handle messages MaximumMessageLength bytes in
467
415
// size, we need to allow a bit more than that in FragmentationUtility since this needs
468
416
// to account for headers and such. 128 bytes is plenty enough for such overhead.
469
417
var maxFragmentationCapacity = MaximumMessageLength + 128 ;
470
418
m_NetworkParameters . Add ( new FragmentationUtility . Parameters ( ) { PayloadCapacity = maxFragmentationCapacity } ) ;
471
419
472
420
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
421
}
480
422
481
423
public override NetworkEvent PollEvent ( out ulong clientId , out NetworkChannel networkChannel , out ArraySegment < byte > payload , out float receiveTime )
@@ -510,7 +452,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
510
452
}
511
453
512
454
if ( m_Driver . EndSend ( writer ) == size )
455
+ {
513
456
return ;
457
+ }
514
458
}
515
459
516
460
Debug . LogError ( "Error sending the message" ) ;
@@ -519,7 +463,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
519
463
public override SocketTasks StartClient ( )
520
464
{
521
465
if ( m_Driver . IsCreated )
466
+ {
522
467
return SocketTask . Fault . AsTasks ( ) ;
468
+ }
523
469
524
470
var task = SocketTask . Working ;
525
471
StartCoroutine ( ClientBindAndConnect ( task ) ) ;
@@ -529,7 +475,9 @@ public override SocketTasks StartClient()
529
475
public override SocketTasks StartServer ( )
530
476
{
531
477
if ( m_Driver . IsCreated )
478
+ {
532
479
return SocketTask . Fault . AsTasks ( ) ;
480
+ }
533
481
534
482
var task = SocketTask . Working ;
535
483
switch ( m_ProtocolType )
0 commit comments