Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add and Get Struct is bug #28

Closed
nvh2001 opened this issue Jul 3, 2024 · 38 comments
Closed

Add and Get Struct is bug #28

nvh2001 opened this issue Jul 3, 2024 · 38 comments
Assignees
Labels
good first issue Good for newcomers help wanted Extra attention is needed solved the question is solved

Comments

@nvh2001
Copy link

nvh2001 commented Jul 3, 2024

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
Copy link
Owner

alec1o commented Jul 3, 2024

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

struct ServerResponse
{
    ?
}

@nvh2001
Copy link
Author

nvh2001 commented Jul 4, 2024

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
Copy link
Owner

alec1o commented Jul 4, 2024

What is TypeResponse? (enum‽)

@nvh2001
Copy link
Author

nvh2001 commented Jul 4, 2024

What is TypeResponse? (enum‽)

yep

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

@alec1o
Copy link
Owner

alec1o commented Jul 4, 2024 via email

@alec1o
Copy link
Owner

alec1o commented Jul 4, 2024

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
# 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

@alec1o alec1o added good first issue Good for newcomers solved the question is solved labels Jul 4, 2024
@alec1o alec1o pinned this issue Jul 4, 2024
@alec1o alec1o unpinned this issue Jul 4, 2024
@alec1o alec1o pinned this issue Jul 4, 2024
@vanhaodev
Copy link

vanhaodev commented Jul 4, 2024

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
Copy link
Owner

alec1o commented Jul 4, 2024

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

Let me test it on unity 6

@vanhaodev
Copy link

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
Copy link
Owner

alec1o commented Jul 4, 2024

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

@vanhaodev
Copy link

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
Copy link
Owner

alec1o commented Jul 4, 2024

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
Copy link
Owner

alec1o commented Jul 4, 2024

  • 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

@vanhaodev
Copy link

  • 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
Copy link
Owner

alec1o commented Jul 4, 2024

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

Debug.Log(message);
Debug.Log(message.Length);

@alec1o
Copy link
Owner

alec1o commented Jul 4, 2024

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 😀 . (image)
    Screenshot from 2024-07-04 12-29-02

@vanhaodev
Copy link

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
Copy link

have same issue when Struct in struct

@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

I see more. Byter error on WEBGL unity

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

ok lemme test it

@alec1o alec1o added the help wanted Extra attention is needed label Jul 5, 2024
@alec1o alec1o removed their assignment Jul 5, 2024
@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

You made 2 mistakes:

  • 1st. Byter does not support object type "typeof(object)": (WebUserInfo->banner, wallets is object type),
    The reason has already been answered here: Good way to put Struct and Class in params object[] args? #26 (comment)

    • NOTE: I ignored (WebUserInfo->Avatar =?)
  • 2nd. [STOP USE C# NULLABLE] Nullable has been added since C# 8 .0 (.net core 3.0). Don't use (? suffix), Byter uses .NET Standard 2.0 (to support legacy and recent versions, from .NET framework 4.6.1 to the latest) and byter doesn't know what (?) is for example (Avatar? avatar) , If you stop using (?) the byter will understand your code. Note it is "impossible" to add support to (?) because of using .NET standard 2.0 and not .NET Standard 2.1 (just supported by .NET 3, 5, 6, 7, 8, 9...)

❤️ Everything is working, just fix the 2 errors mentioned above! 🌹

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

(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
Copy link
Author

nvh2001 commented Jul 5, 2024

(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
Copy link
Owner

alec1o commented Jul 5, 2024

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

@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

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
Copy link
Owner

alec1o commented Jul 5, 2024

Give me 1s

@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

Give me 1s

just slowly comfortable

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

Just slowly comfortable
🤣 🤣 🤣 🤣

It's working! 🤣 🤣 🤣 🤣

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)

  • Invalid
    idol.group = new Group();
    idol.group.name = "aespa";
    idol.group.birthdayYear = 2019;
  • Valid
    idol.group = new Group()
    {
        name = "aespa";
        birthdayYear = 2019;
    }

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

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

It's working now?

@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

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

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

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
Copy link
Author

nvh2001 commented Jul 5, 2024

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

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

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

@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

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 nvh2001 closed this as completed Jul 5, 2024
@nvh2001
Copy link
Author

nvh2001 commented Jul 5, 2024

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
Copy link
Owner

alec1o commented Jul 5, 2024

Give me 1s

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

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! 🤣 🤣 🤣

I was not know that you had build to WebGL 🌐

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 😀 . (image)
    image

It's working?

@alec1o
Copy link
Owner

alec1o commented Jul 5, 2024

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... 🤣 🤣 🤣 (I love use package manager instead of manual past sources in my projects) 🤣 🤣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed solved the question is solved
Projects
None yet
Development

No branches or pull requests

4 participants