예제 #1
0
        public void RegisterDelegateDoesntOverwrite()
        {
            // registerdelegate is protected, but we can use
            // RegisterCommandDelegate which calls RegisterDelegate
            NetworkBehaviour.RegisterCommandDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                NetworkBehaviourDelegateComponent.Delegate);

            // registering the exact same one should be fine. it should simply
            // do nothing.
            NetworkBehaviour.RegisterCommandDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                NetworkBehaviourDelegateComponent.Delegate);

            // 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");
            NetworkBehaviour.RegisterCommandDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                NetworkBehaviourDelegateComponent.Delegate2);

            // clean up
            NetworkBehaviour.ClearDelegates();
        }
예제 #2
0
        public void GetDelegate()
        {
            // registerdelegate is protected, but we can use
            // RegisterCommandDelegate which calls RegisterDelegate
            NetworkBehaviour.RegisterCommandDelegate(
                typeof(NetworkBehaviourDelegateComponent),
                nameof(NetworkBehaviourDelegateComponent.Delegate),
                NetworkBehaviourDelegateComponent.Delegate);

            // get handler
            int cmdHash = NetworkBehaviour.GetMethodHash(typeof(NetworkBehaviourDelegateComponent), nameof(NetworkBehaviourDelegateComponent.Delegate));

            NetworkBehaviour.CmdDelegate func     = NetworkBehaviour.GetDelegate(cmdHash);
            NetworkBehaviour.CmdDelegate expected = NetworkBehaviourDelegateComponent.Delegate;
            Assert.That(func, Is.EqualTo(expected));

            // invalid hash should return null handler
            NetworkBehaviour.CmdDelegate funcNull = NetworkBehaviour.GetDelegate(1234);
            Assert.That(funcNull, Is.Null);

            // clean up
            NetworkBehaviour.ClearDelegates();
        }
예제 #3
0
        public void CommandMessageCallsCommandTest()
        {
            // listen
            NetworkServer.Listen(1);
            Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));

            // add connection
            ULocalConnectionToClient connection = new ULocalConnectionToClient();

            connection.connectionToServer = new ULocalConnectionToServer();
            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
            NetworkBehaviour.RegisterCommandDelegate(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated), CommandTestNetworkBehaviour.CommandGenerated);

            // 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   = NetworkBehaviour.GetMethodHash(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated)),
                netId          = identity.netId,
                payload        = new ArraySegment <byte>(new byte[0])
            };
            NetworkWriter writer = new NetworkWriter();

            MessagePacker.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();
            MessagePacker.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 ULocalConnectionToClient();
            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
            MessagePacker.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
            NetworkBehaviour.ClearDelegates();
            NetworkIdentity.spawned.Clear();
            NetworkBehaviour.ClearDelegates();
            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);
        }