Skip to content

Commit 55c71ff

Browse files
committed
fix: DA client connection flow
1 parent 0561073 commit 55c71ff

File tree

6 files changed

+307
-38
lines changed

6 files changed

+307
-38
lines changed

com.unity.netcode.gameobjects/Runtime/Configuration/SessionConfig.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ internal class SessionConfig
1010
public const uint ServerDistributionCompatible = 2;
1111
public const uint SessionStateToken = 3;
1212
public const uint NetworkBehaviourSerializationSafety = 4;
13+
public const uint FixConnectionFlow = 5;
1314

1415
// The most current session version (!!!!set this when you increment!!!!!)
15-
public static uint PackageSessionVersion => NetworkBehaviourSerializationSafety;
16+
public static uint PackageSessionVersion => FixConnectionFlow;
1617

1718
internal uint SessionVersion;
1819

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ public enum ConnectionEvent
2828
/// On the server side, the <see cref="ConnectionEventData.ClientId"/> will be the ID of the client that just connected.
2929
/// </remarks>
3030
ClientConnected,
31+
3132
/// <summary>
3233
/// This event is set on clients that are already connected to the session.
3334
/// </summary>
3435
/// <remarks>
3536
/// The <see cref="ConnectionEventData.ClientId"/> will be the ID of the client that just connected.
3637
/// </remarks>
3738
PeerConnected,
39+
3840
/// <summary>
3941
/// This event is set on the client-side of the client that disconnected client and on the server-side.
4042
/// </summary>
@@ -43,6 +45,7 @@ public enum ConnectionEvent
4345
/// On the server side, this will be the ID of the client that disconnected.
4446
/// </remarks>
4547
ClientDisconnected,
48+
4649
/// <summary>
4750
/// This event is set on clients that are already connected to the session.
4851
/// </summary>
@@ -133,48 +136,49 @@ internal void InvokeOnClientConnectedCallback(ulong clientId)
133136
Debug.LogException(exception);
134137
}
135138

136-
if (!NetworkManager.IsServer)
139+
if (NetworkManager.IsServer || NetworkManager.LocalClient.IsSessionOwner)
137140
{
138-
var peerClientIds = new NativeArray<ulong>(Math.Max(NetworkManager.ConnectedClientsIds.Count - 1, 0), Allocator.Temp);
139-
// `using var peerClientIds` or `using(peerClientIds)` renders it immutable...
140-
using var sentinel = peerClientIds;
141-
142-
var idx = 0;
143-
foreach (var peerId in NetworkManager.ConnectedClientsIds)
144-
{
145-
if (peerId == NetworkManager.LocalClientId)
146-
{
147-
continue;
148-
}
149-
150-
// This assures if the server has not timed out prior to the client synchronizing that it doesn't exceed the allocated peer count.
151-
if (peerClientIds.Length > idx)
152-
{
153-
peerClientIds[idx] = peerId;
154-
++idx;
155-
}
156-
}
157-
158141
try
159142
{
160-
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = NetworkManager.LocalClientId, EventType = ConnectionEvent.ClientConnected, PeerClientIds = peerClientIds });
143+
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = clientId, EventType = ConnectionEvent.ClientConnected });
161144
}
162145
catch (Exception exception)
163146
{
164147
Debug.LogException(exception);
165148
}
149+
150+
return;
166151
}
167-
else
152+
153+
// Invoking connection event on NonAuthority client. Need to calculate PeerIds.
154+
var peerClientIds = new NativeArray<ulong>(Math.Max(NetworkManager.ConnectedClientsIds.Count - 1, 0), Allocator.Temp);
155+
// `using var peerClientIds` or `using(peerClientIds)` renders it immutable...
156+
using var sentinel = peerClientIds;
157+
158+
var idx = 0;
159+
foreach (var peerId in NetworkManager.ConnectedClientsIds)
168160
{
169-
try
161+
if (peerId == NetworkManager.LocalClientId)
170162
{
171-
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = clientId, EventType = ConnectionEvent.ClientConnected });
163+
continue;
172164
}
173-
catch (Exception exception)
165+
166+
// This assures if the server has not timed out prior to the client synchronizing that it doesn't exceed the allocated peer count.
167+
if (peerClientIds.Length > idx)
174168
{
175-
Debug.LogException(exception);
169+
peerClientIds[idx] = peerId;
170+
++idx;
176171
}
177172
}
173+
174+
try
175+
{
176+
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = NetworkManager.LocalClientId, EventType = ConnectionEvent.ClientConnected, PeerClientIds = peerClientIds });
177+
}
178+
catch (Exception exception)
179+
{
180+
Debug.LogException(exception);
181+
}
178182
}
179183

180184
internal void InvokeOnClientDisconnectCallback(ulong clientId)
@@ -853,6 +857,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
853857
};
854858
}
855859
}
860+
856861
if (!MockSkippingApproval)
857862
{
858863
SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, ownerClientId);
@@ -861,6 +866,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
861866
{
862867
NetworkLog.LogInfo("Mocking server not responding with connection approved...");
863868
}
869+
864870
message.MessageVersions.Dispose();
865871
message.ConnectedClientIds.Dispose();
866872
if (MockSkippingApproval)
@@ -877,8 +883,8 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
877883
{
878884
InvokeOnPeerConnectedCallback(ownerClientId);
879885
}
880-
NetworkManager.SpawnManager.DistributeNetworkObjects(ownerClientId);
881886

887+
NetworkManager.SpawnManager.DistributeNetworkObjects(ownerClientId);
882888
}
883889
else // Otherwise, let NetworkSceneManager handle the initial scene and NetworkObject synchronization
884890
{
@@ -921,6 +927,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
921927
{
922928
return;
923929
}
930+
924931
// Separating this into a contained function call for potential further future separation of when this notification is sent.
925932
ApprovedPlayerSpawn(ownerClientId, response.PlayerPrefabHash ?? NetworkManager.NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash);
926933
}
@@ -935,6 +942,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
935942
SendMessage(ref disconnectReason, NetworkDelivery.Reliable, ownerClientId);
936943
MessageManager.ProcessSendQueues();
937944
}
945+
938946
DisconnectRemoteClient(ownerClientId);
939947
}
940948
}
@@ -1009,12 +1017,14 @@ internal NetworkClient AddClient(ulong clientId)
10091017
{
10101018
networkClient = new NetworkClient();
10111019
}
1020+
10121021
networkClient.SetRole(clientId == NetworkManager.ServerClientId, isClient: true, NetworkManager);
10131022
networkClient.ClientId = clientId;
10141023
if (!ConnectedClients.ContainsKey(clientId))
10151024
{
10161025
ConnectedClients.Add(clientId, networkClient);
10171026
}
1027+
10181028
if (!ConnectedClientsList.Contains(networkClient))
10191029
{
10201030
ConnectedClientsList.Add(networkClient);
@@ -1038,6 +1048,7 @@ internal NetworkClient AddClient(ulong clientId)
10381048
NetworkManager.MessageManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.CurrentSessionOwner);
10391049
}
10401050
}
1051+
10411052
if (!ConnectedClientIds.Contains(clientId))
10421053
{
10431054
ConnectedClientIds.Add(clientId);
@@ -1063,6 +1074,7 @@ internal NetworkClient AddClient(ulong clientId)
10631074
{
10641075
continue;
10651076
}
1077+
10661078
networkObject.Observers.Add(clientId);
10671079
}
10681080
}
@@ -1080,6 +1092,7 @@ internal void RemoveClient(ulong clientId)
10801092
{
10811093
ConnectedClientIds.Remove(clientId);
10821094
}
1095+
10831096
if (ConnectedClients.ContainsKey(clientId))
10841097
{
10851098
ConnectedClientsList.Remove(ConnectedClients[clientId]);
@@ -1186,6 +1199,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
11861199
// Don't destroy (prefab handler will determine this, but always notify
11871200
NetworkManager.SpawnManager.DespawnObject(ownedObject, false, true);
11881201
}
1202+
11891203
NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(ownedObject);
11901204
}
11911205
else
@@ -1225,6 +1239,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
12251239
break;
12261240
}
12271241
}
1242+
12281243
if (EnableDistributeLogging)
12291244
{
12301245
Debug.Log($"[Disconnected][Client-{clientId}][NetworkObjectId-{ownedObject.NetworkObjectId} Distributed to Client-{targetOwner}");
@@ -1247,6 +1262,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
12471262
{
12481263
continue;
12491264
}
1265+
12501266
// If the client owner disconnected, it is ok to unlock this at this point in time.
12511267
if (childObject.IsOwnershipLocked)
12521268
{

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,14 +2603,6 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
26032603
// Mark this client as being connected
26042604
NetworkManager.ConnectedClients[clientId].IsConnected = true;
26052605

2606-
// Notify the local server that a client has finished synchronizing
2607-
OnSceneEvent?.Invoke(new SceneEvent()
2608-
{
2609-
SceneEventType = sceneEventData.SceneEventType,
2610-
SceneName = string.Empty,
2611-
ClientId = clientId
2612-
});
2613-
26142606
// For non-authority clients in a distributed authority session, we show hidden objects,
26152607
// we distribute NetworkObjects, and then we end the scene event.
26162608
if (NetworkManager.DistributedAuthorityMode && !NetworkManager.LocalClient.IsSessionOwner)
@@ -2630,14 +2622,21 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
26302622
}
26312623

26322624
// All scenes are synchronized, let the server know we are done synchronizing
2625+
2626+
// Notify the local server that a client has finished synchronizing
2627+
OnSceneEvent?.Invoke(new SceneEvent()
2628+
{
2629+
SceneEventType = sceneEventData.SceneEventType,
2630+
ClientId = clientId
2631+
});
26332632
OnSynchronizeComplete?.Invoke(clientId);
26342633

26352634
// At this time the client is fully synchronized with all loaded scenes and
26362635
// NetworkObjects and should be considered "fully connected". Send the
26372636
// notification that the client is connected.
26382637
NetworkManager.ConnectionManager.InvokeOnClientConnectedCallback(clientId);
26392638

2640-
if (NetworkManager.IsHost)
2639+
if (NetworkManager.IsHost || NetworkManager.LocalClient.IsSessionOwner)
26412640
{
26422641
NetworkManager.ConnectionManager.InvokeOnPeerConnectedCallback(clientId);
26432642
}

com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ protected NetworkManager GetAuthorityNetworkManager()
206206
/// <returns>A <see cref="NetworkManager"/> instance that will not be the session owner</returns>
207207
protected NetworkManager GetNonAuthorityNetworkManager()
208208
{
209+
// If we haven't even started any NetworkManager, then return the assumed first non-authority NetworkManager
210+
if (!NetcodeIntegrationTestHelpers.IsStarted)
211+
{
212+
return m_UseCmbService ? m_ClientNetworkManagers[1] : m_ClientNetworkManagers[0];
213+
}
214+
209215
return m_ClientNetworkManagers.First(client => !client.LocalClient.IsSessionOwner);
210216
}
211217

0 commit comments

Comments
 (0)