Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .yamato/wrench/recipe-regeneration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ test_-_wrench_jobs_up_to_date:
type: Unity::VM
flavor: b1.large
commands:
- command: dotnet run --project Tools\CI\NGO.Cookbook.csproj
- command: dotnet run --project Tools/CI/NGO.Cookbook.csproj
- command: |-
if [ -n "$(git status --porcelain -- .yamato/wrench)" ]; then
git status
echo "Your repo is not clean - diff output:"
git diff
echo "You must run recipe generation after updating recipes to update the generated YAML!"
echo "Run 'dotnet run --project Tools\CI\NGO.Cookbook.csproj' from the root of your repository to regenerate all job definitions created by wrench."
echo "Run 'dotnet run --project Tools/CI/NGO.Cookbook.csproj' from the root of your repository to regenerate all job definitions created by wrench."
exit 1
fi
variables:
Expand Down
72 changes: 36 additions & 36 deletions .yamato/wrench/validation-jobs.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yamato/wrench/wrench_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@
"branch_pattern": "ReleaseSlash",
"wrench_version": "0.12.2.0",
"pvp_exemption_path": ".yamato/wrench/pvp-exemptions.json",
"cs_project_path": "Tools\\CI\\NGO.Cookbook.csproj"
"cs_project_path": "Tools/CI/NGO.Cookbook.csproj"
}
2 changes: 1 addition & 1 deletion Tools/CI/Settings/NGOSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class NGOSettings : AnnotatedSettingsBase
static ValidationOptions validationOptions = new ValidationOptions()
{
ProjectPath = "testproject",
UtrTestingYamatoTimeout = 40
UtrTestingYamatoTimeout = 180 // 3h This it to address the issue that we are running both package and project test and that their execution is much slower on editors below 6000
};

// update this to list all packages in this repo that you want to release.
Expand Down
3 changes: 3 additions & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Added

### Added

### Fixed

- Fixed issue where NetworkConfig.ConnectionData could cause the ConnectionRequestMessage to exceed the transport's MTU size and would result in a buffer overflow error. (#3565)

### Changed


## [1.14.0] - 2025-07-21

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public unsafe void Send(ulong clientId, NetworkDelivery delivery, FastBufferWrit
for (int i = 0; i < 4; i++)
{
var currentByte = batchData.GetUnsafePtr()[i];
batchData.WriteByteSafe((byte)(currentByte == 0 ? 1 : 0));
currentByte = (byte)((currentByte + 1) % 255);
batchData.WriteByteSafe(currentByte);
MessageQueue.Add(batchData.ToArray());
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,28 @@ protected override void OnServerAndClientsCreated()
base.OnServerAndClientsCreated();
}

private MessageCatcher<ConnectionRequestMessage> m_ConnectionRequestCatcher;
private MessageCatcher<ConnectionApprovedMessage> m_ConnectionApprovedCatcher;
protected override IEnumerator OnStartedServerAndClients()
{
m_ClientStopped = false;
m_ServerStopped = false;
m_ClientNetworkManagers[0].OnClientStopped += OnClientStopped;
m_ServerNetworkManager.OnServerStopped += OnServerStopped;
if (m_ApprovalFailureType == ApprovalTimedOutTypes.ServerDoesNotRespond)
{
// We catch (don't process) the incoming approval message to simulate the server not sending the approved message in time
m_ClientNetworkManagers[0].ConnectionManager.MessageManager.Hook(new MessageCatcher<ConnectionApprovedMessage>(m_ClientNetworkManagers[0]));
m_ConnectionApprovedCatcher = new MessageCatcher<ConnectionApprovedMessage>(m_ClientNetworkManagers[0], m_EnableVerboseDebug);
m_ClientNetworkManagers[0].ConnectionManager.MessageManager.Hook(m_ConnectionApprovedCatcher);
m_ExpectedLogMessage = new Regex("Timed out waiting for the server to approve the connection request.");
m_LogType = LogType.Log;
}
else
{
// We catch (don't process) the incoming connection request message to simulate a transport connection but the client never
// sends (or takes too long to send) the connection request.
m_ServerNetworkManager.ConnectionManager.MessageManager.Hook(new MessageCatcher<ConnectionRequestMessage>(m_ServerNetworkManager));
m_ConnectionRequestCatcher = new MessageCatcher<ConnectionRequestMessage>(m_ServerNetworkManager, m_EnableVerboseDebug);
m_ServerNetworkManager.ConnectionManager.MessageManager.Hook(m_ConnectionRequestCatcher);

// For this test, we know the timed out client will be Client-1
m_ExpectedLogMessage = new Regex("Server detected a transport connection from Client-1, but timed out waiting for the connection request message.");
Expand Down Expand Up @@ -98,6 +106,43 @@ public IEnumerator ValidateApprovalTimeout()

Assert.AreEqual(0, m_ServerNetworkManager.ConnectionManager.PendingClients.Count, $"Expected no pending clients when there were {m_ServerNetworkManager.ConnectionManager.PendingClients.Count} pending clients!");
Assert.True(!m_ClientNetworkManagers[0].LocalClient.IsApproved, $"Expected the client to not have been approved, but it was!");

if (m_ApprovalFailureType == ApprovalTimedOutTypes.ServerDoesNotRespond)
{
m_ConnectionApprovedCatcher.ClearMessages();
}
else
{
m_ConnectionRequestCatcher.ClearMessages();
}

if (!m_ClientStopped)
{
m_ClientNetworkManagers[0].Shutdown();
}

if (!m_ServerStopped)
{
m_ServerNetworkManager.Shutdown();
}

yield return WaitForConditionOrTimeOut(() => m_ClientStopped && m_ServerStopped);
AssertOnTimeout($"Timed out waiting for the client or server to stop!");
}

private bool m_ClientStopped;
private void OnClientStopped(bool obj)
{
m_ClientNetworkManagers[0].OnClientStopped -= OnClientStopped;
m_ClientStopped = true;
}

private bool m_ServerStopped;
private void OnServerStopped(bool obj)
{
m_ServerNetworkManager.OnServerStopped -= OnServerStopped;
m_ServerStopped = true;
}

}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;

namespace Unity.Netcode.RuntimeTests
{
internal class MessageCatcher<TMessageType> : INetworkHooks where TMessageType : INetworkMessage
{
private NetworkManager m_OwnerNetworkManager;

public MessageCatcher(NetworkManager ownerNetworkManager)
private bool m_VerboseDebug;

public MessageCatcher(NetworkManager ownerNetworkManager, bool verboseDebug = false)
{
m_OwnerNetworkManager = ownerNetworkManager;
}
Expand All @@ -23,9 +26,38 @@ private struct TriggerData
}
private readonly List<TriggerData> m_CaughtMessages = new List<TriggerData>();

public void ReleaseMessages()

private void Log(string message)
{
if (!m_VerboseDebug)
{
return;
}

Debug.Log($"[Client-{m_OwnerNetworkManager.LocalClientId}] {message}");
}

internal void ClearMessages()
{
if (m_CaughtMessages.Count == 0)
{
return;
}
Log($"Clearing messages.");
foreach (var caughtSpawn in m_CaughtMessages)
{
if (caughtSpawn.Reader.IsInitialized)
{
Log($"Disposing reader (size: {caughtSpawn.Reader.Length}).");
caughtSpawn.Reader.Dispose();
}
}

m_CaughtMessages.Clear();
}

public void ReleaseMessages()
{
foreach (var caughtSpawn in m_CaughtMessages)
{
// Reader will be disposed within HandleMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public IEnumerator Cleanup()

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Server.gameObject);
m_Server = null;
}

if (m_Client1)
Expand All @@ -51,6 +52,7 @@ public IEnumerator Cleanup()

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Client1.gameObject);
m_Client1 = null;
}

if (m_Client2)
Expand All @@ -59,6 +61,7 @@ public IEnumerator Cleanup()

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Client2.gameObject);
m_Client2 = null;
}

m_ServerEvents?.Clear();
Expand Down Expand Up @@ -315,7 +318,7 @@ public IEnumerator DisconnectOnReliableSendQueueOverflow()
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events, 5.0f);

m_Server.Shutdown();

Expand Down
Loading