Skip to content

CC: Tweaked 1.18.2 does not seem to take into account NBT Long arrays. #778

@masecla22

Description

@masecla22

Describe

Minecraft Version

1.20.1

Version

1.18.2:1.101.0

Details

Hello!

I was playing on my modpack, (Stoneblock 3), and happened upon a bug.

When using Advanced Peripherals, alongside the ME Bridge and Applied Energistics 2 mod, I saw that the amts NBT tag appears to get dropped when using the getItems function on the ME Bridge as a peripheral.

I have tracked the issue down, and have gone through the source for both CC: Tweaked, AE2 and Advanced Peripherals, and have narrowed it down to the following function:

private static Map<String, Object> getObjectFromItemStack(Pair<Long, AEItemKey> stack, @Nullable ICraftingService craftingService) {
Map<String, Object> map = new HashMap<>();
String displayName = stack.getRight().getDisplayName().getString();
CompoundTag nbt = stack.getRight().toTag();
long amount = stack.getLeft();
map.put("fingerprint", ItemUtil.getFingerprint(stack.getRight().toStack()));
map.put("name", stack.getRight().getItem().getRegistryName().toString());
map.put("amount", amount);
map.put("displayName", displayName);
map.put("nbt", NBTUtil.toLua(nbt));
map.put("tags", LuaConverter.tagsToList(() -> stack.getRight().getItem().builtInRegistryHolder().tags()));
map.put("isCraftable", craftingService != null && craftingService.isCraftable(stack.getRight()));
return map;
}

This seems to make use of the function NBTUtil.toLua, which, as far as I can tell is sourced from CC: Tweaked.

I am unsure whether CC: Tweaked further sources it upstream from CC, however, with IntelliJ, I was able to find this implementation of the function being used:

    public static Object toLua( Tag tag )
    {
        if( tag == null ) return null;

        byte typeID = tag.getId();
        switch( typeID )
        {
            case Tag.TAG_BYTE:
            case Tag.TAG_SHORT:
            case Tag.TAG_INT:
            case Tag.TAG_LONG:
                return ((NumericTag) tag).getAsLong();
            case Tag.TAG_FLOAT:
            case Tag.TAG_DOUBLE:
                return ((NumericTag) tag).getAsDouble();
            case Tag.TAG_STRING: // String
                return tag.getAsString();
            case Tag.TAG_COMPOUND: // Compound
            {
                CompoundTag compound = (CompoundTag) tag;
                Map<String, Object> map = new HashMap<>( compound.size() );
                for( String key : compound.getAllKeys() )
                {
                    Object value = toLua( compound.get( key ) );
                    if( value != null ) map.put( key, value );
                }
                return map;
            }
            case Tag.TAG_LIST:
            {
                ListTag list = (ListTag) tag;
                Map<Integer, Object> map = new HashMap<>( list.size() );
                for( int i = 0; i < list.size(); i++ ) map.put( i, toLua( list.get( i ) ) );
                return map;
            }
            case Tag.TAG_BYTE_ARRAY:
            {
                byte[] array = ((ByteArrayTag) tag).getAsByteArray();
                Map<Integer, Byte> map = new HashMap<>( array.length );
                for( int i = 0; i < array.length; i++ ) map.put( i + 1, array[i] );
                return map;
            }
            case Tag.TAG_INT_ARRAY:
            {
                int[] array = ((IntArrayTag) tag).getAsIntArray();
                Map<Integer, Integer> map = new HashMap<>( array.length );
                for( int i = 0; i < array.length; i++ ) map.put( i + 1, array[i] );
                return map;
            }

            default:
                return null;
        }
    }

Which, after some debugging landed me with this in my logs:

 {id:"ae2:item_storage_cell_256k",tag:{amts:[L;1L],ic:1L,keys:[{"#c":"ae2:i",id:"ae2:cyan_smart_dense_cable"}]}}
Tag Type ID: 10
Tag Type ID: 8
Tag Type ID: 10
Tag Type ID: 4
Tag Type ID: 9
Tag Type ID: 10
Tag Type ID: 8
Tag Type ID: 8
Tag Type ID: 12
Unsupported NBT tag: 12

Looking in the Tag class, I can see that NBT Tag 12 corresponds to TAG_LONG_ARRAY = 12;, and with that it makes quite a bit of sense why it's getting dropped.

That being said, I've gone ahead and have Advanced Peripherals as well, in this way:

    public static Object toLua(Tag tag) {
        if (tag == null) return null;

        byte typeID = tag.getId();
        switch (typeID) {
            case Tag.TAG_BYTE:
            case Tag.TAG_SHORT:
            case Tag.TAG_INT:
            case Tag.TAG_LONG:
                return ((NumericTag) tag).getAsLong();
            case Tag.TAG_FLOAT:
            case Tag.TAG_DOUBLE:
                return ((NumericTag) tag).getAsDouble();
            case Tag.TAG_STRING: // String
                return tag.getAsString();
            case Tag.TAG_COMPOUND: // Compound
            {
                CompoundTag compound = (CompoundTag) tag;
                Map<String, Object> map = new HashMap<>(compound.size());
                for (String key : compound.getAllKeys()) {
                    Object value = toLua(compound.get(key));
                    if (value != null) map.put(key, value);
                }
                return map;
            }
            case Tag.TAG_LIST: {
                ListTag list = (ListTag) tag;
                Map<Integer, Object> map = new HashMap<>(list.size());
                for (int i = 0; i < list.size(); i++) map.put(i, toLua(list.get(i)));
                return map;
            }
            case Tag.TAG_BYTE_ARRAY: {
                byte[] array = ((ByteArrayTag) tag).getAsByteArray();
                Map<Integer, Byte> map = new HashMap<>(array.length);
                for (int i = 0; i < array.length; i++) map.put(i + 1, array[i]);
                return map;
            }
            case Tag.TAG_INT_ARRAY: {
                int[] array = ((IntArrayTag) tag).getAsIntArray();
                Map<Integer, Integer> map = new HashMap<>(array.length);
                for (int i = 0; i < array.length; i++) map.put(i + 1, array[i]);
                return map;
            }
            case Tag.TAG_LONG_ARRAY: {
                long[] array = ((LongArrayTag) tag).getAsLongArray();
                Map<Integer, Long> map = new HashMap<>(array.length);
                for (int i = 0; i < array.length; i++) map.put(i + 1, array[i]);
                return map;
            }
            default: 
                return null;
        }
    }

I renamed this function to patchedToLua, and have simply been playing with the patched version of the mod.

I am unsure whether you guys take contributions / PRs for older versions, I apologize for wasting your time if not 😅 , that being said, my investigations show that this is patched in the latest version in 1.21 (likely due to the whole switch to data components).

I have also made an issue about this within CC (identical text), and hopefully something comes of this!

If you'd like me to make a PR in AP where I replace all usages for the toLua, or source our own NBT conversion technique, let me know!

Kind regards,

Steps to reproduce

  1. Place an ME bridge interacting with a storage bus pointed to an ME drive (a sort of meta network? You should be able to control drives )
  2. Use peripherals.call("getItems")
  3. I'd expect to see the amts tag there, however I do not.

Multiplayer?

Yes

Version

Own compiled build.

Minecraft, Forge and maybe other related mods versions

forge_version=40.2.4, cc_version=1.18.2:1.101.0

Screenshots or Videos

No response

Crashlog/log

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions