Skip to content

Commit

Permalink
com.unity.netcode@1.0.12
Browse files Browse the repository at this point in the history
## [1.0.12] - 2023-06-19

### Changed
* Updated com.unity.entities dependency to 1.0.11

### Fixed
* `MultiplayerPlayModeWindow > Dump Packet Logs` now works more reliably, now works with NUnit tests, and dump files are named with more context.
* Fixed bug in `GhostSendSystem` that caused it to not replicate ghosts when enabling packet dumps. `GhostValuesAreSerialized_WithPacketDumpsEnabled` test added.
  • Loading branch information
Unity Technologies committed Jun 19, 2023
1 parent 1467245 commit b414c7e
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 175 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog


## [1.0.12] - 2023-06-19

### Changed
* Updated com.unity.entities dependency to 1.0.11

### Fixed
* `MultiplayerPlayModeWindow > Dump Packet Logs` now works more reliably, now works with NUnit tests, and dump files are named with more context.
* Fixed bug in `GhostSendSystem` that caused it to not replicate ghosts when enabling packet dumps. `GhostValuesAreSerialized_WithPacketDumpsEnabled` test added.


## [1.0.11] - 2023-06-02

### Fixed
Expand Down
72 changes: 0 additions & 72 deletions Editor/MultiplayerPlayModeWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,78 +1267,6 @@ protected override void OnUpdate()
}
}


/// <summary>
/// System that sync enable/disable packet dump for the <see cref="NetworkStreamConnection"/> based on the
/// playmode tool setting.
/// </summary>
[RequireMatchingQueriesForUpdate]
[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
internal partial class MultiplayerPlaymodeLoggingSystem : SystemBase
{
public bool ShouldDumpPackets { get; set; }
public bool IsDumpingPackets { get; private set; }

private BeginSimulationEntityCommandBufferSystem m_CmdBuffer;
EntityQuery m_logQuery;

protected override void OnCreate()
{
ShouldDumpPackets = false;
IsDumpingPackets = false;
m_CmdBuffer = World.GetOrCreateSystemManaged<BeginSimulationEntityCommandBufferSystem>();
m_logQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly<EnablePacketLogging>());
}

protected override void OnUpdate()
{
if (World.IsThinClient())
return;

if (SystemAPI.TryGetSingleton<NetCodeDebugConfig>(out var cfg))
{
if (ShouldDumpPackets != IsDumpingPackets)
{
cfg.DumpPackets = ShouldDumpPackets;
SystemAPI.SetSingleton(cfg);
}
else
ShouldDumpPackets = cfg.DumpPackets;
IsDumpingPackets = cfg.DumpPackets;
}
else
{
if (ShouldDumpPackets != IsDumpingPackets)
{
if (ShouldDumpPackets)
{
var cmdBuffer = m_CmdBuffer.CreateCommandBuffer();
Entities.WithNone<EnablePacketLogging>()
.ForEach((Entity entity, in NetworkStreamConnection conn) =>
{
cmdBuffer.AddComponent<EnablePacketLogging>(entity);
}).Schedule();
}
else
{
var cmdBuffer = m_CmdBuffer.CreateCommandBuffer();
Entities.WithAll<EnablePacketLogging>().ForEach((Entity entity, in NetworkStreamConnection conn) =>
{
cmdBuffer.RemoveComponent<EnablePacketLogging>(entity);
}).Schedule();
}
m_CmdBuffer.AddJobHandleForProducer(Dependency);
IsDumpingPackets = ShouldDumpPackets;
}
else
{
IsDumpingPackets = m_logQuery.CalculateEntityCount()>0;
ShouldDumpPackets = IsDumpingPackets;
}
}
}
}

[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation | WorldSystemFilterFlags.Editor)]
[CreateAfter(typeof(SceneSystem))]
internal partial struct ConfigureClientGUIDSystem : ISystem
Expand Down
3 changes: 1 addition & 2 deletions Runtime/Connection/WarnAboutStaleRpcSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public void Execute(Entity entity, ref ReceiveRpcCommandRequest command)
{
if (!command.IsConsumed && ++command.Age >= netDebug.MaxRpcAgeFrames)
{
var warning = (FixedString512Bytes)FixedString.Format("In '{0}', NetCode RPC {1} has not been consumed or destroyed for '{2}' (MaxRpcAgeFrames) frames!", worldName, entity.ToFixedString(), command.Age);
warning.Append((FixedString128Bytes)" Assumed unhandled. Call .Consume(), or remove the RPC component, or destroy the entity.");
var warning = (FixedString512Bytes) $"[{worldName}] NetCode RPC {entity.ToFixedString()} has not been consumed or destroyed for '{command.Age}' (MaxRpcAgeFrames) frames! Assumed unhandled. Either a) call .Consume(), or b) remove the ReceiveRpcCommandRequestComponent component, or c) destroy the entity.";
netDebug.LogWarning(warning);

command.Consume();
Expand Down
29 changes: 18 additions & 11 deletions Runtime/Debug/NetCodeDebugConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,40 +29,47 @@ public struct NetCodeDebugConfig : IComponentData
/// When the <see cref="NetCodeDebugConfig.DumpPackets"/> is set to true, a <see cref="EnablePacketLogging"/> component is added to all connection.
/// </summary>
[BurstCompile]
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ServerSimulation)]
[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
internal partial struct DebugConnections : ISystem
{
EntityQuery m_ConnectionsQueryWithout;
EntityQuery m_ConnectionsQueryWith;

public bool EditorApplyLoggerSettings;
public NetCodeDebugConfig ForceSettings;

[BurstCompile]
public void OnCreate(ref SystemState state)
{
m_ConnectionsQueryWithout = state.EntityManager.CreateEntityQuery(new EntityQueryBuilder(Allocator.Temp).WithAll<NetworkStreamConnection>().WithNone<EnablePacketLogging>());
m_ConnectionsQueryWith = state.EntityManager.CreateEntityQuery(new EntityQueryBuilder(Allocator.Temp).WithAll<NetworkStreamConnection>().WithAll<EnablePacketLogging>());
state.RequireForUpdate<NetCodeDebugConfig>();
}

public void OnUpdate(ref SystemState state)
{
if (state.WorldUnmanaged.IsThinClient())
return;

var debugConfig = SystemAPI.GetSingleton<NetCodeDebugConfig>();
var targetLogLevel = debugConfig.LogLevel;
var shouldDumpPackets = debugConfig.DumpPackets;
var netDbg = SystemAPI.GetSingletonRW<NetDebug>();
if (!SystemAPI.TryGetSingleton<NetCodeDebugConfig>(out var debugConfig))
{
// No user-defined config, so take the NetDebug defaults:
debugConfig.LogLevel = netDbg.ValueRO.LogLevel;
debugConfig.DumpPackets = false;
}

#if UNITY_EDITOR
if (MultiplayerPlayModePreferences.ApplyLoggerSettings)
{
targetLogLevel = MultiplayerPlayModePreferences.TargetLogLevel;
shouldDumpPackets = MultiplayerPlayModePreferences.TargetShouldDumpPackets;
debugConfig.LogLevel = MultiplayerPlayModePreferences.TargetLogLevel;
debugConfig.DumpPackets = MultiplayerPlayModePreferences.TargetShouldDumpPackets;
}
#endif

SystemAPI.GetSingletonRW<NetDebug>().ValueRW.LogLevel = targetLogLevel;
if (netDbg.ValueRO.LogLevel != debugConfig.LogLevel)
{
netDbg.ValueRW.LogLevel = debugConfig.LogLevel;
}

if (shouldDumpPackets)
if (debugConfig.DumpPackets)
{
state.EntityManager.AddComponent<EnablePacketLogging>(m_ConnectionsQueryWithout);
}
Expand Down
20 changes: 8 additions & 12 deletions Runtime/Debug/NetDebug.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void Init(ref FixedString512Bytes logFolder, ref FixedString128Bytes worl
m_NetDebugPacketLoggerHandle = new LoggerConfig()
.OutputTemplate("{Message}")
.MinimumLevel.Set(LogLevel.Verbose)
.WriteTo.File($"{logFolder}/NetcodePackets-New-{worldName}-{connectionId}.log")
.WriteTo.File($"{logFolder}/NetcodePacket-{worldName}-{connectionId}.log")
.CreateLogger(parameters).Handle;
}

Expand Down Expand Up @@ -489,22 +489,18 @@ internal static FixedString64Bytes PrintMask(uint mask)
/// <summary>
/// Method that print a human readable error message when the version protocol mismatch.
/// </summary>
/// <param name="netDebug"></param>
/// <param name="debugPrefix"></param>
/// <param name="error"></param>
/// <param name="protocolVersion"></param>
internal static void PrintProtocolVersionError(NetDebug netDebug, FixedString64Bytes debugPrefix, NetworkProtocolVersion protocolVersion)
internal static void AppendProtocolVersionError(ref FixedString512Bytes error, NetworkProtocolVersion protocolVersion)
{
FixedString512Bytes debugLog = default;
debugLog.Append(debugPrefix);
debugLog.Append(FixedString.Format("NetCode={0} Game={1}", protocolVersion.NetCodeVersion,
error.Append(FixedString.Format("NetCode={0} Game={1}", protocolVersion.NetCodeVersion,
protocolVersion.GameVersion));
FixedString32Bytes msg = " RpcCollection=";
debugLog.Append(msg);
debugLog.Append(protocolVersion.RpcCollectionVersion);
error.Append(msg);
error.Append(protocolVersion.RpcCollectionVersion);
msg = " ComponentCollection=";
debugLog.Append(msg);
debugLog.Append(protocolVersion.ComponentCollectionVersion);
netDebug.LogError(debugLog);
error.Append(msg);
error.Append(protocolVersion.ComponentCollectionVersion);
}

/// <summary>
Expand Down
10 changes: 5 additions & 5 deletions Runtime/Debug/NetDebugSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ private void CreateNetDebugSingleton(EntityManager entityManager)
var netDebug = new NetDebug();
netDebug.Initialize();

#if UNITY_EDITOR
if (MultiplayerPlayModePreferences.ApplyLoggerSettings)
netDebug.LogLevel = MultiplayerPlayModePreferences.TargetLogLevel;
#endif

#if NETCODE_DEBUG
m_ComponentTypeNameLookupData = new NativeParallelHashMap<int, FixedString128Bytes>(1024, Allocator.Persistent);
netDebug.ComponentTypeNameLookup = m_ComponentTypeNameLookupData.AsReadOnly();
Expand All @@ -57,11 +62,6 @@ public void OnCreate(ref SystemState state)
ComponentType.ReadOnly<Prefab>(),
ComponentType.ReadOnly<GhostPrefabMetaData>(),
ComponentType.Exclude<PrefabDebugName>());

#if UNITY_EDITOR
if (MultiplayerPlayModePreferences.ApplyLoggerSettings)
m_NetDebugQuery.GetSingletonRW<NetDebug>().ValueRW.LogLevel = MultiplayerPlayModePreferences.TargetLogLevel;
#endif
#endif
}

Expand Down
9 changes: 3 additions & 6 deletions Runtime/Rpc/RpcCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,10 @@ public void RegisterRpc(ComponentType type, PortableFunctionPointer<RpcExecutor.
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
if (rpcData.RpcType == type)
throw new InvalidOperationException(
String.Format("Registering RPC {0} multiple times is not allowed", type.GetManagedType()));
throw new InvalidOperationException(
String.Format("Type hash collision between types {0} and {1}", type.GetManagedType(), rpcData.RpcType.GetManagedType()));
throw new InvalidOperationException($"Registering RPC {type.ToFixedString()} multiple times is not allowed! Existing: {rpcData.RpcType.ToFixedString()}!");
throw new InvalidOperationException($"StableTypeHash collision between types {type.ToFixedString()} and {rpcData.RpcType.ToFixedString()} while registering RPC!");
#else
throw new InvalidOperationException(
String.Format("Hash collision or multiple registrations for {0}", type.GetManagedType()));
throw new InvalidOperationException($"Hash collision or multiple registrations for {type.ToFixedString()} while registering RPC! Existing: {rpcData.TypeHash}!");
#endif
}

Expand Down
20 changes: 11 additions & 9 deletions Runtime/Rpc/RpcSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,25 +537,27 @@ public void Execute(Entity entity, in RpcSystem.ProtocolVersionError rpcError)
{ Reason = NetworkStreamDisconnectReason.InvalidRpc });
connection = connections[rpcError.connection].Value.ToFixedString();
}
netDebug.LogError(FixedString.Format("[{0}] RpcSystem received bad protocol version from {1}", worldName, connection));
FixedString64Bytes prefix = "Local protocol: ";
NetDebug.PrintProtocolVersionError(netDebug, prefix, localProtocol);
prefix = "Remote protocol: ";
NetDebug.PrintProtocolVersionError(netDebug, prefix, rpcError.remoteProtocol);

var s = (FixedString512Bytes)"RPC List: ";
var errorHeader = (FixedString512Bytes)$"[{worldName}] RpcSystem received bad protocol version from {connection}";
errorHeader.Append((FixedString32Bytes)"\nLocal protocol: ");
NetDebug.AppendProtocolVersionError(ref errorHeader, localProtocol);
errorHeader.Append((FixedString32Bytes)"\nRemote protocol: ");
NetDebug.AppendProtocolVersionError(ref errorHeader, rpcError.remoteProtocol);
netDebug.LogError(errorHeader);

var s = (FixedString512Bytes)"RPC List (for above 'bad protocol version' error): ";
s.Append(rpcs.Length);
netDebug.LogError(s);

for (int i = 0; i < rpcs.Length; ++i)
netDebug.LogError(rpcs[i]);
netDebug.LogError($"RpcHash[{i}] = {rpcs[i]}");

s = (FixedString512Bytes)"Component serializer data: ";
s = (FixedString512Bytes)"Component serializer data (for above 'bad protocol version' error): ";
s.Append(componentInfo.Length);
netDebug.LogError(s);

for (int i = 0; i < componentInfo.Length; ++i)
netDebug.LogError(componentInfo[i]);
netDebug.LogError($"ComponentHash[{i}] = {componentInfo[i]}");

commandBuffer.DestroyEntity(entity);
}
Expand Down
9 changes: 9 additions & 0 deletions Runtime/Snapshot/GhostComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ public struct GhostInstance : IComponentData
{
return new SpawnedGhost(comp.ghostId, comp.spawnTick);
}

/// <summary>
/// Returns a human-readable GhostComponent FixedString, containing its values.
/// </summary>
/// <returns>A human-readable GhostComponent FixedString, containing its values.</returns>
public FixedString128Bytes ToFixedString()
{
return $"GhostComponent[type:{ghostType}|id:{ghostId},st:{spawnTick.ToFixedString()}]";
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ public void AddSerializer(GhostComponentSerializer.State state)
/// <param name="context">The context of this call, to aid in error reporting.</param>
/// <exception cref="InvalidOperationException">Throws if user-code queries too early.</exception>
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
public void ThrowIfNotInRegistrationPhase(FixedString128Bytes context)
public void ThrowIfNotInRegistrationPhase(in FixedString512Bytes context)
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
if(!CollectionFinalized.IsCreated)
Expand All @@ -348,7 +348,7 @@ public void ThrowIfNotInRegistrationPhase(FixedString128Bytes context)
/// <param name="context">The context of this call, to aid in error reporting.</param>
/// <exception cref="InvalidOperationException">Throws if user-code queries too early.</exception>
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
public void ThrowIfCollectionNotFinalized(FixedString512Bytes context)
public void ThrowIfCollectionNotFinalized(in FixedString512Bytes context)
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
if (!CollectionFinalized.IsCreated || CollectionFinalized.Value == 0)
Expand Down
6 changes: 4 additions & 2 deletions Runtime/Snapshot/GhostSendSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1589,10 +1589,12 @@ public void OnUpdate(ref SystemState state)

foreach (var packet in SystemAPI.Query<AspectPacket>())
{
if (!m_ConnectionStateLookup.ContainsKey(packet.Entity)) { return; }
if (!m_ConnectionStateLookup.ContainsKey(packet.Entity))
continue;

var conState = m_ConnectionStates[m_ConnectionStateLookup[packet.Entity]];
if (conState.NetDebugPacket.IsCreated) { return; }
if (conState.NetDebugPacket.IsCreated)
continue;

NetDebugInterop.InitDebugPacketIfNotCreated(ref conState.NetDebugPacket, ref m_LogFolder, ref worldNameFixed, packet.Id.ValueRO.Value);

Expand Down
Loading

0 comments on commit b414c7e

Please sign in to comment.