CC: Tweaked 1.18.2 does not seem to take into account NBT Long arrays.
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:
https://github.com/IntelligenceModding/AdvancedPeripherals/blob/a8d481af49ca6d0f1a7b740e894fce9511858fdd/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/AppEngApi.java#L135-L149
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
- 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 )
- Use peripherals.call("getItems")
- I'd expect to see the
amtstag 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
Thanks for your investigation! Unfortunately, 1.18.2 only accepts critical fixes. But if you can make a PR for 1.19.2, I'm glad to review it. Or idk if @SirEndii will count this as a critical issue.