diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataKey.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataKey.java index 1a0bcbe5d..ea34f2cd9 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataKey.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataKey.java @@ -42,6 +42,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.Instrument; import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker; import com.viaversion.viaversion.api.minecraft.item.data.PotionContents; import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect; +import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable; import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; @@ -51,7 +52,7 @@ public final class StructuredDataKey { public static final StructuredDataKey CUSTOM_DATA = new StructuredDataKey<>("custom_data", Type.COMPOUND_TAG); public static final StructuredDataKey DAMAGE = new StructuredDataKey<>("damage", Type.VAR_INT); - public static final StructuredDataKey UNBREAKABLE = new StructuredDataKey<>("unbreakable", Type.BOOLEAN); + public static final StructuredDataKey UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE); public static final StructuredDataKey CUSTOM_NAME = new StructuredDataKey<>("custom_name", Type.TAG); public static final StructuredDataKey LORE = new StructuredDataKey<>("lore", Type.TAG_ARRAY); public static final StructuredDataKey ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Unbreakable.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Unbreakable.java new file mode 100644 index 000000000..841506322 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Unbreakable.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.minecraft.item.data; + +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; + +public final class Unbreakable { + + public static final Type TYPE = new Type(Unbreakable.class) { + @Override + public Unbreakable read(final ByteBuf buffer) { + return new Unbreakable(buffer.readBoolean()); + } + + @Override + public void write(final ByteBuf buffer, final Unbreakable value) { + buffer.writeBoolean(value.showInTooltip()); + } + }; + + private final boolean showInTooltip; + + public Unbreakable(final boolean showInTooltip) { + this.showInTooltip = showInTooltip; + } + + public boolean showInTooltip() { + return showInTooltip; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/AttributeMappings.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Attributes1_20_3.java similarity index 94% rename from common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/AttributeMappings.java rename to common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Attributes1_20_3.java index 5e1a8ae48..7e20b3516 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/AttributeMappings.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Attributes1_20_3.java @@ -20,10 +20,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; import com.viaversion.viaversion.util.KeyMappings; import org.checkerframework.checker.nullness.qual.Nullable; -/** - * String to/from int ID mappings for 1.20.3 attributes. - */ -public final class AttributeMappings { +public final class Attributes1_20_3 { private static final KeyMappings ATTRIBUTES = new KeyMappings( "generic.armor", diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/EnchantmentMappings.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Enchantments1_20_3.java similarity index 98% rename from common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/EnchantmentMappings.java rename to common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Enchantments1_20_3.java index 3fd7b5bfe..a6db68bb5 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/EnchantmentMappings.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Enchantments1_20_3.java @@ -20,7 +20,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; import com.viaversion.viaversion.util.KeyMappings; import org.checkerframework.checker.nullness.qual.Nullable; -public final class EnchantmentMappings { +public final class Enchantments1_20_3 { public static final KeyMappings ENCHANTMENTS = new KeyMappings( "protection", diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/InstrumentMappings.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Instruments1_20_3.java similarity index 97% rename from common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/InstrumentMappings.java rename to common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Instruments1_20_3.java index 33948b568..4616ed7bb 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/InstrumentMappings.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Instruments1_20_3.java @@ -20,7 +20,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; import com.viaversion.viaversion.util.KeyMappings; import org.checkerframework.checker.nullness.qual.Nullable; -public final class InstrumentMappings { +public final class Instruments1_20_3 { private static final KeyMappings MAPPINGS = new KeyMappings( "ponder_goat_horn", diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorationMappings.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorations1_20_3.java similarity index 97% rename from common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorationMappings.java rename to common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorations1_20_3.java index 24c46bc31..f9a2a8e56 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorationMappings.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MapDecorations1_20_3.java @@ -19,7 +19,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; import com.viaversion.viaversion.util.KeyMappings; -public final class MapDecorationMappings { +public final class MapDecorations1_20_3 { private static final KeyMappings MAP_DECORATIONS = new KeyMappings( "player", diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Potions1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Potions1_20_3.java new file mode 100644 index 000000000..717943bed --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/Potions1_20_3.java @@ -0,0 +1,78 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; + +import com.viaversion.viaversion.util.KeyMappings; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class Potions1_20_3 { + + private static final KeyMappings POTIONS = new KeyMappings( + "empty", + "water", + "mundane", + "thick", + "awkward", + "night_vision", + "long_night_vision", + "invisibility", + "long_invisibility", + "leaping", + "long_leaping", + "strong_leaping", + "fire_resistance", + "long_fire_resistance", + "swiftness", + "long_swiftness", + "strong_swiftness", + "slowness", + "long_slowness", + "strong_slowness", + "turtle_master", + "long_turtle_master", + "strong_turtle_master", + "water_breathing", + "long_water_breathing", + "healing", + "strong_healing", + "harming", + "strong_harming", + "poison", + "long_poison", + "strong_poison", + "regeneration", + "long_regeneration", + "strong_regeneration", + "strength", + "long_strength", + "strong_strength", + "weakness", + "long_weakness", + "luck", + "slow_falling", + "long_slow_falling" + ); + + public static @Nullable String idToKey(final int id) { + return POTIONS.idToKey(id); + } + + public static int keyToId(final String attribute) { + return POTIONS.keyToId(attribute); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimMaterials1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimMaterials1_20_3.java new file mode 100644 index 000000000..52e96f414 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimMaterials1_20_3.java @@ -0,0 +1,45 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; + +import com.viaversion.viaversion.util.KeyMappings; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class TrimMaterials1_20_3 { + + private static final KeyMappings MATERIALS = new KeyMappings( + "quartz", + "iron", + "netherite", + "redstone", + "copper", + "gold", + "emerald", + "diamond", + "lapis", + "amethyst" + ); + + public static @Nullable String idToKey(final int id) { + return MATERIALS.idToKey(id); + } + + public static int keyToId(final String attribute) { + return MATERIALS.keyToId(attribute); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimPatterns1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimPatterns1_20_3.java new file mode 100644 index 000000000..e34d6e449 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/TrimPatterns1_20_3.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data; + +import com.viaversion.viaversion.util.KeyMappings; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class TrimPatterns1_20_3 { + + private static final KeyMappings PATTERNS = new KeyMappings( + "sentry", + "dune", + "coast", + "wild", + "ward", + "eye", + "vex", + "tide", + "snout", + "rib", + "spire", + "wayfinder", + "shaper", + "silence", + "raiser", + "host" + ); + + public static @Nullable String idToKey(final int id) { + return PATTERNS.idToKey(id); + } + + public static int keyToId(final String attribute) { + return PATTERNS.keyToId(attribute); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java index f2f11dad6..6ca32476a 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java @@ -34,6 +34,9 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.DataItem; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.StructuredItem; +import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim; +import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimMaterial; +import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimPattern; import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties; import com.viaversion.viaversion.api.minecraft.item.data.DyedColor; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; @@ -42,7 +45,11 @@ import com.viaversion.viaversion.api.minecraft.item.data.FilterableString; import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion; import com.viaversion.viaversion.api.minecraft.item.data.Fireworks; import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker; +import com.viaversion.viaversion.api.minecraft.item.data.PotionContents; +import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect; +import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData; import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect; +import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable; import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; @@ -53,9 +60,12 @@ import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.Clientb import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3; -import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.EnchantmentMappings; -import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.InstrumentMappings; -import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorationMappings; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Enchantments1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Instruments1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorations1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Potions1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.TrimMaterials1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.TrimPatterns1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.rewriter.BlockRewriter; @@ -68,11 +78,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import org.checkerframework.checker.nullness.qual.Nullable; public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter { + private static final String[] MOB_TAGS = {"NoAI", "Silent", "NoGravity", "Glowing", "Invulnerable", "Health", "Age", "Variant", "HuntingCooldown", "BucketVariantTag"}; private static final GameProfile.Property[] EMPTY_PROPERTIES = new GameProfile.Property[0]; public BlockItemPacketRewriter1_20_5(final Protocol1_20_5To1_20_3 protocol) { @@ -86,14 +98,19 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter updateBlockEntityTag(blockEntity.tag())); protocol.registerClientbound(ClientboundPackets1_20_3.BLOCK_ENTITY_DATA, wrapper -> { wrapper.passthrough(Type.POSITION1_14); // Position wrapper.passthrough(Type.VAR_INT); // Block entity type - // No longer nullable - final CompoundTag tag = wrapper.read(Type.COMPOUND_TAG); - wrapper.write(Type.COMPOUND_TAG, tag != null ? tag : new CompoundTag()); + CompoundTag tag = wrapper.read(Type.COMPOUND_TAG); + if (tag != null) { + updateBlockEntityTag(tag); + } else { + // No longer nullable + tag = new CompoundTag(); + } + wrapper.write(Type.COMPOUND_TAG, tag); }); registerSetCooldown(ClientboundPackets1_20_3.COOLDOWN); @@ -196,7 +213,13 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter explosionsTag = fireworksTag.getListTag("Explosions", CompoundTag.class); if (explosionsTag != null) { - updateFireworks(fireworksTag, explosionsTag, data); + updateFireworks(data, fireworksTag, explosionsTag); } } @@ -339,6 +356,10 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter 0 ? id - 1 : null; // Empty potion type removed + } + + final NumberTag customPotionColorTag = tag.getNumberTag("CustomPotionColor"); + final ListTag customPotionEffectsTag = tag.getListTag("custom_potion_effects", CompoundTag.class); + PotionEffect[] potionEffects = null; + if (customPotionEffectsTag != null) { + potionEffects = customPotionEffectsTag.stream().map(effectTag -> { + final StringTag idTag = effectTag.getStringTag("id"); + if (idTag == null) { + return null; + } + + final int id = PotionEffects.keyToId(idTag.getValue()) - 1; + if (id < 0) { + return null; + } + + final NumberTag amplifierTag = effectTag.getNumberTag("amplifier"); + final NumberTag durationTag = effectTag.getNumberTag("duration"); + final NumberTag ambientTag = effectTag.getNumberTag("ambient"); + final NumberTag showParticlesTag = effectTag.getNumberTag("show_particles"); + final NumberTag showIconTag = effectTag.getNumberTag("show_icon"); + final PotionEffectData effectData = new PotionEffectData( + amplifierTag != null ? amplifierTag.asByte() : 0, + durationTag != null ? durationTag.asInt() : 0, + ambientTag != null && ambientTag.asBoolean(), + showParticlesTag != null && showParticlesTag.asBoolean(), + showIconTag != null && showIconTag.asBoolean(), + null //TODO + ); + return new PotionEffect(id, effectData); + }).filter(Objects::nonNull).toArray(PotionEffect[]::new); + } + + if (potionId != null || customPotionColorTag != null || potionEffects != null) { + data.set(StructuredDataKey.POTION_CONTENTS, new PotionContents( + potionId, + customPotionColorTag != null ? customPotionColorTag.asInt() : null, + potionEffects != null ? potionEffects : new PotionEffect[0] + )); + } + } + + private void updateArmorTrim(final StructuredDataContainer data, final CompoundTag trimTag, final boolean showInTooltip) { + final Tag materialTag = trimTag.get("material"); + final Holder materialHolder; + if (materialTag instanceof StringTag) { + final int id = TrimMaterials1_20_3.keyToId(((StringTag) materialTag).getValue()); + if (id == -1) { + return; + } + materialHolder = Holder.of(id); + } else if (materialTag instanceof CompoundTag) { + /*final CompoundTag materialCompoundTag = (CompoundTag) materialTag; + final StringTag assetNameTag = materialCompoundTag.getStringTag("asset_name"); + final StringTag ingredientTag = materialCompoundTag.getStringTag("ingredient"); + final NumberTag itemModelIndexTag = materialCompoundTag.getNumberTag("item_model_index"); + final CompoundTag overrideArmorMaterialsTag = materialCompoundTag.get("override_armor_materials"); + final Tag descriptionTag = materialCompoundTag.get("description");*/ + return; // TODO + } else return; + + final Tag patternTag = trimTag.get("pattern"); + final Holder patternHolder; + if (patternTag instanceof StringTag) { + final int id = TrimPatterns1_20_3.keyToId(((StringTag) patternTag).getValue()); + if (id == -1) { + return; + } + patternHolder = Holder.of(id); + } else if (patternTag instanceof CompoundTag) { + return; // TODO + } else return; + + data.set(StructuredDataKey.TRIM, new ArmorTrim(materialHolder, patternHolder, showInTooltip)); + } + + private void updateMobTags(final StructuredDataContainer data, final CompoundTag tag) { + final CompoundTag bucketEntityData = new CompoundTag(); + for (final String mobTagKey : MOB_TAGS) { + final Tag mobTag = tag.get(mobTagKey); + if (mobTag != null) { + bucketEntityData.put(mobTagKey, mobTag); + } + } + + if (!bucketEntityData.isEmpty()) { + data.set(StructuredDataKey.BUCKET_ENTITY_DATA, bucketEntityData); + } + } + + private void updateBlockState(final StructuredDataContainer data, final CompoundTag blockState) { final Map properties = new HashMap<>(); for (final Map.Entry entry : blockState.entrySet()) { // It's all strings now because ??? @@ -401,16 +512,16 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter explosionsTag, final StructuredDataContainer data) { + private void updateFireworks(final StructuredDataContainer data, final CompoundTag fireworksTag, final ListTag explosionsTag) { final NumberTag flightDuration = fireworksTag.getNumberTag("Flight"); final Fireworks fireworks = new Fireworks( flightDuration != null ? flightDuration.asInt() : 0, - explosionsTag.stream().map(BlockItemPacketRewriter1_20_5::readExplosion).toArray(FireworkExplosion[]::new) + explosionsTag.stream().map(this::readExplosion).toArray(FireworkExplosion[]::new) ); data.set(StructuredDataKey.FIREWORKS, fireworks); } - private static void updateEffects(final ListTag effects, final StructuredDataContainer data) { + private void updateEffects(final ListTag effects, final StructuredDataContainer data) { final SuspiciousStewEffect[] suspiciousStewEffects = new SuspiciousStewEffect[effects.size()]; for (int i = 0; i < effects.size(); i++) { final CompoundTag effect = effects.get(i); @@ -425,7 +536,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter