Compare commits

...

2 Commits

Author SHA1 Message Date
mischa
c78d78ceca
Merge 0b56a49a5f into e7b3aa77df 2024-10-31 17:30:11 +05:00
vis2k
0b56a49a5f cmds on sv 2024-07-16 14:12:33 +02:00
2 changed files with 83 additions and 0 deletions

View File

@ -10,6 +10,14 @@ public static class CommandProcessor
// generates code like:
public void CmdThrust(float thrusting, int spin)
{
// on server-only, allow calling the original function directly.
if (isServer && !isClient)
{
UserCode_CmdThrust(value);
return;
}
// otherwise send a command message over the network
NetworkWriterPooled writer = NetworkWriterPool.Get();
writer.Write(thrusting);
writer.WritePackedUInt32((uint)spin);
@ -38,6 +46,32 @@ public static MethodDefinition ProcessCommandCall(WeaverTypes weaverTypes, Write
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
Instruction skipIfNotServerOnly = worker.Create(OpCodes.Nop);
// Check if isServer && !isClient
// worker.Emit(OpCodes.Ldarg_0); // loads this. for isClient check later
worker.Emit(OpCodes.Call, weaverTypes.NetworkServerGetActive); // TODO isServer?
worker.Emit(OpCodes.Brfalse, skipIfNotServerOnly);
// worker.Emit(OpCodes.Ldarg_0); // loads this. for isClient check later
worker.Emit(OpCodes.Call, weaverTypes.NetworkClientGetActive); // TODO isClient?
worker.Emit(OpCodes.Brtrue, skipIfNotServerOnly);
// Load 'this' reference (Ldarg_0)
worker.Emit(OpCodes.Ldarg_0);
// Load all the remaining arguments (Ldarg_1, Ldarg_2, ...)
for (int i = 1; i < md.Parameters.Count + 1; i++)
worker.Emit(OpCodes.Ldarg, i);
// Call the original function directly (UserCode_CmdTest__Int32)
worker.Emit(OpCodes.Call, cmd);
worker.Emit(OpCodes.Ret);
worker.Append(skipIfNotServerOnly);
// NetworkWriter writer = new NetworkWriter();
NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);

View File

@ -9,10 +9,15 @@ namespace Mirror.Tests.Rpcs
class AuthorityBehaviour : NetworkBehaviour
{
public event Action<int> onSendInt;
public event Action<int, string, bool> onSendMulti;
[Command]
public void SendInt(int someInt) =>
onSendInt?.Invoke(someInt);
[Command]
public void SendMulti(int someInt, string someString, bool someBool) =>
onSendMulti?.Invoke(someInt, someString, someBool);
}
class IgnoreAuthorityBehaviour : NetworkBehaviour
@ -278,4 +283,48 @@ public void Command_RequiresAuthorityFalse_ForOtherObjectWithoutConnectionToServ
Assert.That(called, Is.EqualTo(1));
}
}
// need server-only mode for some test
public class CommandTest_ServerOnly : MirrorTest
{
[SetUp]
public override void SetUp()
{
base.SetUp();
// start server without client
NetworkServer.Listen(1);
}
[TearDown]
public override void TearDown() => base.TearDown();
// [Command] functions should be callable on server-only for convenience.
// https://github.com/MirrorNetworking/Mirror/issues/3450
[Test]
public void CommandCalledWhenServerOnly()
{
// spawn
CreateNetworked(out _, out _, out AuthorityBehaviour serverComponent);
// set up a callback and check
int callCount = 0;
serverComponent.onSendMulti += (a, b, c) =>
{
callCount++;
Assert.That(a, Is.EqualTo(42));
Assert.That(b, Is.EqualTo("test"));
Assert.That(c, Is.EqualTo(true));
};
// call [Command] on server.
// test multiple parameters to ensure weaver properly injects all
// LdArg0,1,2, etc. instructions.
//
// this should call the function immediately,
// without processing messages.
serverComponent.SendMulti(42, "test", true);
// ProcessMessages();
Assert.That(callCount, Is.EqualTo(1));
}
}
}