colyseus / colyseus-unity-sdk

⚔ Colyseus Multiplayer SDK for Unity
https://docs.colyseus.io/getting-started/unity-sdk/
MIT License
371 stars 102 forks source link

ArraySchema: JsonSerializationException: Unexpected token readed 'BeginArray' while 'BeginObject' is expected #176

Open Lonri opened 2 years ago

Lonri commented 2 years ago

I can't seem to get any ArraySchema to work, being it string, number or something else. I know there's this closed issue about an ArraySchema problem but updating to the latest versions of colyseus didn't fix it for me.

Am I being blind or is there still a bug?

What I'm using:

Schema class on the server:

export class ServerGameDataRules extends Schema {
    @type(["int8"])
    stagesOrder: ArraySchema<number> = new ArraySchema<number>();
}

Schema class on the client generated using schema-codegen:

// 
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
// 
// GENERATED USING @colyseus/schema 1.0.28
// 

using Colyseus.Schema;

namespace OurGame.Networking.States {
    public partial class ServerGameDataRules : Schema {
        [Type(0, "array", typeof(ArraySchema<sbyte>), "int8")]
        public ArraySchema<sbyte> stagesOrder = new ArraySchema<sbyte>();
    }
}

Stack trace:

JsonSerializationException: Unexpected token readed 'BeginArray' while 'BeginObject' is expected.
GameDevWare.Serialization.Serializers.ObjectSerializer.Deserialize (GameDevWare.Serialization.IJsonReader reader) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:69)
GameDevWare.Serialization.JsonReaderExtentions.ReadValue (GameDevWare.Serialization.IJsonReader reader, System.Type valueType, System.Boolean nextToken) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs:726)
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:191)
Rethrow as SerializationException: Failed to read value for member 'stagesOrder' of 'ServerGameDataRules' type.
More detailed information in inner exception.
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:195)
GameDevWare.Serialization.Serializers.ObjectSerializer.Deserialize (GameDevWare.Serialization.IJsonReader reader) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:74)
GameDevWare.Serialization.JsonReaderExtentions.ReadValue (GameDevWare.Serialization.IJsonReader reader, System.Type valueType, System.Boolean nextToken) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs:726)
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:191)
Rethrow as SerializationException: Failed to read value for member 'rules' of 'ServerGameData' type.
More detailed information in inner exception.
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:195)
GameDevWare.Serialization.Serializers.ObjectSerializer.Deserialize (GameDevWare.Serialization.IJsonReader reader) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:74)
GameDevWare.Serialization.JsonReaderExtentions.ReadValue (GameDevWare.Serialization.IJsonReader reader, System.Type valueType, System.Boolean nextToken) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs:726)
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:191)
Rethrow as SerializationException: Failed to read value for member 'ServerData' of 'OnRoomJoinedResponseMessage' type.
More detailed information in inner exception.
GameDevWare.Serialization.Serializers.ObjectSerializer.DeserializeMembers (GameDevWare.Serialization.IJsonReader reader, GameDevWare.Serialization.IndexedDictionary`2[KeyT,ValueT] container, GameDevWare.Serialization.Serializers.ObjectSerializer& serializerOverride) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:195)
GameDevWare.Serialization.Serializers.ObjectSerializer.Deserialize (GameDevWare.Serialization.IJsonReader reader) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs:74)
GameDevWare.Serialization.JsonReaderExtentions.ReadValue (GameDevWare.Serialization.IJsonReader reader, System.Type valueType, System.Boolean nextToken) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs:726)
GameDevWare.Serialization.MsgPack.Deserialize (System.Type objectType, System.IO.Stream msgPackInput, GameDevWare.Serialization.SerializationContext context) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/MsgPack.cs:79)
GameDevWare.Serialization.MsgPack.Deserialize (System.Type objectType, System.IO.Stream msgPackInput) (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/GameDevWare.Serialization/MsgPack.cs:65)
Colyseus.ColyseusRoom`1+<ParseMessage>d__37[T].MoveNext () (at Library/PackageCache/io.colyseus.sdk@65008fe25d/Runtime/Scripts/Room/ColyseusRoom.cs:448)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <eae584ce26bc40229c1b1aa476bfa589>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:153)
UnityEngine.UnitySynchronizationContext:ExecuteTasks() (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:107)
endel commented 2 years ago

Hi @Lonri, the schema structures should be used for the room's state (this.state).

But if you are trying to send it as a message I suggest using .toJSON() when sending the data:

// server-side
this.broadcast("type", schemaInstance.toJSON())

// client-side
room.OnMessage("type", (message) => {...});

Alternatively, you can send schema messages as well by doing this:

// server-side
this.broadcast(schemaInstance);

// client-side
room.OnMessage<ServerGameDataRules>((message) => {...});

Please let me know if this helps you out. Cheers!

Lonri commented 2 years ago

Hi @endel, that makes total sense, I'll change my approach and try out your suggestions. Thank you so much for the fast reply!

SleepingProgrammer commented 2 years ago

Sorry for reviving this but did you get any luck here? Got the same issue. Changed to .JSON on server but still nah

deniszykov commented 1 year ago

You can make your ArraySchema type IEnumerable in C# and MsgPack serializer will try to deserialize it as Array, also constructor accepting T[] on type is expected.