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 1de87af3b..e0b8afbe0 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 @@ -36,6 +36,8 @@ import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer; import com.viaversion.viaversion.api.minecraft.item.data.Bee; import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties; import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2; +import com.viaversion.viaversion.api.minecraft.item.data.DamageResistant; +import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection; import com.viaversion.viaversion.api.minecraft.item.data.DyedColor; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; import com.viaversion.viaversion.api.minecraft.item.data.Equippable; @@ -93,12 +95,14 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey USE_REMAINDER = new StructuredDataKey<>("use_remainder", Types1_21_2.ITEM); public static final StructuredDataKey USE_COOLDOWN = new StructuredDataKey<>("use_cooldown", UseCooldown.TYPE); public static final StructuredDataKey FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY); + public static final StructuredDataKey DAMAGE_RESISTANT = new StructuredDataKey<>("damage_resistant", DamageResistant.TYPE); public static final StructuredDataKey TOOL = new StructuredDataKey<>("tool", ToolProperties.TYPE); public static final StructuredDataKey ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT); public static final StructuredDataKey EQUIPPABLE = new StructuredDataKey<>("equippable", Equippable.TYPE); public static final StructuredDataKey REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET); public static final StructuredDataKey GLIDER = new StructuredDataKey<>("glider", Types.EMPTY); public static final StructuredDataKey TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING); + public static final StructuredDataKey DEATH_PROTECTION = new StructuredDataKey<>("death_protection", DeathProtection.TYPE); public static final StructuredDataKey STORED_ENCHANTMENTS = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE); public static final StructuredDataKey DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE); public static final StructuredDataKey MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT); @@ -111,7 +115,8 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey BUNDLE_CONTENTS1_20_5 = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY); public static final StructuredDataKey BUNDLE_CONTENTS1_21 = new StructuredDataKey<>("bundle_contents", Types1_21.ITEM_ARRAY); public static final StructuredDataKey BUNDLE_CONTENTS1_21_2 = new StructuredDataKey<>("bundle_contents", Types1_21_2.ITEM_ARRAY); - public static final StructuredDataKey POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE); + public static final StructuredDataKey POTION_CONTENTS1_20_5 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_20_5); + public static final StructuredDataKey POTION_CONTENTS1_21_2 = new StructuredDataKey<>("potion_contents", PotionContents.TYPE1_21_2); public static final StructuredDataKey SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE); public static final StructuredDataKey WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE); public static final StructuredDataKey WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DamageResistant.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DamageResistant.java new file mode 100644 index 000000000..39ed94a57 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DamageResistant.java @@ -0,0 +1,43 @@ +/* + * 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 com.viaversion.viaversion.api.type.Types; +import io.netty.buffer.ByteBuf; + +public record DamageResistant(String typesTagKey) { + + public static final Type TYPE = new Type<>(DamageResistant.class) { + @Override + public DamageResistant read(final ByteBuf buffer) { + final String typesTagKey = Types.STRING.read(buffer); + return new DamageResistant(typesTagKey); + } + + @Override + public void write(final ByteBuf buffer, final DamageResistant value) { + Types.STRING.write(buffer, value.typesTagKey()); + } + }; +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DeathProtection.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DeathProtection.java new file mode 100644 index 000000000..3a5c784d1 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/DeathProtection.java @@ -0,0 +1,44 @@ +/* + * 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.minecraft.item.data.Consumable1_21_2.ConsumeEffect; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.Types; +import io.netty.buffer.ByteBuf; + +public record DeathProtection(ConsumeEffect[] deathEffects) { + + public static final Type TYPE = new Type<>(DeathProtection.class) { + @Override + public DeathProtection read(final ByteBuf buffer) { + final ConsumeEffect[] deathEffects = ConsumeEffect.ARRAY_TYPE.read(buffer); + return new DeathProtection(deathEffects); + } + + @Override + public void write(final ByteBuf buffer, final DeathProtection value) { + ConsumeEffect.ARRAY_TYPE.write(buffer, value.deathEffects); + } + }; +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java index 5b3eb58a7..292a8cf6a 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java @@ -32,7 +32,8 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction; import org.checkerframework.checker.nullness.qual.Nullable; public record Equippable(int equipmentSlot, Holder soundEvent, @Nullable String model, - @Nullable HolderSet allowedEntities, boolean dispensable) { + @Nullable HolderSet allowedEntities, boolean dispensable, boolean swappable, + boolean damageOnHurt) { public static final Type TYPE = new Type<>(Equippable.class) { @Override @@ -42,7 +43,9 @@ public record Equippable(int equipmentSlot, Holder soundEvent, @Null final String model = Types.STRING.read(buffer); final HolderSet allowedEntities = Types.HOLDER_SET.read(buffer); final boolean dispensable = buffer.readBoolean(); - return new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable); + final boolean swappable = buffer.readBoolean(); + final boolean damageOnHurt = buffer.readBoolean(); + return new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable, swappable, damageOnHurt); } @Override @@ -52,11 +55,13 @@ public record Equippable(int equipmentSlot, Holder soundEvent, @Null Types.STRING.write(buffer, value.model()); Types.HOLDER_SET.write(buffer, value.allowedEntities()); buffer.writeBoolean(value.dispensable()); + buffer.writeBoolean(value.swappable()); + buffer.writeBoolean(value.damageOnHurt()); } }; public Equippable rewrite(final Int2IntFunction soundIdRewriter) { final Holder soundEvent = this.soundEvent.updateId(soundIdRewriter); - return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable); + return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable, swappable, damageOnHurt); } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/PotionContents.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/PotionContents.java index 81fdbb956..154c33d36 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/PotionContents.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/PotionContents.java @@ -27,15 +27,20 @@ import com.viaversion.viaversion.api.type.Types; import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; -public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects) { +public record PotionContents(@Nullable Integer potion, @Nullable Integer customColor, PotionEffect[] customEffects, + @Nullable String customName) { - public static final Type TYPE = new Type<>(PotionContents.class) { + public PotionContents(final @Nullable Integer potion, final @Nullable Integer customColor, final PotionEffect[] customEffects) { + this(potion, customColor, customEffects, null); + } + + public static final Type TYPE1_20_5 = new Type<>(PotionContents.class) { @Override public PotionContents read(final ByteBuf buffer) { final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null; final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null; final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer); - return new PotionContents(potion, customColor, customEffects); + return new PotionContents(potion, customColor, customEffects, null); } @Override @@ -53,4 +58,31 @@ public record PotionContents(@Nullable Integer potion, @Nullable Integer customC PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects); } }; + + public static final Type TYPE1_21_2 = new Type<>(PotionContents.class) { + @Override + public PotionContents read(final ByteBuf buffer) { + final Integer potion = buffer.readBoolean() ? Types.VAR_INT.readPrimitive(buffer) : null; + final Integer customColor = buffer.readBoolean() ? buffer.readInt() : null; + final PotionEffect[] customEffects = PotionEffect.ARRAY_TYPE.read(buffer); + final String customName = Types.OPTIONAL_STRING.read(buffer); + return new PotionContents(potion, customColor, customEffects, customName); + } + + @Override + public void write(final ByteBuf buffer, final PotionContents value) { + buffer.writeBoolean(value.potion != null); + if (value.potion != null) { + Types.VAR_INT.writePrimitive(buffer, value.potion); + } + + buffer.writeBoolean(value.customColor != null); + if (value.customColor != null) { + buffer.writeInt(value.customColor); + } + + PotionEffect.ARRAY_TYPE.write(buffer, value.customEffects); + Types.OPTIONAL_STRING.write(buffer, value.customName); + } + }; } diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java index a82ddee97..74c995bb9 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java @@ -86,7 +86,7 @@ public class ProtocolVersion implements Comparable { public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4)); public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6)); public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1)); - public static final ProtocolVersion v1_21_2 = register(768, 208, "1.21.2"); + public static final ProtocolVersion v1_21_2 = register(768, 209, "1.21.2"); public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null); public static ProtocolVersion register(int version, String name) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/Protocol1_20_3To1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/Protocol1_20_3To1_20_5.java index 8f7fc2003..7043d9a9a 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/Protocol1_20_3To1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/Protocol1_20_3To1_20_5.java @@ -272,7 +272,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol extends Co registerEmpty(StructuredDataKey.MAP_POST_PROCESSING); register(StructuredDataKey.CHARGED_PROJECTILES1_20_5, this::convertChargedProjectiles); register(StructuredDataKey.BUNDLE_CONTENTS1_20_5, this::convertBundleContents); - register(StructuredDataKey.POTION_CONTENTS, this::convertPotionContents); + register(StructuredDataKey.POTION_CONTENTS1_20_5, this::convertPotionContents); register(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, this::convertSuspiciousStewEffects); register(StructuredDataKey.WRITABLE_BOOK_CONTENT, this::convertWritableBookContent); register(StructuredDataKey.WRITTEN_BOOK_CONTENT, this::convertWrittenBookContent); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/StructuredDataConverter.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/StructuredDataConverter.java index 8233cae93..1c303b05b 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/StructuredDataConverter.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/StructuredDataConverter.java @@ -398,7 +398,7 @@ public final class StructuredDataConverter { enchantmentsTag.add(invalidEnchantment); }); - register(StructuredDataKey.POTION_CONTENTS, (data, tag) -> { + register(StructuredDataKey.POTION_CONTENTS1_20_5, (data, tag) -> { if (data.potion() != null) { final String potion = Potions1_20_5.idToKey(data.potion()); // Include 1.20.5 names if (potion != null) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java index 2e013b40e..c731bb4ab 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java @@ -201,7 +201,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol { @@ -281,6 +284,8 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter< dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21, StructuredDataKey.CONTAINER1_21_2); dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21, StructuredDataKey.CHARGED_PROJECTILES1_21_2); dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21, StructuredDataKey.BUNDLE_CONTENTS1_21_2); + dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_20_5, StructuredDataKey.POTION_CONTENTS1_21_2); + dataContainer.replace(StructuredDataKey.FIRE_RESISTANT, StructuredDataKey.DAMAGE_RESISTANT, fireResistant -> new DamageResistant("minecraft:is_fire")); } public static void downgradeItemData(final Item item) { @@ -302,6 +307,13 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter< dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21_2, StructuredDataKey.CONTAINER1_21); dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21_2, StructuredDataKey.CHARGED_PROJECTILES1_21); dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21_2, StructuredDataKey.BUNDLE_CONTENTS1_21); + dataContainer.replaceKey(StructuredDataKey.POTION_CONTENTS1_21_2, StructuredDataKey.POTION_CONTENTS1_20_5); + dataContainer.replace(StructuredDataKey.DAMAGE_RESISTANT, StructuredDataKey.FIRE_RESISTANT, damageResistant -> { + if (Key.stripMinecraftNamespace(damageResistant.typesTagKey()).equals("is_fire")) { + return Unit.INSTANCE; + } + return null; + }); dataContainer.remove(StructuredDataKey.REPAIRABLE); dataContainer.remove(StructuredDataKey.ENCHANTABLE); dataContainer.remove(StructuredDataKey.CONSUMABLE1_21_2); @@ -311,5 +323,6 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter< dataContainer.remove(StructuredDataKey.EQUIPPABLE); dataContainer.remove(StructuredDataKey.GLIDER); dataContainer.remove(StructuredDataKey.TOOLTIP_STYLE); + dataContainer.remove(StructuredDataKey.DEATH_PROTECTION); } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/ComponentRewriter1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/ComponentRewriter1_21_2.java index 74d79188e..2840e8745 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/ComponentRewriter1_21_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/ComponentRewriter1_21_2.java @@ -53,6 +53,8 @@ public final class ComponentRewriter1_21_2 extends ComponentRewriter