@@ -30,15 +30,16 @@ public abstract class NetworkedBehaviour : MonoBehaviour
30
30
/// <summary>
31
31
/// Gets if we are executing as server
32
32
/// </summary>
33
- protected bool isServer => NetworkingManager . singleton . isServer ;
33
+ protected bool isServer => isRunning && NetworkingManager . singleton . isServer ;
34
34
/// <summary>
35
35
/// Gets if we are executing as client
36
36
/// </summary>
37
- protected bool isClient => NetworkingManager . singleton . isClient ;
37
+ protected bool isClient => isRunning && NetworkingManager . singleton . isClient ;
38
38
/// <summary>
39
39
/// Gets if we are executing as Host, I.E Server and Client
40
40
/// </summary>
41
- protected bool isHost => NetworkingManager . singleton . isHost ;
41
+ protected bool isHost => isRunning && NetworkingManager . singleton . isHost ;
42
+ private bool isRunning => NetworkingManager . singleton == null || NetworkingManager . singleton . isListening ;
42
43
/// <summary>
43
44
/// Gets wheter or not the object has a owner
44
45
/// </summary>
@@ -75,10 +76,23 @@ private void OnEnable()
75
76
if ( _networkedObject == null )
76
77
_networkedObject = GetComponentInParent < NetworkedObject > ( ) ;
77
78
78
- CacheAttributes ( ) ;
79
79
NetworkedObject . NetworkedBehaviours . Add ( this ) ;
80
80
OnEnabled ( ) ;
81
81
}
82
+
83
+ private void OnDisable ( )
84
+ {
85
+ OnDisabled ( ) ;
86
+ }
87
+
88
+ private void OnDestroy ( )
89
+ {
90
+ NetworkedObject . NetworkedBehaviours . Remove ( this ) ; // O(n)
91
+ CachedClientRpcs . Remove ( this ) ;
92
+ CachedServerRpcs . Remove ( this ) ;
93
+ OnDestroyed ( ) ;
94
+ }
95
+
82
96
internal bool networkedStartInvoked = false ;
83
97
/// <summary>
84
98
/// Gets called when message handlers are ready to be registered and the networking is setup
@@ -189,17 +203,6 @@ protected NetworkedBehaviour GetBehaviour(ushort id)
189
203
return networkedObject . GetBehaviourAtOrderIndex ( id ) ;
190
204
}
191
205
192
- private void OnDisable ( )
193
- {
194
- OnDisabled ( ) ;
195
- }
196
-
197
- private void OnDestroy ( )
198
- {
199
- NetworkedObject . NetworkedBehaviours . Remove ( this ) ; // O(n)
200
- OnDestroyed ( ) ;
201
- }
202
-
203
206
#region NetworkedVar
204
207
205
208
private bool networkedVarInit = false ;
@@ -296,7 +299,7 @@ internal void NetworkedVarUpdate()
296
299
if ( isServer )
297
300
InternalMessageHandler . Send ( clientId , MLAPIConstants . MLAPI_NETWORKED_VAR_DELTA , channelsForVarGroups [ j ] , stream ) ;
298
301
else
299
- InternalMessageHandler . Send ( NetworkingManager . singleton . NetworkConfig . NetworkTransport . ServerClientId , MLAPIConstants . MLAPI_NETWORKED_VAR_DELTA , channelsForVarGroups [ j ] , stream ) ;
302
+ InternalMessageHandler . Send ( NetworkingManager . singleton . ServerClientId , MLAPIConstants . MLAPI_NETWORKED_VAR_DELTA , channelsForVarGroups [ j ] , stream ) ;
300
303
}
301
304
}
302
305
}
@@ -360,10 +363,10 @@ internal void HandleNetworkedVarUpdate(Stream stream, uint clientId)
360
363
#endregion
361
364
362
365
#region MESSAGING_SYSTEM
363
- private static readonly Dictionary < Type , Dictionary < ulong , ClientRPC > > CachedClientRpcs = new Dictionary < Type , Dictionary < ulong , ClientRPC > > ( ) ;
364
- private static readonly Dictionary < Type , Dictionary < ulong , ServerRPC > > CachedServerRpcs = new Dictionary < Type , Dictionary < ulong , ServerRPC > > ( ) ;
366
+ private readonly Dictionary < NetworkedBehaviour , Dictionary < ulong , ClientRPC > > CachedClientRpcs = new Dictionary < NetworkedBehaviour , Dictionary < ulong , ClientRPC > > ( ) ;
367
+ private readonly Dictionary < NetworkedBehaviour , Dictionary < ulong , ServerRPC > > CachedServerRpcs = new Dictionary < NetworkedBehaviour , Dictionary < ulong , ServerRPC > > ( ) ;
368
+ private static readonly Dictionary < Type , MethodInfo [ ] > Methods = new Dictionary < Type , MethodInfo [ ] > ( ) ;
365
369
private static readonly Dictionary < ulong , string > HashResults = new Dictionary < ulong , string > ( ) ;
366
- private static readonly HashSet < Type > CachedTypes = new HashSet < Type > ( ) ;
367
370
368
371
private ulong HashMethodName ( string name )
369
372
{
@@ -382,13 +385,18 @@ private ulong HashMethodName(string name)
382
385
private void CacheAttributes ( )
383
386
{
384
387
Type type = GetType ( ) ;
385
- if ( CachedTypes . Contains ( type ) ) return ; //Already cached
386
388
387
- CachedTypes . Add ( type ) ;
388
- CachedClientRpcs . Add ( type , new Dictionary < ulong , ClientRPC > ( ) ) ;
389
- CachedServerRpcs . Add ( type , new Dictionary < ulong , ServerRPC > ( ) ) ;
390
-
391
- MethodInfo [ ] methods = type . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) ;
389
+ CachedClientRpcs . Add ( this , new Dictionary < ulong , ClientRPC > ( ) ) ;
390
+ CachedServerRpcs . Add ( this , new Dictionary < ulong , ServerRPC > ( ) ) ;
391
+
392
+ MethodInfo [ ] methods ;
393
+ if ( Methods . ContainsKey ( type ) ) methods = Methods [ type ] ;
394
+ else
395
+ {
396
+ methods = type . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) ;
397
+ Methods . Add ( type , methods ) ;
398
+ }
399
+
392
400
for ( int i = 0 ; i < methods . Length ; i ++ )
393
401
{
394
402
if ( methods [ i ] . IsDefined ( typeof ( ServerRPC ) , true ) )
@@ -403,7 +411,7 @@ private void CacheAttributes()
403
411
if ( parameters . Length == 2 && parameters [ 0 ] . ParameterType == typeof ( uint ) && parameters [ 1 ] . ParameterType == typeof ( Stream ) )
404
412
{
405
413
//use delegate
406
- attributes [ 0 ] . rpcDelegate = ( RpcDelegate ) Delegate . CreateDelegate ( typeof ( RpcDelegate ) , this , methods [ i ] , true ) ;
414
+ attributes [ 0 ] . rpcDelegate = ( RpcDelegate ) Delegate . CreateDelegate ( typeof ( RpcDelegate ) , this , methods [ i ] . Name ) ;
407
415
}
408
416
else
409
417
{
@@ -415,12 +423,12 @@ private void CacheAttributes()
415
423
{
416
424
if ( LogHelper . CurrentLogLevel <= LogLevel . Error ) LogHelper . LogError ( "Hash collision detected for RPC method. The method \" " + methods [ i ] . Name + "\" collides with the method \" " + HashResults [ hash ] + "\" . This can be solved by increasing the amount of bytes to use for hashing in the NetworkConfig or changing the name of one of the conflicting methods." ) ;
417
425
}
418
- else
426
+ else if ( ! HashResults . ContainsKey ( hash ) )
419
427
{
420
428
HashResults . Add ( hash , methods [ i ] . Name ) ;
421
429
}
422
430
423
- CachedServerRpcs [ type ] . Add ( hash , attributes [ 0 ] ) ;
431
+ CachedServerRpcs [ this ] . Add ( hash , attributes [ 0 ] ) ;
424
432
}
425
433
426
434
if ( methods [ i ] . IsDefined ( typeof ( ClientRPC ) , true ) )
@@ -435,21 +443,31 @@ private void CacheAttributes()
435
443
if ( parameters . Length == 2 && parameters [ 0 ] . ParameterType == typeof ( uint ) && parameters [ 1 ] . ParameterType == typeof ( Stream ) )
436
444
{
437
445
//use delegate
438
- attributes [ 0 ] . rpcDelegate = ( RpcDelegate ) Delegate . CreateDelegate ( typeof ( RpcDelegate ) , this , methods [ i ] , true ) ;
446
+ attributes [ 0 ] . rpcDelegate = ( RpcDelegate ) Delegate . CreateDelegate ( typeof ( RpcDelegate ) , this , methods [ i ] . Name ) ;
439
447
}
440
448
else
441
449
{
442
450
attributes [ 0 ] . reflectionMethod = new ReflectionMehtod ( methods [ i ] ) ;
443
451
}
444
-
445
- CachedClientRpcs [ type ] . Add ( HashMethodName ( methods [ i ] . Name ) , attributes [ 0 ] ) ;
452
+
453
+ ulong hash = HashMethodName ( methods [ i ] . Name ) ;
454
+ if ( HashResults . ContainsKey ( hash ) && HashResults [ hash ] != methods [ i ] . Name )
455
+ {
456
+ if ( LogHelper . CurrentLogLevel <= LogLevel . Error ) LogHelper . LogError ( "Hash collision detected for RPC method. The method \" " + methods [ i ] . Name + "\" collides with the method \" " + HashResults [ hash ] + "\" . This can be solved by increasing the amount of bytes to use for hashing in the NetworkConfig or changing the name of one of the conflicting methods." ) ;
457
+ }
458
+ else if ( ! HashResults . ContainsKey ( hash ) )
459
+ {
460
+ HashResults . Add ( hash , methods [ i ] . Name ) ;
461
+ }
462
+
463
+ CachedClientRpcs [ this ] . Add ( HashMethodName ( methods [ i ] . Name ) , attributes [ 0 ] ) ;
446
464
}
447
465
}
448
466
}
449
467
450
468
internal void OnRemoteServerRPC ( ulong hash , uint senderClientId , Stream stream )
451
469
{
452
- if ( ! CachedServerRpcs . ContainsKey ( GetType ( ) ) || ! CachedServerRpcs [ GetType ( ) ] . ContainsKey ( hash ) )
470
+ if ( ! CachedServerRpcs . ContainsKey ( this ) || ! CachedServerRpcs [ this ] . ContainsKey ( hash ) )
453
471
{
454
472
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "ServerRPC request method not found" ) ;
455
473
return ;
@@ -459,7 +477,7 @@ internal void OnRemoteServerRPC(ulong hash, uint senderClientId, Stream stream)
459
477
460
478
internal void OnRemoteClientRPC ( ulong hash , uint senderClientId , Stream stream )
461
479
{
462
- if ( ! CachedClientRpcs . ContainsKey ( GetType ( ) ) || ! CachedClientRpcs [ GetType ( ) ] . ContainsKey ( hash ) )
480
+ if ( ! CachedClientRpcs . ContainsKey ( this ) || ! CachedClientRpcs [ this ] . ContainsKey ( hash ) )
463
481
{
464
482
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "ClientRPC request method not found" ) ;
465
483
return ;
@@ -469,43 +487,57 @@ internal void OnRemoteClientRPC(ulong hash, uint senderClientId, Stream stream)
469
487
470
488
private void InvokeServerRPCLocal ( ulong hash , uint senderClientId , Stream stream )
471
489
{
472
- if ( ! CachedServerRpcs . ContainsKey ( GetType ( ) ) || ! CachedServerRpcs [ GetType ( ) ] . ContainsKey ( hash ) )
490
+ if ( ! CachedServerRpcs . ContainsKey ( this ) || ! CachedServerRpcs [ this ] . ContainsKey ( hash ) )
473
491
return ;
474
492
475
- ServerRPC rpc = CachedServerRpcs [ GetType ( ) ] [ hash ] ;
493
+ ServerRPC rpc = CachedServerRpcs [ this ] [ hash ] ;
476
494
477
495
if ( rpc . RequireOwnership && senderClientId != OwnerClientId )
478
496
{
479
497
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "Only owner can invoke ServerRPC that is marked to require ownership" ) ;
480
498
return ;
481
499
}
482
-
483
- if ( rpc . reflectionMethod != null )
484
- {
485
- rpc . reflectionMethod . Invoke ( this , stream ) ;
486
- }
487
500
488
- if ( rpc . rpcDelegate != null )
501
+ //Create a new stream so that the stream they get ONLY contains user data and not MLAPI headers
502
+ using ( PooledBitStream userStream = PooledBitStream . Get ( ) )
489
503
{
490
- rpc . rpcDelegate ( senderClientId , stream ) ;
504
+ userStream . CopyUnreadFrom ( stream ) ;
505
+ userStream . Position = 0 ;
506
+
507
+ if ( rpc . reflectionMethod != null )
508
+ {
509
+ rpc . reflectionMethod . Invoke ( this , userStream ) ;
510
+ }
511
+
512
+ if ( rpc . rpcDelegate != null )
513
+ {
514
+ rpc . rpcDelegate ( senderClientId , userStream ) ;
515
+ }
491
516
}
492
517
}
493
518
494
519
private void InvokeClientRPCLocal ( ulong hash , uint senderClientId , Stream stream )
495
520
{
496
- if ( ! CachedClientRpcs . ContainsKey ( GetType ( ) ) || ! CachedClientRpcs [ GetType ( ) ] . ContainsKey ( hash ) )
521
+ if ( ! CachedClientRpcs . ContainsKey ( this ) || ! CachedClientRpcs [ this ] . ContainsKey ( hash ) )
497
522
return ;
498
523
499
- ClientRPC rpc = CachedClientRpcs [ GetType ( ) ] [ hash ] ;
500
-
501
- if ( rpc . reflectionMethod != null )
502
- {
503
- rpc . reflectionMethod . Invoke ( this , stream ) ;
504
- }
524
+ ClientRPC rpc = CachedClientRpcs [ this ] [ hash ] ;
505
525
506
- if ( rpc . rpcDelegate != null )
526
+ //Create a new stream so that the stream they get ONLY contains user data and not MLAPI headers
527
+ using ( PooledBitStream userStream = PooledBitStream . Get ( ) )
507
528
{
508
- rpc . rpcDelegate ( senderClientId , stream ) ;
529
+ userStream . CopyUnreadFrom ( stream ) ;
530
+ userStream . Position = 0 ;
531
+
532
+ if ( rpc . reflectionMethod != null )
533
+ {
534
+ rpc . reflectionMethod . Invoke ( this , userStream ) ;
535
+ }
536
+
537
+ if ( rpc . rpcDelegate != null )
538
+ {
539
+ rpc . rpcDelegate ( senderClientId , userStream ) ;
540
+ }
509
541
}
510
542
}
511
543
@@ -552,7 +584,7 @@ internal void SendClientRPCBoxed(ulong hash, uint clientId, params object[] para
552
584
553
585
internal void SendServerRPCPerformance ( ulong hash , Stream messageStream )
554
586
{
555
- if ( ! isClient )
587
+ if ( ! isClient && isRunning )
556
588
{
557
589
//We are ONLY a server.
558
590
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "Only server and host can invoke ServerRPC" ) ;
@@ -573,14 +605,16 @@ internal void SendServerRPCPerformance(ulong hash, Stream messageStream)
573
605
messageStream . Position = 0 ;
574
606
InvokeServerRPCLocal ( hash , NetworkingManager . singleton . LocalClientId , messageStream ) ;
575
607
}
576
-
577
- InternalMessageHandler . Send ( NetworkingManager . singleton . ServerClientId , MLAPIConstants . MLAPI_SERVER_RPC , "MLAPI_DEFAULT_MESSAGE" , stream ) ;
608
+ else
609
+ {
610
+ InternalMessageHandler . Send ( NetworkingManager . singleton . ServerClientId , MLAPIConstants . MLAPI_SERVER_RPC , "MLAPI_DEFAULT_MESSAGE" , stream ) ;
611
+ }
578
612
}
579
613
}
580
614
581
615
internal void SendClientRPCPerformance ( ulong hash , List < uint > clientIds , Stream messageStream )
582
616
{
583
- if ( ! isServer )
617
+ if ( ! isServer && isRunning )
584
618
{
585
619
//We are NOT a server.
586
620
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "Only clients and host can invoke ClientRPC" ) ;
@@ -631,7 +665,7 @@ internal void SendClientRPCPerformance(ulong hash, List<uint> clientIds, Stream
631
665
632
666
internal void SendClientRPCPerformance ( ulong hash , uint clientId , Stream messageStream )
633
667
{
634
- if ( ! isServer )
668
+ if ( ! isServer && isRunning )
635
669
{
636
670
//We are NOT a server.
637
671
if ( LogHelper . CurrentLogLevel <= LogLevel . Normal ) LogHelper . LogWarning ( "Only clients and host can invoke ClientRPC" ) ;
0 commit comments