Skip to content

Commit e988d10

Browse files
author
vis2k
committed
cmds on sv
1 parent 20b7e53 commit e988d10

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/CommandTest.cs

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

0 commit comments

Comments
 (0)