Skip to content

Commit

Permalink
fix: send to not owner server warning message (#3111)
Browse files Browse the repository at this point in the history
* fix

When sending to not owner, use the not authority target when using a distributed authority network topology.

* fix

When sending to owner, use the authority target when using a distributed authority network topology.

* update

adding change log entry

* fix

This resolves the remaining issues with universal rpcs when using a distributed authority network topology.
  • Loading branch information
NoelStephensUnity authored Nov 4, 2024
1 parent b64117e commit d709df4
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 3 deletions.
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Fixed

- Fixed issue where `NotOwnerRpcTarget` or `OwnerRpcTarget` were not using their replacements `NotAuthorityRpcTarget` and `AuthorityRpcTarget` which would invoke a warning. (#3111)
- Fixed issue where client is removed as an observer from spawned objects when their player instance is despawned. (#3110)
- Fixed issue where `NetworkAnimator` would statically allocate write buffer space for `Animator` parameters that could cause a write error if the number of parameters exceeded the space allocated. (#3108)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message,
// ClientsAndHost sends to everyone who runs any client logic
// So if the server is a host, this target includes it (as hosts run client logic)
// If the server is not a host, this target leaves it out, ergo the selection of NotServer.
if (behaviour.NetworkManager.ServerIsHost)
// If we are in distributed authority mode and connected to a service, then send to all clients.
if (behaviour.NetworkManager.ServerIsHost || (m_NetworkManager.DistributedAuthorityMode && m_NetworkManager.CMBServiceConnection))
{
m_UnderlyingTarget = behaviour.RpcTarget.Everyone;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ internal class NotOwnerRpcTarget : BaseRpcTarget
{
private IGroupRpcTarget m_GroupSendTarget;
private ServerRpcTarget m_ServerRpcTarget;
private NotAuthorityRpcTarget m_NotAuthorityRpcTarget;
private LocalSendRpcTarget m_LocalSendRpcTarget;

public override void Dispose()
{
m_ServerRpcTarget.Dispose();
m_LocalSendRpcTarget.Dispose();
m_NotAuthorityRpcTarget.Dispose();
if (m_GroupSendTarget != null)
{
m_GroupSendTarget.Target.Dispose();
Expand All @@ -19,6 +21,13 @@ public override void Dispose()

internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
{
// Not owner is the same as not authority in distributed authority mode
if (m_NetworkManager.DistributedAuthorityMode)
{
m_NotAuthorityRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
return;
}

if (m_GroupSendTarget == null)
{
if (behaviour.IsServer)
Expand Down Expand Up @@ -86,6 +95,7 @@ internal NotOwnerRpcTarget(NetworkManager manager) : base(manager)
{
m_ServerRpcTarget = new ServerRpcTarget(manager);
m_LocalSendRpcTarget = new LocalSendRpcTarget(manager);
m_NotAuthorityRpcTarget = new NotAuthorityRpcTarget(manager);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@ internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message,
continue;
}

if (clientId == behaviour.NetworkManager.LocalClientId)
// If we are in distributed authority mode and connected to the service, then we exclude the owner/authority from the list
if (m_NetworkManager.DistributedAuthorityMode && m_NetworkManager.CMBServiceConnection && clientId == behaviour.OwnerClientId)
{
continue;
}

if (clientId == m_NetworkManager.LocalClientId)
{
m_LocalSendRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ internal class OwnerRpcTarget : BaseRpcTarget
private IIndividualRpcTarget m_UnderlyingTarget;
private LocalSendRpcTarget m_LocalRpcTarget;
private ServerRpcTarget m_ServerRpcTarget;
private AuthorityRpcTarget m_AuthorityRpcTarget;

public override void Dispose()
{
m_AuthorityRpcTarget.Dispose();
m_ServerRpcTarget.Dispose();
m_LocalRpcTarget.Dispose();
if (m_UnderlyingTarget != null)
{
Expand All @@ -18,6 +21,13 @@ public override void Dispose()

internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
{
// Sending to owner is the same as sending to authority in distributed authority mode
if (m_NetworkManager.DistributedAuthorityMode)
{
m_AuthorityRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
return;
}

if (behaviour.OwnerClientId == behaviour.NetworkManager.LocalClientId)
{
m_LocalRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
Expand Down Expand Up @@ -49,6 +59,7 @@ internal OwnerRpcTarget(NetworkManager manager) : base(manager)
{
m_LocalRpcTarget = new LocalSendRpcTarget(manager);
m_ServerRpcTarget = new ServerRpcTarget(manager);
m_AuthorityRpcTarget = new AuthorityRpcTarget(manager);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Unity.Collections;
namespace Unity.Netcode
{
internal class ServerRpcTarget : BaseRpcTarget
{
protected BaseRpcTarget m_UnderlyingTarget;
protected ProxyRpcTarget m_ProxyRpcTarget;

public override void Dispose()
{
Expand All @@ -11,13 +13,62 @@ public override void Dispose()
m_UnderlyingTarget.Dispose();
m_UnderlyingTarget = null;
}

if (m_ProxyRpcTarget != null)
{
m_ProxyRpcTarget.Dispose();
m_ProxyRpcTarget = null;
}
}

internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
{
// For distributed authority the "server" is considered the authority of the object
if (behaviour.NetworkManager.DistributedAuthorityMode && behaviour.NetworkManager.CMBServiceConnection)
{
UnityEngine.Debug.LogWarning("[Invalid Target] There is no server to send to when in Distributed Authority mode!");
// If the local instance is the owner, then invoke the message locally on this behaviour
if (behaviour.IsOwner)
{
var context = new NetworkContext
{
SenderId = m_NetworkManager.LocalClientId,
Timestamp = m_NetworkManager.RealTimeProvider.RealTimeSinceStartup,
SystemOwner = m_NetworkManager,
// header information isn't valid since it's not a real message.
// RpcMessage doesn't access this stuff so it's just left empty.
Header = new NetworkMessageHeader(),
SerializedHeaderSize = 0,
MessageSize = 0
};
using var tempBuffer = new FastBufferReader(message.WriteBuffer, Allocator.None);
message.ReadBuffer = tempBuffer;
message.Handle(ref context);
// If enabled, then add the RPC metrics for this
#if DEVELOPMENT_BUILD || UNITY_EDITOR || UNITY_MP_TOOLS_NET_STATS_MONITOR_ENABLED_IN_RELEASE
int length = tempBuffer.Length;
if (NetworkBehaviour.__rpc_name_table[behaviour.GetType()].TryGetValue(message.Metadata.NetworkRpcMethodId, out var rpcMethodName))
{
m_NetworkManager.NetworkMetrics.TrackRpcSent(
m_NetworkManager.LocalClientId,
behaviour.NetworkObject,
rpcMethodName,
behaviour.__getTypeName(),
length);
}
#endif
}
else // Otherwise, send a proxied message to the owner of the object
{
if (m_ProxyRpcTarget == null)
{
m_ProxyRpcTarget = new ProxyRpcTarget(behaviour.OwnerClientId, m_NetworkManager);
}
else
{
m_ProxyRpcTarget.SetClientId(behaviour.OwnerClientId);
}
m_ProxyRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
}
return;
}

Expand Down

0 comments on commit d709df4

Please sign in to comment.