Skip to content

Commit d709df4

Browse files
fix: send to not owner server warning message (#3111)
* 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.
1 parent b64117e commit d709df4

File tree

6 files changed

+83
-3
lines changed

6 files changed

+83
-3
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

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

1313
### Fixed
1414

15+
- Fixed issue where `NotOwnerRpcTarget` or `OwnerRpcTarget` were not using their replacements `NotAuthorityRpcTarget` and `AuthorityRpcTarget` which would invoke a warning. (#3111)
1516
- Fixed issue where client is removed as an observer from spawned objects when their player instance is despawned. (#3110)
1617
- 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)
1718

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/ClientsAndHostRpcTarget.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message,
1717
// ClientsAndHost sends to everyone who runs any client logic
1818
// So if the server is a host, this target includes it (as hosts run client logic)
1919
// If the server is not a host, this target leaves it out, ergo the selection of NotServer.
20-
if (behaviour.NetworkManager.ServerIsHost)
20+
// If we are in distributed authority mode and connected to a service, then send to all clients.
21+
if (behaviour.NetworkManager.ServerIsHost || (m_NetworkManager.DistributedAuthorityMode && m_NetworkManager.CMBServiceConnection))
2122
{
2223
m_UnderlyingTarget = behaviour.RpcTarget.Everyone;
2324
}

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/NotOwnerRpcTarget.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ internal class NotOwnerRpcTarget : BaseRpcTarget
44
{
55
private IGroupRpcTarget m_GroupSendTarget;
66
private ServerRpcTarget m_ServerRpcTarget;
7+
private NotAuthorityRpcTarget m_NotAuthorityRpcTarget;
78
private LocalSendRpcTarget m_LocalSendRpcTarget;
89

910
public override void Dispose()
1011
{
1112
m_ServerRpcTarget.Dispose();
1213
m_LocalSendRpcTarget.Dispose();
14+
m_NotAuthorityRpcTarget.Dispose();
1315
if (m_GroupSendTarget != null)
1416
{
1517
m_GroupSendTarget.Target.Dispose();
@@ -19,6 +21,13 @@ public override void Dispose()
1921

2022
internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
2123
{
24+
// Not owner is the same as not authority in distributed authority mode
25+
if (m_NetworkManager.DistributedAuthorityMode)
26+
{
27+
m_NotAuthorityRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
28+
return;
29+
}
30+
2231
if (m_GroupSendTarget == null)
2332
{
2433
if (behaviour.IsServer)
@@ -86,6 +95,7 @@ internal NotOwnerRpcTarget(NetworkManager manager) : base(manager)
8695
{
8796
m_ServerRpcTarget = new ServerRpcTarget(manager);
8897
m_LocalSendRpcTarget = new LocalSendRpcTarget(manager);
98+
m_NotAuthorityRpcTarget = new NotAuthorityRpcTarget(manager);
8999
}
90100
}
91101
}

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/NotServerRpcTarget.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message,
5151
continue;
5252
}
5353

54-
if (clientId == behaviour.NetworkManager.LocalClientId)
54+
// If we are in distributed authority mode and connected to the service, then we exclude the owner/authority from the list
55+
if (m_NetworkManager.DistributedAuthorityMode && m_NetworkManager.CMBServiceConnection && clientId == behaviour.OwnerClientId)
56+
{
57+
continue;
58+
}
59+
60+
if (clientId == m_NetworkManager.LocalClientId)
5561
{
5662
m_LocalSendRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
5763
continue;

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/OwnerRpcTarget.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ internal class OwnerRpcTarget : BaseRpcTarget
55
private IIndividualRpcTarget m_UnderlyingTarget;
66
private LocalSendRpcTarget m_LocalRpcTarget;
77
private ServerRpcTarget m_ServerRpcTarget;
8+
private AuthorityRpcTarget m_AuthorityRpcTarget;
89

910
public override void Dispose()
1011
{
12+
m_AuthorityRpcTarget.Dispose();
13+
m_ServerRpcTarget.Dispose();
1114
m_LocalRpcTarget.Dispose();
1215
if (m_UnderlyingTarget != null)
1316
{
@@ -18,6 +21,13 @@ public override void Dispose()
1821

1922
internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
2023
{
24+
// Sending to owner is the same as sending to authority in distributed authority mode
25+
if (m_NetworkManager.DistributedAuthorityMode)
26+
{
27+
m_AuthorityRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
28+
return;
29+
}
30+
2131
if (behaviour.OwnerClientId == behaviour.NetworkManager.LocalClientId)
2232
{
2333
m_LocalRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
@@ -49,6 +59,7 @@ internal OwnerRpcTarget(NetworkManager manager) : base(manager)
4959
{
5060
m_LocalRpcTarget = new LocalSendRpcTarget(manager);
5161
m_ServerRpcTarget = new ServerRpcTarget(manager);
62+
m_AuthorityRpcTarget = new AuthorityRpcTarget(manager);
5263
}
5364
}
5465
}

com.unity.netcode.gameobjects/Runtime/Messaging/RpcTargets/ServerRpcTarget.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using Unity.Collections;
12
namespace Unity.Netcode
23
{
34
internal class ServerRpcTarget : BaseRpcTarget
45
{
56
protected BaseRpcTarget m_UnderlyingTarget;
7+
protected ProxyRpcTarget m_ProxyRpcTarget;
68

79
public override void Dispose()
810
{
@@ -11,13 +13,62 @@ public override void Dispose()
1113
m_UnderlyingTarget.Dispose();
1214
m_UnderlyingTarget = null;
1315
}
16+
17+
if (m_ProxyRpcTarget != null)
18+
{
19+
m_ProxyRpcTarget.Dispose();
20+
m_ProxyRpcTarget = null;
21+
}
1422
}
1523

1624
internal override void Send(NetworkBehaviour behaviour, ref RpcMessage message, NetworkDelivery delivery, RpcParams rpcParams)
1725
{
26+
// For distributed authority the "server" is considered the authority of the object
1827
if (behaviour.NetworkManager.DistributedAuthorityMode && behaviour.NetworkManager.CMBServiceConnection)
1928
{
20-
UnityEngine.Debug.LogWarning("[Invalid Target] There is no server to send to when in Distributed Authority mode!");
29+
// If the local instance is the owner, then invoke the message locally on this behaviour
30+
if (behaviour.IsOwner)
31+
{
32+
var context = new NetworkContext
33+
{
34+
SenderId = m_NetworkManager.LocalClientId,
35+
Timestamp = m_NetworkManager.RealTimeProvider.RealTimeSinceStartup,
36+
SystemOwner = m_NetworkManager,
37+
// header information isn't valid since it's not a real message.
38+
// RpcMessage doesn't access this stuff so it's just left empty.
39+
Header = new NetworkMessageHeader(),
40+
SerializedHeaderSize = 0,
41+
MessageSize = 0
42+
};
43+
using var tempBuffer = new FastBufferReader(message.WriteBuffer, Allocator.None);
44+
message.ReadBuffer = tempBuffer;
45+
message.Handle(ref context);
46+
// If enabled, then add the RPC metrics for this
47+
#if DEVELOPMENT_BUILD || UNITY_EDITOR || UNITY_MP_TOOLS_NET_STATS_MONITOR_ENABLED_IN_RELEASE
48+
int length = tempBuffer.Length;
49+
if (NetworkBehaviour.__rpc_name_table[behaviour.GetType()].TryGetValue(message.Metadata.NetworkRpcMethodId, out var rpcMethodName))
50+
{
51+
m_NetworkManager.NetworkMetrics.TrackRpcSent(
52+
m_NetworkManager.LocalClientId,
53+
behaviour.NetworkObject,
54+
rpcMethodName,
55+
behaviour.__getTypeName(),
56+
length);
57+
}
58+
#endif
59+
}
60+
else // Otherwise, send a proxied message to the owner of the object
61+
{
62+
if (m_ProxyRpcTarget == null)
63+
{
64+
m_ProxyRpcTarget = new ProxyRpcTarget(behaviour.OwnerClientId, m_NetworkManager);
65+
}
66+
else
67+
{
68+
m_ProxyRpcTarget.SetClientId(behaviour.OwnerClientId);
69+
}
70+
m_ProxyRpcTarget.Send(behaviour, ref message, delivery, rpcParams);
71+
}
2172
return;
2273
}
2374

0 commit comments

Comments
 (0)