@@ -97,7 +97,7 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj
9797 }
9898
9999 /// <summary>
100- /// Total number of clients that should be connected at any point during a test
100+ /// Total number of clients that should be connected at any point during a test.
101101 /// </summary>
102102 protected int TotalClients => m_UseHost ? m_NumberOfClients + 1 : m_NumberOfClients ;
103103
@@ -107,15 +107,21 @@ public static void DeregisterNetworkObject(ulong localClientId, ulong networkObj
107107 /// Specifies the number of client instances to be created for the integration test.
108108 /// </summary>
109109 /// <remarks>
110- /// When running with a hosted CMB Service, NumberOfClients + 1 clients are created.
111- /// This holds assumptions throughout the test suite that when running with a host, there is an extra client.
112- /// For example, see the calculation for <see cref="TotalClients"/>.
110+ /// Client-Server network topology:<br />
111+ /// When running as a host the total number of clients will be NumberOfClients + 1.<br />
112+ /// See the calculation for <see cref="TotalClients"/>.
113+ /// Distributed Authority network topology:<br />
114+ /// When connecting to a CMB server, if the <see cref="NumberOfClients"/> == 0 then a session owner client will
115+ /// be automatically added in order to start the session and the private internal m_NumberOfClients value, which
116+ /// is initialized as <see cref="NumberOfClients"/>, will be incremented by 1 making <see cref="TotalClients"/> yield the
117+ /// same results as if we were running a Host where it will effectively be <see cref="NumberOfClients"/>
118+ /// + 1.
113119 /// </remarks>
114120 protected abstract int NumberOfClients { get ; }
115121 private int m_NumberOfClients ;
116122
117123 /// <summary>
118- /// Set this to false to create the clients first.
124+ /// Set this to false to create the clients first.<br />
119125 /// Note: If you are using scene placed NetworkObjects or doing any form of scene testing and
120126 /// get prefab hash id "soft synchronization" errors, then set this to false and run your test
121127 /// again. This is a work-around until we can resolve some issues with NetworkManagerOwner and
@@ -513,7 +519,13 @@ protected virtual void OnServerAndClientsCreated()
513519 /// </summary>
514520 protected void CreateServerAndClients ( )
515521 {
516- CreateServerAndClients ( NumberOfClients ) ;
522+ // If we are connecting to a CMB server and we have a zero client count,
523+ // then we must make m_NumberOfClients = 1 for the session owner.
524+ if ( UseCMBService ( ) && NumberOfClients == 0 && m_NumberOfClients == 0 )
525+ {
526+ m_NumberOfClients = 1 ;
527+ }
528+ CreateServerAndClients ( m_NumberOfClients ) ;
517529 }
518530
519531 private void AddRemoveNetworkManager ( NetworkManager networkManager , bool addNetworkManager )
@@ -546,7 +558,7 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw
546558 protected virtual void OnNewClientCreated ( NetworkManager networkManager )
547559 {
548560 // Ensure any late joining client has all NetworkPrefabs required to connect.
549- foreach ( var networkPrefab in m_ServerNetworkManager . NetworkConfig . Prefabs . Prefabs )
561+ foreach ( var networkPrefab in GetAuthorityNetworkManager ( ) . NetworkConfig . Prefabs . Prefabs )
550562 {
551563 if ( ! networkManager . NetworkConfig . Prefabs . Contains ( networkPrefab . Prefab ) )
552564 {
@@ -761,7 +773,7 @@ protected void StopOneClientWithTimeTravel(NetworkManager networkManager, bool d
761773
762774 protected void SetTimeTravelSimulatedLatency ( float latencySeconds )
763775 {
764- ( ( MockTransport ) m_ServerNetworkManager . NetworkConfig . NetworkTransport ) . SimulatedLatencySeconds = latencySeconds ;
776+ ( ( MockTransport ) GetAuthorityNetworkManager ( ) . NetworkConfig . NetworkTransport ) . SimulatedLatencySeconds = latencySeconds ;
765777 foreach ( var client in m_ClientNetworkManagers )
766778 {
767779 ( ( MockTransport ) client . NetworkConfig . NetworkTransport ) . SimulatedLatencySeconds = latencySeconds ;
@@ -770,7 +782,7 @@ protected void SetTimeTravelSimulatedLatency(float latencySeconds)
770782
771783 protected void SetTimeTravelSimulatedDropRate ( float dropRatePercent )
772784 {
773- ( ( MockTransport ) m_ServerNetworkManager . NetworkConfig . NetworkTransport ) . PacketDropRate = dropRatePercent ;
785+ ( ( MockTransport ) GetAuthorityNetworkManager ( ) . NetworkConfig . NetworkTransport ) . PacketDropRate = dropRatePercent ;
774786 foreach ( var client in m_ClientNetworkManagers )
775787 {
776788 ( ( MockTransport ) client . NetworkConfig . NetworkTransport ) . PacketDropRate = dropRatePercent ;
@@ -779,7 +791,7 @@ protected void SetTimeTravelSimulatedDropRate(float dropRatePercent)
779791
780792 protected void SetTimeTravelSimulatedLatencyJitter ( float jitterSeconds )
781793 {
782- ( ( MockTransport ) m_ServerNetworkManager . NetworkConfig . NetworkTransport ) . LatencyJitter = jitterSeconds ;
794+ ( ( MockTransport ) GetAuthorityNetworkManager ( ) . NetworkConfig . NetworkTransport ) . LatencyJitter = jitterSeconds ;
783795 foreach ( var client in m_ClientNetworkManagers )
784796 {
785797 ( ( MockTransport ) client . NetworkConfig . NetworkTransport ) . LatencyJitter = jitterSeconds ;
@@ -801,10 +813,23 @@ protected void CreateServerAndClients(int numberOfClients)
801813 m_TargetFrameRate = - 1 ;
802814 }
803815
804- // Add an extra session owner client when using the cmb service
805- if ( m_UseCmbService )
816+ // In the event this is invoked within a derived integration test and
817+ // the number of clients is 0, then we need to have at least 1 client
818+ // to be the session owner.
819+ if ( UseCMBService ( ) && numberOfClients == 0 )
806820 {
807- numberOfClients += 1 ;
821+ numberOfClients = 1 ;
822+ // If m_NumberOfCleints == 0, then we should increment it.
823+ if ( m_NumberOfClients == 0 )
824+ {
825+ m_NumberOfClients = 1 ;
826+ }
827+ else
828+ {
829+ // Otherwise, log a warning to the developer that they may be doing something bad.
830+ Debug . LogWarning ( $ "[{ nameof ( CreateServerAndClients ) } ] Invoked with number of clients set to zero but m_NumberOfClients was { m_NumberOfClients } . " +
831+ $ "Unless this was intended, this could cause issues with the { nameof ( NetcodeIntegrationTest ) } !") ;
832+ }
808833 }
809834
810835 // Create multiple NetworkManager instances
@@ -824,7 +849,7 @@ protected void CreateServerAndClients(int numberOfClients)
824849 }
825850 m_NetworkManagers = managers . ToArray ( ) ;
826851
827- s_DefaultWaitForTick = new WaitForSecondsRealtime ( 1.0f / m_ServerNetworkManager . NetworkConfig . TickRate ) ;
852+ s_DefaultWaitForTick = new WaitForSecondsRealtime ( 1.0f / GetAuthorityNetworkManager ( ) . NetworkConfig . TickRate ) ;
828853
829854 // Set the player prefab for the server and clients
830855 foreach ( var manager in m_NetworkManagers )
@@ -943,7 +968,7 @@ protected void ClientNetworkManagerPostStartInit()
943968 if ( m_UseHost )
944969 {
945970#if UNITY_2023_1_OR_NEWER
946- var clientSideServerPlayerClones = Object . FindObjectsByType < NetworkObject > ( FindObjectsSortMode . None ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == m_ServerNetworkManager . LocalClientId ) ;
971+ var clientSideServerPlayerClones = Object . FindObjectsByType < NetworkObject > ( FindObjectsSortMode . None ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == NetworkManager . ServerClientId ) ;
947972#else
948973 var clientSideServerPlayerClones = Object . FindObjectsOfType < NetworkObject > ( ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == m_ServerNetworkManager . LocalClientId ) ;
949974#endif
@@ -955,9 +980,9 @@ protected void ClientNetworkManagerPostStartInit()
955980 m_PlayerNetworkObjects . Add ( playerNetworkObject . NetworkManager . LocalClientId , new Dictionary < ulong , NetworkObject > ( ) ) ;
956981 }
957982
958- if ( ! m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . ContainsKey ( m_ServerNetworkManager . LocalClientId ) )
983+ if ( ! m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . ContainsKey ( NetworkManager . ServerClientId ) )
959984 {
960- m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( m_ServerNetworkManager . LocalClientId , playerNetworkObject ) ;
985+ m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( NetworkManager . ServerClientId , playerNetworkObject ) ;
961986 }
962987 }
963988 }
@@ -1021,7 +1046,7 @@ protected IEnumerator StartServerAndClients()
10211046
10221047 AssertOnTimeout ( $ "{ nameof ( StartServerAndClients ) } timed out waiting for all clients to be connected!\n { m_InternalErrorLog } ") ;
10231048
1024- if ( m_UseHost || m_ServerNetworkManager . IsHost )
1049+ if ( m_UseHost || authorityManager . IsHost )
10251050 {
10261051#if UNITY_2023_1_OR_NEWER
10271052 // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries
@@ -1039,7 +1064,7 @@ protected IEnumerator StartServerAndClients()
10391064
10401065 if ( ! m_UseCmbService )
10411066 {
1042- m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( m_ServerNetworkManager . LocalClientId , playerNetworkObject ) ;
1067+ m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( authorityManager . LocalClientId , playerNetworkObject ) ;
10431068 }
10441069 }
10451070 }
@@ -1111,7 +1136,7 @@ protected void StartServerAndClientsWithTimeTravel()
11111136
11121137 AssertOnTimeout ( $ "{ nameof ( StartServerAndClients ) } timed out waiting for all clients to be connected!") ;
11131138
1114- if ( m_UseHost || m_ServerNetworkManager . IsHost )
1139+ if ( m_UseHost || authorityManager . IsHost )
11151140 {
11161141#if UNITY_2023_1_OR_NEWER
11171142 // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries
@@ -1129,7 +1154,7 @@ protected void StartServerAndClientsWithTimeTravel()
11291154
11301155 if ( ! m_UseCmbService )
11311156 {
1132- m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( m_ServerNetworkManager . LocalClientId , playerNetworkObject ) ;
1157+ m_PlayerNetworkObjects [ playerNetworkObject . NetworkManager . LocalClientId ] . Add ( authorityManager . LocalClientId , playerNetworkObject ) ;
11331158 }
11341159 }
11351160 }
@@ -1449,10 +1474,9 @@ protected void DestroySceneNetworkObjects()
14491474 /// </summary>
14501475 protected void EnableMessageLogging ( )
14511476 {
1452- m_ServerNetworkManager . ConnectionManager . MessageManager . Hook ( new DebugNetworkHooks ( ) ) ;
1453- foreach ( var client in m_ClientNetworkManagers )
1477+ foreach ( var networkManager in m_NetworkManagers )
14541478 {
1455- client . ConnectionManager . MessageManager . Hook ( new DebugNetworkHooks ( ) ) ;
1479+ networkManager . ConnectionManager . MessageManager . Hook ( new DebugNetworkHooks ( ) ) ;
14561480 }
14571481 }
14581482
@@ -1632,10 +1656,11 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck)
16321656 protected bool WaitForClientsConnectedOrTimeOutWithTimeTravel ( NetworkManager [ ] clientsToCheck )
16331657 {
16341658 var remoteClientCount = clientsToCheck . Length ;
1635- var serverClientCount = m_ServerNetworkManager . IsHost ? remoteClientCount + 1 : remoteClientCount ;
1659+ var authorityNetworkManager = GetAuthorityNetworkManager ( ) ;
1660+ var serverClientCount = authorityNetworkManager . IsHost ? remoteClientCount + 1 : remoteClientCount ;
16361661
16371662 return WaitForConditionOrTimeOutWithTimeTravel ( ( ) => clientsToCheck . Where ( ( c ) => c . IsConnectedClient ) . Count ( ) == remoteClientCount &&
1638- m_ServerNetworkManager . ConnectedClients . Count == serverClientCount ) ;
1663+ authorityNetworkManager . ConnectedClients . Count == serverClientCount ) ;
16391664 }
16401665
16411666 /// <summary>
@@ -1746,9 +1771,10 @@ protected GameObject CreateNetworkObjectPrefab(string baseName)
17461771 {
17471772 var prefabCreateAssertError = $ "You can only invoke this method during { nameof ( OnServerAndClientsCreated ) } " +
17481773 $ "but before { nameof ( OnStartedServerAndClients ) } !";
1749- Assert . IsNotNull ( m_ServerNetworkManager , prefabCreateAssertError ) ;
1750- Assert . IsFalse ( m_ServerNetworkManager . IsListening , prefabCreateAssertError ) ;
1751- var prefabObject = NetcodeIntegrationTestHelpers . CreateNetworkObjectPrefab ( baseName , m_ServerNetworkManager , m_ClientNetworkManagers ) ;
1774+ var authorityNetworkManager = GetAuthorityNetworkManager ( ) ;
1775+ Assert . IsNotNull ( authorityNetworkManager , prefabCreateAssertError ) ;
1776+ Assert . IsFalse ( authorityNetworkManager . IsListening , prefabCreateAssertError ) ;
1777+ var prefabObject = NetcodeIntegrationTestHelpers . CreateNetworkObjectPrefab ( baseName , authorityNetworkManager , m_ClientNetworkManagers ) ;
17521778 // DANGO-TODO: Ownership flags could require us to change this
17531779 // For testing purposes, we default to true for the distribute ownership property when in a distirbuted authority network topology.
17541780 prefabObject . GetComponent < NetworkObject > ( ) . Ownership |= NetworkObject . OwnershipStatus . Distributable ;
0 commit comments