@@ -1122,18 +1122,16 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11221122 {
11231123 if ( ! playerObject . DontDestroyWithOwner )
11241124 {
1125- // DANGO-TODO: This is something that would be best for CMB Service to handle as it is part of the disconnection process
11261125 // If a player NetworkObject is being despawned, make sure to remove all children if they are marked to not be destroyed
11271126 // with the owner.
1128- if ( NetworkManager . DistributedAuthorityMode && NetworkManager . DAHost )
1127+ if ( NetworkManager . DAHost )
11291128 {
11301129 // Remove any children from the player object if they are not going to be destroyed with the owner
11311130 var childNetworkObjects = playerObject . GetComponentsInChildren < NetworkObject > ( ) ;
11321131 foreach ( var child in childNetworkObjects )
11331132 {
1134- // TODO: We have always just removed all children, but we might think about changing this to preserve the nested child
1135- // hierarchy.
1136- if ( child . DontDestroyWithOwner && child . transform . transform . parent != null )
1133+ // TODO: We have always just removed all children, but we might think about changing this to preserve the nested child hierarchy.
1134+ if ( child . DontDestroyWithOwner && child . transform . transform . parent )
11371135 {
11381136 // If we are here, then we are running in DAHost mode and have the authority to remove the child from its parent
11391137 child . AuthorityAppliedParenting = true ;
@@ -1158,10 +1156,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11581156 }
11591157 else if ( ! NetworkManager . ShutdownInProgress )
11601158 {
1161- if ( ! NetworkManager . ShutdownInProgress )
1162- {
1163- playerObject . RemoveOwnership ( ) ;
1164- }
1159+ playerObject . RemoveOwnership ( ) ;
11651160 }
11661161 }
11671162
@@ -1175,7 +1170,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11751170 for ( int i = clientOwnedObjects . Count - 1 ; i >= 0 ; i -- )
11761171 {
11771172 var ownedObject = clientOwnedObjects [ i ] ;
1178- if ( ownedObject != null )
1173+ if ( ownedObject )
11791174 {
11801175 // If destroying with owner, then always despawn and destroy (or defer destroying to prefab handler)
11811176 if ( ! ownedObject . DontDestroyWithOwner )
@@ -1196,68 +1191,93 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11961191 }
11971192 else if ( ! NetworkManager . ShutdownInProgress )
11981193 {
1194+ // DANGO-TODO: We will want to match how the CMB service handles this. For now, we just try to evenly distribute
1195+ // ownership.
11991196 // NOTE: All of the below code only handles ownership transfer.
12001197 // For client-server, we just remove the ownership.
12011198 // For distributed authority, we need to change ownership based on parenting
12021199 if ( NetworkManager . DistributedAuthorityMode )
12031200 {
1204- // Only NetworkObjects that have the OwnershipStatus.Distributable flag set and no parent
1205- // (ownership is transferred to all children) will have their ownership redistributed.
1206- if ( ownedObject . IsOwnershipDistributable && ownedObject . GetCachedParent ( ) == null && ! ownedObject . IsOwnershipSessionOwner )
1201+ // Only NetworkObjects that have the OwnershipStatus.Distributable flag set and are not OwnershipSessionOwner are distributed.
1202+ // If the object has a parent - skip it for now, it will be distributed when its root parent is distributed.
1203+ if ( ! ownedObject . IsOwnershipDistributable || ownedObject . IsOwnershipSessionOwner || ownedObject . GetCachedParent ( ) )
1204+ {
1205+ continue ;
1206+ }
1207+
1208+ if ( ownedObject . IsOwnershipLocked )
1209+ {
1210+ ownedObject . SetOwnershipLock ( false ) ;
1211+ }
1212+
1213+ var targetOwner = NetworkManager . ServerClientId ;
1214+ // Cycle through the full count of clients to find
1215+ // the next viable owner. If none are found, then
1216+ // the DAHost defaults to the owner.
1217+ for ( int j = 0 ; j < remainingClients . Count ; j ++ )
12071218 {
1208- if ( ownedObject . IsOwnershipLocked )
1219+ clientCounter ++ ;
1220+ clientCounter = clientCounter % predictedClientCount ;
1221+ if ( ownedObject . Observers . Contains ( remainingClients [ clientCounter ] . ClientId ) )
12091222 {
1210- ownedObject . SetOwnershipLock ( false ) ;
1223+ targetOwner = remainingClients [ clientCounter ] . ClientId ;
1224+ break ;
12111225 }
1226+ }
1227+ if ( EnableDistributeLogging )
1228+ {
1229+ Debug . Log ( $ "[Disconnected][Client-{ clientId } ][NetworkObjectId-{ ownedObject . NetworkObjectId } Distributed to Client-{ targetOwner } ") ;
1230+ }
12121231
1213- // DANGO-TODO: We will want to match how the CMB service handles this. For now, we just try to evenly distribute
1214- // ownership.
1215- var targetOwner = NetworkManager . ServerClientId ;
1216- if ( predictedClientCount > 1 )
1232+ NetworkManager . SpawnManager . ChangeOwnership ( ownedObject , targetOwner , true ) ;
1233+
1234+ // Ownership gets passed down to all children that have the same owner.
1235+ var childNetworkObjects = ownedObject . GetComponentsInChildren < NetworkObject > ( ) ;
1236+ foreach ( var childObject in childNetworkObjects )
1237+ {
1238+ // We already changed ownership for this
1239+ if ( childObject == ownedObject )
12171240 {
1218- clientCounter ++ ;
1219- clientCounter = clientCounter % predictedClientCount ;
1220- targetOwner = remainingClients [ clientCounter ] . ClientId ;
1241+ continue ;
12211242 }
1222- if ( EnableDistributeLogging )
1243+ // If the client owner disconnected, it is ok to unlock this at this point in time.
1244+ if ( childObject . IsOwnershipLocked )
12231245 {
1224- Debug . Log ( $ "[Disconnected][Client- { clientId } ][NetworkObjectId- { ownedObject . NetworkObjectId } Distributed to Client- { targetOwner } " ) ;
1246+ childObject . SetOwnershipLock ( false ) ;
12251247 }
1226- NetworkManager . SpawnManager . ChangeOwnership ( ownedObject , targetOwner , true ) ;
1227- // DANGO-TODO: Should we try handling inactive NetworkObjects?
1228- // Ownership gets passed down to all children that have the same owner.
1229- var childNetworkObjects = ownedObject . GetComponentsInChildren < NetworkObject > ( ) ;
1230- foreach ( var childObject in childNetworkObjects )
1248+
1249+ // Ignore session owner marked objects
1250+ if ( childObject . IsOwnershipSessionOwner )
12311251 {
1232- // We already changed ownership for this
1233- if ( childObject == ownedObject )
1234- {
1235- continue ;
1236- }
1237- // If the client owner disconnected, it is ok to unlock this at this point in time.
1238- if ( childObject . IsOwnershipLocked )
1239- {
1240- childObject . SetOwnershipLock ( false ) ;
1241- }
1252+ continue ;
1253+ }
12421254
1243- // Ignore session owner marked objects
1244- if ( childObject . IsOwnershipSessionOwner )
1245- {
1246- continue ;
1247- }
1255+ // If the child's owner is not the client disconnected and the objects are marked with either distributable or transferable, then
1256+ // do not change ownership.
1257+ if ( childObject . OwnerClientId != clientId && ( childObject . IsOwnershipDistributable || childObject . IsOwnershipTransferable ) )
1258+ {
1259+ continue ;
1260+ }
12481261
1249- // If the child's owner is not the client disconnected and the objects are marked with either distributable or transferable, then
1250- // do not change ownership.
1251- if ( childObject . OwnerClientId != clientId && ( childObject . IsOwnershipDistributable || childObject . IsOwnershipTransferable ) )
1262+ var childOwner = targetOwner ;
1263+ if ( ! childObject . Observers . Contains ( childOwner ) )
1264+ {
1265+ for ( int j = 0 ; j < remainingClients . Count ; j ++ )
12521266 {
1253- continue ;
1267+ clientCounter ++ ;
1268+ clientCounter = clientCounter % predictedClientCount ;
1269+ if ( ownedObject . Observers . Contains ( remainingClients [ clientCounter ] . ClientId ) )
1270+ {
1271+ childOwner = remainingClients [ clientCounter ] . ClientId ;
1272+ break ;
1273+ }
12541274 }
1275+ }
12551276
1256- NetworkManager . SpawnManager . ChangeOwnership ( childObject , targetOwner , true ) ;
1257- if ( EnableDistributeLogging )
1258- {
1259- Debug . Log ( $ "[Disconnected][Client-{ clientId } ][Child of { ownedObject . NetworkObjectId } ][NetworkObjectId-{ ownedObject . NetworkObjectId } Distributed to Client-{ targetOwner } ") ;
1260- }
1277+ NetworkManager . SpawnManager . ChangeOwnership ( childObject , childOwner , true ) ;
1278+ if ( EnableDistributeLogging )
1279+ {
1280+ Debug . Log ( $ "[Disconnected][Client-{ clientId } ][Child of { ownedObject . NetworkObjectId } ][NetworkObjectId-{ ownedObject . NetworkObjectId } Distributed to Client-{ targetOwner } ") ;
12611281 }
12621282 }
12631283 }
0 commit comments