@@ -180,24 +180,16 @@ protected NetworkManager GetAuthorityNetworkManager()
180180 {
181181 if ( m_UseCmbService )
182182 {
183- // TODO: Because we start the NetworkManagers back-to-back, the service can make a NetworkManager
184- // (other than the very first one) the session owner. This could lead to test instabilities and
185- // we need to add additional code during the start process that will start the very 1st instance
186- // and wait for it to be approved and assigned the session owner before we assume anything.
187- // Otherwise, any pick from the m_NetworkManagers could result in that specific instance not being
188- // the first session owner.
189- // If we haven't even started any NetworkManager, then just return the first
190- // instance until we resolve the above issue.
183+ // If we haven't even started any NetworkManager, then return the first instance
184+ // since it will be the session owner.
191185 if ( ! NetcodeIntegrationTestHelpers . IsStarted )
192186 {
193187 return m_NetworkManagers [ 0 ] ;
194188 }
195189
196190 foreach ( var client in m_NetworkManagers )
197191 {
198- // See above notes.
199- // TODO: Once the above is resolved, just check for client.LocalClient.IsSessionOwner
200- if ( ! client . LocalClient . IsApproved || client . LocalClient . IsSessionOwner )
192+ if ( client . LocalClient . IsSessionOwner )
201193 {
202194 return client ;
203195 }
@@ -584,15 +576,6 @@ private void CreatePlayerPrefab()
584576 VerboseDebug ( $ "Exiting { nameof ( CreatePlayerPrefab ) } ") ;
585577 }
586578
587- /// <summary>
588- /// This is invoked before the server and client(s) are started.
589- /// Override this method if you want to make any adjustments to their
590- /// NetworkManager instances.
591- /// </summary>
592- protected virtual void OnServerAndClientsCreated ( )
593- {
594- }
595-
596579 private void AddRemoveNetworkManager ( NetworkManager networkManager , bool addNetworkManager )
597580 {
598581 var clientNetworkManagersList = new List < NetworkManager > ( m_ClientNetworkManagers ) ;
@@ -615,6 +598,78 @@ private void AddRemoveNetworkManager(NetworkManager networkManager, bool addNetw
615598 m_NetworkManagers = clientNetworkManagersList . ToArray ( ) ;
616599 }
617600
601+ /// <summary>
602+ /// This is invoked before the server and client(s) are started.
603+ /// Override this method if you want to make any adjustments to their
604+ /// NetworkManager instances.
605+ /// </summary>
606+ protected virtual void OnServerAndClientsCreated ( )
607+ {
608+ }
609+
610+ /// <summary>
611+ /// Will create <see cref="NumberOfClients"/> number of clients.
612+ /// To create a specific number of clients <see cref="CreateServerAndClients(int)"/>
613+ /// </summary>
614+ protected void CreateServerAndClients ( )
615+ {
616+ CreateServerAndClients ( NumberOfClients ) ;
617+ }
618+
619+ /// <summary>
620+ /// Creates the server and clients
621+ /// </summary>
622+ /// <param name="numberOfClients">The number of client instances to create</param>
623+ protected void CreateServerAndClients ( int numberOfClients )
624+ {
625+ VerboseDebug ( $ "Entering { nameof ( CreateServerAndClients ) } ") ;
626+
627+ CreatePlayerPrefab ( ) ;
628+
629+ if ( m_EnableTimeTravel )
630+ {
631+ m_TargetFrameRate = - 1 ;
632+ }
633+
634+ // If we are connecting to a CMB server we add +1 for the session owner
635+ if ( m_UseCmbService )
636+ {
637+ numberOfClients ++ ;
638+ }
639+
640+ // Create multiple NetworkManager instances
641+ if ( ! NetcodeIntegrationTestHelpers . Create ( numberOfClients , out NetworkManager server , out NetworkManager [ ] clients , m_TargetFrameRate , m_CreateServerFirst , m_EnableTimeTravel , m_UseCmbService ) )
642+ {
643+ Debug . LogError ( "Failed to create instances" ) ;
644+ Assert . Fail ( "Failed to create instances" ) ;
645+ }
646+ m_NumberOfClients = numberOfClients ;
647+ m_ClientNetworkManagers = clients ;
648+ m_ServerNetworkManager = server ;
649+
650+ var managers = clients . ToList ( ) ;
651+ if ( ! m_UseCmbService )
652+ {
653+ managers . Insert ( 0 , m_ServerNetworkManager ) ;
654+ }
655+ m_NetworkManagers = managers . ToArray ( ) ;
656+
657+ s_DefaultWaitForTick = new WaitForSecondsRealtime ( 1.0f / GetAuthorityNetworkManager ( ) . NetworkConfig . TickRate ) ;
658+
659+ // Set the player prefab for the server and clients
660+ foreach ( var manager in m_NetworkManagers )
661+ {
662+ manager . NetworkConfig . PlayerPrefab = m_PlayerPrefab ;
663+ SetDistributedAuthorityProperties ( manager ) ;
664+ }
665+
666+ // Provides opportunity to allow child derived classes to
667+ // modify the NetworkManager's configuration before starting.
668+ OnServerAndClientsCreated ( ) ;
669+
670+ VerboseDebug ( $ "Exiting { nameof ( CreateServerAndClients ) } ") ;
671+ }
672+
618673 /// <summary>
619674 /// CreateAndStartNewClient Only
620675 /// Invoked when the newly created client has been created
@@ -863,69 +918,6 @@ protected void SetTimeTravelSimulatedLatencyJitter(float jitterSeconds)
863918 }
864919 }
865920
866- /// <summary>
867- /// Will create <see cref="NumberOfClients"/> number of clients.
868- /// To create a specific number of clients <see cref="CreateServerAndClients(int)"/>
869- /// </summary>
870- protected void CreateServerAndClients ( )
871- {
872- CreateServerAndClients ( NumberOfClients ) ;
873- }
874-
875- /// <summary>
876- /// Creates the server and clients
877- /// </summary>
878- /// <param name="numberOfClients">The number of client instances to create</param>
879- protected void CreateServerAndClients ( int numberOfClients )
880- {
881- VerboseDebug ( $ "Entering { nameof ( CreateServerAndClients ) } ") ;
882-
883- CreatePlayerPrefab ( ) ;
884-
885- if ( m_EnableTimeTravel )
886- {
887- m_TargetFrameRate = - 1 ;
888- }
889-
890- // If we are connecting to a CMB server we add +1 for the session owner
891- if ( m_UseCmbService )
892- {
893- numberOfClients ++ ;
894- }
895-
896- // Create multiple NetworkManager instances
897- if ( ! NetcodeIntegrationTestHelpers . Create ( numberOfClients , out NetworkManager server , out NetworkManager [ ] clients , m_TargetFrameRate , m_CreateServerFirst , m_EnableTimeTravel , m_UseCmbService ) )
898- {
899- Debug . LogError ( "Failed to create instances" ) ;
900- Assert . Fail ( "Failed to create instances" ) ;
901- }
902- m_NumberOfClients = numberOfClients ;
903- m_ClientNetworkManagers = clients ;
904- m_ServerNetworkManager = server ;
905-
906- var managers = clients . ToList ( ) ;
907- if ( ! m_UseCmbService )
908- {
909- managers . Insert ( 0 , m_ServerNetworkManager ) ;
910- }
911- m_NetworkManagers = managers . ToArray ( ) ;
912-
913- s_DefaultWaitForTick = new WaitForSecondsRealtime ( 1.0f / GetAuthorityNetworkManager ( ) . NetworkConfig . TickRate ) ;
914-
915- // Set the player prefab for the server and clients
916- foreach ( var manager in m_NetworkManagers )
917- {
918- manager . NetworkConfig . PlayerPrefab = m_PlayerPrefab ;
919- SetDistributedAuthorityProperties ( manager ) ;
920- }
921-
922- // Provides opportunity to allow child derived classes to
923- // modify the NetworkManager's configuration before starting.
924- OnServerAndClientsCreated ( ) ;
925-
926- VerboseDebug ( $ "Exiting { nameof ( CreateServerAndClients ) } ") ;
927- }
928-
929921 /// <summary>
930922 /// Override this method and return false in order to be able
931923 /// to manually control when the server and clients are started.
@@ -1028,11 +1020,7 @@ protected void ClientNetworkManagerPostStartInit()
10281020
10291021 if ( m_UseHost )
10301022 {
1031- #if UNITY_2023_1_OR_NEWER
10321023 var clientSideServerPlayerClones = Object . FindObjectsByType < NetworkObject > ( FindObjectsSortMode . None ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == NetworkManager . ServerClientId ) ;
1033- #else
1034- var clientSideServerPlayerClones = Object . FindObjectsOfType < NetworkObject > ( ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == m_ServerNetworkManager . LocalClientId ) ;
1035- #endif
10361024 foreach ( var playerNetworkObject in clientSideServerPlayerClones )
10371025 {
10381026 // When the server is not the host this needs to be done
@@ -1056,6 +1044,19 @@ protected virtual bool ShouldCheckForSpawnedPlayers()
10561044 return true ;
10571045 }
10581046
1047+ /// <summary>
1048+ /// Starts the session owner and awaits for it to connect before starting the remaining clients.
1049+ /// </summary>
1050+ private IEnumerator StartSessionOwner ( )
1051+ {
1052+ VerboseDebug ( "Starting session owner..." ) ;
1053+ NetcodeIntegrationTestHelpers . StartOneClient ( m_ClientNetworkManagers [ 0 ] ) ;
1054+ yield return WaitForConditionOrTimeOut ( ( ) => m_ClientNetworkManagers [ 0 ] . IsConnectedClient ) ;
1055+ AssertOnTimeout ( $ "Timed out waiting for the session owner to connect to CMB Server!") ;
1056+ Assert . True ( m_ClientNetworkManagers [ 0 ] . LocalClient . IsSessionOwner , $ "Client-{ m_ClientNetworkManagers [ 0 ] . LocalClientId } started session but was not set to be the session owner!") ;
1057+ VerboseDebug ( "Session owner connected and approved." ) ;
1058+ }
1059+
10591060 /// <summary>
10601061 /// This starts the server and clients as long as <see cref="CanStartServerAndClients"/>
10611062 /// returns true.
@@ -1066,17 +1067,21 @@ protected IEnumerator StartServerAndClients()
10661067 {
10671068 VerboseDebug ( $ "Entering { nameof ( StartServerAndClients ) } ") ;
10681069
1070+ if ( m_UseCmbService )
1071+ {
1072+ VerboseDebug ( "Using a distributed authority CMB Server for connection." ) ;
1073+ yield return StartSessionOwner ( ) ;
1074+ }
1075+
10691076 // Start the instances and pass in our SceneManagerInitialization action that is invoked immediately after host-server
10701077 // is started and after each client is started.
1071-
1072- VerboseDebug ( $ "Starting with useCmbService: { m_UseCmbService } ") ;
10731078 if ( ! NetcodeIntegrationTestHelpers . Start ( m_UseHost , ! m_UseCmbService , m_ServerNetworkManager , m_ClientNetworkManagers ) )
10741079 {
10751080 Debug . LogError ( "Failed to start instances" ) ;
10761081 Assert . Fail ( "Failed to start instances" ) ;
10771082 }
10781083
1079- // When using the CMBService, we don't have a server, so get the appropriate authority network manager
1084+ // Get the authority NetworkMananger (Server, Host, or Session Owner)
10801085 var authorityManager = GetAuthorityNetworkManager ( ) ;
10811086
10821087 // When scene management is enabled, we need to re-apply the scenes populated list since we have overriden the ISceneManagerHandler
@@ -1108,13 +1113,8 @@ protected IEnumerator StartServerAndClients()
11081113
11091114 if ( m_UseHost || authorityManager . IsHost )
11101115 {
1111- #if UNITY_2023_1_OR_NEWER
11121116 // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries
11131117 var serverPlayerClones = Object . FindObjectsByType < NetworkObject > ( FindObjectsSortMode . None ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == authorityManager . LocalClientId ) ;
1114- #else
1115- // Add the server player instance to all m_ClientSidePlayerNetworkObjects entries
1116- var serverPlayerClones = Object . FindObjectsOfType < NetworkObject > ( ) . Where ( ( c ) => c . IsPlayerObject && c . OwnerClientId == authorityManager . LocalClientId ) ;
1117- #endif
11181118 foreach ( var playerNetworkObject in serverPlayerClones )
11191119 {
11201120 if ( ! m_PlayerNetworkObjects . ContainsKey ( playerNetworkObject . NetworkManager . LocalClientId ) )
@@ -1128,6 +1128,8 @@ protected IEnumerator StartServerAndClients()
11281128 }
11291129 }
11301130 }
1131+
1132+ // With distributed authority, we check that all players have spawned on all NetworkManager instances
11311133 if ( m_DistributedAuthority )
11321134 {
11331135 foreach ( var networkManager in m_NetworkManagers )
@@ -1137,8 +1139,10 @@ protected IEnumerator StartServerAndClients()
11371139 }
11381140 }
11391141
1140- if ( ShouldCheckForSpawnedPlayers ( ) )
1142+ // Client-Server or DAHost
1143+ if ( ShouldCheckForSpawnedPlayers ( ) && ! m_UseCmbService )
11411144 {
1145+ // Check for players being spawned on server instance
11421146 ClientNetworkManagerPostStartInit ( ) ;
11431147 }
11441148
@@ -1698,13 +1702,12 @@ private bool CheckClientsConnected(NetworkManager[] clientsToCheck)
16981702 }
16991703
17001704 var manager = GetAuthorityNetworkManager ( ) ;
1701- var expectedCount = manager . IsHost ? clientsToCheck . Length + 1 : clientsToCheck . Length ;
17021705 var currentCount = manager . ConnectedClients . Count ;
17031706
1704- if ( currentCount != expectedCount )
1707+ if ( currentCount != TotalClients )
17051708 {
17061709 allClientsConnected = false ;
1707- m_InternalErrorLog . AppendLine ( $ "[Server-Side] Expected { expectedCount } clients to connect but only { currentCount } connected!") ;
1710+ m_InternalErrorLog . AppendLine ( $ "[Server-Side] Expected { TotalClients } clients to connect but only { currentCount } connected!") ;
17081711 }
17091712
17101713 return allClientsConnected ;
0 commit comments