281 lines
9.8 KiB
C#
281 lines
9.8 KiB
C#
using System;
|
|
using System.Text.RegularExpressions;
|
|
using NUnit.Framework;
|
|
using UnityEngine;
|
|
using UnityEngine.TestTools;
|
|
|
|
namespace Mirror.Tests.RemoteAttrributeTest
|
|
{
|
|
class AuthorityBehaviour : NetworkBehaviour
|
|
{
|
|
public event Action<int> onSendInt;
|
|
|
|
[Command]
|
|
public void SendInt(int someInt) =>
|
|
onSendInt?.Invoke(someInt);
|
|
}
|
|
|
|
class IgnoreAuthorityBehaviour : NetworkBehaviour
|
|
{
|
|
public event Action<int> onSendInt;
|
|
|
|
[Command(requiresAuthority = false)]
|
|
public void CmdSendInt(int someInt) =>
|
|
onSendInt?.Invoke(someInt);
|
|
}
|
|
|
|
class SenderConnectionBehaviour : NetworkBehaviour
|
|
{
|
|
public event Action<int, NetworkConnection> onSendInt;
|
|
|
|
[Command]
|
|
public void CmdSendInt(int someInt, NetworkConnectionToClient conn = null) =>
|
|
onSendInt?.Invoke(someInt, conn);
|
|
}
|
|
|
|
class SenderConnectionIgnoreAuthorityBehaviour : NetworkBehaviour
|
|
{
|
|
public event Action<int, NetworkConnection> onSendInt;
|
|
|
|
[Command(requiresAuthority = false)]
|
|
public void CmdSendInt(int someInt, NetworkConnectionToClient conn = null) =>
|
|
onSendInt?.Invoke(someInt, conn);
|
|
}
|
|
|
|
class ThrowBehaviour : NetworkBehaviour
|
|
{
|
|
public const string ErrorMessage = "Bad things happened";
|
|
|
|
[Command]
|
|
public void SendThrow(int _) => throw new Exception(ErrorMessage);
|
|
}
|
|
|
|
class CommandOverloads : NetworkBehaviour
|
|
{
|
|
public int firstCalled = 0;
|
|
public int secondCalled = 0;
|
|
|
|
[Command]
|
|
public void TheCommand(int _) => ++firstCalled;
|
|
|
|
[Command]
|
|
public void TheCommand(string _) => ++secondCalled;
|
|
}
|
|
|
|
public class CommandTest : MirrorTest
|
|
{
|
|
NetworkConnectionToClient connectionToClient;
|
|
|
|
[SetUp]
|
|
public override void SetUp()
|
|
{
|
|
base.SetUp();
|
|
// start server/client
|
|
NetworkServer.Listen(1);
|
|
ConnectClientBlockingAuthenticatedAndReady(out connectionToClient);
|
|
}
|
|
|
|
[TearDown]
|
|
public override void TearDown() => base.TearDown();
|
|
|
|
[Test]
|
|
public void CommandIsSentWithAuthority()
|
|
{
|
|
// spawn with owner
|
|
CreateNetworkedAndSpawn(out _, out _, out AuthorityBehaviour serverComponent,
|
|
out _, out _, out AuthorityBehaviour clientComponent,
|
|
connectionToClient);
|
|
|
|
const int someInt = 20;
|
|
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += incomingInt =>
|
|
{
|
|
callCount++;
|
|
Assert.That(incomingInt, Is.EqualTo(someInt));
|
|
};
|
|
clientComponent.SendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void WarningForCommandSentWithoutAuthority()
|
|
{
|
|
// spawn without owner
|
|
CreateNetworkedAndSpawn(out _, out _, out AuthorityBehaviour serverComponent,
|
|
out _, out _, out AuthorityBehaviour clientComponent);
|
|
|
|
const int someInt = 20;
|
|
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += incomingInt =>
|
|
{
|
|
callCount++;
|
|
};
|
|
LogAssert.Expect(LogType.Warning, $"Trying to send command for object without authority. System.Void Mirror.Tests.RemoteAttrributeTest.AuthorityBehaviour::SendInt(System.Int32)");
|
|
clientComponent.SendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.Zero);
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void CommandIsSentWithAuthorityWhenIgnoringAuthority()
|
|
{
|
|
// spawn with owner
|
|
CreateNetworkedAndSpawn(out _, out _, out IgnoreAuthorityBehaviour serverComponent,
|
|
out _, out _, out IgnoreAuthorityBehaviour clientComponent,
|
|
connectionToClient);
|
|
|
|
const int someInt = 20;
|
|
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += incomingInt =>
|
|
{
|
|
callCount++;
|
|
Assert.That(incomingInt, Is.EqualTo(someInt));
|
|
};
|
|
clientComponent.CmdSendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void CommandIsSentWithoutAuthorityWhenIgnoringAuthority()
|
|
{
|
|
// spawn without owner
|
|
CreateNetworkedAndSpawn(out _, out _, out IgnoreAuthorityBehaviour serverComponent,
|
|
out _, out _, out IgnoreAuthorityBehaviour clientComponent);
|
|
|
|
const int someInt = 20;
|
|
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += incomingInt =>
|
|
{
|
|
callCount++;
|
|
Assert.That(incomingInt, Is.EqualTo(someInt));
|
|
};
|
|
clientComponent.CmdSendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void SenderConnectionIsSetWhenCommandIsRecieved()
|
|
{
|
|
// spawn with owner
|
|
CreateNetworkedAndSpawn(out _, out _, out SenderConnectionBehaviour serverComponent,
|
|
out _, out _, out SenderConnectionBehaviour clientComponent,
|
|
connectionToClient);
|
|
|
|
const int someInt = 20;
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += (incomingInt, incomingConn) =>
|
|
{
|
|
callCount++;
|
|
Assert.That(incomingInt, Is.EqualTo(someInt));
|
|
Assert.That(incomingConn, Is.EqualTo(connectionToClient));
|
|
};
|
|
clientComponent.CmdSendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void SenderConnectionIsSetWhenCommandIsRecievedWithIgnoreAuthority()
|
|
{
|
|
// spawn without owner
|
|
CreateNetworkedAndSpawn(out _, out _, out SenderConnectionIgnoreAuthorityBehaviour serverComponent,
|
|
out _, out _, out SenderConnectionIgnoreAuthorityBehaviour clientComponent);
|
|
|
|
const int someInt = 20;
|
|
int callCount = 0;
|
|
serverComponent.onSendInt += (incomingInt, incomingConn) =>
|
|
{
|
|
callCount++;
|
|
Assert.That(incomingInt, Is.EqualTo(someInt));
|
|
Assert.That(incomingConn, Is.EqualTo(connectionToClient));
|
|
};
|
|
clientComponent.CmdSendInt(someInt);
|
|
ProcessMessages();
|
|
Assert.That(callCount, Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void CommandThatThrowsShouldBeCaught()
|
|
{
|
|
// spawn with owner
|
|
CreateNetworkedAndSpawn(out _, out _, out ThrowBehaviour serverComponent,
|
|
out _, out _, out ThrowBehaviour clientComponent,
|
|
connectionToClient);
|
|
|
|
const int someInt = 20;
|
|
LogAssert.Expect(LogType.Error, new Regex($".*{ThrowBehaviour.ErrorMessage}.*"));
|
|
Assert.DoesNotThrow(() =>
|
|
{
|
|
clientComponent.SendThrow(someInt);
|
|
ProcessMessages();
|
|
}, "Processing new message should not throw, the exception from SendThrow should be caught");
|
|
}
|
|
|
|
// RemoteCalls uses md.FullName which gives us the full command/rpc name
|
|
// like "System.Void Mirror.Tests.RemoteAttrributeTest.AuthorityBehaviour::SendInt(System.Int32)"
|
|
// which means overloads with same name but different types should work.
|
|
[Test]
|
|
public void CommandOverloads()
|
|
{
|
|
// spawn with owner
|
|
CreateNetworkedAndSpawn(out _, out _, out CommandOverloads serverComponent,
|
|
out _, out _, out CommandOverloads clientComponent,
|
|
connectionToClient);
|
|
|
|
// call both overloads once
|
|
clientComponent.TheCommand(42);
|
|
clientComponent.TheCommand("A");
|
|
ProcessMessages();
|
|
Assert.That(serverComponent.firstCalled, Is.EqualTo(1));
|
|
Assert.That(serverComponent.secondCalled, Is.EqualTo(1));
|
|
}
|
|
}
|
|
|
|
// need host mode for this one test
|
|
public class CommandTest_HostMode : MirrorTest
|
|
{
|
|
[SetUp]
|
|
public override void SetUp()
|
|
{
|
|
base.SetUp();
|
|
// start server/client
|
|
NetworkServer.Listen(1);
|
|
ConnectHostClientBlockingAuthenticatedAndReady();
|
|
}
|
|
|
|
[TearDown]
|
|
public override void TearDown() => base.TearDown();
|
|
|
|
// test to prevent https://github.com/vis2k/Mirror/issues/2629
|
|
// from happening again in the future
|
|
// -> [Command]s can be called on other objects with requiresAuthority=false.
|
|
// -> those objects don't have a .connectionToServer
|
|
// -> we broke it when using .connectionToServer instead of
|
|
// NetworkClient.connection in SendCommandInternal.
|
|
[Test]
|
|
public void Command_RequiresAuthorityFalse_ForOtherObjectWithoutConnectionToServer()
|
|
{
|
|
// spawn without owner (= without connectionToClient)
|
|
CreateNetworkedAndSpawn(out _, out _, out IgnoreAuthorityBehaviour comp);
|
|
|
|
// setup callback
|
|
int called = 0;
|
|
comp.onSendInt += _ => { ++called; };
|
|
|
|
// call command. don't require authority.
|
|
// the object doesn't have a .connectionToServer (like a scene object)
|
|
Assert.That(comp.connectionToServer, Is.Null);
|
|
comp.CmdSendInt(0);
|
|
Assert.That(called, Is.EqualTo(1));
|
|
}
|
|
}
|
|
}
|