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;
}