Skip to content

Commit eb8e536

Browse files
Merge develop-2.0.0 into fix/dont-destroy-with-owner-not-being-honored-when-client-exits
2 parents 93f7e6c + e24c2e5 commit eb8e536

File tree

10 files changed

+334
-80
lines changed

10 files changed

+334
-80
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1919
- Fixed issue where non-authority `NetworkTransform` instances would not allow non-synchronized axis values to be updated locally. (#3471)
2020
- Fixed issue where invoking `NetworkObject.NetworkShow` and `NetworkObject.ChangeOwnership` consecutively within the same call stack location could result in an unnecessary change in ownership error message generated on the target client side. (#3468)
2121
- Fixed issue where `NetworkVariable`s on a `NetworkBehaviour` could fail to synchronize changes if one has `NetworkVariableUpdateTraits` set and is dirty but is not ready to send. (#3466)
22+
- Fixed issue with the Distributed Authority connection sequence with scene management enabled where the `ClientConnected` event was fired before the client was synchronized. (#3459)
2223
- Fixed inconsistencies in the `OnSceneEvent` callback. (#3458)
2324
- Fixed issues with the `NetworkBehaviour` and `NetworkVariable` length safety checks. (#3405)
2425
- Fixed memory leaks when domain reload is disabled. (#3427)

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: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -133,48 +133,49 @@ internal void InvokeOnClientConnectedCallback(ulong clientId)
133133
Debug.LogException(exception);
134134
}
135135

136-
if (!NetworkManager.IsServer)
136+
if (NetworkManager.IsServer || NetworkManager.LocalClient.IsSessionOwner)
137137
{
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-
158138
try
159139
{
160-
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = NetworkManager.LocalClientId, EventType = ConnectionEvent.ClientConnected, PeerClientIds = peerClientIds });
140+
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = clientId, EventType = ConnectionEvent.ClientConnected });
161141
}
162142
catch (Exception exception)
163143
{
164144
Debug.LogException(exception);
165145
}
146+
147+
return;
166148
}
167-
else
149+
150+
// Invoking connection event on non-authority local client. Need to calculate PeerIds.
151+
var peerClientIds = new NativeArray<ulong>(Math.Max(NetworkManager.ConnectedClientsIds.Count - 1, 0), Allocator.Temp);
152+
// `using var peerClientIds` or `using(peerClientIds)` renders it immutable...
153+
using var sentinel = peerClientIds;
154+
155+
var idx = 0;
156+
foreach (var peerId in NetworkManager.ConnectedClientsIds)
168157
{
169-
try
158+
if (peerId == NetworkManager.LocalClientId)
170159
{
171-
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = clientId, EventType = ConnectionEvent.ClientConnected });
160+
continue;
172161
}
173-
catch (Exception exception)
162+
163+
// This assures if the server has not timed out prior to the client synchronizing that it doesn't exceed the allocated peer count.
164+
if (peerClientIds.Length > idx)
174165
{
175-
Debug.LogException(exception);
166+
peerClientIds[idx] = peerId;
167+
++idx;
176168
}
177169
}
170+
171+
try
172+
{
173+
OnConnectionEvent?.Invoke(NetworkManager, new ConnectionEventData { ClientId = NetworkManager.LocalClientId, EventType = ConnectionEvent.ClientConnected, PeerClientIds = peerClientIds });
174+
}
175+
catch (Exception exception)
176+
{
177+
Debug.LogException(exception);
178+
}
178179
}
179180

180181
internal void InvokeOnClientDisconnectCallback(ulong clientId)

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ClientConnectedMessage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
3131
public void Handle(ref NetworkContext context)
3232
{
3333
var networkManager = (NetworkManager)context.SystemOwner;
34-
if (ShouldSynchronize && networkManager.NetworkConfig.EnableSceneManagement && networkManager.DistributedAuthorityMode && networkManager.LocalClient.IsSessionOwner)
34+
if (ShouldSynchronize && networkManager.NetworkConfig.EnableSceneManagement && networkManager.DistributedAuthorityMode && !networkManager.CMBServiceConnection && networkManager.LocalClient.IsSessionOwner)
3535
{
3636
networkManager.SceneManager.SynchronizeNetworkObjects(ClientId);
3737
}

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ClientDisconnectedMessage.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
2525
public void Handle(ref NetworkContext context)
2626
{
2727
var networkManager = (NetworkManager)context.SystemOwner;
28+
if (networkManager.DistributedAuthorityMode && networkManager.CMBServiceConnection && networkManager.LocalClient.IsSessionOwner && networkManager.NetworkConfig.EnableSceneManagement)
29+
{
30+
networkManager.SceneManager.ClientConnectionQueue.Remove(ClientId);
31+
}
2832
// All modes support removing NetworkClients
2933
networkManager.ConnectionManager.RemoveClient(ClientId);
3034
networkManager.ConnectionManager.ConnectedClientIds.Remove(ClientId);

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,30 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
246246
public void Handle(ref NetworkContext context)
247247
{
248248
var networkManager = (NetworkManager)context.SystemOwner;
249+
250+
if (networkManager.CMBServiceConnection && networkManager.LocalClient.IsSessionOwner && networkManager.NetworkConfig.EnableSceneManagement)
251+
{
252+
if (networkManager.LocalClientId != OwnerClientId)
253+
{
254+
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
255+
{
256+
NetworkLog.LogInfo($"[Session Owner] Received connection approved for Client-{OwnerClientId}! Synchronizing...");
257+
}
258+
259+
networkManager.SceneManager.SynchronizeNetworkObjects(OwnerClientId);
260+
}
261+
else
262+
{
263+
NetworkLog.LogWarning($"[Client-{OwnerClientId}] Receiving duplicate connection approved. Client is already connected!");
264+
}
265+
return;
266+
}
267+
249268
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
250269
{
251270
NetworkLog.LogInfo($"[Client-{OwnerClientId}] Connection approved! Synchronizing...");
252271
}
272+
253273
networkManager.LocalClientId = OwnerClientId;
254274
networkManager.MessageManager.SetLocalClientId(networkManager.LocalClientId);
255275
networkManager.NetworkMetrics.SetConnectionId(networkManager.LocalClientId);

com.unity.netcode.gameobjects/Runtime/Messaging/NetworkManagerHooks.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public bool OnVerifyCanReceive(ulong senderId, Type messageType, FastBufferReade
9898
return false;
9999
}
100100

101-
if (m_NetworkManager.IsConnectedClient && messageType == typeof(ConnectionApprovedMessage))
101+
if (m_NetworkManager.IsConnectedClient && messageType == typeof(ConnectionApprovedMessage) &&
102+
!(m_NetworkManager.CMBServiceConnection && m_NetworkManager.LocalClient.IsSessionOwner && m_NetworkManager.NetworkConfig.EnableSceneManagement))
102103
{
103104
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
104105
{

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

Lines changed: 15 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,10 @@ private void OnClientLoadedScene(uint sceneEventId, Scene scene)
19251925
/// when many clients attempt to connect at the same time they will be
19261926
/// handled sequentially so as to not saturate the session owner's maximum
19271927
/// reliable messages.
1928+
/// DANGO-TODO: Get clients to track their synchronization status (if they haven't finished synchronizing)
1929+
/// - pending clients can listen to SessionOwnerChanged messages
1930+
/// - If the session owner changes, fire "some sort of event" to the service
1931+
/// - service can fire ConnectionApproved at new session owner
19281932
/// </summary>
19291933
internal List<ulong> ClientConnectionQueue = new List<ulong>();
19301934

@@ -2332,37 +2336,15 @@ private void HandleClientSceneEvent(uint sceneEventId)
23322336
sceneEventData.SceneEventType = SceneEventType.SynchronizeComplete;
23332337
if (NetworkManager.DistributedAuthorityMode)
23342338
{
2335-
if (NetworkManager.CMBServiceConnection)
2339+
sceneEventData.TargetClientId = NetworkManager.CurrentSessionOwner;
2340+
sceneEventData.SenderClientId = NetworkManager.LocalClientId;
2341+
var message = new SceneEventMessage
23362342
{
2337-
foreach (var clientId in NetworkManager.ConnectedClientsIds)
2338-
{
2339-
if (clientId == NetworkManager.LocalClientId)
2340-
{
2341-
continue;
2342-
}
2343-
sceneEventData.TargetClientId = clientId;
2344-
sceneEventData.SenderClientId = NetworkManager.LocalClientId;
2345-
var message = new SceneEventMessage
2346-
{
2347-
EventData = sceneEventData,
2348-
};
2349-
var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
2350-
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
2351-
NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
2352-
}
2353-
}
2354-
else
2355-
{
2356-
sceneEventData.TargetClientId = NetworkManager.CurrentSessionOwner;
2357-
sceneEventData.SenderClientId = NetworkManager.LocalClientId;
2358-
var message = new SceneEventMessage
2359-
{
2360-
EventData = sceneEventData,
2361-
};
2362-
var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
2363-
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
2364-
NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
2365-
}
2343+
EventData = sceneEventData,
2344+
};
2345+
var target = NetworkManager.DAHost ? NetworkManager.CurrentSessionOwner : NetworkManager.ServerClientId;
2346+
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, target);
2347+
NetworkManager.NetworkMetrics.TrackSceneEventSent(target, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), size);
23662348
}
23672349
else
23682350
{
@@ -2485,13 +2467,13 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
24852467
// Mark this client as being connected
24862468
NetworkManager.ConnectedClients[clientId].IsConnected = true;
24872469

2488-
// Notify the local server that a client has finished synchronizing
2470+
// Notify that a client has finished synchronizing
24892471
OnSceneEvent?.Invoke(new SceneEvent()
24902472
{
24912473
SceneEventType = sceneEventData.SceneEventType,
2492-
SceneName = string.Empty,
24932474
ClientId = clientId
24942475
});
2476+
OnSynchronizeComplete?.Invoke(clientId);
24952477

24962478
// For non-authority clients in a distributed authority session, we show hidden objects,
24972479
// we distribute NetworkObjects, and then we end the scene event.
@@ -2511,9 +2493,6 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
25112493
return;
25122494
}
25132495

2514-
// All scenes are synchronized, let the server know we are done synchronizing
2515-
OnSynchronizeComplete?.Invoke(clientId);
2516-
25172496
// At this time the client is fully synchronized with all loaded scenes and
25182497
// NetworkObjects and should be considered "fully connected". Send the
25192498
// notification that the client is connected.
@@ -2555,26 +2534,12 @@ private void HandleSessionOwnerEvent(uint sceneEventId, ulong clientId)
25552534
// Remove the client that just synchronized
25562535
ClientConnectionQueue.Remove(clientId);
25572536

2558-
// If we have pending clients to synchronize, then make sure they are still connected
2559-
while (ClientConnectionQueue.Count > 0)
2560-
{
2561-
// If the next client is no longer connected then remove it from the list
2562-
if (!NetworkManager.ConnectedClientsIds.Contains(ClientConnectionQueue[0]))
2563-
{
2564-
ClientConnectionQueue.RemoveAt(0);
2565-
}
2566-
else
2567-
{
2568-
break;
2569-
}
2570-
}
2571-
25722537
// If we still have any pending clients waiting, then synchronize the next one
25732538
if (ClientConnectionQueue.Count > 0)
25742539
{
25752540
if (NetworkManager.LogLevel <= LogLevel.Developer)
25762541
{
2577-
Debug.Log($"Synchronizing Client-{ClientConnectionQueue[0]}...");
2542+
Debug.Log($"Synchronizing deferred Client-{ClientConnectionQueue[0]}...");
25782543
}
25792544
SynchronizeNetworkObjects(ClientConnectionQueue[0]);
25802545
}

0 commit comments

Comments
 (0)