2.2.0
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Unity.Netcode
|
||||
/// <summary>
|
||||
/// Enum representing the different types of messages that can be sent over the network.
|
||||
/// The values cannot be changed, as they are used to serialize and deserialize messages.
|
||||
/// Adding new messages should be done by adding new values to the end of the enum
|
||||
/// Adding new messages should be done by adding new values to the end of the enum
|
||||
/// using the next free value.
|
||||
/// </summary>
|
||||
/// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Unity.Netcode
|
||||
/// <summary>
|
||||
/// When requesting, RequestClientId is the requestor.
|
||||
/// When approving, RequestClientId is the owner that approved.
|
||||
/// When responding (only for denied), RequestClientId is the requestor
|
||||
/// When responding (only for denied), RequestClientId is the requestor
|
||||
/// </summary>
|
||||
internal ulong RequestClientId;
|
||||
internal int ClientIdCount;
|
||||
@@ -272,7 +272,7 @@ namespace Unity.Netcode
|
||||
networkManager.ConnectionManager.SendMessage(ref message, NetworkDelivery.Reliable, clientId);
|
||||
}
|
||||
}
|
||||
// If the NetworkObject is not visible to the DAHost client, then exit early
|
||||
// If the NetworkObject is not visible to the DAHost client, then exit early
|
||||
if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(NetworkObjectId))
|
||||
{
|
||||
return;
|
||||
@@ -294,7 +294,7 @@ namespace Unity.Netcode
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the
|
||||
/// Handle the extended distributed authority ownership updates
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
private void HandleExtendedOwnershipUpdate(ref NetworkContext context)
|
||||
@@ -332,8 +332,8 @@ namespace Unity.Netcode
|
||||
// Sanity check that we are not sending duplicated change ownership messages
|
||||
if (networkObject.OwnerClientId == OwnerClientId)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Unnecessary ownership changed message for {NetworkObjectId}.");
|
||||
// Ignore the message
|
||||
// Log error and then ignore the message
|
||||
UnityEngine.Debug.LogError($"Client-{context.SenderId} ({RequestClientId}) sent unnecessary ownership changed message for {NetworkObjectId}.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -351,10 +351,10 @@ namespace Unity.Netcode
|
||||
networkObject.InvokeBehaviourOnLostOwnership();
|
||||
}
|
||||
|
||||
// If in distributed authority mode
|
||||
// If in distributed authority mode
|
||||
if (networkManager.DistributedAuthorityMode)
|
||||
{
|
||||
// Always update the network properties in distributed authority mode
|
||||
// Always update the network properties in distributed authority mode
|
||||
for (int i = 0; i < networkObject.ChildNetworkBehaviours.Count; i++)
|
||||
{
|
||||
networkObject.ChildNetworkBehaviours[i].UpdateNetworkProperties();
|
||||
|
||||
@@ -55,19 +55,24 @@ namespace Unity.Netcode
|
||||
// Don't redistribute for the local instance
|
||||
if (ClientId != networkManager.LocalClientId)
|
||||
{
|
||||
// Synchronize the client with spawned objects (relative to each client)
|
||||
networkManager.SpawnManager.SynchronizeObjectsToNewlyJoinedClient(ClientId);
|
||||
|
||||
// Keeping for reference in case the above doesn't resolve for hidden objects (theoretically it should)
|
||||
// Show any NetworkObjects that are:
|
||||
// - Hidden from the session owner
|
||||
// - Owned by this client
|
||||
// - Has NetworkObject.SpawnWithObservers set to true (the default)
|
||||
if (!networkManager.LocalClient.IsSessionOwner)
|
||||
{
|
||||
networkManager.SpawnManager.ShowHiddenObjectsToNewlyJoinedClient(ClientId);
|
||||
}
|
||||
//if (!networkManager.LocalClient.IsSessionOwner)
|
||||
//{
|
||||
// networkManager.SpawnManager.ShowHiddenObjectsToNewlyJoinedClient(ClientId);
|
||||
//}
|
||||
|
||||
// We defer redistribution to the end of the NetworkUpdateStage.PostLateUpdate
|
||||
networkManager.RedistributeToClient = true;
|
||||
networkManager.ClientToRedistribute = ClientId;
|
||||
networkManager.TickToRedistribute = networkManager.ServerTime.Tick + 20;
|
||||
/// We defer redistribution to happen after NetworkShow has been invoked
|
||||
/// <see cref="NetworkBehaviourUpdater.NetworkBehaviourUpdater_Tick"/>
|
||||
/// DANGO-TODO: Determine if this needs to be removed once the service handles object distribution
|
||||
networkManager.RedistributeToClients = true;
|
||||
networkManager.ClientsToRedistribute.Add(ClientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,23 +5,38 @@ namespace Unity.Netcode
|
||||
{
|
||||
internal struct ServiceConfig : INetworkSerializable
|
||||
{
|
||||
public uint Version;
|
||||
public uint SessionVersion;
|
||||
public bool IsRestoredSession;
|
||||
public ulong CurrentSessionOwner;
|
||||
public bool ServerRedistribution;
|
||||
|
||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
||||
{
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
BytePacker.WriteValueBitPacked(serializer.GetFastBufferWriter(), Version);
|
||||
BytePacker.WriteValueBitPacked(serializer.GetFastBufferWriter(), SessionVersion);
|
||||
serializer.SerializeValue(ref IsRestoredSession);
|
||||
BytePacker.WriteValueBitPacked(serializer.GetFastBufferWriter(), CurrentSessionOwner);
|
||||
|
||||
if (SessionVersion >= SessionConfig.ServerDistributionCompatible)
|
||||
{
|
||||
serializer.SerializeValue(ref ServerRedistribution);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteUnpacker.ReadValueBitPacked(serializer.GetFastBufferReader(), out Version);
|
||||
ByteUnpacker.ReadValueBitPacked(serializer.GetFastBufferReader(), out SessionVersion);
|
||||
serializer.SerializeValue(ref IsRestoredSession);
|
||||
ByteUnpacker.ReadValueBitPacked(serializer.GetFastBufferReader(), out CurrentSessionOwner);
|
||||
|
||||
if (SessionVersion >= SessionConfig.ServerDistributionCompatible)
|
||||
{
|
||||
serializer.SerializeValue(ref ServerRedistribution);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerRedistribution = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,11 +205,13 @@ namespace Unity.Netcode
|
||||
if (receivedMessageVersion >= k_AddCMBServiceConfig)
|
||||
{
|
||||
reader.ReadNetworkSerializable(out ServiceConfig);
|
||||
networkManager.SessionConfig = new SessionConfig(ServiceConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.ReadValueSafe(out IsRestoredSession);
|
||||
ByteUnpacker.ReadValueBitPacked(reader, out CurrentSessionOwner);
|
||||
networkManager.SessionConfig = new SessionConfig(SessionConfig.NoFeatureCompatibility);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,31 +7,28 @@ namespace Unity.Netcode
|
||||
/// </summary>
|
||||
internal struct ClientConfig : INetworkSerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// We start at version 1, where anything less than version 1 on the service side
|
||||
/// is not bypass feature compatible.
|
||||
/// </summary>
|
||||
private const int k_BypassFeatureCompatible = 1;
|
||||
public int Version => k_BypassFeatureCompatible;
|
||||
public SessionConfig SessionConfig;
|
||||
public int SessionVersion => (int)SessionConfig.SessionVersion;
|
||||
public uint TickRate;
|
||||
public bool EnableSceneManagement;
|
||||
|
||||
// Only gets deserialized but should never be used unless testing
|
||||
public int RemoteClientVersion;
|
||||
public int RemoteClientSessionVersion;
|
||||
|
||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
||||
{
|
||||
// Clients always write
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
var writer = serializer.GetFastBufferWriter();
|
||||
BytePacker.WriteValueBitPacked(writer, Version);
|
||||
BytePacker.WriteValueBitPacked(writer, SessionVersion);
|
||||
BytePacker.WriteValueBitPacked(writer, TickRate);
|
||||
writer.WriteValueSafe(EnableSceneManagement);
|
||||
}
|
||||
else
|
||||
{
|
||||
var reader = serializer.GetFastBufferReader();
|
||||
ByteUnpacker.ReadValueBitPacked(reader, out RemoteClientVersion);
|
||||
ByteUnpacker.ReadValueBitPacked(reader, out RemoteClientSessionVersion);
|
||||
ByteUnpacker.ReadValueBitPacked(reader, out TickRate);
|
||||
reader.ReadValueSafe(out EnableSceneManagement);
|
||||
}
|
||||
@@ -40,6 +37,8 @@ namespace Unity.Netcode
|
||||
|
||||
internal struct ConnectionRequestMessage : INetworkMessage
|
||||
{
|
||||
internal const string InvalidSessionVersionMessage = "The client version is not compatible with the session version.";
|
||||
|
||||
// This version update is unidirectional (client to service) and version
|
||||
// handling occurs on the service side. This serialized data is never sent
|
||||
// to a host or server.
|
||||
@@ -47,7 +46,7 @@ namespace Unity.Netcode
|
||||
public int Version => k_SendClientConfigToService;
|
||||
|
||||
public ulong ConfigHash;
|
||||
public bool CMBServiceConnection;
|
||||
public bool DistributedAuthority;
|
||||
public ClientConfig ClientConfig;
|
||||
|
||||
public byte[] ConnectionData;
|
||||
@@ -72,7 +71,7 @@ namespace Unity.Netcode
|
||||
// END FORBIDDEN SEGMENT
|
||||
// ============================================================
|
||||
|
||||
if (CMBServiceConnection)
|
||||
if (DistributedAuthority)
|
||||
{
|
||||
writer.WriteNetworkSerializable(ClientConfig);
|
||||
}
|
||||
@@ -120,6 +119,11 @@ namespace Unity.Netcode
|
||||
// END FORBIDDEN SEGMENT
|
||||
// ============================================================
|
||||
|
||||
if (networkManager.DAHost)
|
||||
{
|
||||
reader.ReadNetworkSerializable(out ClientConfig);
|
||||
}
|
||||
|
||||
if (networkManager.NetworkConfig.ConnectionApproval)
|
||||
{
|
||||
if (!reader.TryBeginRead(FastBufferWriter.GetWriteSize(ConfigHash) + FastBufferWriter.GetWriteSize<int>()))
|
||||
@@ -182,6 +186,17 @@ namespace Unity.Netcode
|
||||
var networkManager = (NetworkManager)context.SystemOwner;
|
||||
var senderId = context.SenderId;
|
||||
|
||||
// DAHost mocking the service logic to disconnect clients trying to connect with a lower session version
|
||||
if (networkManager.DAHost)
|
||||
{
|
||||
if (ClientConfig.RemoteClientSessionVersion < networkManager.SessionConfig.SessionVersion)
|
||||
{
|
||||
//Disconnect with reason
|
||||
networkManager.ConnectionManager.DisconnectClient(senderId, InvalidSessionVersionMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (networkManager.ConnectionManager.PendingClients.TryGetValue(senderId, out PendingClient client))
|
||||
{
|
||||
// Set to pending approval to prevent future connection requests from being approved
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
// DA - NGO CMB SERVICE NOTES:
|
||||
// (*** See above notes fist ***)
|
||||
// If it is a player object freshly spawning and one or more clients all connect at the exact same time (i.e. received on effectively
|
||||
// If it is a player object freshly spawning and one or more clients all connect at the exact same time (i.e. received on effectively
|
||||
// the same frame), then we need to check the observers list to make sure all players are visible upon first spawning. At a later date,
|
||||
// for area of interest we will need to have some form of follow up "observer update" message to cull out players not within each
|
||||
// player's AOI.
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Unity.Netcode
|
||||
}
|
||||
else if (networkManager.DAHost)
|
||||
{
|
||||
// Specific to distributed authority mode, the only sender of state updates will be the owner
|
||||
// Specific to distributed authority mode, the only sender of state updates will be the owner
|
||||
ownerClientId = context.SenderId;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,10 +70,6 @@ namespace Unity.Netcode
|
||||
public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int receivedMessageVersion)
|
||||
{
|
||||
var networkManager = (NetworkManager)context.SystemOwner;
|
||||
if (!networkManager.IsClient)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ByteUnpacker.ReadValueBitPacked(reader, out NetworkObjectId);
|
||||
reader.ReadValueSafe(out m_BitField);
|
||||
|
||||
@@ -141,28 +141,6 @@ namespace Unity.Netcode
|
||||
{
|
||||
RegisterMessageType(type);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (EnableMessageOrderConsoleLog)
|
||||
{
|
||||
// DANGO-TODO: Remove this when we have some form of message type indices stability in place
|
||||
// For now, just log the messages and their assigned types for reference purposes.
|
||||
var networkManager = m_Owner as NetworkManager;
|
||||
if (networkManager != null)
|
||||
{
|
||||
if (networkManager.DistributedAuthorityMode)
|
||||
{
|
||||
var messageListing = new StringBuilder();
|
||||
messageListing.AppendLine("NGO Message Index to Type Listing:");
|
||||
foreach (var message in m_MessageTypes)
|
||||
{
|
||||
messageListing.AppendLine($"[{message.Value}][{message.Key.Name}]");
|
||||
}
|
||||
Debug.Log(messageListing);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace Unity.Netcode
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ namespace Unity.Netcode
|
||||
{
|
||||
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();
|
||||
@@ -19,6 +21,13 @@ namespace Unity.Netcode
|
||||
|
||||
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)
|
||||
@@ -86,6 +95,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
m_ServerRpcTarget = new ServerRpcTarget(manager);
|
||||
m_LocalSendRpcTarget = new LocalSendRpcTarget(manager);
|
||||
m_NotAuthorityRpcTarget = new NotAuthorityRpcTarget(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,13 @@ namespace Unity.Netcode
|
||||
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;
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace Unity.Netcode
|
||||
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)
|
||||
{
|
||||
@@ -18,6 +21,13 @@ namespace Unity.Netcode
|
||||
|
||||
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);
|
||||
@@ -49,6 +59,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
m_LocalRpcTarget = new LocalSendRpcTarget(manager);
|
||||
m_ServerRpcTarget = new ServerRpcTarget(manager);
|
||||
m_AuthorityRpcTarget = new AuthorityRpcTarget(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,9 +79,28 @@ namespace Unity.Netcode
|
||||
SpecifiedInParams
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This parameter configures a performance optimization. This optimization is not valid in all situations.<br />
|
||||
/// Because BaseRpcTarget is a managed type, allocating a new one is expensive, as it puts pressure on the garbage collector.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When using a <see cref="Temp"/> allocation type for the RPC target(s):<br />
|
||||
/// You typically don't need to worry about persisting the <see cref="BaseRpcTarget"/> generated.
|
||||
/// When using a <see cref="Persistent"/> allocation type for the RPC target(s): <br />
|
||||
/// You will want to use <see cref="RpcTarget"/>, which returns <see cref="BaseRpcTarget"/>, during <see cref="NetworkBehaviour"/> initialization (i.e. <see cref="NetworkBehaviour.OnNetworkPostSpawn"/>) and it to a property.<br />
|
||||
/// Then, When invoking the RPC, you would use your <see cref="BaseRpcTarget"/> which is a persisted allocation of a given set of client identifiers.
|
||||
/// !! Important !!<br />
|
||||
/// You will want to invoke <see cref="BaseRpcTarget.Dispose"/> of any persisted properties created via <see cref="RpcTarget"/> when despawning or destroying the associated <see cref="NetworkBehaviour"/> component's <see cref="NetworkObject"/>. Not doing so will result in small memory leaks.
|
||||
/// </remarks>
|
||||
public enum RpcTargetUse
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a temporary <see cref="BaseRpcTarget"/> used for the frame an <see cref="RpcAttribute"/> decorated method is invoked.
|
||||
/// </summary>
|
||||
Temp,
|
||||
/// <summary>
|
||||
/// Creates a persisted <see cref="BaseRpcTarget"/> that does not change and will persist until <see cref="BaseRpcTarget.Dispose"/> is called.
|
||||
/// </summary>
|
||||
Persistent
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
@@ -11,13 +13,62 @@ namespace Unity.Netcode
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user