Skip to content

Commit e517377

Browse files
committed
Fixed MirrorSendRpcPatch
1 parent 4f4fa41 commit e517377

3 files changed

Lines changed: 65 additions & 52 deletions

File tree

LabExtended/Events/MirrorEvents.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,22 @@ public delegate void BehaviourUpdatedSyncVarEventHandler(NetworkBehaviour behavi
9595
public delegate void RemovedObserverEventHandler(NetworkIdentity identity, ExPlayer observer);
9696

9797
/// <summary>
98-
/// Represents the method that handles the event raised before a remote procedure call (RPC) is sent to network
99-
/// targets.
100-
/// </summary>
101-
/// <remarks>This event allows inspection or modification of the RPC message and its delivery. Handlers
102-
/// can change the message contents or cancel the RPC by setting <paramref name="isAllowed"/> to <see
103-
/// langword="false"/>.</remarks>
104-
/// <param name="behaviour">The network behaviour instance initiating the RPC.</param>
105-
/// <param name="rpcName">The name of the RPC method being invoked.</param>
98+
/// Represents the method that handles the event raised before a remote procedure call (RPC) is sent to specified
99+
/// targets on the network.
100+
/// </summary>
101+
/// <remarks>This event allows inspection and modification of RPC data and targets before the message is
102+
/// sent. It can be used to implement custom filtering, logging, or security checks. Modifying <paramref
103+
/// name="isAllowed"/> to <see langword="false"/> will prevent the RPC from being sent.</remarks>
104+
/// <param name="behaviour">The network behaviour instance that is invoking the RPC.</param>
105+
/// <param name="rpcName">The name of the RPC method being called.</param>
106106
/// <param name="rpcHash">The hash value identifying the RPC method.</param>
107-
/// <param name="writer">The writer used to serialize the RPC parameters.</param>
108-
/// <param name="targets">The list of target players to whom the RPC will be sent.</param>
109-
/// <param name="message">A reference to the RPC message that will be sent. Can be modified to alter the outgoing message.</param>
110-
/// <param name="isAllowed">A reference to a value indicating whether the RPC is permitted to be sent. Set to <see langword="false"/> to
111-
/// prevent the RPC from being sent.</param>
112-
public delegate void SendingRpcEventHandler(NetworkBehaviour behaviour, string rpcName, int rpcHash, NetworkWriter writer, List<ExPlayer> targets,
113-
ref RpcMessage message, ref bool isAllowed);
107+
/// <param name="writer">The writer used to serialize the RPC payload data.</param>
108+
/// <param name="connectionTargets">The list of network connections to which the RPC will be sent.</param>
109+
/// <param name="message">A reference to the RPC message being sent. Can be modified to alter the message before transmission.</param>
110+
/// <param name="isAllowed">A reference to a Boolean value indicating whether the RPC is permitted to be sent. Set to <see
111+
/// langword="false"/> to block the RPC.</param>
112+
public delegate void SendingRpcEventHandler(NetworkBehaviour behaviour, string rpcName, int rpcHash, NetworkWriter writer,
113+
List<NetworkConnection> connectionTargets, List<ExPlayer> playerTargets, ref RpcMessage message, ref bool isAllowed);
114114

115115
/// <summary>
116116
/// Represents the method that handles an event triggered when a remote procedure call (RPC) is sent from a network
@@ -372,13 +372,14 @@ public static void OnUpdatedSyncVar(NetworkBehaviour behaviour, Type syncVarType
372372
/// <summary>
373373
/// Invokes the <see cref="SendingRpc"/> event.
374374
/// </summary>
375-
public static bool OnSendingRpc(NetworkBehaviour behaviour, string rpcName, int rpcHash, NetworkWriter writer, List<ExPlayer> targets, ref RpcMessage message)
375+
public static bool OnSendingRpc(NetworkBehaviour behaviour, string rpcName, int rpcHash, NetworkWriter writer, List<NetworkConnection> connections,
376+
List<ExPlayer> players, ref RpcMessage message)
376377
{
377378
var isAllowed = true;
378379

379380
try
380381
{
381-
SendingRpc?.Invoke(behaviour, rpcName, rpcHash, writer, targets, ref message, ref isAllowed);
382+
SendingRpc?.Invoke(behaviour, rpcName, rpcHash, writer, connections, players, ref message, ref isAllowed);
382383
}
383384
catch (Exception ex)
384385
{
@@ -405,4 +406,7 @@ public static void OnSentRpc(NetworkBehaviour behaviour, string rpcName, int rpc
405406

406407
internal static bool Internal_AnySyncVarSubsribers()
407408
=> UpdatingSyncVar is not null || UpdatedSyncVar is not null;
409+
410+
internal static bool Internal_AnySerializingSubscribers()
411+
=> BehaviourSerializing is not null || BehaviourSerialized is not null;
408412
}

LabExtended/Patches/Events/Mirror/MirrorBehaviourSerializePatch.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public static class MirrorBehaviourSerializePatch
1414
[HarmonyPatch(typeof(NetworkIdentity), nameof(NetworkIdentity.SerializeServer))]
1515
private static bool Prefix(NetworkIdentity __instance, bool initialState, NetworkWriter ownerWriter, NetworkWriter observersWriter)
1616
{
17+
if (!MirrorEvents.Internal_AnySerializingSubscribers())
18+
return true;
19+
1720
__instance.ValidateComponents();
1821

1922
var behaviours = __instance.NetworkBehaviours;

LabExtended/Patches/Events/Mirror/MirrorSendRpcPatch.cs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,54 +25,63 @@ private static bool SendAllRpcPrefix(NetworkBehaviour __instance, string functio
2525
return false;
2626
}
2727

28-
if (__instance.netIdentity.observers == null || __instance.netIdentity.observers.Count == 0)
29-
return false;
30-
3128
var rpcMessage = new RpcMessage
3229
{
3330
netId = __instance.netId,
3431
componentIndex = __instance.ComponentIndex,
35-
3632
functionHash = (ushort)functionHashCode,
3733
payload = writer.ToArraySegment()
3834
};
3935

36+
if (__instance.netIdentity.observers == null || __instance.netIdentity.observers.Count == 0)
37+
return false;
38+
4039
var players = ListPool<ExPlayer>.Shared.Rent();
40+
var connections = ListPool<NetworkConnection>.Shared.Rent();
4141

42-
for (var i = 0; i < ExPlayer.Players.Count; i++)
42+
foreach (var pair in __instance.netIdentity.observers)
4343
{
44-
var player = ExPlayer.Players[i];
45-
46-
if (player?.ReferenceHub == null || !player.Connection.isReady)
47-
continue;
48-
49-
if (__instance.netIdentity.connectionToClient != null && __instance.netIdentity.connectionToClient == player.Connection && !includeOwner)
50-
continue;
51-
52-
if (!__instance.netIdentity.observers.ContainsKey(player.ConnectionId))
53-
continue;
44+
if (ExPlayer.TryGet(pair.Value, out var player))
45+
{
46+
players.Add(player);
47+
}
48+
else
49+
{
50+
if (__instance.connectionToClient == pair.Value && !includeOwner)
51+
continue;
5452

55-
players.Add(player);
53+
connections.Add(pair.Value);
54+
}
5655
}
5756

58-
if (players.Count > 0)
57+
if (MirrorEvents.OnSendingRpc(__instance, functionFullName, functionHashCode, writer, connections, players, ref rpcMessage))
5958
{
60-
if (MirrorEvents.OnSendingRpc(__instance, functionFullName, functionHashCode, writer, players, ref rpcMessage)
61-
&& players.Count > 0)
62-
{
63-
using var writer2 = NetworkWriterPool.Get();
59+
using var writer2 = NetworkWriterPool.Get();
6460

65-
writer2.Write(rpcMessage);
61+
writer2.Write(rpcMessage);
6662

67-
var segment = writer2.ToArraySegment();
63+
players.ForEach(ply =>
64+
{
65+
if (ply.Connection.isReady)
66+
{
67+
ply.Connection.Send(rpcMessage, channelId);
68+
}
69+
});
6870

69-
players.ForEach(ply => ply.ConnectionToClient.Send(segment, channelId));
71+
connections.ForEach(conn =>
72+
{
73+
if (conn.isReady)
74+
{
75+
conn.Send(rpcMessage, channelId);
76+
}
77+
});
7078

71-
MirrorEvents.OnSentRpc(__instance, functionFullName, functionHashCode, writer, players, ref rpcMessage);
72-
}
79+
MirrorEvents.OnSentRpc(__instance, functionFullName, functionHashCode, writer, players, ref rpcMessage);
7380
}
7481

7582
ListPool<ExPlayer>.Shared.Return(players);
83+
ListPool<NetworkConnection>.Shared.Return(connections);
84+
7685
return false;
7786
}
7887

@@ -103,24 +112,21 @@ private static bool SendTargetRpcPrefix(NetworkBehaviour __instance, NetworkConn
103112
};
104113

105114
var players = ListPool<ExPlayer>.Shared.Rent();
115+
var connections = ListPool<NetworkConnection>.Shared.Rent();
106116

107117
players.Add(player);
118+
connections.Add(conn);
108119

109-
if (MirrorEvents.OnSendingRpc(__instance, functionFullName, functionHashCode, writer, players, ref rpcMessage)
110-
&& players.Count > 0)
120+
if (MirrorEvents.OnSendingRpc(__instance, functionFullName, functionHashCode, writer, connections, players, ref rpcMessage))
111121
{
112-
using var writer2 = NetworkWriterPool.Get();
113-
114-
writer2.Write(rpcMessage);
115-
116-
var segment = writer2.ToArraySegment();
117-
118-
player.ConnectionToClient.Send(segment, channelId);
122+
conn.Send(rpcMessage, channelId);
119123

120124
MirrorEvents.OnSentRpc(__instance, functionFullName, functionHashCode, writer, players, ref rpcMessage);
121125
}
122126

123127
ListPool<ExPlayer>.Shared.Return(players);
128+
ListPool<NetworkConnection>.Shared.Return(connections);
129+
124130
return false;
125131
}
126132
}

0 commit comments

Comments
 (0)