Skip to content

Commit 4957aa4

Browse files
Merge branch 'develop-2.0.0' into fix/disabling-either-physics-modules-causes-compilation-errors
2 parents 767b15a + 169a1ae commit 4957aa4

File tree

13 files changed

+176
-285
lines changed

13 files changed

+176
-285
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

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

1515
### Fixed
1616

17+
- Fixed issues with the `NetworkBehaviour` and `NetworkVariable` length safety checks. (#3405)
1718
- Fixed memory leaks when domain reload is disabled. (#3427)
1819
- Fixed issue where disabling the physics or physics2D package modules could result in a compilation error. (#3422)
1920
- Fixed an exception being thrown when unregistering a custom message handler from within the registered callback. (#3417)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ internal class SessionConfig
99
public const uint BypassFeatureCompatible = 1;
1010
public const uint ServerDistributionCompatible = 2;
1111
public const uint SessionStateToken = 3;
12+
public const uint NetworkBehaviourSerializationSafety = 4;
1213

1314
// The most current session version (!!!!set this when you increment!!!!!)
14-
public static uint PackageSessionVersion => SessionStateToken;
15+
public static uint PackageSessionVersion => NetworkBehaviourSerializationSafety;
1516

1617
internal uint SessionVersion;
1718

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

Lines changed: 31 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,55 +1232,41 @@ internal void WriteNetworkVariableData(FastBufferWriter writer, ulong targetClie
12321232
var networkManager = NetworkManager;
12331233
var ensureLengthSafety = networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety;
12341234

1235-
1236-
// Exit early if there are no NetworkVariables
1237-
if (NetworkVariableFields.Count == 0)
1238-
{
1239-
return;
1240-
}
1241-
1242-
for (int j = 0; j < NetworkVariableFields.Count; j++)
1235+
foreach (var field in NetworkVariableFields)
12431236
{
12441237
// Client-Server: Try to write values only for clients that have read permissions.
12451238
// Distributed Authority: All clients have read permissions, always try to write the value.
1246-
if (NetworkVariableFields[j].CanClientRead(targetClientId))
1239+
if (field.CanClientRead(targetClientId))
12471240
{
1248-
// Write additional NetworkVariable information when length safety is enabled or when in distributed authority mode
1241+
// Write additional NetworkVariable information when length safety is enabled
12491242
if (ensureLengthSafety)
12501243
{
12511244
var writePos = writer.Position;
12521245
// Note: This value can't be packed because we don't know how large it will be in advance
1253-
// we reserve space for it, then write the data, then come back and fill in the space
1254-
// to pack here, we'd have to write data to a temporary buffer and copy it in - which
1255-
// isn't worth possibly saving one byte if and only if the data is less than 63 bytes long...
1256-
// The way we do packing, any value > 63 in a ushort will use the full 2 bytes to represent.
1257-
writer.WriteValueSafe((ushort)0);
1246+
// we reserve space for it, then write the data, then come back and write the final size value
1247+
writer.WriteValueSafe(0);
12581248
var startPos = writer.Position;
1249+
12591250
// Write the NetworkVariable field value
1260-
// WriteFieldSynchronization will write the current value only if there are no pending changes.
1261-
// Otherwise, it will write the previous value if there are pending changes since the pending
1262-
// changes will be sent shortly after the client's synchronization.
1263-
NetworkVariableFields[j].WriteFieldSynchronization(writer);
1251+
field.WriteFieldSynchronization(writer);
1252+
1253+
// Write the NetworkVariable field value size
12641254
var size = writer.Position - startPos;
12651255
writer.Seek(writePos);
1266-
// Write the NetworkVariable field value size
1267-
writer.WriteValueSafe((ushort)size);
1256+
writer.WriteValueSafe(size);
12681257
writer.Seek(startPos + size);
12691258
}
1270-
else // Client-Server Only: Should only ever be invoked when using a client-server NetworkTopology
1259+
else
12711260
{
12721261
// Write the NetworkVariable field value
1273-
// WriteFieldSynchronization will write the current value only if there are no pending changes.
1274-
// Otherwise, it will write the previous value if there are pending changes since the pending
1275-
// changes will be sent shortly after the client's synchronization.
1276-
NetworkVariableFields[j].WriteFieldSynchronization(writer);
1262+
field.WriteFieldSynchronization(writer);
12771263
}
12781264
}
12791265
else if (ensureLengthSafety)
12801266
{
12811267
// Client-Server Only: If the client cannot read this field, then skip it but write a 0 for this NetworkVariable's position
12821268
{
1283-
writer.WriteValueSafe((ushort)0);
1269+
writer.WriteValueSafe(0);
12841270
}
12851271
}
12861272
}
@@ -1300,26 +1286,20 @@ internal void SetNetworkVariableData(FastBufferReader reader, ulong clientId)
13001286
var networkManager = NetworkManager;
13011287
var ensureLengthSafety = networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety;
13021288

1303-
// Exit early if nothing else to read
1304-
if (NetworkVariableFields.Count == 0)
1289+
foreach (var field in NetworkVariableFields)
13051290
{
1306-
return;
1307-
}
1308-
1309-
for (int j = 0; j < NetworkVariableFields.Count; j++)
1310-
{
1311-
var varSize = (ushort)0;
1291+
int expectedBytesToRead = 0;
13121292
var readStartPos = 0;
13131293
// Client-Server: Clients that only have read permissions will try to read the value
13141294
// Distributed Authority: All clients have read permissions, always try to read the value
1315-
if (NetworkVariableFields[j].CanClientRead(clientId))
1295+
if (field.CanClientRead(clientId))
13161296
{
13171297
if (ensureLengthSafety)
13181298
{
1319-
reader.ReadValueSafe(out varSize);
1320-
if (varSize == 0)
1299+
reader.ReadValueSafe(out expectedBytesToRead);
1300+
if (expectedBytesToRead == 0)
13211301
{
1322-
Debug.LogError($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{NetworkVariableFields[j].Name}] Expected non-zero size readable NetworkVariable! (Skipping)");
1302+
Debug.LogError($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{field.Name}] Expected non-zero size readable NetworkVariable! (Skipping)");
13231303
continue;
13241304
}
13251305
readStartPos = reader.Position;
@@ -1330,38 +1310,29 @@ internal void SetNetworkVariableData(FastBufferReader reader, ulong clientId)
13301310
// If skipping and length safety, then fill in a 0 size for this one spot
13311311
if (ensureLengthSafety)
13321312
{
1333-
reader.ReadValueSafe(out ushort size);
1334-
if (size != 0)
1313+
reader.ReadValueSafe(out expectedBytesToRead);
1314+
if (expectedBytesToRead != 0)
13351315
{
1336-
Debug.LogError($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{NetworkVariableFields[j].Name}] Expected zero size for non-readable NetworkVariable when EnsureNetworkVariableLengthSafety is enabled! (Skipping)");
1316+
Debug.LogError($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{field.Name}] Expected zero size for non-readable NetworkVariable when EnsureNetworkVariableLengthSafety is enabled! (Skipping)");
13371317
}
13381318
}
13391319
continue;
13401320
}
13411321

13421322
// Read the NetworkVariable value
1343-
NetworkVariableFields[j].ReadField(reader);
1323+
field.ReadField(reader);
13441324

13451325
// When EnsureNetworkVariableLengthSafety always do a bounds check
13461326
if (ensureLengthSafety)
13471327
{
1348-
if (reader.Position > (readStartPos + varSize))
1349-
{
1350-
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
1351-
{
1352-
NetworkLog.LogWarning($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{NetworkVariableFields[j].Name}] NetworkVariable data read too big. {reader.Position - (readStartPos + varSize)} bytes.");
1353-
}
1354-
1355-
reader.Seek(readStartPos + varSize);
1356-
}
1357-
else if (reader.Position < (readStartPos + varSize))
1328+
var totalBytesRead = reader.Position - readStartPos;
1329+
if (totalBytesRead != expectedBytesToRead)
13581330
{
1359-
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
1331+
if (NetworkManager.LogLevel <= LogLevel.Normal)
13601332
{
1361-
NetworkLog.LogWarning($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{NetworkVariableFields[j].Name}] NetworkVariable data read too small. {(readStartPos + varSize) - reader.Position} bytes.");
1333+
NetworkLog.LogWarning($"[{name}][NetworkObjectId: {NetworkObjectId}][NetworkBehaviourId: {NetworkBehaviourId}][{field.Name}] NetworkVariable read {totalBytesRead} bytes but was expected to read {expectedBytesToRead} bytes during synchronization deserialization!");
13621334
}
1363-
1364-
reader.Seek(readStartPos + varSize);
1335+
reader.Seek(readStartPos + expectedBytesToRead);
13651336
}
13661337
}
13671338
}
@@ -1443,7 +1414,7 @@ internal bool Synchronize<T>(ref BufferSerializer<T> serializer, ulong targetCli
14431414
// Save our position where we will write the final size being written so we can skip over it in the
14441415
// event an exception occurs when deserializing.
14451416
var sizePosition = writer.Position;
1446-
writer.WriteValueSafe((ushort)0);
1417+
writer.WriteValueSafe(0);
14471418

14481419
// Save our position before synchronizing to determine how much was written
14491420
var positionBeforeSynchronize = writer.Position;
@@ -1481,7 +1452,7 @@ internal bool Synchronize<T>(ref BufferSerializer<T> serializer, ulong targetCli
14811452
// Write the number of bytes serialized to handle exceptions on the deserialization side
14821453
var bytesWritten = finalPosition - positionBeforeSynchronize;
14831454
writer.Seek(sizePosition);
1484-
writer.WriteValueSafe((ushort)bytesWritten);
1455+
writer.WriteValueSafe(bytesWritten);
14851456
writer.Seek(finalPosition);
14861457
}
14871458
return true;
@@ -1490,7 +1461,7 @@ internal bool Synchronize<T>(ref BufferSerializer<T> serializer, ulong targetCli
14901461
{
14911462
var reader = serializer.GetFastBufferReader();
14921463
// We will always read the expected byte count
1493-
reader.ReadValueSafe(out ushort expectedBytesToRead);
1464+
reader.ReadValueSafe(out int expectedBytesToRead);
14941465

14951466
// Save our position before we begin synchronization deserialization
14961467
var positionBeforeSynchronize = reader.Position;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,14 @@ internal void NetworkBehaviourUpdate(bool forceSend = false)
104104
}
105105
}
106106
}
107+
107108
// Now, reset all the no-longer-dirty variables
108-
foreach (var dirtyobj in m_DirtyNetworkObjects)
109+
foreach (var dirtyObj in m_DirtyNetworkObjects)
109110
{
110-
dirtyobj.PostNetworkVariableWrite(forceSend);
111+
foreach (var behaviour in dirtyObj.ChildNetworkBehaviours)
112+
{
113+
behaviour.PostNetworkVariableWrite(forceSend);
114+
}
111115
}
112116
m_DirtyNetworkObjects.Clear();
113117
}

0 commit comments

Comments
 (0)