Skip to content

Commit f99e914

Browse files
committed
Ensure the DAHost complains if the senderId is included in the ClientIds list
1 parent bb4cded commit f99e914

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

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

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System.Linq;
12
using System.Runtime.CompilerServices;
3+
using UnityEngine;
24

35
namespace Unity.Netcode
46
{
@@ -143,42 +145,47 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int
143145
public void Handle(ref NetworkContext context)
144146
{
145147
var networkManager = (NetworkManager)context.SystemOwner;
148+
var hasObject = networkManager.SpawnManager.SpawnedObjects.TryGetValue(NetworkObjectId, out var networkObject);
146149

147150
// If we are the DAHost then forward this message
148151
if (networkManager.DAHost)
149152
{
150-
var shouldProcessLocally = HandleDAHostMessageForwarding(ref networkManager, context.SenderId);
153+
var shouldProcessLocally = HandleDAHostMessageForwarding(ref networkManager, context.SenderId, hasObject, ref networkObject);
151154
if (!shouldProcessLocally)
152155
{
153156
return;
154157
}
155158
}
156159

160+
if (!hasObject)
161+
{
162+
if (networkManager.LogLevel <= LogLevel.Normal)
163+
{
164+
NetworkLog.LogError("Ownership change received for an unknown network object. This should not happen.");
165+
}
166+
return;
167+
}
168+
157169
// If ownership is changing (either a straight change or a request approval), then run through the ownership changed sequence
158170
// Note: There is some extended ownership script at the bottom of HandleOwnershipChange
159171
// If not in distributed authority mode, ChangeMessageType will always be OwnershipChanging.
160172
if (ChangeMessageType == ChangeType.OwnershipChanging || ChangeMessageType == ChangeType.RequestApproved || !networkManager.DistributedAuthorityMode)
161173
{
162-
HandleOwnershipChange(ref context);
174+
HandleOwnershipChange(ref context, ref networkManager, ref networkObject);
163175
}
164176
else if (networkManager.DistributedAuthorityMode)
165177
{
166178
// Otherwise, we handle and extended ownership update
167-
HandleExtendedOwnershipUpdate(ref context);
179+
HandleExtendedOwnershipUpdate(ref context, ref networkObject);
168180
}
169181
}
170182

171183
/// <summary>
172184
/// Handle the extended distributed authority ownership updates
173185
/// </summary>
174186
[MethodImpl(MethodImplOptions.AggressiveInlining)]
175-
private void HandleExtendedOwnershipUpdate(ref NetworkContext context)
187+
private void HandleExtendedOwnershipUpdate(ref NetworkContext context, ref NetworkObject networkObject)
176188
{
177-
var networkManager = (NetworkManager)context.SystemOwner;
178-
179-
// Handle the extended ownership message types
180-
var networkObject = networkManager.SpawnManager.SpawnedObjects[NetworkObjectId];
181-
182189
if (ChangeMessageType == ChangeType.OwnershipFlagsUpdate)
183190
{
184191
// Just update the ownership flags
@@ -199,10 +206,8 @@ private void HandleExtendedOwnershipUpdate(ref NetworkContext context)
199206
/// Handle the traditional change in ownership message type logic
200207
/// </summary>
201208
[MethodImpl(MethodImplOptions.AggressiveInlining)]
202-
private void HandleOwnershipChange(ref NetworkContext context)
209+
private void HandleOwnershipChange(ref NetworkContext context, ref NetworkManager networkManager, ref NetworkObject networkObject)
203210
{
204-
var networkManager = (NetworkManager)context.SystemOwner;
205-
var networkObject = networkManager.SpawnManager.SpawnedObjects[NetworkObjectId];
206211
var distributedAuthorityMode = networkManager.DistributedAuthorityMode;
207212

208213
// Sanity check that we are not sending duplicated change ownership messages
@@ -260,12 +265,12 @@ private void HandleOwnershipChange(ref NetworkContext context)
260265
/// </summary>
261266
/// <param name="networkManager">The current NetworkManager from the NetworkContext</param>
262267
/// <param name="senderId">The sender of the current message from the NetworkContext</param>
268+
/// <param name="hasObject">Whether the local client has this object spawned</param>
269+
/// <param name="networkObject">The networkObject we are changing ownership on. Will be null if hasObject is false.</param>
263270
/// <returns>true if this message should also be processed locally; false if the message should only be forwarded</returns>
264271
[MethodImpl(MethodImplOptions.AggressiveInlining)]
265-
private bool HandleDAHostMessageForwarding(ref NetworkManager networkManager, ulong senderId)
272+
private bool HandleDAHostMessageForwarding(ref NetworkManager networkManager, ulong senderId, bool hasObject, ref NetworkObject networkObject)
266273
{
267-
var clientList = ClientIdCount > 0 ? ClientIds : networkManager.ConnectedClientsIds;
268-
269274
var message = new ChangeOwnershipMessage()
270275
{
271276
NetworkObjectId = NetworkObjectId,
@@ -302,20 +307,44 @@ private bool HandleDAHostMessageForwarding(ref NetworkManager networkManager, ul
302307
}
303308
else
304309
{
310+
var clientList = ClientIds;
311+
var errorOnSender = true;
312+
313+
// OwnershipFlagsUpdate doesn't populate the ClientIds list.
314+
if (ChangeMessageType == ChangeType.OwnershipFlagsUpdate)
315+
{
316+
// if the DAHost can see this object, forward the message to all observers.
317+
// if the DAHost can't see the object, forward the message to everyone.
318+
clientList = hasObject ? networkObject.Observers.ToArray() : networkManager.ConnectedClientsIds.ToArray();
319+
320+
// Both clientList arrays will have the local client so we can not throw an error.
321+
errorOnSender = false;
322+
}
323+
305324
foreach (var clientId in clientList)
306325
{
307326
// Don't forward to self or originating client
308-
if (clientId == networkManager.LocalClientId || clientId == senderId)
327+
if (clientId == networkManager.LocalClientId)
309328
{
310329
continue;
311330
}
312331

332+
if (clientId == senderId)
333+
{
334+
if (errorOnSender)
335+
{
336+
Debug.LogError($"client-{senderId} sent a ChangeOwnershipMessage with themself inside the ClientIds list.");
337+
}
338+
339+
continue;
340+
}
341+
313342
networkManager.ConnectionManager.SendMessage(ref message, NetworkDelivery.Reliable, clientId);
314343
}
315344
}
316345

317346
// Return whether to process the message on the DAHost itself (only if object is spawned).
318-
return networkManager.SpawnManager.SpawnedObjects.ContainsKey(NetworkObjectId);
347+
return hasObject;
319348
}
320349
}
321350
}

0 commit comments

Comments
 (0)