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 7f40096ce..e6835b092 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 @@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.nbt.tag.Tag; import com.viaversion.viaversion.api.minecraft.GameProfile; import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.HolderSet; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate; import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim; @@ -40,7 +41,8 @@ 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.FoodProperties; -import com.viaversion.viaversion.api.minecraft.item.data.Instrument; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2; import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable; import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker; import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations; @@ -53,6 +55,7 @@ import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; import com.viaversion.viaversion.api.type.types.version.Types1_21; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; import com.viaversion.viaversion.util.Unit; public record StructuredDataKey(String identifier, Type type) { @@ -82,6 +85,8 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21); public static final StructuredDataKey FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY); 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 REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET); 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); @@ -90,8 +95,10 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey MAP_POST_PROCESSING = new StructuredDataKey<>("map_post_processing", Types.VAR_INT); public static final StructuredDataKey CHARGED_PROJECTILES1_20_5 = new StructuredDataKey<>("charged_projectiles", Types1_20_5.ITEM_ARRAY); public static final StructuredDataKey CHARGED_PROJECTILES1_21 = new StructuredDataKey<>("charged_projectiles", Types1_21.ITEM_ARRAY); + public static final StructuredDataKey CHARGED_PROJECTILES1_21_2 = new StructuredDataKey<>("charged_projectiles", Types1_21_2.ITEM_ARRAY); 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 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); @@ -101,7 +108,8 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG); public static final StructuredDataKey BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG); public static final StructuredDataKey BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG); - public static final StructuredDataKey> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE); + public static final StructuredDataKey> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE); + public static final StructuredDataKey> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE); public static final StructuredDataKey OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT); public static final StructuredDataKey JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE); public static final StructuredDataKey RECIPES = new StructuredDataKey<>("recipes", Types.TAG); @@ -115,6 +123,7 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE); public static final StructuredDataKey CONTAINER1_20_5 = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY); public static final StructuredDataKey CONTAINER1_21 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY); + public static final StructuredDataKey CONTAINER1_21_2 = new StructuredDataKey<>("container", Types1_21_2.ITEM_ARRAY); public static final StructuredDataKey BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE); public static final StructuredDataKey BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE); public static final StructuredDataKey LOCK = new StructuredDataKey<>("lock", Types.TAG); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_20_5.java similarity index 87% rename from api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java rename to api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_20_5.java index bb81c61cf..3d34f3989 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_20_5.java @@ -29,19 +29,19 @@ import com.viaversion.viaversion.api.type.types.misc.HolderType; import io.netty.buffer.ByteBuf; import it.unimi.dsi.fastutil.ints.Int2IntFunction; -public record Instrument(Holder soundEvent, int useDuration, float range) { +public record Instrument1_20_5(Holder soundEvent, int useDuration, float range) { - public static final HolderType TYPE = new HolderType<>() { + public static final HolderType TYPE = new HolderType<>() { @Override - public Instrument readDirect(final ByteBuf buffer) { + public Instrument1_20_5 readDirect(final ByteBuf buffer) { final Holder soundEvent = Types.SOUND_EVENT.read(buffer); final int useDuration = Types.VAR_INT.readPrimitive(buffer); final float range = buffer.readFloat(); - return new Instrument(soundEvent, useDuration, range); + return new Instrument1_20_5(soundEvent, useDuration, range); } @Override - public void writeDirect(final ByteBuf buffer, final Instrument value) { + public void writeDirect(final ByteBuf buffer, final Instrument1_20_5 value) { Types.SOUND_EVENT.write(buffer, value.soundEvent()); Types.VAR_INT.writePrimitive(buffer, value.useDuration()); buffer.writeFloat(value.range()); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_21_2.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_21_2.java new file mode 100644 index 000000000..f9f7c8c22 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument1_21_2.java @@ -0,0 +1,54 @@ +/* + * 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.nbt.tag.Tag; +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.SoundEvent; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import io.netty.buffer.ByteBuf; +import org.checkerframework.checker.nullness.qual.Nullable; + +public record Instrument1_21_2(Holder soundEvent, float useDuration, float range, @Nullable Tag description) { + + public static final HolderType TYPE = new HolderType<>() { + @Override + public Instrument1_21_2 readDirect(final ByteBuf buffer) { + final Holder soundEvent = Types.SOUND_EVENT.read(buffer); + final float useDuration = Types.FLOAT.readPrimitive(buffer); + final float range = buffer.readFloat(); + final Tag description = Types.TAG.read(buffer); + return new Instrument1_21_2(soundEvent, useDuration, range, description); + } + + @Override + public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) { + Types.SOUND_EVENT.write(buffer, value.soundEvent()); + Types.FLOAT.writePrimitive(buffer, value.useDuration()); + buffer.writeFloat(value.range()); + Types.TAG.write(buffer, value.description()); + } + }; + +} 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 2e7e8e15f..25073d75b 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 @@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable { private static final List VERSION_LIST = new ArrayList<>(); public static final ProtocolVersion v1_7_2 = register(4, "1.7.2-1.7.5", new SubVersionRange("1.7", 2, 5)); - @Deprecated(forRemoval=true) public static final ProtocolVersion v1_7_1 = v1_7_2; + @Deprecated(forRemoval = true) + public static final ProtocolVersion v1_7_1 = v1_7_2; public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new SubVersionRange("1.7", 6, 10)); public static final ProtocolVersion v1_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9)); public static final ProtocolVersion v1_9 = register(107, "1.9"); @@ -85,6 +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, 205, "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/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21_2.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21_2.java new file mode 100644 index 000000000..3982b74cb --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21_2.java @@ -0,0 +1,56 @@ +/* + * 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.type.types.version; + +import com.viaversion.viaversion.api.minecraft.Particle; +import com.viaversion.viaversion.api.minecraft.data.StructuredData; +import com.viaversion.viaversion.api.minecraft.entitydata.EntityData; +import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.ArrayType; +import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType; +import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType; +import com.viaversion.viaversion.api.type.types.item.ItemCostType1_20_5; +import com.viaversion.viaversion.api.type.types.item.ItemType1_20_5; +import com.viaversion.viaversion.api.type.types.item.StructuredDataType; +import com.viaversion.viaversion.api.type.types.misc.ParticleType; +import java.util.List; + +// Most of these are only safe to use after protocol loading +public final class Types1_21_2 { + + public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType(); + public static final Type[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA); + public static final ItemType1_20_5 ITEM = new ItemType1_20_5(STRUCTURED_DATA); + public static final Type OPTIONAL_ITEM = ITEM.new OptionalItemType(); // Optional as in boolean prefixed, not via the amount + public static final Type ITEM_ARRAY = new ArrayType<>(ITEM); + public static final Type ITEM_COST = new ItemCostType1_20_5(STRUCTURED_DATA_ARRAY); + public static final Type OPTIONAL_ITEM_COST = new ItemCostType1_20_5.OptionalItemCostType(ITEM_COST); + + public static final ParticleType PARTICLE = new ParticleType(); + public static final ArrayType PARTICLES = new ArrayType<>(PARTICLE); + public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(PARTICLE, PARTICLES); + public static final Type ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES); + public static final Type> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA); +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java index cc00403bb..19bf8f8d0 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java @@ -76,6 +76,7 @@ import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21; import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2; import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9; import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.Protocol1_9_1To1_9_3; import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10; @@ -192,6 +193,7 @@ public class ProtocolManagerImpl implements ProtocolManager { registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3); registerProtocol(new Protocol1_20_5To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5); + registerProtocol(new Protocol1_21To1_21_2(), ProtocolVersion.v1_21_2, ProtocolVersion.v1_21); } @Override diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/template/BlockItemPacketRewriter1_99.java b/common/src/main/java/com/viaversion/viaversion/protocols/template/BlockItemPacketRewriter1_99.java index 655e1db33..1a340a153 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/template/BlockItemPacketRewriter1_99.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/template/BlockItemPacketRewriter1_99.java @@ -19,11 +19,11 @@ package com.viaversion.viaversion.protocols.template; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.version.Types1_21; -import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.RecipeRewriter1_21_2; import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.StructuredItemRewriter; @@ -59,19 +59,19 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); + new RecipeRewriter1_21_2<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); // OR do this if serialization of recipes changed and override the relevant method // Add new serializers to RecipeRewriter, or extend the last one for changes - // new RecipeRewriter1_20_3(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES); + // new RecipeRewriter1_21_2(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES); } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java index 7df19e7cb..2a7e1b24a 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java @@ -353,7 +353,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT))); } }); @@ -594,7 +594,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol { String s = wrapper.read(Types.STRING); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_1to1_19_3/rewriter/RecipeRewriter1_19_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_1to1_19_3/rewriter/RecipeRewriter1_19_3.java index 9dc66ac5b..e23430f51 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_1to1_19_3/rewriter/RecipeRewriter1_19_3.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_1to1_19_3/rewriter/RecipeRewriter1_19_3.java @@ -50,8 +50,7 @@ public class RecipeRewriter1_19_3 extends Recip wrapper.passthrough(Types.STRING); // Group wrapper.passthrough(Types.VAR_INT); // Crafting book category handleIngredients(wrapper); - final Item result = rewrite(wrapper.user(), wrapper.read(itemType())); - wrapper.write(mappedItemType(), result); + wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); } @Override diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_2to1_20_3/rewriter/RecipeRewriter1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_2to1_20_3/rewriter/RecipeRewriter1_20_3.java index 85ac0e454..a069154a9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_2to1_20_3/rewriter/RecipeRewriter1_20_3.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_2to1_20_3/rewriter/RecipeRewriter1_20_3.java @@ -64,4 +64,4 @@ public class RecipeRewriter1_20_3 extends Recip protected Type mappedItemArrayType() { return protocol.getItemRewriter().mappedItemArrayType(); } -} \ No newline at end of file +} 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 909b8adf4..8f7fc2003 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 @@ -275,7 +275,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol extends Co register(StructuredDataKey.ENTITY_DATA, this::convertEntityData); register(StructuredDataKey.BUCKET_ENTITY_DATA, this::convertBucketEntityData); register(StructuredDataKey.BLOCK_ENTITY_DATA, this::convertBlockEntityData); - register(StructuredDataKey.INSTRUMENT, this::convertInstrument); + register(StructuredDataKey.INSTRUMENT1_20_5, this::convertInstrument); register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, this::convertOminousBottleAmplifier); register(StructuredDataKey.RECIPES, this::convertRecipes); register(StructuredDataKey.LODESTONE_TRACKER, this::convertLodestoneTracker); @@ -745,12 +745,12 @@ public class ComponentRewriter1_20_5 extends Co return convertNbtWithId(value); } - protected Tag convertInstrument(final Holder value) { + protected Tag convertInstrument(final Holder value) { if (value.hasId()) { return new StringTag(Instruments1_20_3.idToKey(value.id())); } - final Instrument instrument = value.value(); + final Instrument1_20_5 instrument = value.value(); final CompoundTag tag = new CompoundTag(); final Holder sound = instrument.soundEvent(); if (sound.hasId()) { 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 1951e1294..13d008cb8 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 @@ -45,7 +45,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent; 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.FoodEffect; -import com.viaversion.viaversion.api.minecraft.item.data.Instrument; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5; 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.StatePropertyMatcher; @@ -278,12 +278,12 @@ public final class StructuredDataConverter { } profileTag.put("Properties", propertiesTag); }); - register(StructuredDataKey.INSTRUMENT, (data, tag) -> { + register(StructuredDataKey.INSTRUMENT1_20_5, (data, tag) -> { // Can't do anything with direct values if (!data.hasId()) { if (backupInconvertibleData) { final CompoundTag backupTag = new CompoundTag(); - final Instrument instrument = data.value(); + final Instrument1_20_5 instrument = data.value(); if (instrument.soundEvent().hasId()) { backupTag.putInt("sound_event", instrument.soundEvent().id()); } else { 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 9178ff36b..2e013b40e 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 @@ -204,7 +204,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol. + */ +package com.viaversion.viaversion.protocols.v1_21to1_21_2; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.data.MappingData; +import com.viaversion.viaversion.api.data.MappingDataBase; +import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; +import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; +import com.viaversion.viaversion.api.protocol.AbstractProtocol; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; +import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.misc.ParticleType; +import com.viaversion.viaversion.api.type.types.version.Types1_21; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; +import com.viaversion.viaversion.data.entity.EntityTrackerBase; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.EntityPacketRewriter1_21_2; +import com.viaversion.viaversion.rewriter.AttributeRewriter; +import com.viaversion.viaversion.rewriter.SoundRewriter; +import com.viaversion.viaversion.rewriter.StatisticsRewriter; +import com.viaversion.viaversion.rewriter.TagRewriter; + +import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap; + +public final class Protocol1_21To1_21_2 extends AbstractProtocol { + + public static final MappingData MAPPINGS = new MappingDataBase("1.21", "1.21.2"); + private final EntityPacketRewriter1_21_2 entityRewriter = new EntityPacketRewriter1_21_2(this); + private final BlockItemPacketRewriter1_21_2 itemRewriter = new BlockItemPacketRewriter1_21_2(this); + private final TagRewriter tagRewriter = new TagRewriter<>(this); + + public Protocol1_21To1_21_2() { + super(ClientboundPacket1_21.class, ClientboundPacket1_21_2.class, ServerboundPacket1_20_5.class, ServerboundPacket1_21_2.class); + } + + @Override + protected void registerPackets() { + super.registerPackets(); + + // TODO Container ids + // TODO Ingredient now holder set??? + + tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS); + tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS); + + final SoundRewriter soundRewriter = new SoundRewriter<>(this); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND); + soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY); + + new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS); + new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.UPDATE_ATTRIBUTES); + + // Uncomment if an existing type changed serialization format. Mappings for argument type keys can also be defined in mapping files + /*new CommandRewriter1_19_4<>(this) { + @Override + public void handleArgument(final PacketWrapper wrapper, final String argumentType) { + if (argumentType.equals("minecraft:abc")) { + // New argument + wrapper.write(Types.INT, 0); + } else { + super.handleArgument(wrapper, argumentType); + } + } + }.registerDeclareCommands1_19(ClientboundPackets1_21.COMMANDS);*/ + + registerServerbound(ServerboundPackets1_21_2.CLIENT_INFORMATION, this::clientInformation); + registerServerbound(ServerboundConfigurationPackets1_20_5.CLIENT_INFORMATION, this::clientInformation); + + cancelServerbound(ServerboundPackets1_21_2.BUNDLE_ITEM_SELECTED); + cancelServerbound(ServerboundPackets1_21_2.CLIENT_TICK_END); + } + + private void clientInformation(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Locale + wrapper.passthrough(Types.BYTE); // View distance + wrapper.passthrough(Types.VAR_INT); // Chat visibility + wrapper.passthrough(Types.BOOLEAN); // Chat colors + wrapper.passthrough(Types.BYTE); // Skin parts + wrapper.passthrough(Types.VAR_INT); // Main hand + wrapper.passthrough(Types.BOOLEAN); // Text filtering enabled + wrapper.passthrough(Types.BOOLEAN); // Allow listing + wrapper.read(Types.VAR_INT); + } + + @Override + protected void onMappingDataLoaded() { + Types1_21_2.PARTICLE.filler(this) + .reader("block", ParticleType.Readers.BLOCK) + .reader("block_marker", ParticleType.Readers.BLOCK) + .reader("dust", ParticleType.Readers.DUST) + .reader("falling_dust", ParticleType.Readers.BLOCK) + .reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION) + .reader("item", ParticleType.Readers.item(Types1_21_2.ITEM)) + .reader("vibration", ParticleType.Readers.VIBRATION1_20_3) + .reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE) + .reader("shriek", ParticleType.Readers.SHRIEK); + Types1_21_2.STRUCTURED_DATA.filler(this) + .add(StructuredDataKey.CUSTOM_DATA).add(StructuredDataKey.MAX_STACK_SIZE).add(StructuredDataKey.MAX_DAMAGE) + .add(StructuredDataKey.DAMAGE).add(StructuredDataKey.UNBREAKABLE).add(StructuredDataKey.RARITY) + .add(StructuredDataKey.HIDE_TOOLTIP).add(StructuredDataKey.FIRE_RESISTANT) + .add(StructuredDataKey.CUSTOM_NAME).add(StructuredDataKey.LORE).add(StructuredDataKey.ENCHANTMENTS) + .add(StructuredDataKey.CAN_PLACE_ON).add(StructuredDataKey.CAN_BREAK) + .add(StructuredDataKey.CUSTOM_MODEL_DATA).add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP).add(StructuredDataKey.REPAIR_COST) + .add(StructuredDataKey.CREATIVE_SLOT_LOCK).add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE).add(StructuredDataKey.INTANGIBLE_PROJECTILE) + .add(StructuredDataKey.STORED_ENCHANTMENTS).add(StructuredDataKey.DYED_COLOR).add(StructuredDataKey.MAP_COLOR) + .add(StructuredDataKey.MAP_ID).add(StructuredDataKey.MAP_DECORATIONS).add(StructuredDataKey.MAP_POST_PROCESSING) + .add(StructuredDataKey.CHARGED_PROJECTILES1_21_2).add(StructuredDataKey.BUNDLE_CONTENTS1_21_2).add(StructuredDataKey.POTION_CONTENTS) + .add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT) + .add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA) + .add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_21_2) + .add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION) + .add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND) + .add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS) + .add(StructuredDataKey.CONTAINER1_21_2).add(StructuredDataKey.BLOCK_STATE).add(StructuredDataKey.BEES) + .add(StructuredDataKey.LOCK).add(StructuredDataKey.CONTAINER_LOOT).add(StructuredDataKey.TOOL) + .add(StructuredDataKey.ITEM_NAME).add(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER) + .add(StructuredDataKey.FOOD1_21).add(StructuredDataKey.JUKEBOX_PLAYABLE).add(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21) + .add(StructuredDataKey.REPAIRABLE).add(StructuredDataKey.ENCHANTABLE); + super.onMappingDataLoaded(); + } + + @Override + public void init(final UserConnection connection) { + addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_20_5.PLAYER)); + } + + @Override + public MappingData getMappingData() { + return MAPPINGS; + } + + @Override + public EntityPacketRewriter1_21_2 getEntityRewriter() { + return entityRewriter; + } + + @Override + public BlockItemPacketRewriter1_21_2 getItemRewriter() { + return itemRewriter; + } + + @Override + public TagRewriter getTagRewriter() { + return tagRewriter; + } + + @Override + protected PacketTypesProvider createPacketTypesProvider() { + return new SimplePacketTypesProvider<>( + packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class), + packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class), + packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class) + ); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPacket1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPacket1_21_2.java new file mode 100644 index 000000000..59c1ede63 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPacket1_21_2.java @@ -0,0 +1,23 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.packet; + +import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; + +public interface ClientboundPacket1_21_2 extends ClientboundPacketType { +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPackets1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPackets1_21_2.java new file mode 100644 index 000000000..7daf7518f --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ClientboundPackets1_21_2.java @@ -0,0 +1,159 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.packet; + +public enum ClientboundPackets1_21_2 implements ClientboundPacket1_21_2 { + + BUNDLE_DELIMITER, // 0x00 + ADD_ENTITY, // 0x01 + ADD_EXPERIENCE_ORB, // 0x02 + ANIMATE, // 0x03 + AWARD_STATS, // 0x04 + BLOCK_CHANGED_ACK, // 0x05 + BLOCK_DESTRUCTION, // 0x06 + BLOCK_ENTITY_DATA, // 0x07 + BLOCK_EVENT, // 0x08 + BLOCK_UPDATE, // 0x09 + BOSS_EVENT, // 0x0A + CHANGE_DIFFICULTY, // 0x0B + CHUNK_BATCH_FINISHED, // 0x0C + CHUNK_BATCH_START, // 0x0D + CHUNKS_BIOMES, // 0x0E + CLEAR_TITLES, // 0x0F + COMMAND_SUGGESTIONS, // 0x10 + COMMANDS, // 0x11 + CONTAINER_CLOSE, // 0x12 + CONTAINER_SET_CONTENT, // 0x13 + CONTAINER_SET_DATA, // 0x14 + CONTAINER_SET_SLOT, // 0x15 + COOKIE_REQUEST, // 0x16 + COOLDOWN, // 0x17 + CUSTOM_CHAT_COMPLETIONS, // 0x18 + CUSTOM_PAYLOAD, // 0x19 + DAMAGE_EVENT, // 0x1A + DEBUG_SAMPLE, // 0x1B + DELETE_CHAT, // 0x1C + DISCONNECT, // 0x1D + DISGUISED_CHAT, // 0x1E + ENTITY_EVENT, // 0x1F + EXPLODE, // 0x20 + FORGET_LEVEL_CHUNK, // 0x21 + GAME_EVENT, // 0x22 + HORSE_SCREEN_OPEN, // 0x23 + HURT_ANIMATION, // 0x24 + INITIALIZE_BORDER, // 0x25 + KEEP_ALIVE, // 0x26 + LEVEL_CHUNK_WITH_LIGHT, // 0x27 + LEVEL_EVENT, // 0x28 + LEVEL_PARTICLES, // 0x29 + LIGHT_UPDATE, // 0x2A + LOGIN, // 0x2B + MAP_ITEM_DATA, // 0x2C + MERCHANT_OFFERS, // 0x2D + MOVE_ENTITY_POS, // 0x2E + MOVE_ENTITY_POS_ROT, // 0x2F + MOVE_MINECART_ALONG_TRACK, // 0x30 + MOVE_ENTITY_ROT, // 0x31 + MOVE_VEHICLE, // 0x32 + OPEN_BOOK, // 0x33 + OPEN_SCREEN, // 0x34 + OPEN_SIGN_EDITOR, // 0x35 + PING, // 0x36 + PONG_RESPONSE, // 0x37 + PLACE_GHOST_RECIPE, // 0x38 + PLAYER_ABILITIES, // 0x39 + PLAYER_CHAT, // 0x3A + PLAYER_COMBAT_END, // 0x3B + PLAYER_COMBAT_ENTER, // 0x3C + PLAYER_COMBAT_KILL, // 0x3D + PLAYER_INFO_REMOVE, // 0x3E + PLAYER_INFO_UPDATE, // 0x3F + PLAYER_LOOK_AT, // 0x40 + PLAYER_POSITION, // 0x41 + RECIPE, // 0x42 + REMOVE_ENTITIES, // 0x43 + REMOVE_MOB_EFFECT, // 0x44 + RESET_SCORE, // 0x45 + RESOURCE_PACK_POP, // 0x46 + RESOURCE_PACK_PUSH, // 0x47 + RESPAWN, // 0x48 + ROTATE_HEAD, // 0x49 + SECTION_BLOCKS_UPDATE, // 0x4A + SELECT_ADVANCEMENTS_TAB, // 0x4B + SERVER_DATA, // 0x4C + SET_ACTION_BAR_TEXT, // 0x4D + SET_BORDER_CENTER, // 0x4E + SET_BORDER_LERP_SIZE, // 0x4F + SET_BORDER_SIZE, // 0x50 + SET_BORDER_WARNING_DELAY, // 0x51 + SET_BORDER_WARNING_DISTANCE, // 0x52 + SET_CAMERA, // 0x53 + SET_CHUNK_CACHE_CENTER, // 0x54 + SET_CHUNK_CACHE_RADIUS, // 0x55 + SET_CURSOR_ITEM, // 0x56 + SET_DEFAULT_SPAWN_POSITION, // 0x57 + SET_DISPLAY_OBJECTIVE, // 0x58 + SET_ENTITY_DATA, // 0x59 + SET_ENTITY_LINK, // 0x5A + SET_ENTITY_MOTION, // 0x5B + SET_EQUIPMENT, // 0x5C + SET_EXPERIENCE, // 0x5D + SET_HEALTH, // 0x5E + SET_HELD_SLOT, // 0x5F + SET_OBJECTIVE, // 0x60 + SET_PASSENGERS, // 0x61 + SET_PLAYER_INVENTORY, // 0x62 + SET_PLAYER_TEAM, // 0x63 + SET_SCORE, // 0x64 + SET_SIMULATION_DISTANCE, // 0x65 + SET_SUBTITLE_TEXT, // 0x66 + SET_TIME, // 0x67 + SET_TITLE_TEXT, // 0x68 + SET_TITLES_ANIMATION, // 0x69 + SOUND_ENTITY, // 0x6A + SOUND, // 0x6B + START_CONFIGURATION, // 0x6C + STOP_SOUND, // 0x6D + STORE_COOKIE, // 0x6E + SYSTEM_CHAT, // 0x6F + TAB_LIST, // 0x70 + TAG_QUERY, // 0x71 + TAKE_ITEM_ENTITY, // 0x72 + TELEPORT_ENTITY, // 0x73 + TICKING_STATE, // 0x74 + TICKING_STEP, // 0x75 + TRANSFER, // 0x76 + UPDATE_ADVANCEMENTS, // 0x77 + UPDATE_ATTRIBUTES, // 0x78 + UPDATE_MOB_EFFECT, // 0x79 + UPDATE_RECIPES, // 0x7A + UPDATE_TAGS, // 0x7B + PROJECTILE_POWER, // 0x7C + CUSTOM_REPORT_DETAILS, // 0x7D + SERVER_LINKS; // 0x7E + + @Override + public int getId() { + return ordinal(); + } + + @Override + public String getName() { + return name(); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPacket1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPacket1_21_2.java new file mode 100644 index 000000000..4999141e6 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPacket1_21_2.java @@ -0,0 +1,23 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.packet; + +import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; + +public interface ServerboundPacket1_21_2 extends ServerboundPacketType { +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPackets1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPackets1_21_2.java new file mode 100644 index 000000000..3e5d837c7 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/packet/ServerboundPackets1_21_2.java @@ -0,0 +1,92 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.packet; + +public enum ServerboundPackets1_21_2 implements ServerboundPacket1_21_2 { + + ACCEPT_TELEPORTATION, // 0x00 + BLOCK_ENTITY_TAG_QUERY, // 0x01 + BUNDLE_ITEM_SELECTED, // 0x02 + CHANGE_DIFFICULTY, // 0x03 + CHAT_ACK, // 0x04 + CHAT_COMMAND, // 0x05 + CHAT_COMMAND_SIGNED, // 0x06 + CHAT, // 0x07 + CHAT_SESSION_UPDATE, // 0x08 + CHUNK_BATCH_RECEIVED, // 0x09 + CLIENT_COMMAND, // 0x0A + CLIENT_TICK_END, // 0x0B + CLIENT_INFORMATION, // 0x0C + COMMAND_SUGGESTION, // 0x0D + CONFIGURATION_ACKNOWLEDGED, // 0x0E + CONTAINER_BUTTON_CLICK, // 0x0F + CONTAINER_CLICK, // 0x10 + CONTAINER_CLOSE, // 0x11 + CONTAINER_SLOT_STATE_CHANGED, // 0x12 + COOKIE_RESPONSE, // 0x13 + CUSTOM_PAYLOAD, // 0x14 + DEBUG_SAMPLE_SUBSCRIPTION, // 0x15 + EDIT_BOOK, // 0x16 + ENTITY_TAG_QUERY, // 0x17 + INTERACT, // 0x18 + JIGSAW_GENERATE, // 0x19 + KEEP_ALIVE, // 0x1A + LOCK_DIFFICULTY, // 0x1B + MOVE_PLAYER_POS, // 0x1C + MOVE_PLAYER_POS_ROT, // 0x1D + MOVE_PLAYER_ROT, // 0x1E + MOVE_PLAYER_STATUS_ONLY, // 0x1F + MOVE_VEHICLE, // 0x20 + PADDLE_BOAT, // 0x21 + PICK_ITEM, // 0x22 + PING_REQUEST, // 0x23 + PLACE_RECIPE, // 0x24 + PLAYER_ABILITIES, // 0x25 + PLAYER_ACTION, // 0x26 + PLAYER_COMMAND, // 0x27 + PLAYER_INPUT, // 0x28 + PONG, // 0x29 + RECIPE_BOOK_CHANGE_SETTINGS, // 0x2A + RECIPE_BOOK_SEEN_RECIPE, // 0x2B + RENAME_ITEM, // 0x2C + RESOURCE_PACK, // 0x2D + SEEN_ADVANCEMENTS, // 0x2E + SELECT_TRADE, // 0x2F + SET_BEACON, // 0x30 + SET_CARRIED_ITEM, // 0x31 + SET_COMMAND_BLOCK, // 0x32 + SET_COMMAND_MINECART, // 0x33 + SET_CREATIVE_MODE_SLOT, // 0x34 + SET_JIGSAW_BLOCK, // 0x35 + SET_STRUCTURE_BLOCK, // 0x36 + SIGN_UPDATE, // 0x37 + SWING, // 0x38 + TELEPORT_TO_ENTITY, // 0x39 + USE_ITEM_ON, // 0x3A + USE_ITEM; // 0x3B + + @Override + public int getId() { + return ordinal(); + } + + @Override + public String getName() { + return name(); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/BlockItemPacketRewriter1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/BlockItemPacketRewriter1_21_2.java new file mode 100644 index 000000000..d771d4292 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/BlockItemPacketRewriter1_21_2.java @@ -0,0 +1,267 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.rewriter; + +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.Particle; +import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; +import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; +import com.viaversion.viaversion.api.type.types.version.Types1_21; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; +import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.BlockRewriter; +import com.viaversion.viaversion.rewriter.SoundRewriter; +import com.viaversion.viaversion.rewriter.StructuredItemRewriter; + +public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter { + + public BlockItemPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) { + super(protocol, + Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY, + Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST, + Types1_21.PARTICLE, Types1_21_2.PARTICLE + ); + } + + @Override + public void registerPackets() { + final BlockRewriter blockRewriter = BlockRewriter.for1_20_2(protocol); + blockRewriter.registerBlockEvent(ClientboundPackets1_21.BLOCK_EVENT); + blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE); + blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE); + blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001); + blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new); + blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA); + + registerCooldown(ClientboundPackets1_21.COOLDOWN); + registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS); + registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT); + registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS); + registerSetCreativeModeSlot(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT); + registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES); + + protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_CONTENT, wrapper -> { + updateContainerId(wrapper); + wrapper.passthrough(Types.VAR_INT); // State id + Item[] items = wrapper.read(itemArrayType()); + wrapper.write(mappedItemArrayType(), items); + for (int i = 0; i < items.length; i++) { + items[i] = handleItemToClient(wrapper.user(), items[i]); + } + passthroughClientboundItem(wrapper); + }); + protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_SLOT, wrapper -> { + updateContainerId(wrapper); + wrapper.passthrough(Types.VAR_INT); // State id + wrapper.passthrough(Types.SHORT); // Slot id + passthroughClientboundItem(wrapper); + }); + protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_CLOSE, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_DATA, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21.HORSE_SCREEN_OPEN, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21.PLACE_GHOST_RECIPE, this::updateContainerId); + protocol.registerClientbound(ClientboundPackets1_21.SET_CARRIED_ITEM, ClientboundPackets1_21_2.SET_HELD_SLOT); + protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLOSE, this::updateContainerIdServerbound); + protocol.registerServerbound(ServerboundPackets1_21_2.PLACE_RECIPE, this::updateContainerIdServerbound); + protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLICK, wrapper -> { + updateContainerIdServerbound(wrapper); + wrapper.passthrough(Types.VAR_INT); // State id + wrapper.passthrough(Types.SHORT); // Slot + wrapper.passthrough(Types.BYTE); // Button + wrapper.passthrough(Types.VAR_INT); // Mode + final int length = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < length; i++) { + wrapper.passthrough(Types.SHORT); // Slot + passthroughServerboundItem(wrapper); + } + passthroughServerboundItem(wrapper); + }); + + protocol.registerClientbound(ClientboundPackets1_21.EXPLODE, wrapper -> { + wrapper.passthrough(Types.DOUBLE); // Center X + wrapper.passthrough(Types.DOUBLE); // Center Y + wrapper.passthrough(Types.DOUBLE); // Center Z + + final float power = wrapper.read(Types.FLOAT); // Power + final int blocks = wrapper.read(Types.VAR_INT); + for (int i = 0; i < blocks; i++) { + // TODO ? + wrapper.read(Types.BYTE); // Relative X + wrapper.read(Types.BYTE); // Relative Y + wrapper.read(Types.BYTE); // Relative Z + } + + final float knockbackX = wrapper.read(Types.FLOAT); + final float knockbackY = wrapper.read(Types.FLOAT); + final float knockbackZ = wrapper.read(Types.FLOAT); + if (knockbackX != 0 && knockbackY != 0 && knockbackZ != 0) { + wrapper.write(Types.BOOLEAN, true); + wrapper.write(Types.DOUBLE, (double) knockbackX); + wrapper.write(Types.DOUBLE, (double) knockbackY); + wrapper.write(Types.DOUBLE, (double) knockbackZ); + } else { + wrapper.write(Types.BOOLEAN, false); + } + + wrapper.read(Types.VAR_INT); // Block interaction type + + final Particle smallExplosionParticle = wrapper.read(Types1_21.PARTICLE); + final Particle largeExplosionParticle = wrapper.read(Types1_21.PARTICLE); + if (power >= 2.0F && blocks != 0) { + rewriteParticle(wrapper.user(), largeExplosionParticle); + wrapper.write(Types1_21_2.PARTICLE, largeExplosionParticle); + } else { + rewriteParticle(wrapper.user(), smallExplosionParticle); + wrapper.write(Types1_21_2.PARTICLE, smallExplosionParticle); + } + + new SoundRewriter<>(protocol).soundHolderHandler().handle(wrapper); + }); + + new RecipeRewriter1_20_3<>(protocol) { + @Override + protected void handleIngredient(final PacketWrapper wrapper) { + wrapper.write(Types.HOLDER_SET, ingredient(wrapper)); + } + + @Override + public void handleCraftingShaped(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Group + wrapper.passthrough(Types.VAR_INT); // Crafting book category + final int width = wrapper.passthrough(Types.VAR_INT); + final int height = wrapper.passthrough(Types.VAR_INT); + final int ingredients = width * height; + + wrapper.write(Types.VAR_INT, ingredients); + for (int i = 0; i < ingredients; i++) { + wrapper.write(Types.HOLDER_SET, ingredient(wrapper)); + } + + wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result + wrapper.passthrough(Types.BOOLEAN); // Show notification + } + + @Override + public void handleCraftingShapeless(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Group + wrapper.passthrough(Types.VAR_INT); // Crafting book category + + final int ingredients = wrapper.read(Types.VAR_INT); + final HolderSet[] ingredient = new HolderSet[ingredients]; + for (int i = 0; i < ingredients; i++) { + ingredient[i] = ingredient(wrapper); + } + + wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); + + // Also moved below here + wrapper.write(Types.VAR_INT, ingredients); + for (final HolderSet item : ingredient) { + wrapper.write(Types.HOLDER_SET, item); + } + } + + private HolderSet ingredient(final PacketWrapper wrapper) { + final Item[] items = wrapper.read(itemArrayType()); + final int[] ids = new int[items.length]; + for (int i = 0; i < items.length; i++) { + final Item item = rewrite(wrapper.user(), items[i]); + ids[i] = item.identifier(); + } + return HolderSet.of(ids); + } + + @Override + public void handleRecipeType(final PacketWrapper wrapper, final String type) { + if (type.equals("crafting_special_suspiciousstew")) { + wrapper.read(Types.VAR_INT); // Crafting book category + } else { + super.handleRecipeType(wrapper, type); + } + } + }.register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); + } + + @Override + public Item handleItemToClient(final UserConnection connection, final Item item) { + super.handleItemToClient(connection, item); + updateItemData(item); + return item; + } + + @Override + public Item handleItemToServer(final UserConnection connection, final Item item) { + super.handleItemToServer(connection, item); + downgradeItemData(item); + return item; + } + + private void updateContainerId(final PacketWrapper wrapper) { + final int containerId = wrapper.read(Types.UNSIGNED_BYTE).intValue(); + wrapper.write(Types.VAR_INT, containerId); + } + + private void updateContainerIdServerbound(final PacketWrapper wrapper) { + final int containerId = wrapper.read(Types.VAR_INT); + wrapper.write(Types.UNSIGNED_BYTE, (short) containerId); + } + + public static void updateItemData(final Item item) { + final StructuredDataContainer dataContainer = item.dataContainer(); + dataContainer.replace(StructuredDataKey.INSTRUMENT1_20_5, StructuredDataKey.INSTRUMENT1_21_2, instrument -> { + if (instrument.hasId()) { + return Holder.of(instrument.id()); + } + final Instrument1_20_5 value = instrument.value(); + return Holder.of(new Instrument1_21_2(value.soundEvent(), value.useDuration(), value.range(), null)); + }); + 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); + } + + public static void downgradeItemData(final Item item) { + final StructuredDataContainer dataContainer = item.dataContainer(); + dataContainer.replace(StructuredDataKey.INSTRUMENT1_21_2, StructuredDataKey.INSTRUMENT1_20_5, instrument -> { + if (instrument.hasId()) { + return Holder.of(instrument.id()); + } + final Instrument1_21_2 value = instrument.value(); + return Holder.of(new Instrument1_20_5(value.soundEvent(), (int) value.useDuration(), value.range())); + }); + 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.remove(StructuredDataKey.REPAIRABLE); + dataContainer.remove(StructuredDataKey.ENCHANTABLE); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/EntityPacketRewriter1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/EntityPacketRewriter1_21_2.java new file mode 100644 index 000000000..40693695b --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/EntityPacketRewriter1_21_2.java @@ -0,0 +1,227 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.rewriter; + +import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; +import com.viaversion.nbt.tag.StringTag; +import com.viaversion.viaversion.api.minecraft.RegistryEntry; +import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.version.Types1_21; +import com.viaversion.viaversion.api.type.types.version.Types1_21_2; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; +import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2; +import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2; +import com.viaversion.viaversion.rewriter.EntityRewriter; +import com.viaversion.viaversion.util.Key; +import com.viaversion.viaversion.util.TagUtil; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +public final class EntityPacketRewriter1_21_2 extends EntityRewriter { + + public EntityPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) { + super(protocol); + } + + @Override + public void registerPackets() { + registerTrackerWithData1_19(ClientboundPackets1_21.ADD_ENTITY, EntityTypes1_20_5.FALLING_BLOCK); + registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, Types1_21.ENTITY_DATA_LIST, Types1_21_2.ENTITY_DATA_LIST); + registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES); + + protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> { + final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING)); + RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY); + if (registryKey.equals("enchantment")) { + for (final RegistryEntry entry : entries) { + if (entry.tag() == null) { + continue; + } + + final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects"); + if (effects != null) { + updateLocationChangedAttributes(effects); + updateAttributesFields(effects); + } + } + } else if (registryKey.equals("damage_type")) { + // Add new damage types + final int length = entries.length; + entries = Arrays.copyOf(entries, length + 2); + + final CompoundTag enderpearlData = new CompoundTag(); + enderpearlData.putString("scaling", "when_caused_by_living_non_player"); + enderpearlData.putString("message_id", "fall"); + enderpearlData.putFloat("exhaustion", 0.0F); + entries[length] = new RegistryEntry("minecraft:ender_pearl", enderpearlData); + + final CompoundTag maceSmashData = new CompoundTag(); + maceSmashData.putString("scaling", "when_caused_by_living_non_player"); + maceSmashData.putString("message_id", "mace_smash"); + maceSmashData.putFloat("exhaustion", 0.1F); + entries[length + 1] = new RegistryEntry("minecraft:mace_smash", maceSmashData); + } + + wrapper.write(Types.REGISTRY_ENTRY_ARRAY, entries); + handleRegistryData1_20_5(wrapper.user(), registryKey, entries); + }); + + protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() { + @Override + public void register() { + map(Types.INT); // Entity id + map(Types.BOOLEAN); // Hardcore + map(Types.STRING_ARRAY); // World List + map(Types.VAR_INT); // Max players + map(Types.VAR_INT); // View distance + map(Types.VAR_INT); // Simulation distance + map(Types.BOOLEAN); // Reduced debug info + map(Types.BOOLEAN); // Show death screen + map(Types.BOOLEAN); // Limited crafting + map(Types.VAR_INT); // Dimension id + map(Types.STRING); // World + map(Types.LONG); // Seed + map(Types.BYTE); // Gamemode + map(Types.BYTE); // Previous gamemode + map(Types.BOOLEAN); // Debug + map(Types.BOOLEAN); // Flat + map(Types.OPTIONAL_GLOBAL_POSITION); // Last death location + map(Types.VAR_INT); // Portal cooldown + handler(worldDataTrackerHandlerByKey1_20_5(3)); + handler(playerTrackerHandler()); + create(Types.VAR_INT, 64); // Sea level, was hardcoded at 64 before + } + }); + + protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> { + final int dimensionId = wrapper.passthrough(Types.VAR_INT); + final String world = wrapper.passthrough(Types.STRING); + wrapper.passthrough(Types.LONG); // Seed + wrapper.passthrough(Types.BYTE); // Gamemode + wrapper.passthrough(Types.BYTE); // Previous gamemode + wrapper.passthrough(Types.BOOLEAN); // Debug + wrapper.passthrough(Types.BOOLEAN); // Flat + wrapper.passthrough(Types.OPTIONAL_GLOBAL_POSITION); // Last death location + wrapper.passthrough(Types.VAR_INT); // Portal cooldown + + wrapper.write(Types.VAR_INT, 64); // Sea level + trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world); + }); + + protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS, wrapper -> { + wrapper.passthrough(Types.DOUBLE); // X + wrapper.passthrough(Types.DOUBLE); // Y + wrapper.passthrough(Types.DOUBLE); // Z + readOnGround(wrapper); + }); + protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS_ROT, wrapper -> { + wrapper.passthrough(Types.DOUBLE); // X + wrapper.passthrough(Types.DOUBLE); // Y + wrapper.passthrough(Types.DOUBLE); // Z + wrapper.passthrough(Types.FLOAT); // Yaw + wrapper.passthrough(Types.FLOAT); // Pitch + readOnGround(wrapper); + }); + protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper -> { + wrapper.passthrough(Types.FLOAT); // Yaw + wrapper.passthrough(Types.FLOAT); // Pitch + readOnGround(wrapper); + }); + protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround); + } + + private void updateAttributesFields(final CompoundTag effects) { + final ListTag attributesList = TagUtil.getNamespacedCompoundTagList(effects, "attributes"); + if (attributesList == null) { + return; + } + + for (final CompoundTag attributeData : attributesList) { + updateAttributeField(attributeData); + } + } + + private void updateLocationChangedAttributes(final CompoundTag effects) { + final ListTag locationChanged = TagUtil.getNamespacedCompoundTagList(effects, "location_changed"); + if (locationChanged == null) { + return; + } + + for (final CompoundTag data : locationChanged) { + final CompoundTag effect = data.getCompoundTag("effect"); + if (effect != null) { + updateAttributeField(effect); + } + } + } + + private void updateAttributeField(final CompoundTag attributeData) { + final StringTag attributeTag = attributeData.getStringTag("attribute"); + if (attributeTag == null) { + return; + } + + final String attribute = Key.stripMinecraftNamespace(attributeTag.getValue()); + final int firstSeparator = attribute.indexOf('.'); + if (firstSeparator == -1) { + return; + } + + // Remove prefix from attributes + final String prefix = attribute.substring(0, firstSeparator); + if (prefix.equals("generic") || prefix.equals("player") || prefix.equals("zombie")) { + attributeTag.setValue(attribute.substring(firstSeparator + 1)); + } + } + + private void readOnGround(final PacketWrapper wrapper) { + final short data = wrapper.read(Types.UNSIGNED_BYTE); + wrapper.write(Types.BOOLEAN, (data & 1) != 0); // On ground, ignoring horizontal collision data + } + + @Override + protected void registerRewrites() { + filter().mapDataType(Types1_21_2.ENTITY_DATA_TYPES::byId); + + registerEntityDataTypeHandler( + Types1_21_2.ENTITY_DATA_TYPES.itemType, + Types1_21_2.ENTITY_DATA_TYPES.blockStateType, + Types1_21_2.ENTITY_DATA_TYPES.optionalBlockStateType, + Types1_21_2.ENTITY_DATA_TYPES.particleType, + Types1_21_2.ENTITY_DATA_TYPES.particlesType, + Types1_21_2.ENTITY_DATA_TYPES.componentType, + Types1_21_2.ENTITY_DATA_TYPES.optionalComponentType + ); + registerBlockStateHandler(EntityTypes1_20_5.ABSTRACT_MINECART, 11); // Data type + + filter().type(EntityTypes1_20_5.SALMON).addIndex(17); + } + + @Override + public EntityType typeFromId(final int type) { + return EntityTypes1_20_5.getTypeFromId(type); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/RecipeRewriter1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/RecipeRewriter1_21_2.java new file mode 100644 index 000000000..eeb5359ee --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/rewriter/RecipeRewriter1_21_2.java @@ -0,0 +1,78 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 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.v1_21to1_21_2.rewriter; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.HolderSet; +import com.viaversion.viaversion.api.minecraft.item.Item; +import com.viaversion.viaversion.api.protocol.Protocol; +import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; + +public class RecipeRewriter1_21_2 extends RecipeRewriter1_20_3 { + + public RecipeRewriter1_21_2(final Protocol protocol) { + super(protocol); + } + + @Override + public void handleCraftingShaped(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Group + wrapper.passthrough(Types.VAR_INT); // Crafting book category + wrapper.passthrough(Types.VAR_INT); // Width + wrapper.passthrough(Types.VAR_INT); // Height + + final int ingredients = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < ingredients; i++) { + handleIngredient(wrapper); + } + + wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result + wrapper.passthrough(Types.BOOLEAN); // Show notification + } + + @Override + public void handleCraftingShapeless(final PacketWrapper wrapper) { + wrapper.passthrough(Types.STRING); // Group + wrapper.passthrough(Types.VAR_INT); // Crafting book category + wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result + handleIngredients(wrapper); + } + + @Override + protected void handleIngredient(final PacketWrapper wrapper) { + final HolderSet items = wrapper.passthrough(Types.HOLDER_SET); + if (items.hasTagKey()) { + return; + } + + final int[] ids = items.ids(); + for (int i = 0; i < ids.length; i++) { + ids[i] = rewriteItemId(wrapper.user(), ids[i]); + } + } + + protected int rewriteItemId(final UserConnection connection, final int id) { + if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) { + return protocol.getMappingData().getItemMappings().getNewIdOrDefault(id, id); + } + return id; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java index d9a66f176..8e80f4cdf 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/ItemRewriter.java @@ -105,30 +105,30 @@ public class ItemRewriter { - Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType); - for (int i = 0; i < items.length; i++) { - items[i] = handleItemToClient(wrapper.user(), items[i]); - } + registerSetContent1_17_1(packetType, Types.UNSIGNED_BYTE); + } - handleClientboundItem(wrapper); - }); + public void registerSetContent1_21_2(C packetType) { + registerSetContent1_17_1(packetType, Types.VAR_INT); + } + + private void registerSetContent1_17_1(C packetType, Type containerIdType) { + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(containerIdType); // Container id + wrapper.passthrough(Types.VAR_INT); // State id + Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType); + for (int i = 0; i < items.length; i++) { + items[i] = handleItemToClient(wrapper.user(), items[i]); } + + passthroughClientboundItem(wrapper); }); } public void registerOpenScreen(C packetType) { - protocol.registerClientbound(packetType, new PacketHandlers() { - @Override - public void register() { - map(Types.VAR_INT); // Container id - handler(wrapper -> handleMenuType(wrapper)); - } + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(Types.VAR_INT); // Container id + handleMenuType(wrapper); }); } @@ -147,22 +147,27 @@ public class ItemRewriter handleClientboundItem(wrapper)); + handler(wrapper -> passthroughClientboundItem(wrapper)); } }); } public void registerSetSlot1_17_1(C packetType) { - protocol.registerClientbound(packetType, new PacketHandlers() { - @Override - public void register() { - map(Types.UNSIGNED_BYTE); // Window id - map(Types.VAR_INT); // State id - map(Types.SHORT); // Slot id - handler(wrapper -> handleClientboundItem(wrapper)); - } + registerSetSlot1_17_1(packetType, Types.UNSIGNED_BYTE); + } + + public void registerSetSlot1_21_2(C packetType) { + registerSetSlot1_17_1(packetType, Types.VAR_INT); + } + + private void registerSetSlot1_17_1(C packetType, Type containerIdType) { + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(containerIdType); // Container id + wrapper.passthrough(Types.VAR_INT); // State id + wrapper.passthrough(Types.SHORT); // Slot id + passthroughClientboundItem(wrapper); }); } @@ -173,7 +178,7 @@ public class ItemRewriter handleClientboundItem(wrapper)); + handler(wrapper -> passthroughClientboundItem(wrapper)); } }); } @@ -190,7 +195,7 @@ public class ItemRewriter handleServerboundItem(wrapper)); + handler(wrapper -> passthroughServerboundItem(wrapper)); } }); } @@ -211,38 +216,41 @@ public class ItemRewriter handleServerboundItem(wrapper)); + handler(wrapper -> passthroughServerboundItem(wrapper)); } }); } public void registerContainerClick1_17_1(S packetType) { - protocol.registerServerbound(packetType, new PacketHandlers() { - @Override - public void register() { - map(Types.UNSIGNED_BYTE); // Window Id - map(Types.VAR_INT); // State id - map(Types.SHORT); // Slot - map(Types.BYTE); // Button - map(Types.VAR_INT); // Mode + registerContainerClick1_17_1(packetType, Types.UNSIGNED_BYTE); + } - handler(wrapper -> { - // Affected items - int length = wrapper.passthrough(Types.VAR_INT); - for (int i = 0; i < length; i++) { - wrapper.passthrough(Types.SHORT); // Slot - handleServerboundItem(wrapper); - } + public void registerContainerClick1_21_2(S packetType) { + registerContainerClick1_17_1(packetType, Types.VAR_INT); + } - // Carried item - handleServerboundItem(wrapper); - }); + public void registerContainerClick1_17_1(S packetType, Type containerIdType) { + protocol.registerServerbound(packetType, wrapper -> { + wrapper.passthrough(containerIdType); // Container id + wrapper.passthrough(Types.VAR_INT); // State id + wrapper.passthrough(Types.SHORT); // Slot + wrapper.passthrough(Types.BYTE); // Button + wrapper.passthrough(Types.VAR_INT); // Mode + + // Affected items + final int length = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < length; i++) { + wrapper.passthrough(Types.SHORT); // Slot + passthroughServerboundItem(wrapper); } + + // Carried item + passthroughServerboundItem(wrapper); }); } @@ -274,11 +282,11 @@ public class ItemRewriter soundRewriter = new SoundRewriter<>(protocol); + protocol.registerClientbound(packetType, wrapper -> { + wrapper.passthrough(Types.DOUBLE); // X + wrapper.passthrough(Types.DOUBLE); // Y + wrapper.passthrough(Types.DOUBLE); // Z + wrapper.passthrough(Types.DOUBLE); // Knockback X + wrapper.passthrough(Types.DOUBLE); // Knockback Y + wrapper.passthrough(Types.DOUBLE); // Knockback Z + + final Particle smallExplosionParticle = wrapper.read(particleType); + final Particle largeExplosionParticle = wrapper.read(particleType); + wrapper.write(mappedParticleType, smallExplosionParticle); + wrapper.write(mappedParticleType, largeExplosionParticle); + rewriteParticle(wrapper.user(), smallExplosionParticle); + rewriteParticle(wrapper.user(), largeExplosionParticle); + + soundRewriter.soundHolderHandler().handle(wrapper); + }); + } + public PacketHandler levelParticlesHandler() { return levelParticlesHandler(Types.INT); } @@ -565,7 +594,7 @@ public class ItemRewriter { public void register1_20_5(C packetType) { protocol.registerClientbound(packetType, wrapper -> { - int size = wrapper.passthrough(Types.VAR_INT); + final int size = wrapper.passthrough(Types.VAR_INT); + int newSize = size; for (int i = 0; i < size; i++) { - wrapper.passthrough(Types.STRING); // Recipe Identifier + final String recipeIdentifier = wrapper.read(Types.STRING); - final int typeId = wrapper.passthrough(Types.VAR_INT); - final String type = protocol.getMappingData().getRecipeSerializerMappings().identifier(typeId); - handleRecipeType(wrapper, type); + final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings(); + final int typeId = wrapper.read(Types.VAR_INT); + final int mappedId = recipeSerializerMappings.getNewId(typeId); + if (mappedId != -1) { + wrapper.write(Types.STRING, recipeIdentifier); + wrapper.write(Types.VAR_INT, mappedId); + } else { + wrapper.set(Types.VAR_INT, 0, --newSize); + } + + handleRecipeType(wrapper, Key.stripMinecraftNamespace(recipeSerializerMappings.identifier(typeId))); // Use the original } }); } diff --git a/common/src/main/resources/assets/viaversion/data/identifier-table.nbt b/common/src/main/resources/assets/viaversion/data/identifier-table.nbt index b32d3f93e..94afda037 100644 Binary files a/common/src/main/resources/assets/viaversion/data/identifier-table.nbt and b/common/src/main/resources/assets/viaversion/data/identifier-table.nbt differ diff --git a/common/src/main/resources/assets/viaversion/data/identifiers-1.21.2.nbt b/common/src/main/resources/assets/viaversion/data/identifiers-1.21.2.nbt new file mode 100644 index 000000000..7ebcf107e Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/identifiers-1.21.2.nbt differ diff --git a/common/src/main/resources/assets/viaversion/data/mappings-1.21to1.21.2.nbt b/common/src/main/resources/assets/viaversion/data/mappings-1.21to1.21.2.nbt new file mode 100644 index 000000000..c649cf9ba Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/mappings-1.21to1.21.2.nbt differ