Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.15k stars 435 forks source link

Exception when Serializing Null Strings #3114

Closed Moe-Baker closed 1 week ago

Moe-Baker commented 2 weeks ago

Hello, NGO causes an exception when serializing a null string. The code throws an exception on this method as it doesn't do null checks. Are null strings supported or is this expected behavior.

NoelStephensUnity commented 2 weeks ago

@Moe-Baker

There are two places that that could be invoked:

Could you provide me with the code/script that is invoking this for context purposes? I might be able to provide you with an alternative that will avoid that exception.

Moe-Baker commented 1 week ago

Could you provide me with the code/script that is invoking this for context purposes?

This code causes the exception, basically a usage of INetworkSerializable. I already have a workaround, so I wanted to report this if this is a bug.

[Serializable]
public struct MiniGamesUserProfileDefinition : INetworkSerializable
{
    public string Username;

    public string FirebaseID;

    public int Level;
    public string Country;
    public string ClanName;

    public string Character;
    public string Background;
    public string Badge;

    public MiniGamesUserProfile ToProfile() => MiniGamesUserProfile.DefinitionToProfile(this);

    public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    {
        if (serializer.IsWriter)
        {
            //NGO doesn't serialize null strings for some reason, so we replace all possibly null string with empty strings
            ClanName ??= string.Empty;
            Badge ??= string.Empty;
        }

        serializer.SerializeValue(ref Username);
        serializer.SerializeValue(ref FirebaseID);
        serializer.SerializeValue(ref Country);
        serializer.SerializeValue(ref Character);
        serializer.SerializeValue(ref Level);
        serializer.SerializeValue(ref ClanName);
        serializer.SerializeValue(ref Badge);
        serializer.SerializeValue(ref Background);
    }

    public MiniGamesUserProfileDefinition(string Username, string FirebaseID, string Country, string Character, int Level, string ClanName, string Badge, string Background)
    {
        this.Username = Username;
        this.FirebaseID = FirebaseID;
        this.Country = Country;
        this.Character = Character;
        this.Level = Level;
        this.ClanName = ClanName;
        this.Badge = Badge;
        this.Background = Background;
    }
}
NoelStephensUnity commented 1 week ago

@Moe-Baker Ahhh, yeah super appreciate the script reference... helps me a bunch.

So, your approach is one way to handle this for sure and most of NGO's serialization of things like strings/arrays doesn't support handling null entries.

The exception is the same kind of exception you would get if you had a string property that was null and tried to access it directly without checking if it was null or empty.

It is recommended to make sure strings are at least assigned "empty" if you are trying to serialize them.

Moe-Baker commented 1 week ago

Understandable, thank you for the help.