Beispiel #1
0
        /// <summary>
        /// Send fake values to client's <see cref="Mirror.SyncVarAttribute"/>.
        /// </summary>
        /// <param name="target">Target to send.</param>
        /// <param name="behaviorOwner"><see cref="Mirror.NetworkIdentity"/> of object that owns <see cref="Mirror.NetworkBehaviour"/>.</param>
        /// <param name="targetType"><see cref="Mirror.NetworkBehaviour"/>'s type.</param>
        /// <param name="propertyName">Property name starting with Network.</param>
        /// <param name="value">Value of send to target.</param>
        public static void SendFakeSyncVar(this Player target, NetworkIdentity behaviorOwner, Type targetType, string propertyName, object value)
        {
            Action <NetworkWriter> customSyncVarGenerator = (targetWriter) =>
            {
                targetWriter.WritePackedUInt64(SyncVarDirtyBits[$"{targetType.Name}.{propertyName}"]);
                WriterExtensions[value.GetType()]?.Invoke(null, new object[] { targetWriter, value });
            };

            NetworkWriter writer  = NetworkWriterPool.GetWriter();
            NetworkWriter writer2 = NetworkWriterPool.GetWriter();

            MakeCustomSyncWriter(behaviorOwner, targetType, null, customSyncVarGenerator, writer, writer2);
            NetworkServer.SendToClientOfPlayer(target.ReferenceHub.networkIdentity, new UpdateVarsMessage()
            {
                netId = behaviorOwner.netId, payload = writer.ToArraySegment()
            });
            NetworkWriterPool.Recycle(writer);
            NetworkWriterPool.Recycle(writer2);
        }
        public void TestAccessingCustomWriterAndReader()
        {
            var data = new MyType
            {
                id   = 10,
                name = "Yo Gaba Gaba"
            };
            var writer = new NetworkWriter(1300);

            writer.Write(data);
            var reader = new NetworkReader();

            reader.Reset(writer.ToArraySegment());
            MyType copy = reader.Read <MyType>();

            Assert.That(copy, Is.EqualTo(data));

            reader.Dispose();
        }
Beispiel #3
0
        public static UniTask <T> SendWithReturn <T>(NetworkBehaviour behaviour, int index, NetworkWriter writer, int channelId, bool requireAuthority)
        {
            Validate(behaviour, index, requireAuthority);
            var message = new ServerRpcWithReplyMessage
            {
                netId          = behaviour.NetId,
                componentIndex = behaviour.ComponentIndex,
                functionIndex  = index,
                payload        = writer.ToArraySegment()
            };

            (var task, var id) = behaviour.ClientObjectManager.CreateReplyTask <T>();

            message.replyId = id;

            behaviour.Client.Send(message, channelId);

            return(task);
        }
Beispiel #4
0
        public void OnDataReceivedInvalidConnectionIdTest()
        {
            // message handlers
            NetworkServer.RegisterHandler <ConnectMessage>((conn, msg) => { }, false);
            NetworkServer.RegisterHandler <DisconnectMessage>((conn, msg) => { }, false);
            NetworkServer.RegisterHandler <ErrorMessage>((conn, msg) => { }, false);

            // add one custom message handler
            bool wasReceived = false;
            NetworkConnection connectionReceived = null;
            TestMessage       messageReceived    = new TestMessage();

            NetworkServer.RegisterHandler <TestMessage>((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
            TestMessage testMessage = new TestMessage {
                IntValue = 13, DoubleValue = 14, StringValue = "15"
            };
            NetworkWriter writer = new NetworkWriter();

            MessagePacker.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);
        }
Beispiel #5
0
        /// <summary>
        /// Send fake values to client's <see cref="Mirror.ClientRpcAttribute"/>.
        /// </summary>
        /// <param name="target">Target to send.</param>
        /// <param name="behaviorOwner"><see cref="Mirror.NetworkIdentity"/> of object that owns <see cref="Mirror.NetworkBehaviour"/>.</param>
        /// <param name="targetType"><see cref="Mirror.NetworkBehaviour"/>'s type.</param>
        /// <param name="rpcName">Property name starting with Rpc.</param>
        /// <param name="values">Values of send to target.</param>
        public static void SendFakeTargetRpc(Player target, NetworkIdentity behaviorOwner, Type targetType, string rpcName, params object[] values)
        {
            NetworkWriter writer = NetworkWriterPool.GetWriter();

            foreach (var value in values)
            {
                WriterExtensions[value.GetType()].Invoke(null, new object[] { writer, value });
            }

            var msg = new RpcMessage
            {
                netId          = behaviorOwner.netId,
                componentIndex = GetComponentIndex(behaviorOwner, targetType),
                functionHash   = (targetType.FullName.GetStableHashCode() * 503) + rpcName.GetStableHashCode(),
                payload        = writer.ToArraySegment(),
            };

            target.Connection.Send(msg, 0);
            NetworkWriterPool.Recycle(writer);
        }
Beispiel #6
0
        public void SerializeAreAddedWhenEmptyInStruct()
        {
            writer.Reset();

            const int someValue = 3;

            writer.Write(new SomeStructMessage
            {
                someValue = someValue,
            });

            reader.Reset(writer.ToArraySegment());
            SomeStructMessage received = reader.Read <SomeStructMessage>();

            Assert.AreEqual(someValue, received.someValue);

            int writeLength = writer.ByteLength;
            int readLength  = reader.BytePosition;

            Assert.That(writeLength == readLength, $"OnSerializeAll and OnDeserializeAll calls write the same amount of data\n    writeLength={writeLength}\n    readLength={readLength}");
        }
Beispiel #7
0
        public void NetworkSend(int _connectionId, InsightNetworkMessage _netMsg, CallbackHandler _callback = null)
        {
            if (!transport.ServerActive())
            {
                Debug.LogError("[InsightServer] - Can't networking send with server inactive !");
                return;
            }

            _netMsg.connectionId = _connectionId;
            if (_netMsg.callbackId == 0)
            {
                RegisterCallback(_netMsg, _callback);
            }

            var writer = new NetworkWriter();

            _netMsg.Serialize(writer);

            transport.ServerSend(new List <int> {
                _connectionId
            }, 0, writer.ToArraySegment());
        }
Beispiel #8
0
        private static bool Prefix(NetworkBehaviour __instance, NetworkConnection conn, Type invokeClass, string rpcName, NetworkWriter writer, int channelId)
        {
            if (!NetworkServer.active)
            {
                Debug.LogError("TargetRPC Function " + rpcName + " called on client.");
                return(false);
            }
            if (conn == null)
            {
                conn = __instance.connectionToClient;
                if (conn == null)
                {
                    return(false);
                }
            }
            if (conn is ULocalConnectionToServer)
            {
                Debug.LogError("TargetRPC Function " + rpcName + " called on connection to server");
                return(false);
            }
            if (!__instance.isServer)
            {
                Debug.LogWarning("TargetRpc " + rpcName + " called on un-spawned object: " + __instance.name);
                return(false);
            }
            RpcMessage msg = new RpcMessage
            {
                netId          = __instance.netId,
                componentIndex = __instance.ComponentIndex,
                functionHash   = NetworkBehaviour.GetMethodHash(invokeClass, rpcName),
                payload        = writer.ToArraySegment()
            };

            conn.Send <RpcMessage>(msg, channelId);
            return(false);
        }
Beispiel #9
0
        public void AuthRequestMessageTest()
        {
            // try setting value with constructor
            var message = new AuthRequestMessage
            {
                serverCode = "abc",
            };

            Assert.That(message.serverCode, Is.EqualTo("abc"));

            // serialize
            var writer = new NetworkWriter(1300);

            writer.Write(message);

            // try deserialize
            var reader = new NetworkReader();

            reader.Reset(writer.ToArraySegment());
            AuthRequestMessage fresh = reader.Read <AuthRequestMessage>();

            Assert.That(fresh.serverCode, Is.EqualTo("abc"));
            reader.Dispose();
        }
        public IEnumerator SendMany()
        {
            Task <RunNode.Result> task = RunNode.RunAsync("ReceiveManyMessages.js", 5_000);

            yield return(server.WaitForConnection);

            const int messageCount = 100;

            for (int i = 0; i < messageCount; i++)
            {
                var writer = new NetworkWriter();
                writer.WriteByte((byte)i);
                writer.WriteInt32(100);

                var segment = writer.ToArraySegment();

                server.ServerSend(new List <int> {
                    1
                }, Channels.DefaultReliable, segment);
            }

            yield return(new WaitForSeconds(1));

            server.ServerDisconnect(1);

            yield return(new WaitUntil(() => task.IsCompleted));

            RunNode.Result result = task.Result;

            string expectedFormat         = "length: 5 msg: {0:X2} 64 00 00 00";
            IEnumerable <string> expected = Enumerable.Range(0, messageCount).Select(i => string.Format(expectedFormat, i));

            result.AssetTimeout(false);
            result.AssetOutput(expected.ToArray());
            result.AssetErrors();
        }
Beispiel #11
0
        /// <summary>
        /// Send custom values to client's SyncObject.
        /// </summary>
        /// <param name="target">Target to send.</param>
        /// <param name="behaviorOwner"><see cref="Mirror.NetworkIdentity"/> of object that owns <see cref="Mirror.NetworkBehaviour"/>.</param>
        /// <param name="targetType"><see cref="Mirror.NetworkBehaviour"/>'s type.</param>
        /// <param name="customAction">Custom writing action.</param>
        public static void SendCustomSyncObject(this Player target, NetworkIdentity behaviorOwner, Type targetType, Action <NetworkWriter> customAction)
        {
            /*
             * Cant be use if you dont understand(ill make more use easily soonTM)
             * Example(SyncList) [EffectOnlySCP207]:
             * player.SendCustomSync(player.ReferenceHub.networkIdentity, typeof(PlayerEffectsController), (writer) => {
             *      writer.WritePackedUInt64(1ul);								// DirtyObjectsBit
             *      writer.WritePackedUInt32((uint)1);							// DirtyIndexCount
             *      writer.WriteByte((byte)SyncList<byte>.Operation.OP_SET);	// Operations
             *      writer.WritePackedUInt32((uint)0);							// EditIndex
             *      writer.WriteByte((byte)1);									// Item
             * });
             */
            NetworkWriter writer  = NetworkWriterPool.GetWriter();
            NetworkWriter writer2 = NetworkWriterPool.GetWriter();

            MakeCustomSyncWriter(behaviorOwner, targetType, customAction, null, writer, writer2);
            NetworkServer.SendToClientOfPlayer(target.ReferenceHub.networkIdentity, new UpdateVarsMessage()
            {
                netId = behaviorOwner.netId, payload = writer.ToArraySegment()
            });
            NetworkWriterPool.Recycle(writer);
            NetworkWriterPool.Recycle(writer2);
        }
        public void RegisterUnregisterClearHandlerTest()
        {
            // message handlers that are needed for the test
            NetworkServer.RegisterHandler <ConnectMessage>((conn, msg) => { }, false);
            NetworkServer.RegisterHandler <DisconnectMessage>((conn, msg) => { }, false);
            NetworkServer.RegisterHandler <ErrorMessage>((conn, msg) => { }, false);


            // RegisterHandler(conn, msg) variant
            int variant1Called = 0;

            NetworkServer.RegisterHandler <TestMessage>((conn, msg) => { ++variant1Called; }, false);

            // RegisterHandler(msg) variant
            int variant2Called = 0;

            NetworkServer.RegisterHandler <WovenTestMessage>(msg => { ++variant2Called; }, false);

            // listen
            NetworkServer.Listen(1);
            Assert.That(NetworkServer.connections.Count, Is.EqualTo(0));

            // add a connection
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42);

            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();

            MessagePacker.Pack(new TestMessage(), 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();
            MessagePacker.Pack(new WovenTestMessage(), writer);
            Transport.activeTransport.OnServerDataReceived.Invoke(42, writer.ToArraySegment(), 0);
            Assert.That(variant2Called, Is.EqualTo(1));

            // unregister first handler, send, should fail
            NetworkServer.UnregisterHandler <TestMessage>();
            writer = new NetworkWriter();
            MessagePacker.Pack(new TestMessage(), 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)
            NetworkServer.RegisterHandler <DisconnectMessage>((conn, msg) => { }, false);
            writer = new NetworkWriter();
            MessagePacker.Pack(new TestMessage(), 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));

            // clean up
            NetworkServer.Shutdown();
        }
        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);
        }
Beispiel #14
0
        public void TestWritingBytesSegment()
        {
            byte[] data = { 1, 2, 3 };
            writer.WriteBytes(data, 0, data.Length);

            reader.Reset(writer.ToArraySegment());
            ArraySegment <byte> deserialized = reader.ReadBytesSegment(data.Length);

            Assert.That(deserialized.Count, Is.EqualTo(data.Length));
            for (int i = 0; i < data.Length; ++i)
            {
                Assert.That(deserialized.Array[deserialized.Offset + i], Is.EqualTo(data[i]));
            }
        }
Beispiel #15
0
 /// <summary>
 /// Gets Reader using the current data inside writer
 /// </summary>
 /// <returns></returns>
 public NetworkReader GetReader()
 {
     reader.Reset(writer.ToArraySegment());
     return(reader);
 }
Beispiel #16
0
        public void CommandMessageCallsCommand()
        {
            // 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
            CreateNetworked(out GameObject go, out NetworkIdentity identity, out CommandTestNetworkBehaviour comp0, out CommandTestNetworkBehaviour comp1);
            identity.netId = 42;
            // for authority check
            identity.connectionToClient = connection;
            connection.identity         = identity;
            Assert.That(comp0.called, Is.EqualTo(0));
            Assert.That(comp1.called, Is.EqualTo(0));

            // 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.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.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.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.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);
        }