/// <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(); }
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); }
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); }
/// <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); }
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}"); }
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()); }
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); }
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(); }
/// <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); }
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])); } }
/// <summary> /// Gets Reader using the current data inside writer /// </summary> /// <returns></returns> public NetworkReader GetReader() { reader.Reset(writer.ToArraySegment()); return(reader); }
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); }