Skip to content

Commit 0b56a49

Browse files
author
vis2k
committed
cmds on sv
1 parent 19f23cb commit 0b56a49

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ public static class CommandProcessor
1010
// generates code like:
1111
public void CmdThrust(float thrusting, int spin)
1212
{
13+
// on server-only, allow calling the original function directly.
14+
if (isServer && !isClient)
15+
{
16+
UserCode_CmdThrust(value);
17+
return;
18+
}
19+
20+
// otherwise send a command message over the network
1321
NetworkWriterPooled writer = NetworkWriterPool.Get();
1422
writer.Write(thrusting);
1523
writer.WritePackedUInt32((uint)spin);
@@ -38,6 +46,32 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
3846

3947
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
4048

49+
Instruction skipIfNotServerOnly = worker.Create(OpCodes.Nop);
50+
51+
// Check if isServer && !isClient
52+
// worker.Emit(OpCodes.Ldarg_0); // loads this. for isClient check later
53+
worker.Emit(OpCodes.Call, weaverTypes.NetworkServerGetActive); // TODO isServer?
54+
worker.Emit(OpCodes.Brfalse, skipIfNotServerOnly);
55+
56+
// worker.Emit(OpCodes.Ldarg_0); // loads this. for isClient check later
57+
worker.Emit(OpCodes.Call, weaverTypes.NetworkClientGetActive); // TODO isClient?
58+
worker.Emit(OpCodes.Brtrue, skipIfNotServerOnly);
59+
60+
// Load 'this' reference (Ldarg_0)
61+
worker.Emit(OpCodes.Ldarg_0);
62+
63+
// Load all the remaining arguments (Ldarg_1, Ldarg_2, ...)
64+
for (int i = 1; i < md.Parameters.Count + 1; i++)
65+
worker.Emit(OpCodes.Ldarg, i);
66+
67+
// Call the original function directly (UserCode_CmdTest__Int32)
68+
worker.Emit(OpCodes.Call, cmd);
69+
worker.Emit(OpCodes.Ret);
70+
71+
worker.Append(skipIfNotServerOnly);
72+
73+
74+
4175
// NetworkWriter writer = new NetworkWriter();
4276
NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
4377

Assets/Mirror/Tests/Editor/Rpcs/CommandTest.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ namespace Mirror.Tests.Rpcs
99
class AuthorityBehaviour : NetworkBehaviour
1010
{
1111
public event Action<int> onSendInt;
12+
public event Action<int, string, bool> onSendMulti;
1213

1314
[Command]
1415
public void SendInt(int someInt) =>
1516
onSendInt?.Invoke(someInt);
17+
18+
[Command]
19+
public void SendMulti(int someInt, string someString, bool someBool) =>
20+
onSendMulti?.Invoke(someInt, someString, someBool);
1621
}
1722

1823
class IgnoreAuthorityBehaviour : NetworkBehaviour
@@ -278,4 +283,48 @@ public void Command_RequiresAuthorityFalse_ForOtherObjectWithoutConnectionToServ
278283
Assert.That(called, Is.EqualTo(1));
279284
}
280285
}
286+
287+
// need server-only mode for some test
288+
public class CommandTest_ServerOnly : MirrorTest
289+
{
290+
[SetUp]
291+
public override void SetUp()
292+
{
293+
base.SetUp();
294+
// start server without client
295+
NetworkServer.Listen(1);
296+
}
297+
298+
[TearDown]
299+
public override void TearDown() => base.TearDown();
300+
301+
// [Command] functions should be callable on server-only for convenience.
302+
// https://github.com/MirrorNetworking/Mirror/issues/3450
303+
[Test]
304+
public void CommandCalledWhenServerOnly()
305+
{
306+
// spawn
307+
CreateNetworked(out _, out _, out AuthorityBehaviour serverComponent);
308+
309+
// set up a callback and check
310+
int callCount = 0;
311+
serverComponent.onSendMulti += (a, b, c) =>
312+
{
313+
callCount++;
314+
Assert.That(a, Is.EqualTo(42));
315+
Assert.That(b, Is.EqualTo("test"));
316+
Assert.That(c, Is.EqualTo(true));
317+
};
318+
319+
// call [Command] on server.
320+
// test multiple parameters to ensure weaver properly injects all
321+
// LdArg0,1,2, etc. instructions.
322+
//
323+
// this should call the function immediately,
324+
// without processing messages.
325+
serverComponent.SendMulti(42, "test", true);
326+
// ProcessMessages();
327+
Assert.That(callCount, Is.EqualTo(1));
328+
}
329+
}
281330
}

0 commit comments

Comments
 (0)