diff --git a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java index e146c111..bbb3479e 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java @@ -18,13 +18,17 @@ package com.viaversion.viabackwards.api.rewriters; import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.IntArrayTag; import com.viaversion.nbt.tag.IntTag; import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; import com.viaversion.nbt.tag.Tag; import com.viaversion.viabackwards.api.BackwardsProtocol; import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.data.MappedItem; import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.HolderSet; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; @@ -34,6 +38,8 @@ import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.rewriter.StructuredItemRewriter; import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; import org.checkerframework.checker.nullness.qual.Nullable; public class BackwardsStructuredItemRewriter(data.values()); } + protected Tag holderSetToTag(final HolderSet set) { + if (set.hasIds()) { + return new IntArrayTag(set.ids()); + } else { + return new StringTag(set.tagKey()); + } + } + + protected HolderSet restoreHolderSet(final CompoundTag tag, final String key) { + final Tag savedTag = tag.get(key); + if (savedTag == null) { + return HolderSet.of(new int[0]); + } + + if (savedTag instanceof StringTag tagKey) { + return HolderSet.of(tagKey.getValue()); + } else if (savedTag instanceof IntArrayTag idsTag) { + return HolderSet.of(idsTag.getValue()); + } else { + return HolderSet.of(new int[0]); + } + } + + protected Tag holderToTag(final Holder holder, final BiConsumer valueSaveFunction) { + if (holder.hasId()) { + return new IntTag(holder.id()); + } else { + final CompoundTag savedTag = new CompoundTag(); + valueSaveFunction.accept(holder.value(), savedTag); + return savedTag; + } + } + + protected Holder restoreHolder(final CompoundTag tag, final String key, final Function valueRestoreFunction) { + final Tag savedTag = tag.get(key); + if (savedTag == null) { + return Holder.of(0); + } + + if (savedTag instanceof IntTag idTag) { + return Holder.of(idTag.asInt()); + } else if (savedTag instanceof CompoundTag compoundTag) { + return Holder.of(valueRestoreFunction.apply(compoundTag)); + } else { + return Holder.of(0); + } + } + @Override public String nbtTagName() { return "VB|" + protocol.getClass().getSimpleName(); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java index 8438b9df..83ba8933 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_2to1_21/rewriter/BlockItemPacketRewriter1_21_2.java @@ -19,7 +19,7 @@ package com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter; import com.viaversion.nbt.tag.ByteTag; import com.viaversion.nbt.tag.CompoundTag; -import com.viaversion.nbt.tag.IntArrayTag; +import com.viaversion.nbt.tag.FloatTag; import com.viaversion.nbt.tag.IntTag; import com.viaversion.nbt.tag.ListTag; import com.viaversion.nbt.tag.Tag; @@ -321,9 +321,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem final HolderSet repairable = data.get(StructuredDataKey.REPAIRABLE); if (repairable != null) { - final CompoundTag tag = new CompoundTag(); - convertHolderSet(tag, repairable); - backupTag.put("repairable", tag); + backupTag.put("repairable", holderSetToTag(repairable)); } final Integer enchantable = data.get(StructuredDataKey.ENCHANTABLE); @@ -361,10 +359,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem tag.putString("camera_overlay", cameraOverlay); } if (equippable.allowedEntities() != null) { - final CompoundTag allowedEntities = new CompoundTag(); - convertHolderSet(allowedEntities, equippable.allowedEntities()); - - tag.put("allowed_entities", allowedEntities); + tag.put("allowed_entities", holderSetToTag(equippable.allowedEntities())); } tag.putBoolean("dispensable", equippable.dispensable()); tag.putBoolean("swappable", equippable.swappable()); @@ -417,11 +412,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem } else if (effect.type() == Types.HOLDER_SET && effect.value() instanceof HolderSet set) { tag.putString("type", "remove_effects"); - if (set.hasIds()) { - tag.put("ids", new IntArrayTag(set.ids())); - } else { - tag.putString("tag", set.tagKey()); - } + tag.put("remove_effects", holderSetToTag(set)); } else if (effect.type() == Types.EMPTY) { tag.putString("type", "clear_all_effects"); } else if (effect.type() == Types.FLOAT) { @@ -449,23 +440,12 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem } private void convertSoundEventHolder(final CompoundTag tag, final Holder holder) { - if (holder.hasId()) { - tag.putInt("sound", holder.id()); - } else { - final SoundEvent event = holder.value(); - tag.putString("identifier", event.identifier()); + tag.put("sound_event", holderToTag(holder, (event, soundEventTag) -> { + soundEventTag.putString("identifier", event.identifier()); if (event.fixedRange() != null) { - tag.putFloat("fixed_range", event.fixedRange()); + soundEventTag.putFloat("fixed_range", event.fixedRange()); } - } - } - - private void convertHolderSet(final CompoundTag tag, final HolderSet set) { - if (set.hasIds()) { - tag.put("ids", new IntArrayTag(set.ids())); - } else { - tag.putString("tag", set.tagKey()); - } + })); } private Consumable1_21_2.ConsumeEffect convertConsumableEffect(final CompoundTag tag) { @@ -483,7 +463,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem final float probability = tag.getFloat("probability"); return new Consumable1_21_2.ConsumeEffect<>(id, Consumable1_21_2.ApplyStatusEffects.TYPE, new Consumable1_21_2.ApplyStatusEffects(potionEffects, probability)); } else if ("remove_effects".equals(type)) { - final HolderSet set = convertHolderSet(tag); + final HolderSet set = restoreHolderSet(tag, "remove_effects"); return new Consumable1_21_2.ConsumeEffect<>(id, Types.HOLDER_SET, set); } else if ("clear_all_effects".equals(type)) { return new Consumable1_21_2.ConsumeEffect<>(id, Types.EMPTY, Unit.INSTANCE); @@ -508,41 +488,22 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem } private Holder convertSoundEventHolder(final CompoundTag tag) { - final IntTag soundId = tag.getIntTag("sound"); - if (soundId != null) { - return Holder.of(soundId.asInt()); - } - - final String identifier = tag.getString("identifier"); - final Float fixedRange = tag.getFloat("fixed_range"); - return Holder.of(new SoundEvent(identifier, fixedRange)); - } - - private HolderSet convertHolderSet(final CompoundTag tag) { - if (tag == null) { - return null; - } - final IntArrayTag ids = tag.getIntArrayTag("ids"); - if (ids != null) { - return HolderSet.of(ids.getValue()); - } - return HolderSet.of(tag.getString("tag")); + return restoreHolder(tag, "sound_event", soundEventTag -> { + final String identifier = soundEventTag.getString("identifier"); + final FloatTag fixedRange = soundEventTag.getFloatTag("fixed_range"); + return new SoundEvent(identifier, fixedRange != null ? fixedRange.asFloat() : null); + }); } private void restoreInconvertibleData(final Item item) { final StructuredDataContainer data = item.dataContainer(); final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); - if (customData == null) { - return; - } - - final CompoundTag backupTag = customData.removeUnchecked(nbtTagName("inconvertible_data")); - if (backupTag == null) { + if (customData == null || !(customData.remove(nbtTagName("inconvertible_data")) instanceof CompoundTag backupTag)) { return; } final Holder instrument = data.get(StructuredDataKey.INSTRUMENT1_21_2); - if (instrument != null) { + if (instrument != null && instrument.isDirect()) { final Tag description = backupTag.get(nbtTagName("instrument_description")); if (description != null) { final Instrument1_21_2 delegate = instrument.value(); @@ -550,10 +511,8 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem } } - final IntArrayTag repairableIds = backupTag.getIntArrayTag("repairable_ids"); - final String repairableTag = backupTag.getString("repairable_tag"); - if (repairableIds != null || repairableTag != null) { - data.set(StructuredDataKey.REPAIRABLE, repairableIds != null ? HolderSet.of(repairableIds.getValue()) : HolderSet.of(repairableTag)); + if (backupTag.contains("repairable")) { + data.set(StructuredDataKey.REPAIRABLE, restoreHolderSet(backupTag, "repairable")); } final IntTag enchantable = backupTag.getIntTag("enchantable"); @@ -564,7 +523,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem final CompoundTag useCooldown = backupTag.getCompoundTag("use_cooldown"); if (useCooldown != null) { final float seconds = useCooldown.getFloat("seconds"); - final String cooldownGroup = useCooldown.getString("cooldown_group", null); + final String cooldownGroup = useCooldown.getString("cooldown_group"); data.set(StructuredDataKey.USE_COOLDOWN, new UseCooldown(seconds, cooldownGroup)); } @@ -573,17 +532,16 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem data.set(StructuredDataKey.ITEM_MODEL, itemModel); } - final CompoundTag equippable = backupTag.getCompoundTag("equippable"); + final CompoundTag equippable = backupTag.getCompoundTag("equitable"); if (equippable != null) { final int equipmentSlot = equippable.getInt("equipment_slot"); final Holder soundEvent = convertSoundEventHolder(equippable); - final String model = equippable.getString("model", null); - final String cameraOverlay = equippable.getString("camera_overlay", null); - final HolderSet allowedEntities = convertHolderSet(equippable.getCompoundTag("allowed_entities")); + final String model = equippable.getString("model"); + final String cameraOverlay = equippable.getString("camera_overlay"); + final HolderSet allowedEntities = equippable.contains("allowed_entities") ? restoreHolderSet(equippable, "allowed_entities") : null; final boolean dispensable = equippable.getBoolean("dispensable"); final boolean swappable = equippable.getBoolean("swappable"); final boolean damageOnHurt = equippable.getBoolean("damage_on_hurt"); - data.set(StructuredDataKey.EQUIPPABLE, new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt)); } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java index c255e2c6..de9bd49b 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java @@ -279,25 +279,18 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe final CompoundTag tag = new CompoundTag(); if (jukeboxPlayable.song().isLeft()) { - final Holder song = jukeboxPlayable.song().left(); - if (song.hasId()) { - tag.putInt("song_id", song.id()); - } else { - final JukeboxPlayable.JukeboxSong songData = song.value(); - final Holder soundEvent = songData.soundEvent(); - if (soundEvent.hasId()) { - tag.putInt("sound", soundEvent.id()); - } else { - final SoundEvent event = soundEvent.value(); - tag.putString("identifier", event.identifier()); - if (event.fixedRange() != null) { - tag.putFloat("fixed_range", event.fixedRange()); + final Holder songHolder = jukeboxPlayable.song().left(); + tag.put("song", holderToTag(songHolder, (song, songTag) -> { + songTag.put("sound_event", holderToTag(song.soundEvent(), (soundEvent, soundEventTag) -> { + soundEventTag.putString("identifier", soundEvent.identifier()); + if (soundEvent.fixedRange() != null) { + soundEventTag.putFloat("fixed_range", soundEvent.fixedRange()); } - } - tag.put("description", songData.description()); - tag.putFloat("length_in_seconds", songData.lengthInSeconds()); - tag.putInt("comparator_output", songData.comparatorOutput()); - } + })); + songTag.put("description", song.description()); + songTag.putFloat("length_in_seconds", song.lengthInSeconds()); + songTag.putInt("comparator_output", song.comparatorOutput()); + })); } else { tag.putString("song_identifier", jukeboxPlayable.song().right()); } @@ -308,36 +301,26 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe private void restoreInconvertibleData(final Item item) { final StructuredDataContainer data = item.dataContainer(); final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); - if (customData == null) { - return; - } - final CompoundTag tag = customData.removeUnchecked(nbtTagName("jukebox_playable")); - if (tag == null) { + if (customData == null || !(customData.remove(nbtTagName("jukebox_playable")) instanceof CompoundTag tag)) { return; } final Either, String> song; - if (tag.contains("song_identifier")) { - song = Either.right(tag.getString("song_identifier")); + final String songIdentifier = tag.getString("song_identifier"); + if (songIdentifier != null) { + song = Either.right(tag.getString(songIdentifier)); } else { - final Holder songData; - if (tag.contains("song_id")) { - songData = Holder.of(tag.getInt("song_id")); - } else { - final Holder soundEvent; - if (tag.contains("sound")) { - soundEvent = Holder.of(tag.getInt("sound")); - } else { - final String identifier = tag.getString("identifier"); - final Float fixedRange = tag.contains("fixed_range") ? tag.getFloat("fixed_range") : null; - soundEvent = Holder.of(new SoundEvent(identifier, fixedRange)); - } - final Tag description = tag.get("description"); - final float lengthInSeconds = tag.getFloat("length_in_seconds"); - final int comparatorOutput = tag.getInt("comparator_output"); - songData = Holder.of(new JukeboxPlayable.JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput)); - } - song = Either.left(songData); + song = Either.left(restoreHolder(tag, "song", songTag -> { + final Holder soundEvent = restoreHolder(songTag, "sound_event", soundTag -> { + final String identifier = soundTag.getString("identifier"); + final Float fixedRange = soundTag.contains("fixed_range") ? soundTag.getFloat("fixed_range") : null; + return new SoundEvent(identifier, fixedRange); + }); + final Tag description = songTag.get("description"); + final float lengthInSeconds = songTag.getFloat("length_in_seconds"); + final int comparatorOutput = songTag.getInt("comparator_output"); + return new JukeboxPlayable.JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput); + })); } final JukeboxPlayable jukeboxPlayable = new JukeboxPlayable(song, tag.getBoolean("show_in_tooltip"));