godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.13k stars 21.19k forks source link

Debugger reported wrong information. #76086

Closed ChallengeTr closed 1 year ago

ChallengeTr commented 1 year ago

Godot version

4.0.2 stable

System information

Windows10 22H2

Issue description

Strange issue, I'm trying to replace an element in an Array with a Dictionary data. However, the Debugger always interrupts the program. But there are indeed 48 elements in this Array. Moreover, when running the exported program, there is no error message in the log and it runs as expected. Additionally, there is very little information in the debugger.

”players_data" is user data read from a JSON file

@rpc("any_peer","reliable") 
func inv_handle(pack:PackedByteArray) -> void:
    var id = multiplayer.get_remote_sender_id()
    if not uid_to_datakey.has(id):
        return
    var data = players_data[uid_to_datakey[id]]
    var inv = data["inv"]
    var way = pack.decode_u8(0)
    if way == 0:
        inv_item_move(data,pack,id)
    elif way == 1:
        _split_item(inv,pack,id)
    elif way == 2:
        _order_inv(inv,id)
    elif way == 3:
        _add_to_inv(inv,pack,id)
    elif way == 4:
        _throw_item(inv,pack,id)
    elif way == 5:
        _use_item(inv,pack,id)

The program is interrupted after entering this method:

func _add_to_inv(my_inv:Array,pack:PackedByteArray,id:int) -> void:
    # 1 + 1 + 2 + 2 + (10)
    var idx = pack.decode_u8(1)
    var item_id = pack.decode_u16(2)
    var num = pack.decode_u16(4)
    var state = []
    if pack.size() > 6:
        state = MathTools.decode_ar_u16(pack.slice(6))
    var item = my_inv[idx]

    print("typeof my_inv:",typeof(my_inv))
    print("typeof item:",typeof(item))
    print("size:",my_inv.size())
    print("idx:",idx)
    print(my_inv)

    if typeof(item) == TYPE_DICTIONARY:
        if item["i"] != item_id:
            refresh_inv.rpc_id(id,MathTools.encode_var(my_inv))
            return
        item["n"] += num
    else:
        var data = GameRes.ITEMS[item_id].duplicate()
        data["n"] = num

        # *****debugger interrupting here ,data is Dictionary****
        my_inv[idx] = data
    if state.size() > 0:
        my_inv[idx]["s"] = state

This is print result:

img1

This is debugger info.: I swear the array has enough elements, In editor progarm interrupt. When running exported no error log and runs as expected. Invalid set index '2' (on base: 'Array') with value of type 'Dictionary'

img2

Steps to reproduce

skip

Minimal reproduction project

I tested similar operations in a simplified way in other parts of the same project, and did not encounter similar errors:

var dic = {1:3,"inv":[1,2,false,false,5,6]}
var ar = dic["inv"]
var ar1 = ar
var ar2 = ar1
ar2[2] = {"key":666}
print(ar2)
ChallengeTr commented 1 year ago

I'm sorry, I think I have found the reason for the error. When copying the new user's default data, it was not duplicated with duplicate(deep=true), so the Array in the Dictionary was only a copied reference. And the default data is const. So when assigning a value to the Array, an error occurred. I was so noob.. 000 2222