Skip to content

Commit 6a8548d

Browse files
authored
fix: #4058 [Command] on host now populates NetworkConnectionToClient automatically (#4063)
1 parent 51a5980 commit 6a8548d

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

Assets/Mirror/Editor/Weaver/Processors/CommandProcessor.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,22 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
8585

8686
// Load all the remaining arguments (Ldarg_1, Ldarg_2, ...)
8787
for (int i = 0; i < md.Parameters.Count; i++)
88-
worker.Emit(OpCodes.Ldarg, i + 1); // Ldarg_0 is for 'this.'
88+
{
89+
// special case: NetworkConnection parameter in command needs to be
90+
// filled by the sender's connection on server/host.
91+
ParameterDefinition param = md.Parameters[i];
92+
if (NetworkBehaviourProcessor.IsSenderConnection(param, RemoteCallType.Command))
93+
{
94+
// load 'this.'
95+
worker.Emit(OpCodes.Ldarg_0);
96+
// call get_connectionToClient
97+
worker.Emit(OpCodes.Call, weaverTypes.NetworkBehaviourConnectionToClientReference);
98+
}
99+
else
100+
{
101+
worker.Emit(OpCodes.Ldarg, i + 1); // Ldarg_0 is for 'this.'
102+
}
103+
}
89104

90105
// Call the original function directly (UserCode_CmdTest__Int32)
91106
worker.Emit(OpCodes.Call, cmd);

Assets/Mirror/Editor/Weaver/WeaverTypes.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class WeaverTypes
1313
public MethodReference NetworkBehaviourIsClientReference;
1414
public MethodReference NetworkBehaviourIsServerReference;
1515
public FieldReference NetworkBehaviourDirtyBitsReference;
16+
public MethodReference NetworkBehaviourConnectionToClientReference;
1617
public MethodReference GetWriterReference;
1718
public MethodReference ReturnWriterReference;
1819

@@ -97,6 +98,8 @@ public WeaverTypes(AssemblyDefinition assembly, Logger Log, ref bool WeavingFail
9798

9899
NetworkBehaviourDirtyBitsReference = Resolvers.ResolveField(NetworkBehaviourType, assembly, Log, "syncVarDirtyBits", ref WeavingFailed);
99100

101+
NetworkBehaviourConnectionToClientReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "get_connectionToClient", ref WeavingFailed);
102+
100103
generatedSyncVarSetter = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter", ref WeavingFailed);
101104
generatedSyncVarSetter_GameObject = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_GameObject", ref WeavingFailed);
102105
generatedSyncVarSetter_NetworkIdentity = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_NetworkIdentity", ref WeavingFailed);

Assets/Mirror/Tests/Editor/NetworkServer/NetworkServerTest.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ public class CommandTestNetworkBehaviour : NetworkBehaviour
3535
public void TestCommand() => ++called;
3636
}
3737

38+
public class CommandWithConnectionToClientNetworkBehaviour : NetworkBehaviour
39+
{
40+
// counter to make sure that it's called exactly once
41+
public int called;
42+
public NetworkConnectionToClient conn;
43+
44+
[Command]
45+
public void TestCommand(NetworkConnectionToClient conn = null)
46+
{
47+
this.conn = conn;
48+
++called;
49+
}
50+
}
51+
3852
public class RpcTestNetworkBehaviour : NetworkBehaviour
3953
{
4054
// counter to make sure that it's called exactly once
@@ -837,6 +851,30 @@ public void SendCommand_RequiresAuthority()
837851
Assert.That(serverComponent.called, Is.EqualTo(0));
838852
}
839853

854+
// [Command] with NetworkConnectionToClient parameter on host should be automatically set to .connectionToClient.
855+
// this is what happens in server-only mode too.
856+
[Test]
857+
public void SendCommand_ConnectionToClient_HostMode()
858+
{
859+
// listen & connect
860+
NetworkServer.Listen(1);
861+
ConnectHostClientBlockingAuthenticatedAndReady();
862+
863+
// add an identity with two networkbehaviour components
864+
// spawned, otherwise command handler won't find it in .spawned.
865+
// WITH OWNER = WITH AUTHORITY
866+
CreateNetworkedAndSpawn(out GameObject _, out NetworkIdentity _, out CommandWithConnectionToClientNetworkBehaviour comp, NetworkServer.localConnection);
867+
868+
// call the command, which has a 'NetworkConnectionToClient = null' default parameter
869+
comp.TestCommand();
870+
ProcessMessages();
871+
872+
// on server it should be != null
873+
Assert.That(comp.conn, !Is.Null);
874+
Assert.That(comp.conn, Is.EqualTo(comp.connectionToClient));
875+
Assert.That(comp.called, Is.EqualTo(1));
876+
}
877+
840878
[Test]
841879
public void SendToAll()
842880
{

0 commit comments

Comments
 (0)