diff --git a/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.RpcLinks.cs b/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.RpcLinks.cs index 30f3a6672..674bfaf27 100644 --- a/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.RpcLinks.cs +++ b/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.RpcLinks.cs @@ -48,11 +48,26 @@ internal void ParseRpcLink(PooledReader reader, ushort index, Channel channel) { NetworkBehaviour nb = nob.NetworkBehaviours[link.ComponentIndex]; if (link.RpcType == RpcType.Target) + { + var positionBefore = reader.Position; nb.OnTargetRpc(link.RpcHash, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)link.RpcHash, PacketId.TargetRpc, reader.Position-positionBefore)); + } else if (link.RpcType == RpcType.Observers) + { + var positionBefore = reader.Position; nb.OnObserversRpc(link.RpcHash, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)link.RpcHash, PacketId.ObserversRpc, reader.Position-positionBefore)); + } else if (link.RpcType == RpcType.Reconcile) + { + var positionBefore = reader.Position; nb.OnReconcileRpc(link.RpcHash, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)link.RpcHash, PacketId.Reconcile, reader.Position-positionBefore)); + } } //Could not find NetworkObject. else diff --git a/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.cs b/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.cs index cdc8a6da9..fe549b35e 100644 --- a/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.cs +++ b/Assets/FishNet/Runtime/Managing/Client/Object/ClientObjects.cs @@ -376,8 +376,10 @@ internal void ParseReconcileRpc(PooledReader reader, Channel channel) if (nb != null) { - OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.Reconcile, dataLength)); + var positionBefore = reader.Position; nb.OnReconcileRpc(null, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.Reconcile, reader.Position-positionBefore)); } else SkipDataLength((ushort)PacketId.ObserversRpc, reader, dataLength); @@ -395,8 +397,10 @@ internal void ParseObserversRpc(PooledReader reader, Channel channel) if (nb != null) { - OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.ObserversRpc, dataLength)); + var positionBefore = reader.Position; nb.OnObserversRpc(null, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.ObserversRpc, reader.Position-positionBefore)); } else SkipDataLength((ushort)PacketId.ObserversRpc, reader, dataLength); @@ -413,8 +417,10 @@ internal void ParseTargetRpc(PooledReader reader, Channel channel) if (nb != null) { - OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.TargetRpc, dataLength)); + var positionBefore = reader.Position; nb.OnTargetRpc(null, reader, channel); + // rpc read length is variable; so compare the before and after buffer position to know the real size + OnPacketRead?.Invoke(new PacketProcessingArgs(nb, (int)nb.PeekRpcHash(reader), PacketId.TargetRpc, reader.Position-positionBefore)); } else SkipDataLength((ushort)PacketId.TargetRpc, reader, dataLength); diff --git a/Assets/FishNet/Runtime/Managing/NetworkManager.cs b/Assets/FishNet/Runtime/Managing/NetworkManager.cs index f4e95a8be..c570ca598 100644 --- a/Assets/FishNet/Runtime/Managing/NetworkManager.cs +++ b/Assets/FishNet/Runtime/Managing/NetworkManager.cs @@ -339,16 +339,18 @@ internal void UpdateFramerate() else if (serverStarted) frameRate = ServerManager.FrameRate; - /* Make sure framerate isn't set to max on server. - * If it is then default to tick rate. If framerate is - * less than tickrate then also set to tickrate. */ -#if UNITY_SERVER - ushort minimumServerFramerate = (ushort)(TimeManager.TickRate + 1); - if (frameRate == MAXIMUM_FRAMERATE) - frameRate = minimumServerFramerate; - else if (frameRate < TimeManager.TickRate) - frameRate = minimumServerFramerate; -#endif + if (serverStarted) { + ushort minimumServerFramerate = (ushort)(TimeManager.TickRate + 1); + // Make sure framerate isn't set to max on server unless it is also a client. If it is then default to tick rate. + if (!clientStarted && frameRate == MAXIMUM_FRAMERATE) { + frameRate = minimumServerFramerate; + } + // If framerate is less than tickrate then set to tickrate + 1. + if (frameRate < TimeManager.TickRate) { + frameRate = minimumServerFramerate; + } + } + //If there is a framerate to set. if (frameRate > 0) { diff --git a/Assets/FishNet/Runtime/Managing/Server/ServerManager.cs b/Assets/FishNet/Runtime/Managing/Server/ServerManager.cs index 3b1288d48..4f7e4462c 100644 --- a/Assets/FishNet/Runtime/Managing/Server/ServerManager.cs +++ b/Assets/FishNet/Runtime/Managing/Server/ServerManager.cs @@ -115,7 +115,7 @@ public void SetRemoteClientTimeout(RemoteTimeoutType timeoutType, ushort duratio /// SyncTypeRate cannot yet be changed at runtime because this would require recalculating rates on SyncBase, which is not yet implemented. /// /// - internal float GetSynctypeRate() => _syncTypeRate; + public float GetSynctypeRate() => _syncTypeRate; [Tooltip("Default send rate for SyncTypes. A value of 0f will send changed values every tick.")] [Range(0f, 60f)] [SerializeField] diff --git a/Assets/FishNet/Runtime/Object/NetworkBehaviour.Prediction.cs b/Assets/FishNet/Runtime/Object/NetworkBehaviour.Prediction.cs index 270e419bb..a886ea62a 100644 --- a/Assets/FishNet/Runtime/Object/NetworkBehaviour.Prediction.cs +++ b/Assets/FishNet/Runtime/Object/NetworkBehaviour.Prediction.cs @@ -79,6 +79,25 @@ private void SetLastReplicateTick(uint value, bool updateGlobals = true) /// Registered Reconcile methods. /// private readonly Dictionary _reconcileRpcDelegates = new Dictionary(); + + public bool TryGetMethodNameForRpcPrediction(uint hash, out string methodName) + { + if (_reconcileRpcDelegates.TryGetValueIL2CPP(hash, out ReconcileRpcDelegate del1)) + { + methodName = del1.Method.Name; + return true; + } + + if (_replicateRpcDelegates.TryGetValueIL2CPP(hash, out ReplicateRpcDelegate del2)) + { + methodName = del2.Method.Name; + return true; + } + + methodName = null; + return false; + } + /// /// True if initialized compnents for prediction. /// diff --git a/Assets/FishNet/Runtime/Object/NetworkBehaviour.RPCs.cs b/Assets/FishNet/Runtime/Object/NetworkBehaviour.RPCs.cs index 27b363e10..5d5276361 100644 --- a/Assets/FishNet/Runtime/Object/NetworkBehaviour.RPCs.cs +++ b/Assets/FishNet/Runtime/Object/NetworkBehaviour.RPCs.cs @@ -47,6 +47,25 @@ public BufferedRpc(PooledWriter writer, Channel channel, DataOrderType orderType /// Registered TargetRpc methods. /// private readonly Dictionary _targetRpcDelegates = new Dictionary(); + + public bool TryGetMethodNameForRpcRPC(uint hash, out string methodName) + { + if (_targetRpcDelegates.TryGetValueIL2CPP(hash, out ClientRpcDelegate del1)) + { + methodName = del1.Method.Name; + return true; + } + + if (_observersRpcDelegates.TryGetValueIL2CPP(hash, out ClientRpcDelegate del2)) + { + methodName = del2.Method.Name; + return true; + } + + methodName = null; + return false; + } + /// /// Number of total RPC methods for scripts in the same inheritance tree for this instance. /// diff --git a/Assets/FishNet/Runtime/Utility/Performance/Profiling/PacketInfoProvider.cs b/Assets/FishNet/Runtime/Utility/Performance/Profiling/PacketInfoProvider.cs index 95d4820a8..95b45c4f7 100644 --- a/Assets/FishNet/Runtime/Utility/Performance/Profiling/PacketInfoProvider.cs +++ b/Assets/FishNet/Runtime/Utility/Performance/Profiling/PacketInfoProvider.cs @@ -63,6 +63,17 @@ public static string GetPropertyName(NetworkBehaviour nb, int propertyHash, Pack } else { + // check for name of delegate + if (nb.TryGetMethodNameForRpcRPC((uint)propertyHash, out var methodName1)) + { + return methodName1; + } + if (nb.TryGetMethodNameForRpcPrediction((uint)propertyHash, out var methodName2)) + { + return methodName2; + } + + // otherwise.. not a delegate List rpcNamesList = new(); int rpcCount = 0; // Iterate the replicates first, that's what the codegen does @@ -77,11 +88,13 @@ public static string GetPropertyName(NetworkBehaviour nb, int propertyHash, Pack } } } + foreach (var methodInfo in nb.GetType().GetMethods()) { foreach (var customAttribute in methodInfo.CustomAttributes) { - if (customAttribute.AttributeType.FullName == typeof(ObserversRpcAttribute).FullName || + if (customAttribute.AttributeType.FullName == + typeof(ObserversRpcAttribute).FullName || customAttribute.AttributeType.FullName == typeof(TargetRpcAttribute).FullName || customAttribute.AttributeType.FullName == typeof(ReconcileAttribute).FullName) { @@ -90,13 +103,14 @@ public static string GetPropertyName(NetworkBehaviour nb, int propertyHash, Pack res = methodInfo.Name; break; } + rpcCount++; rpcNamesList.Add(methodInfo.Name); } } } - RpcNamesCache[nb.GetType()] = rpcNamesList; + } break; }