Example #1
0
        public void RegisterDelegateDoesntOverwrite()
        {
            // registerdelegate is protected, but we can use
            // RegisterCommandDelegate which calls RegisterDelegate
            int registeredHash1 = RemoteCallHelper.RegisterDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                MirrorInvokeType.Command,
                NetworkBehaviourDelegateComponent.Delegate,
                false);

            // registering the exact same one should be fine. it should simply
            // do nothing.
            int registeredHash2 = RemoteCallHelper.RegisterDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                MirrorInvokeType.Command,
                NetworkBehaviourDelegateComponent.Delegate,
                false);

            // registering the same name with a different callback shouldn't
            // work
            LogAssert.Expect(LogType.Error, $"Function {typeof(NetworkBehaviourDelegateComponent)}.{nameof(NetworkBehaviourDelegateComponent.Delegate)} and {typeof(NetworkBehaviourDelegateComponent)}.{nameof(NetworkBehaviourDelegateComponent.Delegate2)} have the same hash.  Please rename one of them");
            int registeredHash3 = RemoteCallHelper.RegisterDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                MirrorInvokeType.Command,
                NetworkBehaviourDelegateComponent.Delegate2,
                false);

            // clean up
            RemoteCallHelper.RemoveDelegate(registeredHash1);
            RemoteCallHelper.RemoveDelegate(registeredHash2);
            RemoteCallHelper.RemoveDelegate(registeredHash3);
        }
Example #2
0
        public void GetDelegate()
        {
            // registerdelegate is protected, but we can use
            // RegisterCommandDelegate which calls RegisterDelegate
            int registeredHash = RemoteCallHelper.RegisterDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                MirrorInvokeType.Command,
                NetworkBehaviourDelegateComponent.Delegate,
                false);

            // get handler
            int         cmdHash  = RemoteCallHelper.GetMethodHash(typeof(NetworkBehaviourDelegateComponent), nameof(NetworkBehaviourDelegateComponent.Delegate));
            CmdDelegate func     = RemoteCallHelper.GetDelegate(cmdHash);
            CmdDelegate expected = NetworkBehaviourDelegateComponent.Delegate;

            Assert.That(func, Is.EqualTo(expected));

            // invalid hash should return null handler
            CmdDelegate funcNull = RemoteCallHelper.GetDelegate(1234);

            Assert.That(funcNull, Is.Null);

            // clean up
            RemoteCallHelper.RemoveDelegate(registeredHash);
        }
        public void HandleRpc()
        {
            CreateNetworked(out GameObject _, out NetworkIdentity identity, out RpcTestNetworkBehaviour comp0);

            // register the command delegate, otherwise it's not found
            int registeredHash = RemoteCallHelper.RegisterDelegate(typeof(RpcTestNetworkBehaviour),
                                                                   nameof(RpcTestNetworkBehaviour.RpcGenerated),
                                                                   MirrorInvokeType.ClientRpc,
                                                                   RpcTestNetworkBehaviour.RpcGenerated);

            // identity needs to be in spawned dict, otherwise command handler
            // won't find it
            NetworkIdentity.spawned[identity.netId] = identity;

            // call HandleRpc and check if the rpc was called in the component
            int           functionHash = RemoteCallHelper.GetMethodHash(typeof(RpcTestNetworkBehaviour), nameof(RpcTestNetworkBehaviour.RpcGenerated));
            NetworkReader payload      = new NetworkReader(new byte[0]);

            identity.HandleRemoteCall(0, functionHash, MirrorInvokeType.ClientRpc, payload);
            Assert.That(comp0.called, Is.EqualTo(1));

            // try wrong component index. rpc shouldn't be called again.
            // warning is expected
            LogAssert.ignoreFailingMessages = true;
            identity.HandleRemoteCall(1, functionHash, MirrorInvokeType.ClientRpc, payload);
            LogAssert.ignoreFailingMessages = false;
            Assert.That(comp0.called, Is.EqualTo(1));

            // try wrong function hash. rpc shouldn't be called again.
            // warning is expected
            LogAssert.ignoreFailingMessages = true;
            identity.HandleRemoteCall(0, functionHash + 1, MirrorInvokeType.ClientRpc, payload);
            LogAssert.ignoreFailingMessages = false;
            Assert.That(comp0.called, Is.EqualTo(1));

            // clean up
            RemoteCallHelper.RemoveDelegate(registeredHash);
        }
Example #4
0
        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);
        }