fix: Write for non-spawned NB only writes 0 netId (fixes: #3399) (#3400)

* Failing test for non-spawned NB writer/reader

* fix: Write for non-spawned NB only writes 0 netId

Instead of writing 0 and component index which does not match what the reader expects (it will stop reading netId is 0)
Fixes #3399
This commit is contained in:
Robin Rolf 2023-02-28 16:10:49 +01:00 committed by GitHub
parent 17f75b77ca
commit 74f5339b09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 0 deletions

View File

@ -228,6 +228,22 @@ public static void WriteNetworkBehaviour(this NetworkWriter writer, NetworkBehav
writer.WriteUInt(0); writer.WriteUInt(0);
return; return;
} }
// users might try to use unspawned / prefab NetworkBehaviours in
// rpcs/cmds/syncvars/messages. they would be null on the other
// end, and it might not be obvious why. let's make it obvious.
// https://github.com/vis2k/Mirror/issues/2060
// and more recently https://github.com/MirrorNetworking/Mirror/issues/3399
//
// => warning (instead of exception) because we also use a warning
// when writing an unspawned NetworkIdentity
if (value.netId == 0)
{
Debug.LogWarning($"Attempted to serialize unspawned NetworkBehaviour: of type {value.GetType()} on GameObject {value.name}. Prefabs and unspawned GameObjects would always be null on the other side. Please spawn it before using it in [SyncVar]s/Rpcs/Cmds/NetworkMessages etc.");
writer.WriteUInt(0);
return;
}
writer.WriteUInt(value.netId); writer.WriteUInt(value.netId);
writer.WriteByte(value.ComponentIndex); writer.WriteByte(value.ComponentIndex);
} }

View File

@ -1451,6 +1451,25 @@ public void TestNetworkBehaviourNull()
Assert.That(reader.Position, Is.EqualTo(4), "should read 4 bytes when netid is 0"); Assert.That(reader.Position, Is.EqualTo(4), "should read 4 bytes when netid is 0");
} }
// test for https://github.com/MirrorNetworking/Mirror/issues/3399
[Test]
public void TestNetworkBehaviourNotSpawned()
{
CreateNetworked(out _, out _, out RpcNetworkIdentityBehaviour component);
NetworkWriter writer = new NetworkWriter();
writer.WriteNetworkBehaviour(component);
byte[] bytes = writer.ToArray();
Assert.That(bytes.Length, Is.EqualTo(4), "unspawned Networkbehaviour should be 4 bytes long.");
NetworkReader reader = new NetworkReader(bytes);
RpcNetworkIdentityBehaviour actual = reader.ReadNetworkBehaviour<RpcNetworkIdentityBehaviour>();
Assert.That(actual, Is.Null, "should read null");
Assert.That(reader.Position, Is.EqualTo(4), "should read 4 bytes when netid is 0");
}
// test to prevent https://github.com/vis2k/Mirror/issues/2972 // test to prevent https://github.com/vis2k/Mirror/issues/2972
[Test] [Test]
public void TestNetworkBehaviourDoesntExistOnClient() public void TestNetworkBehaviourDoesntExistOnClient()