Skip to content

Commit 06d9771

Browse files
Merge branch 'develop-2.0.0' into fix/cap-maximum-disconnect-timeout
2 parents 17541bf + c3d198d commit 06d9771

File tree

8 files changed

+128
-69
lines changed

8 files changed

+128
-69
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
7878

7979
### Fixed
8080

81+
- CMB service no longer waits for a timeout before disconnecting on an invalid ConnectionRequest. (#3812)
8182
- Initialization errors with NetworkAnimator. (#3767)
8283
- Multiple disconnect events from the same transport will no longer disconnect the host. (#3707)
8384
- Fixed NetworkTransform state synchronization issue when `NetworkTransform.SwitchTransformSpaceWhenParented` is enabled and the associated NetworkObject is parented multiple times in a single frame or within a couple of frames. (#3664)

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ internal void HandleNetworkEvent(NetworkEvent networkEvent, ulong transportClien
492492
/// </remarks>
493493
private ulong m_LocalClientTransportId;
494494

495+
internal ulong LocalClientTransportId => m_LocalClientTransportId;
496+
495497
/// <summary>
496498
/// Handles a <see cref="NetworkEvent.Connect"/> event.
497499
/// </summary>
@@ -595,8 +597,10 @@ internal void DisconnectEventHandler(ulong transportClientId)
595597
// do not remove it just yet.
596598
var (clientId, isConnectedClient) = TransportIdToClientId(transportClientId);
597599

598-
// If the client is not registered and we are the server
599-
if (!isConnectedClient && NetworkManager.IsServer)
600+
// If the client is not registered and we are the server or we are connecting to
601+
// the live CMB service and the client had a transport Id assigned then exit early
602+
/// <see cref="DisconnectReasonMessage"/> handles disconnecting the client
603+
if (!isConnectedClient && (NetworkManager.IsServer || (NetworkManager.CMBServiceConnection && m_LocalClientTransportId != 0)))
600604
{
601605
// Then exit early
602606
return;
@@ -639,8 +643,18 @@ internal void DisconnectEventHandler(ulong transportClientId)
639643
// Client's clean up their transport id separately from the server.
640644
TransportIdCleanUp(transportClientId);
641645

642-
// Notify local client of disconnection
643-
InvokeOnClientDisconnectCallback(clientId);
646+
try
647+
{
648+
// Notify local client of disconnection
649+
InvokeOnClientDisconnectCallback(clientId);
650+
}
651+
catch (Exception ex)
652+
{
653+
Debug.LogException(ex);
654+
}
655+
656+
// Reset the transport ID
657+
m_LocalClientTransportId = 0;
644658

645659
// As long as we are not in the middle of a shutdown
646660
if (!NetworkManager.ShutdownInProgress)

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using System.Collections;
2+
using UnityEngine;
3+
14
namespace Unity.Netcode
25
{
36
internal struct DisconnectReasonMessage : INetworkMessage
@@ -37,10 +40,24 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
3740

3841
public void Handle(ref NetworkContext context)
3942
{
43+
var networkManager = (NetworkManager)context.SystemOwner;
4044
// Always apply the server-side generated disconnect reason to the server specific disconnect reason.
4145
// This is combined with the additional disconnect information when getting NetworkManager.DisconnectReason
4246
// (NetworkConnectionManager.DisconnectReason).
43-
((NetworkManager)context.SystemOwner).ConnectionManager.ServerDisconnectReason = Reason;
47+
networkManager.ConnectionManager.ServerDisconnectReason = Reason;
48+
49+
if (networkManager.NetworkConfig.UseCMBService)
50+
{
51+
networkManager.StartCoroutine(HandleDisconnectAfterReason(networkManager));
52+
}
53+
}
54+
55+
private IEnumerator HandleDisconnectAfterReason(NetworkManager networkManager)
56+
{
57+
yield return new WaitForFixedUpdate();
58+
59+
var connectionManager = networkManager.ConnectionManager;
60+
connectionManager.DisconnectEventHandler(connectionManager.LocalClientTransportId);
4461
}
4562
};
4663
}

com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/SessionVersionConnectionRequest.cs

Lines changed: 69 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,52 +9,36 @@ internal class SessionVersionConnectionRequest : NetcodeIntegrationTest
99
{
1010
protected override int NumberOfClients => 0;
1111

12-
// TODO: [CmbServiceTests] Adapt to run with the service
13-
protected override bool UseCMBService()
14-
{
15-
return false;
16-
}
12+
// Use a specific version for the CMB tests
13+
// The CMB service has more detailed versioning logic. Not all lower versions are invalid to connect with the higher version.
14+
// This version will not connect with the version lower.
15+
private const int k_ValidCMBVersion = 5;
1716

1817
public SessionVersionConnectionRequest() : base(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost) { }
1918

2019
private bool m_UseValidSessionVersion;
2120
private bool m_ClientWasDisconnected;
22-
private NetworkManager m_ClientNetworkManager;
21+
private bool m_CanStartClients;
22+
23+
// Don't start automatically when using the CMB Service
24+
// We want to customize the SessionVersion of the session owner before they connect
25+
protected override bool CanStartServerAndClients() => !m_UseCmbService || m_CanStartClients;
2326

2427
/// <summary>
2528
/// Callback used to mock the scenario where a client has an invalid session version
2629
/// </summary>
27-
/// <returns><see cref="SessionConfig"/></returns>
28-
private SessionConfig GetInavlidSessionConfig()
30+
private SessionConfig GetInvalidSessionConfig()
2931
{
3032
var authority = GetAuthorityNetworkManager();
3133
return new SessionConfig(authority.SessionConfig.SessionVersion - 1);
3234
}
3335

34-
/// <summary>
35-
/// Overriding this method allows us to configure the newly instantiated client's
36-
/// NetworkManager prior to it being started.
37-
/// </summary>
38-
/// <param name="networkManager">the newly instantiated NetworkManager</param>
39-
protected override void OnNewClientCreated(NetworkManager networkManager)
40-
{
41-
m_ClientWasDisconnected = false;
42-
m_ClientNetworkManager = networkManager;
43-
m_ClientNetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback;
44-
if (!m_UseValidSessionVersion)
45-
{
46-
networkManager.OnGetSessionConfig = GetInavlidSessionConfig;
47-
}
48-
base.OnNewClientCreated(networkManager);
49-
}
50-
5136
/// <summary>
5237
/// Tracks if the client was disconnected or not
5338
/// </summary>
5439
private void OnClientDisconnectCallback(ulong clientId)
5540
{
5641
m_ClientWasDisconnected = true;
57-
m_ClientNetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback;
5842
}
5943

6044
/// <summary>
@@ -69,51 +53,76 @@ protected override bool ShouldWaitForNewClientToConnect(NetworkManager networkMa
6953
{
7054
return m_UseValidSessionVersion;
7155
}
72-
73-
internal enum SessionVersionType
74-
{
75-
Valid,
76-
Invalid,
77-
}
78-
7956
/// <summary>
8057
/// Validates that when the client's session config version is valid a client will be
8158
/// allowed to connect and when it is not valid the client will be disconnected.
8259
/// </summary>
83-
/// <remarks>
84-
/// This is just a mock of the service logic to validate everything on the NGO side is
85-
/// working correctly.
86-
/// </remarks>
87-
/// <param name="useValidSessionVersion">true = use valid session version | false = use invalid session version</param>
8860
[UnityTest]
89-
public IEnumerator ValidateSessionVersion([Values] SessionVersionType type)
61+
public IEnumerator ValidateSessionVersion()
9062
{
91-
// Test client being disconnected due to invalid session version
92-
m_UseValidSessionVersion = type == SessionVersionType.Valid;
93-
yield return CreateAndStartNewClient();
94-
yield return s_DefaultWaitForTick;
95-
if (!m_UseValidSessionVersion)
63+
if (m_UseCmbService)
9664
{
97-
yield return WaitForConditionOrTimeOut(() => m_ClientWasDisconnected);
98-
AssertOnTimeout("Client was not disconnected when it should have been!");
99-
Assert.True(m_ClientNetworkManager.DisconnectReason.Contains(ConnectionRequestMessage.InvalidSessionVersionMessage), "Client did not receive the correct invalid session version message!");
65+
var authority = GetAuthorityNetworkManager();
66+
authority.OnGetSessionConfig = () => new SessionConfig(k_ValidCMBVersion);
67+
m_CanStartClients = true;
68+
yield return StartServerAndClients();
10069
}
101-
else
70+
71+
/*
72+
* Test client being disconnected due to invalid session version
73+
*/
74+
m_UseValidSessionVersion = false;
75+
76+
// Create and setup client to use invalid session config
77+
var invalidClient = CreateNewClient();
78+
invalidClient.OnClientDisconnectCallback += OnClientDisconnectCallback;
79+
invalidClient.OnGetSessionConfig = GetInvalidSessionConfig;
80+
81+
// Start client and wait for disconnect callback
82+
m_ClientWasDisconnected = false;
83+
yield return StartClient(invalidClient);
84+
Assert.True(invalidClient.IsListening);
85+
yield return s_DefaultWaitForTick;
86+
87+
var timeoutHelper = new TimeoutHelper(30f);
88+
yield return WaitForConditionOrTimeOut(() => !invalidClient.IsListening, timeoutHelper);
89+
AssertOnTimeout("Client is still listening when it should have been disconnected!", timeoutHelper);
90+
91+
yield return WaitForConditionOrTimeOut(() => m_ClientWasDisconnected);
92+
AssertOnTimeout("Client was not disconnected when it should have been!");
93+
94+
var expectedReason = m_UseCmbService ? "incompatible ngo c# package versions for feature" : ConnectionRequestMessage.InvalidSessionVersionMessage;
95+
Assert.That(invalidClient.DisconnectReason, Does.Contain(expectedReason), $"Client did not receive the correct invalid session version message! Received: {invalidClient.DisconnectReason}");
96+
97+
// Clean up invalid client
98+
invalidClient.OnClientDisconnectCallback -= OnClientDisconnectCallback;
99+
yield return StopOneClient(invalidClient, true);
100+
101+
/*
102+
* Test a later client with a valid version
103+
* They should connect as normal
104+
*/
105+
m_UseValidSessionVersion = true;
106+
107+
// Create and setup client to use invalid session config
108+
var lateJoin = CreateNewClient();
109+
lateJoin.OnClientDisconnectCallback += OnClientDisconnectCallback;
110+
if (m_UseCmbService)
102111
{
103-
Assert.False(m_ClientWasDisconnected, "Client was disconnected when it was expected to connect!");
104-
Assert.True(m_ClientNetworkManager.IsConnectedClient, "Client did not connect properly using the correct session version!");
112+
lateJoin.OnGetSessionConfig = () => new SessionConfig(k_ValidCMBVersion);
105113
}
106-
}
107114

108-
/// <summary>
109-
/// Invoked at the end of each integration test pass.
110-
/// Primarily used to clean up for the next pass.
111-
/// </summary>
112-
protected override IEnumerator OnTearDown()
113-
{
114-
m_ClientNetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback;
115-
m_ClientNetworkManager = null;
116-
yield return base.OnTearDown();
115+
// Start client and wait for disconnect callback
116+
m_ClientWasDisconnected = false;
117+
yield return StartClient(lateJoin);
118+
yield return s_DefaultWaitForTick;
119+
120+
Assert.False(m_ClientWasDisconnected, "Client was disconnected when it was expected to connect!");
121+
Assert.True(lateJoin.IsConnectedClient, "Client did not connect properly using the correct session version!");
122+
Assert.That(GetAuthorityNetworkManager().ConnectedClientsIds, Has.Member(lateJoin.LocalClientId), "Newly joined client should be in connected list!");
123+
124+
// Clean up
125+
lateJoin.OnClientDisconnectCallback -= OnClientDisconnectCallback;
117126
}
118127
}
119128
}

testproject/.vsconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"version": "1.0",
3+
"components": [
4+
"Microsoft.VisualStudio.Workload.ManagedGame"
5+
]
6+
}

testproject/Packages/packages-lock.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@
457457
"com.unity.modules.ui": "1.0.0",
458458
"com.unity.modules.imgui": "1.0.0",
459459
"com.unity.modules.jsonserialize": "1.0.0",
460-
"com.unity.modules.hierarchycore": "1.0.0"
460+
"com.unity.modules.hierarchycore": "1.0.0",
461+
"com.unity.modules.physics": "1.0.0"
461462
}
462463
},
463464
"com.unity.modules.umbra": {

testproject/ProjectSettings/ProjectSettings.asset

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ PlayerSettings:
7070
androidStartInFullscreen: 1
7171
androidRenderOutsideSafeArea: 1
7272
androidUseSwappy: 1
73+
androidDisplayOptions: 1
7374
androidBlitType: 0
7475
androidResizeableActivity: 0
7576
androidDefaultWindowWidth: 1920
@@ -86,6 +87,7 @@ PlayerSettings:
8687
muteOtherAudioSources: 0
8788
Prepare IOS For Recording: 0
8889
Force IOS Speakers When Recording: 0
90+
audioSpatialExperience: 0
8991
deferSystemGesturesMode: 0
9092
hideHomeButton: 0
9193
submitAnalytics: 1
@@ -132,6 +134,7 @@ PlayerSettings:
132134
switchNVNMaxPublicSamplerIDCount: 0
133135
switchMaxWorkerMultiple: 8
134136
switchNVNGraphicsFirmwareMemory: 32
137+
switchGraphicsJobsSyncAfterKick: 1
135138
vulkanNumSwapchainBuffers: 3
136139
vulkanEnableSetSRGBWrite: 0
137140
vulkanEnablePreTransform: 0
@@ -271,6 +274,9 @@ PlayerSettings:
271274
AndroidBuildApkPerCpuArchitecture: 0
272275
AndroidTVCompatibility: 0
273276
AndroidIsGame: 1
277+
androidAppCategory: 3
278+
useAndroidAppCategory: 1
279+
androidAppCategoryOther:
274280
AndroidEnableTango: 0
275281
androidEnableBanner: 1
276282
androidUseLowAccuracyLocation: 0
@@ -442,6 +448,9 @@ PlayerSettings:
442448
- m_BuildTarget: WebGLSupport
443449
m_APIs: 0b000000
444450
m_Automatic: 1
451+
- m_BuildTarget: WindowsStandaloneSupport
452+
m_APIs: 0200000012000000
453+
m_Automatic: 0
445454
m_BuildTargetVRSettings:
446455
- m_BuildTarget: Standalone
447456
m_Enabled: 0
@@ -723,12 +732,12 @@ PlayerSettings:
723732
webGLMemoryLinearGrowthStep: 16
724733
webGLMemoryGeometricGrowthStep: 0.2
725734
webGLMemoryGeometricGrowthCap: 96
726-
webGLEnableWebGPU: 0
727735
webGLPowerPreference: 2
728736
webGLWebAssemblyTable: 0
729737
webGLWebAssemblyBigInt: 0
730738
webGLCloseOnQuit: 0
731739
webWasm2023: 0
740+
webEnableSubmoduleStrippingCompatibility: 0
732741
scriptingDefineSymbols:
733742
Standalone: UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
734743
additionalCompilerArguments:
@@ -866,3 +875,5 @@ PlayerSettings:
866875
insecureHttpOption: 0
867876
androidVulkanDenyFilterList: []
868877
androidVulkanAllowFilterList: []
878+
androidVulkanDeviceFilterListAsset: {fileID: 0}
879+
d3d12DeviceFilterListAsset: {fileID: 0}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
m_EditorVersion: 6000.0.61f1
2-
m_EditorVersionWithRevision: 6000.0.61f1 (74a0adb02c31)
1+
m_EditorVersion: 6000.2.12f1
2+
m_EditorVersionWithRevision: 6000.2.12f1 (e89d5df0e333)

0 commit comments

Comments
 (0)