Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Assets/Mirror/Editor/Weaver/Processors/CommandProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
ParameterDefinition param = md.Parameters[i];
if (NetworkBehaviourProcessor.IsSenderConnection(param, RemoteCallType.Command))
{
// load 'this.'
worker.Emit(OpCodes.Ldarg_0);
// call get_connectionToClient
worker.Emit(OpCodes.Call, weaverTypes.NetworkBehaviourConnectionToClientReference);
// Server-owned object => no owner connection (connectionToClient is null).
// Host calling [Command] should use NetworkServer.localConnection as sender.
// Load NetworkServer.localConnection
worker.Emit(OpCodes.Call, weaverTypes.NetworkServerLocalConnectionReference);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions Assets/Mirror/Editor/Weaver/WeaverTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class WeaverTypes
public MethodReference GetWriterReference;
public MethodReference ReturnWriterReference;

public MethodReference NetworkServerLocalConnectionReference;
public MethodReference NetworkClientConnectionReference;

public MethodReference RemoteCallDelegateConstructor;
Expand Down Expand Up @@ -86,6 +87,7 @@ public WeaverTypes(AssemblyDefinition assembly, Logger Log, ref bool WeavingFail

TypeReference NetworkServerType = Import(typeof(NetworkServer));
NetworkServerGetActive = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_active", ref WeavingFailed);
NetworkServerLocalConnectionReference = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_localConnection", ref WeavingFailed);

TypeReference NetworkClientType = Import(typeof(NetworkClient));
NetworkClientGetActive = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_active", ref WeavingFailed);
Expand Down
30 changes: 27 additions & 3 deletions Assets/Mirror/Tests/Editor/NetworkServer/NetworkServerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -851,10 +851,9 @@ public void SendCommand_RequiresAuthority()
Assert.That(serverComponent.called, Is.EqualTo(0));
}

// [Command] with NetworkConnectionToClient parameter on host should be automatically set to .connectionToClient.
// this is what happens in server-only mode too.
// Command with NetworkConnectionToClient arg expects a non-null connection arg when called on the client owned object.
[Test]
public void SendCommand_ConnectionToClient_HostMode()
public void SendCommand_ClientOwnedObject_ConnectionNotNull()
{
// listen & connect
NetworkServer.Listen(1);
Expand All @@ -871,10 +870,35 @@ public void SendCommand_ConnectionToClient_HostMode()

// on server it should be != null
Assert.That(comp.conn, !Is.Null);
// Host player-owned object: sender == connectionToClient (host's localConnection).
Assert.That(comp.conn, Is.EqualTo(comp.connectionToClient));
Assert.That(comp.called, Is.EqualTo(1));
}

// Command with NetworkConnectionToClient arg expects a non-null connection arg when called on the server owned object.
[Test]
public void SendCommand_ServerOwnedObject_ConnectionNotNull()
{
// listen & connect
NetworkServer.Listen(1);
ConnectHostClientBlockingAuthenticatedAndReady();

// add an identity with two networkbehaviour components
// spawned, otherwise command handler won't find it in .spawned.
// WITHOUT OWNER (SERVER-OWNED OBJECT)
CreateNetworkedAndSpawn(out GameObject _, out NetworkIdentity _, out CommandWithConnectionToClientNetworkBehaviour comp, ownerConnection: null);

// call the command, which has a 'NetworkConnectionToClient = null' default parameter
comp.TestCommand();
ProcessMessages();

// on server it should be != null
Assert.That(comp.conn, !Is.Null);
// Host mode + server-owned object: connectionToClient is null, so sender must be localConnection.
Assert.That(comp.conn, Is.EqualTo(NetworkServer.localConnection));
Assert.That(comp.called, Is.EqualTo(1));
}

[Test]
public void SendToAll()
{
Expand Down