Skip to content

Commit af3c017

Browse files
Merge branch 'develop-2.0.0' into fix/networkanimator-allow-disabling-or-enabling-parameter-synch
2 parents 7433f21 + bcb73cd commit af3c017

File tree

18 files changed

+703
-271
lines changed

18 files changed

+703
-271
lines changed

.yamato/project.metafile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
small_agent_platform:
2424
- name: ubuntu
2525
type: Unity::VM
26-
image: package-ci/ubuntu-22.04:v4
26+
image: package-ci/ubuntu-22.04:v4.77.0
2727
flavor: b1.small
2828

2929

@@ -38,13 +38,13 @@ test_platforms:
3838
default:
3939
- name: ubuntu
4040
type: Unity::VM
41-
image: package-ci/ubuntu-22.04:v4
41+
image: package-ci/ubuntu-22.04:v4.77.0
4242
flavor: b1.large
4343
standalone: StandaloneLinux64
4444
desktop:
4545
- name: ubuntu
4646
type: Unity::VM
47-
image: package-ci/ubuntu-22.04:v4
47+
image: package-ci/ubuntu-22.04:v4.77.0
4848
flavor: b1.large
4949
smaller_flavor: b1.medium
5050
standalone: StandaloneLinux64

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Additional documentation and release notes are available at [Multiplayer Documen
1313

1414
### Changed
1515

16+
- The `NetworkManager` functions `GetTransportIdFromClientId` and `GetClientIdFromTransportId` will now return `ulong.MaxValue` when the clientId or transportId do not exist. (#3707)
17+
- Improved performance of the NetworkVariable. (#3683)
18+
- Improved performance around the NetworkBehaviour component. (#3687)
19+
- The first session owner no longer sends two synchronization messages to the service. (#3563)
1620

1721
### Deprecated
1822

@@ -22,6 +26,10 @@ Additional documentation and release notes are available at [Multiplayer Documen
2226

2327
### Fixed
2428

29+
- Multiple disconnect events from the same transport will no longer disconnect the host. (#3707)
30+
- Distributed authority clients no longer send themselves in the `ClientIds` list when sending a `ChangeOwnershipMessage`. (#3687)
31+
- Made a variety of small performance improvements. (#3683)
32+
- Fixed issue where the disconnect event and provided message was too generic to know why the disconnect occurred. (#3551)
2533

2634
### Security
2735

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

Lines changed: 290 additions & 189 deletions
Large diffs are not rendered by default.

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
using System.Collections.Generic;
33
using Unity.Collections;
44
using System.Linq;
5+
using Unity.Netcode.Components;
6+
using Unity.Netcode.Runtime;
57
using UnityEngine;
68
#if UNITY_EDITOR
79
using UnityEditor;
810
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
911
#endif
1012
using UnityEngine.SceneManagement;
1113
using Debug = UnityEngine.Debug;
12-
using Unity.Netcode.Components;
13-
using Unity.Netcode.Runtime;
1414

1515
namespace Unity.Netcode
1616
{
@@ -241,7 +241,11 @@ internal void SetSessionOwner(ulong sessionOwner)
241241
OnSessionOwnerPromoted?.Invoke(sessionOwner);
242242
}
243243

244+
#if ENABLE_SESSIONOWNER_PROMOTION_NOTIFICATION
245+
public void PromoteSessionOwner(ulong clientId)
246+
#else
244247
internal void PromoteSessionOwner(ulong clientId)
248+
#endif
245249
{
246250
if (!DistributedAuthorityMode)
247251
{
@@ -258,10 +262,18 @@ internal void PromoteSessionOwner(ulong clientId)
258262
{
259263
SessionOwner = clientId,
260264
};
261-
var clients = ConnectionManager.ConnectedClientIds.Where(c => c != LocalClientId).ToArray();
262-
foreach (var targetClient in clients)
265+
266+
if (CMBServiceConnection)
263267
{
264-
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, targetClient);
268+
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, ServerClientId);
269+
}
270+
else
271+
{
272+
var clients = ConnectionManager.ConnectedClientIds.Where(c => c != LocalClientId).ToArray();
273+
foreach (var targetClient in clients)
274+
{
275+
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, targetClient);
276+
}
265277
}
266278
}
267279

@@ -613,6 +625,16 @@ public ulong LocalClientId
613625
/// </summary>
614626
public string DisconnectReason => ConnectionManager.DisconnectReason;
615627

628+
/// <summary>
629+
/// If supported by the <see cref="NetworkTransport"/>, this <see cref="NetworkTransport.DisconnectEvents"/> property will be set for each disconnect event.
630+
/// If not supported, then this remain as the default <see cref="Networking.Transport.Error.DisconnectReason"/> value.
631+
/// </summary>
632+
/// <remarks>
633+
/// A server/host will receive notifications for remote clients disconnecting and will update this <see cref="Networking.Transport.Error.DisconnectReason"/> property
634+
/// upon each disconnect event.<br />
635+
/// </remarks>
636+
public NetworkTransport.DisconnectEvents DisconnectEvent => ConnectionManager.DisconnectEvent;
637+
616638
/// <summary>
617639
/// Is true when a server or host is listening for connections.
618640
/// Is true when a client is connecting or connected to a network session.
@@ -1441,18 +1463,13 @@ private void HostServerInitialize()
14411463
}
14421464
}
14431465

1444-
response.Approved = true;
1445-
ConnectionManager.HandleConnectionApproval(ServerClientId, response);
1466+
ConnectionManager.HandleConnectionApproval(ServerClientId, response.CreatePlayerObject, response.PlayerPrefabHash, response.Position, response.Rotation);
14461467
}
14471468
else
14481469
{
1449-
var response = new ConnectionApprovalResponse
1450-
{
1451-
Approved = true,
1452-
// Distributed authority always returns true since the client side handles spawning (whether automatically or manually)
1453-
CreatePlayerObject = DistributedAuthorityMode || NetworkConfig.PlayerPrefab != null,
1454-
};
1455-
ConnectionManager.HandleConnectionApproval(ServerClientId, response);
1470+
// Distributed authority always tries to create the player object since the client side handles spawning (whether automatically or manually)
1471+
var createPlayerObject = DistributedAuthorityMode || NetworkConfig.PlayerPrefab != null;
1472+
ConnectionManager.HandleConnectionApproval(ServerClientId, createPlayerObject);
14561473
}
14571474

14581475
SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
@@ -1473,21 +1490,33 @@ private void HostServerInitialize()
14731490
/// Get the TransportId from the associated ClientId.
14741491
/// </summary>
14751492
/// <param name="clientId">The ClientId to get the TransportId from</param>
1476-
/// <returns>The TransportId associated with the given ClientId</returns>
1477-
public ulong GetTransportIdFromClientId(ulong clientId) => ConnectionManager.ClientIdToTransportId(clientId);
1493+
/// <returns>
1494+
/// The TransportId associated with the given ClientId if the given clientId is valid; otherwise <see cref="ulong.MaxValue"/>
1495+
/// </returns>
1496+
public ulong GetTransportIdFromClientId(ulong clientId)
1497+
{
1498+
var (id, success) = ConnectionManager.ClientIdToTransportId(clientId);
1499+
return success ? id : ulong.MaxValue;
1500+
}
14781501

14791502
/// <summary>
14801503
/// Get the ClientId from the associated TransportId.
14811504
/// </summary>
14821505
/// <param name="transportId">The TransportId to get the ClientId from</param>
1483-
/// <returns>The ClientId from the associated TransportId</returns>
1484-
public ulong GetClientIdFromTransportId(ulong transportId) => ConnectionManager.TransportIdToClientId(transportId);
1506+
/// <returns>
1507+
/// The ClientId from the associated TransportId if the given transportId is valid; otherwise <see cref="ulong.MaxValue"/>
1508+
/// </returns>
1509+
public ulong GetClientIdFromTransportId(ulong transportId)
1510+
{
1511+
var (id, success) = ConnectionManager.TransportIdToClientId(transportId);
1512+
return success ? id : ulong.MaxValue;
1513+
}
14851514

14861515
/// <summary>
14871516
/// Disconnects the remote client.
14881517
/// </summary>
14891518
/// <param name="clientId">The ClientId to disconnect</param>
1490-
public void DisconnectClient(ulong clientId) => ConnectionManager.DisconnectClient(clientId);
1519+
public void DisconnectClient(ulong clientId) => ConnectionManager.DisconnectClient(clientId, $"Client-{clientId} disconnected by server.");
14911520

14921521
/// <summary>
14931522
/// Disconnects the remote client.

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,19 @@ public DefaultMessageSender(NetworkManager manager)
1919
public void Send(ulong clientId, NetworkDelivery delivery, FastBufferWriter batchData)
2020
{
2121
var sendBuffer = batchData.ToTempByteArray();
22+
var (transportId, clientExists) = m_ConnectionManager.ClientIdToTransportId(clientId);
2223

23-
m_NetworkTransport.Send(m_ConnectionManager.ClientIdToTransportId(clientId), sendBuffer, delivery);
24+
if (!clientExists)
25+
{
26+
if (m_ConnectionManager.NetworkManager.LogLevel <= LogLevel.Error)
27+
{
28+
NetworkLog.LogWarning("Trying to send a message to a client who doesn't have a transport connection");
29+
}
30+
31+
return;
32+
}
33+
34+
m_NetworkTransport.Send(transportId, sendBuffer, delivery);
2435
}
2536
}
2637
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -373,21 +373,18 @@ public void Handle(ref NetworkContext context)
373373

374374
if (!networkManager.SceneManager.IsRestoringSession)
375375
{
376-
// Synchronize the service with the initial session owner's loaded scenes and spawned objects
377-
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);
378-
379376
// Spawn any in-scene placed NetworkObjects
380377
networkManager.SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
381378

379+
// Synchronize the service with the initial session owner's loaded scenes and spawned objects
380+
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);
381+
382382
// Spawn the local player of the session owner
383383
if (networkManager.AutoSpawnPlayerPrefabClientSide)
384384
{
385385
networkManager.ConnectionManager.CreateAndSpawnPlayer(OwnerClientId);
386386
}
387387

388-
// Synchronize the service with the initial session owner's loaded scenes and spawned objects
389-
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);
390-
391388
// With scene management enabled and since the session owner doesn't send a scene event synchronize to itself,
392389
// we need to notify the session owner that everything should be synchronized/spawned at this time.
393390
networkManager.SpawnManager.NotifyNetworkObjectsSynchronized();

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,16 @@ public void Handle(ref NetworkContext context)
210210
}
211211
else
212212
{
213-
var response = new NetworkManager.ConnectionApprovalResponse
213+
var createPlayerObject = networkManager.NetworkConfig.PlayerPrefab != null;
214+
215+
// DAHost only:
216+
// Never create the player object on the server if AutoSpawnPlayerPrefabClientSide is set.
217+
if (networkManager.DistributedAuthorityMode && networkManager.AutoSpawnPlayerPrefabClientSide)
214218
{
215-
Approved = true,
216-
CreatePlayerObject = networkManager.DistributedAuthorityMode && networkManager.AutoSpawnPlayerPrefabClientSide ? false : networkManager.NetworkConfig.PlayerPrefab != null
217-
};
218-
networkManager.ConnectionManager.HandleConnectionApproval(senderId, response);
219+
createPlayerObject = false;
220+
}
221+
222+
networkManager.ConnectionManager.HandleConnectionApproval(senderId, createPlayerObject);
219223
}
220224
}
221225
}

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/NotMeRpcTarget.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@ internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message,
4949
{
5050
continue;
5151
}
52-
// In distributed authority mode, we send to target id 0 (which would be a DAHost) via the group
53-
if (clientId == NetworkManager.ServerClientId && !m_NetworkManager.DistributedAuthorityMode)
52+
// In distributed authority mode, we send to target id 0 (which would be a DAHost).
53+
// We only add when there is a "DAHost" by
54+
// - excluding the server id when using client-server (i.e. !m_NetworkManager.DistributedAuthorityMode )
55+
// - excluding if connected to the CMB backend service (i.e. we don't want to send to service as it will broadcast it back)
56+
if (clientId == NetworkManager.ServerClientId && (!m_NetworkManager.DistributedAuthorityMode || m_NetworkManager.CMBServiceConnection))
5457
{
5558
continue;
5659
}

com.unity.netcode.gameobjects/Runtime/Transports/NetworkTransport.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,104 @@ internal NetworkTopologyTypes CurrentTopology()
164164
{
165165
return OnCurrentTopology();
166166
}
167+
168+
/// <summary>
169+
/// The Netcode for GameObjects standardized disconnection event types.
170+
/// </summary>
171+
public enum DisconnectEvents
172+
{
173+
/// <summary>
174+
/// If transport has mapped its disconnect events, this event signifies that the transport closed the connection due to a locally invoked shutdown.
175+
/// </summary>
176+
TransportShutdown,
177+
/// <summary>
178+
/// If transport has mapped its disconnect events, this event signifies a graceful disconnect.
179+
/// </summary>
180+
Disconnected,
181+
/// <summary>
182+
/// If transport has mapped its disconnect events, this event signifies that the transport's connection to the endpoint has timed out and the connection was closed.
183+
/// </summary>
184+
ProtocolTimeout,
185+
/// <summary>
186+
/// If transport has mapped its disconnect events, this event signifies that the disconnect is due to the maximum number of failed connection attempts has been reached.
187+
/// </summary>
188+
MaxConnectionAttempts,
189+
/// <summary>
190+
/// If transport has mapped its disconnect events, this event signifies that the remote endpoint closed the connection.
191+
/// </summary>
192+
ClosedByRemote,
193+
/// <summary>
194+
/// If transport has mapped its disconnect events, this event signifies the local transport closed the incoming remote endpoint connection.
195+
/// </summary>
196+
ClosedRemoteConnection,
197+
/// <summary>
198+
/// If transport has mapped its disconnect events, this event signifies that the connection was closed due to an authentication failure.
199+
/// </summary>
200+
AuthenticationFailure,
201+
/// <summary>
202+
/// If transport has mapped its disconnect events, this event signifies that a lower-level (unkown) transport error occurred.
203+
/// </summary>
204+
ProtocolError,
205+
}
206+
207+
/// <summary>
208+
/// If the transport has implemented disconnection event mapping, then this will be set to the most recent disconnection event.
209+
/// </summary>
210+
public DisconnectEvents DisconnectEvent { get; private set; }
211+
212+
/// <summary>
213+
/// If the transport has implemented disconnection event mapping and disconnection event message mapping, then this will contain
214+
/// the transport specific message associated with the disconnect event type.
215+
/// </summary>
216+
public string DisconnectEventMessage { get; private set; }
217+
218+
/// <summary>
219+
/// This should be invoked by the <see cref="NetworkTransport"/> derived class when a transport level disconnect event occurs.<br />
220+
/// It is up to the <see cref="NetworkTransport"/> derived class to create a map between the transport's disconnect events and the
221+
/// pre-defined <see cref="DisconnectEvents"/> enum values.
222+
/// </summary>
223+
/// <param name="disconnectEvent">The <see cref="DisconnectEvents"/> type to set.</param>
224+
/// <param name="message">An optional message override.</param>
225+
protected void SetDisconnectEvent(DisconnectEvents disconnectEvent, string message = null)
226+
{
227+
DisconnectEvent = disconnectEvent;
228+
DisconnectEventMessage = string.Empty;
229+
230+
if (message != null)
231+
{
232+
DisconnectEventMessage = message;
233+
}
234+
else
235+
{
236+
DisconnectEventMessage = GetDisconnectEventMessage(disconnectEvent);
237+
}
238+
}
239+
240+
/// <summary>
241+
/// Override this method to provide additional information about the disconnection event.
242+
/// </summary>
243+
/// <param name="disconnectEvent">The disconnect event to get from the <see cref="NetworkTransport"/> derived class.</param>
244+
/// <returns><see cref="string.Empty"/> as a default or if overridden the <see cref="string"/> returned.</returns>
245+
protected virtual string GetDisconnectEventMessage(DisconnectEvents disconnectEvent)
246+
{
247+
return string.Empty;
248+
}
249+
250+
/// <summary>
251+
/// Invoked when the local <see cref="NetworkManager"/> forces the transport to close a remote connection.
252+
/// </summary>
253+
internal void ClosingRemoteConnection()
254+
{
255+
SetDisconnectEvent(DisconnectEvents.ClosedRemoteConnection);
256+
}
257+
258+
/// <summary>
259+
/// Invoked just before the transport is shutdown.
260+
/// </summary>
261+
internal void ShuttingDown()
262+
{
263+
SetDisconnectEvent(DisconnectEvents.TransportShutdown);
264+
}
167265
}
168266

169267
/// <summary>

com.unity.netcode.gameobjects/Runtime/Transports/SinglePlayer/SinglePlayerTransport.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ private struct MessageData
3232

3333
private static Dictionary<ulong, Queue<MessageData>> s_MessageQueue = new Dictionary<ulong, Queue<MessageData>>();
3434

35-
private bool m_Initialized;
3635
private ulong m_TransportId = 0;
3736
private NetworkManager m_NetworkManager;
3837

0 commit comments

Comments
 (0)