public static void Prefix(NetworkReader reader) { if (!DevTools.Instance.Config.LoggingNetworkMessages) { return; } var newreader = NetworkReaderPool.GetReader(reader.buffer); newreader.Position = reader.Position; if (!MessagePacking.Unpack(newreader, out var key)) { return; } if (NetworkServer.handlers.TryGetValue(key, out var networkMessageDelegate) && networkMessageDelegate.Method.DeclaringType.IsGenericType) { string methodName = networkMessageDelegate.Method.DeclaringType.GetGenericArguments()[0].Name; if (methodName == "CommandMessage") { return; } if (DevTools.Instance.Config.DisabledLoggingNetworkMessages.Contains(methodName)) { return; } Log.Debug($"[Receiving: {methodName}]"); } NetworkReaderPool.Recycle(newreader); }
public void ReadyMessageSetsClientReadyTest() { // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add connection LocalConnectionToClient connection = new LocalConnectionToClient(); connection.connectionToServer = new LocalConnectionToServer(); NetworkServer.AddConnection(connection); // set as authenticated, otherwise readymessage is rejected connection.isAuthenticated = true; // serialize a ready message into an arraysegment ReadyMessage message = new ReadyMessage(); NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(message, writer); ArraySegment <byte> segment = writer.ToArraySegment(); // call transport.OnDataReceived with the message // -> calls NetworkServer.OnClientReadyMessage // -> calls SetClientReady(conn) Transport.activeTransport.OnServerDataReceived.Invoke(0, segment, 0); // ready? Assert.That(connection.isReady, Is.True); }
public void SendToAllTest() { // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add connection LocalConnectionToClient connection = new LocalConnectionToClient(); connection.connectionToServer = new LocalConnectionToServer(); // set a client handler int called = 0; connection.connectionToServer.SetHandlers(new Dictionary <ushort, NetworkMessageDelegate>() { { MessagePacking.GetId <TestMessage1>(), ((conn, reader, channelId) => ++ called) } }); NetworkServer.AddConnection(connection); // create a message TestMessage1 message = new TestMessage1 { IntValue = 1, DoubleValue = 2, StringValue = "3" }; // send it to all NetworkServer.SendToAll(message); // update local connection once so that the incoming queue is processed connection.connectionToServer.Update(); // was it send to and handled by the connection? Assert.That(called, Is.EqualTo(1)); }
public void RegisterUnregisterClearHandlerTest() { // RegisterHandler(conn, msg) variant int variant1Called = 0; NetworkServer.RegisterHandler <TestMessage1>((conn, msg) => { ++variant1Called; }, false); // RegisterHandler(msg) variant int variant2Called = 0; NetworkServer.RegisterHandler <TestMessage2>(msg => { ++variant2Called; }, false); // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add a connection NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0); NetworkServer.AddConnection(connection); Assert.That(NetworkServer.connections.Count, Is.EqualTo(1)); // serialize first message, send it to server, check if it was handled NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(new TestMessage1(), writer); Transport.activeTransport.OnServerDataReceived.Invoke(42, writer.ToArraySegment(), 0); Assert.That(variant1Called, Is.EqualTo(1)); // serialize second message, send it to server, check if it was handled writer = new NetworkWriter(); MessagePacking.Pack(new TestMessage2(), writer); Transport.activeTransport.OnServerDataReceived.Invoke(42, writer.ToArraySegment(), 0); Assert.That(variant2Called, Is.EqualTo(1)); // unregister first handler, send, should fail NetworkServer.UnregisterHandler <TestMessage1>(); writer = new NetworkWriter(); MessagePacking.Pack(new TestMessage1(), writer); // log error messages are expected LogAssert.ignoreFailingMessages = true; Transport.activeTransport.OnServerDataReceived.Invoke(42, writer.ToArraySegment(), 0); LogAssert.ignoreFailingMessages = false; // still 1, not 2 Assert.That(variant1Called, Is.EqualTo(1)); // unregister second handler via ClearHandlers to test that one too. send, should fail NetworkServer.ClearHandlers(); // (only add this one to avoid disconnect error) writer = new NetworkWriter(); MessagePacking.Pack(new TestMessage1(), writer); // log error messages are expected LogAssert.ignoreFailingMessages = true; Transport.activeTransport.OnServerDataReceived.Invoke(42, writer.ToArraySegment(), 0); LogAssert.ignoreFailingMessages = false; // still 1, not 2 Assert.That(variant2Called, Is.EqualTo(1)); }
// helper function to pack message into a simple byte[] public static byte[] PackToByteArray <T>(T message) where T : struct, NetworkMessage { using (NetworkWriterPooled writer = NetworkWriterPool.Get()) { MessagePacking.Pack(message, writer); return(writer.ToArray()); } }
public void UnpackInvalidMessage() { // try an invalid message NetworkReader reader2 = new NetworkReader(new byte[0]); bool result2 = MessagePacking.Unpack(reader2, out ushort msgType2); Assert.That(result2, Is.EqualTo(false)); Assert.That(msgType2, Is.EqualTo(0)); }
public void MessageIdIsCorrectLength() { NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(new EmptyMessage(), writer); ArraySegment <byte> segment = writer.ToArraySegment(); Assert.That(segment.Count, Is.EqualTo(MessagePacking.HeaderSize), "Empty message should have same size as HeaderSize"); }
public void ShowForConnection() { // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add connection LocalConnectionToClient connection = new LocalConnectionToClient(); // required for ShowForConnection connection.isReady = true; connection.connectionToServer = new LocalConnectionToServer(); // set a client handler int called = 0; connection.connectionToServer.SetHandlers(new Dictionary <ushort, NetworkMessageDelegate>() { { MessagePacking.GetId <SpawnMessage>(), ((conn, reader, channelId) => ++ called) } }); NetworkServer.AddConnection(connection); // create a gameobject and networkidentity and some unique values NetworkIdentity identity = new GameObject().AddComponent <NetworkIdentity>(); identity.connectionToClient = connection; // call ShowForConnection NetworkServer.ShowForConnection(identity, connection); // update local connection once so that the incoming queue is processed connection.connectionToServer.Update(); // was it sent to and handled by the connection? Assert.That(called, Is.EqualTo(1)); // it shouldn't send it if connection isn't ready, so try that too connection.isReady = false; NetworkServer.ShowForConnection(identity, connection); connection.connectionToServer.Update(); // not 2 but 1 like before? Assert.That(called, Is.EqualTo(1)); // clean up NetworkServer.Shutdown(); // destroy GO after shutdown, otherwise isServer is true in OnDestroy and it tries to call // GameObject.Destroy (but we need DestroyImmediate in Editor) GameObject.DestroyImmediate(identity.gameObject); }
// unpack a message we received public static T UnpackFromByteArray <T>(byte[] data) where T : struct, NetworkMessage { using (NetworkReaderPooled networkReader = NetworkReaderPool.Get(data)) { int msgType = MessagePacking.GetId <T>(); int id = networkReader.ReadUShort(); if (id != msgType) { throw new FormatException($"Invalid message, could not unpack {typeof(T).FullName}"); } return(networkReader.Read <T>()); } }
public void TestUnpackMessageNonGeneric() { // try a regular message TestMessage message = new TestMessage() { IntValue = 42, StringValue = "Hello world" }; byte[] data = PackToByteArray(message); NetworkReader reader = new NetworkReader(data); bool result = MessagePacking.Unpack(reader, out ushort msgType); Assert.That(result, Is.EqualTo(true)); Assert.That(msgType, Is.EqualTo(BitConverter.ToUInt16(data, 0))); }
public void TestUnpackMessageNonGeneric() { // try a regular message SceneMessage message = new SceneMessage() { sceneName = "Hello world", sceneOperation = SceneOperation.LoadAdditive }; byte[] data = PackToByteArray(message); NetworkReader reader = new NetworkReader(data); bool result = MessagePacking.Unpack(reader, out ushort msgType); Assert.That(result, Is.EqualTo(true)); Assert.That(msgType, Is.EqualTo(BitConverter.ToUInt16(data, 0))); }
public void SendToClientOfPlayer() { // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add connection LocalConnectionToClient connection = new LocalConnectionToClient(); connection.connectionToServer = new LocalConnectionToServer(); // set a client handler int called = 0; connection.connectionToServer.SetHandlers(new Dictionary <ushort, NetworkMessageDelegate>() { { MessagePacking.GetId <TestMessage1>(), ((conn, reader, channelId) => ++ called) } }); NetworkServer.AddConnection(connection); // create a message TestMessage1 message = new TestMessage1 { IntValue = 1, DoubleValue = 2, StringValue = "3" }; // create a gameobject and networkidentity NetworkIdentity identity = new GameObject().AddComponent <NetworkIdentity>(); identity.connectionToClient = connection; // send it to that player identity.connectionToClient.Send(message); // update local connection once so that the incoming queue is processed connection.connectionToServer.Update(); // was it send to and handled by the connection? Assert.That(called, Is.EqualTo(1)); // clean up NetworkServer.Shutdown(); // destroy GO after shutdown, otherwise isServer is true in OnDestroy and it tries to call // GameObject.Destroy (but we need DestroyImmediate in Editor) GameObject.DestroyImmediate(identity.gameObject); }
public void OnDataReceivedTest() { // add one custom message handler bool wasReceived = false; NetworkConnection connectionReceived = null; TestMessage1 messageReceived = new TestMessage1(); NetworkServer.RegisterHandler <TestMessage1>((conn, msg) => { wasReceived = true; connectionReceived = conn; messageReceived = msg; }, false); // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add a connection NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0); NetworkServer.AddConnection(connection); Assert.That(NetworkServer.connections.Count, Is.EqualTo(1)); // serialize a test message into an arraysegment TestMessage1 testMessage = new TestMessage1 { IntValue = 13, DoubleValue = 14, StringValue = "15" }; NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(testMessage, writer); ArraySegment <byte> segment = writer.ToArraySegment(); // call transport.OnDataReceived // -> should call NetworkServer.OnDataReceived // -> conn.TransportReceive // -> Handler(CommandMessage) Transport.activeTransport.OnServerDataReceived.Invoke(42, segment, 0); // was our message handler called now? Assert.That(wasReceived, Is.True); Assert.That(connectionReceived, Is.EqualTo(connection)); Assert.That(messageReceived, Is.EqualTo(testMessage)); }
public void Send(NetworkMessage msg) { if (!IsConnected()) { return; } var writer = new CustomDataWriter(); var pack = new MessagePacking(); pack.Pack(msg, writer); lock (Sender) { if (Debug) { Logger.Log($"Send: ({msg.MessageID}) - " + msg.ToString().Split('.').Last(), LogMessageType.Arena); } Socket.Send(writer.Data); } }
public void ClientToServerTest() { Assert.That(connectionToServer.address, Is.EqualTo("localhost")); bool invoked = false; void Handler(NetworkConnection conn, NetworkReader reader, int channelId) { invoked = true; } Dictionary <ushort, NetworkMessageDelegate> handlers = new Dictionary <ushort, NetworkMessageDelegate>(); handlers.Add(MessagePacking.GetId <TestMessage>(), Handler); connectionToServer.SetHandlers(handlers); connectionToClient.Send(new TestMessage()); connectionToServer.Update(); Assert.True(invoked, "handler should have been invoked"); }
public void OnDataReceivedInvalidConnectionIdTest() { // add one custom message handler bool wasReceived = false; NetworkConnection connectionReceived = null; TestMessage1 messageReceived = new TestMessage1(); NetworkServer.RegisterHandler <TestMessage1>((conn, msg) => { wasReceived = true; connectionReceived = conn; messageReceived = msg; }, false); // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // serialize a test message into an arraysegment TestMessage1 testMessage = new TestMessage1 { IntValue = 13, DoubleValue = 14, StringValue = "15" }; NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(testMessage, writer); ArraySegment <byte> segment = writer.ToArraySegment(); // call transport.OnDataReceived with an invalid connectionId // an error log is expected. LogAssert.ignoreFailingMessages = true; Transport.activeTransport.OnServerDataReceived.Invoke(42, segment, 0); LogAssert.ignoreFailingMessages = false; // message handler should never be called Assert.That(wasReceived, Is.False); Assert.That(connectionReceived, Is.Null); }
public void GetId() { // "Mirror.Tests.MessageTests.TestMessage" Debug.Log(typeof(TestMessage).FullName); Assert.That(MessagePacking.GetId <TestMessage>(), Is.EqualTo(0x8706)); }
public void CommandMessageCallsCommandTest() { // listen NetworkServer.Listen(1); Assert.That(NetworkServer.connections.Count, Is.EqualTo(0)); // add connection LocalConnectionToClient connection = new LocalConnectionToClient(); connection.connectionToServer = new LocalConnectionToServer(); NetworkServer.AddConnection(connection); // set as authenticated, otherwise removeplayer is rejected connection.isAuthenticated = true; // add an identity with two networkbehaviour components GameObject go = new GameObject(); NetworkIdentity identity = go.AddComponent <NetworkIdentity>(); identity.netId = 42; // for authority check identity.connectionToClient = connection; CommandTestNetworkBehaviour comp0 = go.AddComponent <CommandTestNetworkBehaviour>(); Assert.That(comp0.called, Is.EqualTo(0)); CommandTestNetworkBehaviour comp1 = go.AddComponent <CommandTestNetworkBehaviour>(); Assert.That(comp1.called, Is.EqualTo(0)); connection.identity = identity; // register the command delegate, otherwise it's not found int registeredHash = RemoteCallHelper.RegisterDelegate(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated), MirrorInvokeType.Command, CommandTestNetworkBehaviour.CommandGenerated, true); // identity needs to be in spawned dict, otherwise command handler // won't find it NetworkIdentity.spawned[identity.netId] = identity; // serialize a removeplayer message into an arraysegment CommandMessage message = new CommandMessage { componentIndex = 0, functionHash = RemoteCallHelper.GetMethodHash(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated)), netId = identity.netId, payload = new ArraySegment <byte>(new byte[0]) }; NetworkWriter writer = new NetworkWriter(); MessagePacking.Pack(message, writer); ArraySegment <byte> segment = writer.ToArraySegment(); // call transport.OnDataReceived with the message // -> calls NetworkServer.OnRemovePlayerMessage // -> destroys conn.identity and sets it to null Transport.activeTransport.OnServerDataReceived.Invoke(0, segment, 0); // was the command called in the first component, not in the second one? Assert.That(comp0.called, Is.EqualTo(1)); Assert.That(comp1.called, Is.EqualTo(0)); // send another command for the second component comp0.called = 0; message.componentIndex = 1; writer = new NetworkWriter(); MessagePacking.Pack(message, writer); segment = writer.ToArraySegment(); Transport.activeTransport.OnServerDataReceived.Invoke(0, segment, 0); // was the command called in the second component, not in the first one? Assert.That(comp0.called, Is.EqualTo(0)); Assert.That(comp1.called, Is.EqualTo(1)); // sending a command without authority should fail // (= if connectionToClient is not what we received the data on) // set wrong authority identity.connectionToClient = new LocalConnectionToClient(); comp0.called = 0; comp1.called = 0; Transport.activeTransport.OnServerDataReceived.Invoke(0, segment, 0); Assert.That(comp0.called, Is.EqualTo(0)); Assert.That(comp1.called, Is.EqualTo(0)); // restore authority identity.connectionToClient = connection; // sending a component with wrong netId should fail // wrong netid message.netId += 1; writer = new NetworkWriter(); // need to serialize the message again with wrong netid MessagePacking.Pack(message, writer); ArraySegment <byte> segmentWrongNetId = writer.ToArraySegment(); comp0.called = 0; comp1.called = 0; Transport.activeTransport.OnServerDataReceived.Invoke(0, segmentWrongNetId, 0); Assert.That(comp0.called, Is.EqualTo(0)); Assert.That(comp1.called, Is.EqualTo(0)); // clean up NetworkIdentity.spawned.Clear(); RemoteCallHelper.RemoveDelegate(registeredHash); NetworkServer.Shutdown(); // destroy the test gameobject AFTER server was stopped. // otherwise isServer is true in OnDestroy, which means it would try // to call Destroy(go). but we need to use DestroyImmediate in // Editor GameObject.DestroyImmediate(go); }