alec1o / Byter

Byter is a C# serializer. It can serialize and deserialize from primitive type e.g (class, struct, list, array, string...)
MIT License
3 stars 1 forks source link

Add and Get Struct is bug #28

Closed nvh2001 closed 3 days ago

nvh2001 commented 5 days ago

I try to send struct with byter but error, the data is null. Tks

private void Start()
{
    // set data
    Primitive primitive = new();
    var a = new ServerResponse() { typeResponse = TypeResponse.WebSocketConnectSucces, message = "xxx1" };
    primitive.Add.Struct(a);

    // get data
    byte[] buffer = primitive.GetBytes();
    var message = Encoding.UTF8.GetString(buffer);
    Debug.Log(message);
}
alec1o commented 5 days ago

Let me know what is ServerResponse: I mean give me acess to ServerResponse

struct ServerResponse
{
    ?
}
nvh2001 commented 4 days ago

Let me know what is ServerResponse: I mean give me acess to ServerResponse

struct ServerResponse
{
    ?
}

sorry for that The struct is here. tks

    public struct ServerResponse
    {
        public TypeResponse typeResponse;
        public string? message;

    }
alec1o commented 4 days ago

What is TypeResponse? (enum‽)

nvh2001 commented 4 days ago

What is TypeResponse? (enum‽)

yep

public enum TypeResponse
{
    None,
    // Player - Sucess
    WebSocketConnectSucces,
    GetUserSuccess,
    // Player - Error
    RemoveSuccess,
    NullId,
    GetUserError,
    SeverMax,
    Have2PlayerId,
}
alec1o commented 4 days ago

Thanks for you help I'll solve this, after I'll give you a feedback. (Nguyen Van Hao) @nvh2001, thanks for your contribution about Byter 💐

alec1o commented 4 days ago

Fixed

use { get; set } on propriety

public struct ServerResponse
{
    public TypeResponse typeResponse { get; set; }
    public string? message { get; set; }
}

This solved your problem? :smile:

#

Optional

You can use Byter Encoding Extension instead of raw System.Text.Encoding ```rb # string to bytes byte[] @bytes = "Byter".GetBytes(); # global encoding is UTF8 byte[] @bytes = @string.GetBytes(Encoding.UTF32) # use custom encoding # bytes to string string @string = [1, 2, 3, 4].GetString(); #global encoding is UTF8 string @string = @bytes.GetString(Encoding.UTF32); #use custom encoding # update global encoding (UTF8) is default. StringExtension.Default = Encoding.UTF32; ``` this will allow on future you update encoding easy. Have good feature: - ``@string.ToCapitalize`` * "Aaa Bbb" - ``@string.ToUpperCase`` * "AAA BBB" - ``@string.ToLowerCase`` * "aaa aaa" Read more about this feature here: https://github.com/alec1o/Netly?tab=readme-ov-file#for-more-information-and-details-see-byters-official-information
vanhaodev commented 4 days ago

Fixed

use { get; set } on propriety

public struct ServerResponse
{
    public TypeResponse typeResponse { get; set; }
    public string? message { get; set; }
}

This solved your problem? 😄

Optional

You can use Byter Encoding Extension instead of raw System.Text.Encoding

it's not working (unity & console .NET 8)

when using {get; set} this lib has error

NullReferenceException: Object reference not set to an instance of an object
Byter.PrimitiveExtension.ToPrimitive[T] (T value, System.Type type) (at Assets/_Game/02.Script/Ultilities/Alec1oByter/extension/PrimitiveExtension.cs:20)
Byter.Primitive+PrimitiveAdd.Struct[T] (T value) (at Assets/_Game/02.Script/Ultilities/Alec1oByter/primitive/partials/PrimitiveAdd.cs:197)
Byter.PrimitiveExtension.ToPrimitive[T] (T value, System.Type type) (at Assets/_Game/02.Script/Ultilities/Alec1oByter/extension/PrimitiveExtension.cs:110)
Byter.Primitive+PrimitiveAdd.Struct[T] (T value) (at Assets/_Game/02.Script/Ultilities/Alec1oByter/primitive/partials/PrimitiveAdd.cs:197)
RoomController.CreateRoom (System.String roomName, System.Int32 password, System.Int32 point) (at Assets/_Game/02.Script/Popup/Controller/RoomController.cs:25)
PopupRoomCreation.Create () (at Assets/_Game/02.Script/Popup/View/Room/PopupRoomCreation.cs:36)
UnityEngine.Events.InvokableCall.Invoke () (at <e509afeff7384f24a8f0ac30527ff01c>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <e509afeff7384f24a8f0ac30527ff01c>:0)
UnityEngine.UI.Button.Press () (at ./Library/PackageCache/com.unity.ugui@2.0.0/Runtime/UGUI/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at ./Library/PackageCache/com.unity.ugui@2.0.0/Runtime/UGUI/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at ./Library/PackageCache/com.unity.ugui@2.0.0/Runtime/UGUI/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at ./Library/PackageCache/com.unity.ugui@2.0.0/Runtime/UGUI/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at ./Library/PackageCache/com.unity.ugui@2.0.0/Runtime/UGUI/EventSystem/EventSystem.cs:530)
alec1o commented 4 days ago

I tested in dotnet 8 console application and this (get;set) fixed the problem.

Let me test it on unity 6

vanhaodev commented 4 days ago

Tôi đã thử nghiệm trong ứng dụng giao diện điều khiển dotnet 8 và điều này (get; bộ) đã khắc phục sự cố.

Hãy để tôi kiểm tra nó trên unity 6

My code, i tested both unity and .net 8

        CreateRoomRequest request = new CreateRoomRequest();
        request.RoomName = roomName;
        request.Password = password;
        request.PriceRoom = point;
        request.PlayerSessionModel = GameHelper.Instance.net.playerSessionModel;

        //var sender = GameHelper.Instance.net.sender;
        Primitive sender = new Primitive();
        sender.Reset();
        sender.Add.Struct(request);
alec1o commented 4 days ago

Isn't working in .NET 8? How did you install Byter? Copy sources or Nuget

vanhaodev commented 4 days ago

Isn't working in .NET 8? How did you install Byter? Copy sources or Nuget

i download src from github (unity & console .net 8)

alec1o commented 4 days ago

It's working for me on Unity 6 and dotnet 8. Just set {get;set} on ServerResponse struct

using UnityEngine;
using Byter;
using System.Text;

public class Scrip : MonoBehaviour
{

    public struct ServerResponse
    {
        public TypeResponse typeResponse { get; set; }
        public string message { get; set; }

    }

    public enum TypeResponse
    {
        None,
        // Player - Sucess
        WebSocketConnectSucces,
        GetUserSuccess,
        // Player - Error
        RemoveSuccess,
        NullId,
        GetUserError,
        SeverMax,
        Have2PlayerId,
    }

    private void Start()
    {
        // set data
        Primitive primitive = new();
        var a = new ServerResponse() { typeResponse = TypeResponse.WebSocketConnectSucces, message = "xxx1" };
        primitive.Add.Struct(a);

        // get data
        byte[] buffer = primitive.GetBytes();
        var message = Encoding.UTF8.GetString(buffer);
        Debug.Log(message);
        Debug.Log(message.Length);
    }
}
alec1o commented 4 days ago

On your server: (i think you are using console application)

  # cd myserverpath
  dotnet add package byter --version 3.0.0

On your unity


NOTE: Note even without putting {get;set} I never got an exception, Byter should never throw an exception (so you should never need try/catch), I think you might be using outdated source-code

vanhaodev commented 4 days ago
  • Delete all sources code on your server and unity

On your server: (i think you are using console application)

# cd myserverpath
dotnet add package byter --version 3.0.0

On your unity

  • Download Byter300.dll and include on /Asset/Plugins/Byter300.dll

NOTE: Note even without putting {get;set} I never got an exception, Byter should never throw an exception (so you should never need try/catch), I think you might be using outdated source-code

Thank you, I will try, my project has a short deadline :)))

alec1o commented 4 days ago

Screenshot from 2024-07-04 12-19-30

Debug.Log(message);
Debug.Log(message.Length);
alec1o commented 4 days ago

Thank you, I will try, my project has a short deadline :)))

Maybe this looks hard, I'll show you how do this.

  1. Delete Alec1oByter folder (image) Screenshot from 2024-07-04 12-32-04

  2. Download Byter300 (v3.0.0) compiled (image). use this link to download Screenshot from 2024-07-04 12-40-44

  3. Copy Byter300.dll to your unity folder. that's all :grinning: . (image) Screenshot from 2024-07-04 12-29-02

vanhaodev commented 4 days ago

Error when the Struct has a Struct as children. (maybe i think) roomName, password and priceRoom will null if i add { get; set; } for 'public PlayerSessionModel playerSessionModel;' but no null if delete { get; set; } for public PlayerSessionModel playerSessionModel;

[Serializable]
public struct CreateRoomRequest
{
    public string roomName { get; set; }
    public int password { get; set; }
    public int priceRoom { get; set; }
    public PlayerSessionModel playerSessionModel;
}

[Serializable]
public struct PlayerSessionModel
{
    public TypeStatePlayer? statePlayer { get; set; }
    public string? name { get; set; }
    public string? id { get; set; }
    public long? point { get; set; }
    public WebUserInfo? webUserInfo;

    public void SetWebUserInfo(WebUserInfo? webUserInfo)
    {
        this.webUserInfo = webUserInfo;
    }

    public void SetModel(PlayerSessionModel model)
    {
        this = model;
    }
}

[Serializable]
public struct WebUserInfo
{
    [JsonProperty("phone")]
    public string? phone {  get; set; }
    [JsonProperty("_id")]
    public string? _id { get; set; }
    [JsonProperty("name")]
    public string? name { get; set; }
    [JsonProperty("email")]
    public string? email { get; set; }
    [JsonProperty("username")]
    public string? username { get; set; }
    [JsonProperty("telegram_id")]
    public string? telegram_id { get; set; }
    [JsonProperty("avatar")]
    public Avatar? avatar { get; set; }
    [JsonProperty("banner")]
    public object? banner { get; set; }
    [JsonProperty("is_active")]
    public bool? is_active { get; set; }
    [JsonProperty("invite_code")]
    public string? invite_code { get; set; }
    [JsonProperty("balance")]
    public long? balance { get; set; }
    [JsonProperty("titles")]
    public string? titles { get; set; }
    [JsonProperty("wallets")]
    public object? wallets { get; set; }
    [JsonProperty("is_online")]
    public bool? is_online { get; set; }
    [JsonProperty("is_email_verified")]
    public bool? is_email_verified { get; set; }
    [JsonProperty("is_phone_verified")]
    public bool? is_phone_verified { get; set; }
    [JsonProperty("is_telegram_verified")]
    public bool? is_telegram_verified { get; set; }
    [JsonProperty("is_wallet_connect")]
    public bool? is_wallet_connect { get; set; }
    [JsonProperty("tickets")]
    public int? tickets { get; set; }
    [JsonProperty("usdt_balance")]
    public int? usdt_balance { get; set; }
    [JsonProperty("last_online_at")]
    public DateTime? last_online_at { get; set; }
    [JsonProperty("about")]
    public string? about { get; set; }
    [JsonProperty("is_use_password")]
    public bool? is_use_password { get; set; }
    [JsonProperty("id")]
    public string? id { get; set; }
    [JsonProperty("telegram_ref")]
    public string? telegram_ref;
}
hcmyxconan15 commented 4 days ago

have same issue when Struct in struct

nvh2001 commented 3 days ago

I see more. Byter error on WEBGL unity

alec1o commented 3 days ago

ok lemme test it

alec1o commented 3 days ago

You made 2 mistakes:

:heart: Everything is working, just fix the 2 errors mentioned above! :rose:

alec1o commented 3 days ago

(maybe i think) roomName, password and priceRoom will null if i add { get; set; } for 'public PlayerSessionModel playerSessionModel;' but no null if delete { get; set; } for public PlayerSessionModel playerSessionModel;

No, that's not it, always use { get; set; } 1000% recommended instead of removing this (as much as it works without { get or set }, I always recommend adding {get; set;})

nvh2001 commented 3 days ago

(maybe i think) roomName, password and priceRoom will null if i add { get; set; } for 'public PlayerSessionModel playerSessionModel;' but no null if delete { get; set; } for public PlayerSessionModel playerSessionModel;

No, that's not it, always use { get; set; } 1000% recommended instead of removing this (as much as it works without { get or set }, I always recommend adding {get; set;})

It's work incorrecly, group will be null

public struct Idol
{
    public string name {  get; set; }
    public ushort birthdayYear { get; set; }
    public Group group;
}
public struct Group
{
    public string name { get; set; }
    public ushort birthdayYear { get; set; }
}

        Idol idol = new Idol();
        idol.name = "Karina";
        idol.birthdayYear = 2000;
        idol.group = new Group();
        idol.group.name = "aespa";
        idol.group.birthdayYear = 2019;

        Primitive send = new Primitive();
        send.Add.Struct(idol);

        Primitive recive = new Primitive(send.GetBytes());
        var reIdol = recive.Get.Struct<Idol>();
        Debug.Log(reIdol.name);
        Debug.Log(reIdol.birthdayYear);
        Debug.Log(reIdol.group.name);
        Debug.Log(reIdol.group.birthdayYear);
alec1o commented 3 days ago

add {get; set;} to Idol->group

nvh2001 commented 3 days ago

add {get; set;} to Idol->group

Severity Code Description Project File Line Suppression State Error CS1612 Cannot modify the return value of 'Idol.group' because it is not a variable Assembly-CSharp

alec1o commented 3 days ago

Give me 1s

nvh2001 commented 3 days ago

Give me 1s

just slowly comfortable

alec1o commented 3 days ago

Just slowly comfortable :rofl: :rofl: :rofl: :rofl:

It's working! :rofl: :rofl: :rofl: :rofl:

Idol idol = new Idol();
idol.name = "Karina";
idol.birthdayYear = 2000;
idol.group = new Group
{
    name = "aespa",
    birthdayYear = 2019,
};

Primitive send = new Primitive();
send.Add.Struct(idol);

Primitive recive = new Primitive(send.GetBytes());
var reIdol = recive.Get.Struct<Idol>();

Debug.Log(reIdol.name);
Debug.Log(reIdol.birthdayYear);
Debug.Log(reIdol.group.name);
Debug.Log(reIdol.group.birthdayYear);

Screenshot from 2024-07-05 09-09-27

you make a mistake (c# side)

Struct looks like a class but is liite but more complex.

alec1o commented 3 days ago

It's working now?

nvh2001 commented 3 days ago

It's woking!!!!!!!! Now I trying test with list and array of struct !!!!

alec1o commented 3 days ago

It's woking!!!!!!!! Now I trying test with list and array of struct !!!!

Ok, I think this supports Array<Struct|Class|List<Array>> .... You can make how many complex structs you want,

Example:

class A
{
    List<B> MyB;
}

class B
{
    C[] MyCs;
}

class C
{
   List<A[]> MyAs;
   List<List<B>> MyBs; 
}
nvh2001 commented 3 days ago

Yep it's working with Array and List of struct, so I trying Struc in struct of a struct

alec1o commented 3 days ago

Byter don't have data deep limitation, Make how much complex data it's possible. :rofl: :partying_face:

nvh2001 commented 3 days ago

Byter don't have data deep limitation, Make how much complex data it's possible. 🤣 🥳

work work!!!!! just get set. And add data from within (a bit tricky)

nvh2001 commented 3 days ago

Byter don't have data deep limitation, Make how much complex data it's possible. 🤣 🥳

A thing i can reveal for u, dll CAN'T build on Webgl but folder src can do it

alec1o commented 3 days ago

Give me 1s

alec1o commented 3 days ago

A thing i can reveal for u, dll CAN'T build on Webgl but folder src can do it

I know. you told me before! :rofl: :rofl: :rofl:

I was not know that you had build to WebGL :globe_with_meridians:

Solution

  1. Delete Byter300.dll to your unity folder. (WebGL don't accept ddl files, but Android, iOS, macOS and Linux supports .dll files). (image) Screenshot from 2024-07-04 12-29-02

  2. Download Byter-300-Include.zip (v3.0.0 sources). (image). use this link to download Screenshot from 2024-07-05 09-54-10

  3. Unzip Byter-300-Include.zip and Copy unziped (Byter-300-Include) folder to your unity folder. that's all :grinning: . (image) image

It's working?

alec1o commented 3 days ago

Byter don't have data deep limitation, Make how much complex data it's possible. 🤣 🥳

A thing i can reveal for u, dll CAN'T build on Webgl but folder src can do it

You reminded me C/C++ programmer, always download and unzip library, GLFW, ImGUI, Glad, GLM... :rofl: :rofl: :rofl: (I love use package manager instead of manual past sources in my projects) :rofl: :rofl: