diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/Protocol1_20_5To1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/Protocol1_20_5To1_20_3.java index 6023368d1..6d4d63f0e 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/Protocol1_20_5To1_20_3.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/Protocol1_20_5To1_20_3.java @@ -18,8 +18,6 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3; 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.RegistryType; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; @@ -40,6 +38,7 @@ import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.Clientb import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPacket1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MappingData; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundConfigurationPackets1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPacket1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPackets1_20_5; @@ -56,7 +55,7 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap; public final class Protocol1_20_5To1_20_3 extends AbstractProtocol { - public static final MappingData MAPPINGS = new MappingDataBase("1.20.3", "1.20.5"); + public static final MappingData MAPPINGS = new MappingData(); private final EntityPacketRewriter1_20_5 entityRewriter = new EntityPacketRewriter1_20_5(this); private final BlockItemPacketRewriter1_20_5 itemRewriter = new BlockItemPacketRewriter1_20_5(this); private final TagRewriter tagRewriter = new TagRewriter<>(this); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MappingData.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MappingData.java new file mode 100644 index 000000000..313a684a8 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/data/MappingData.java @@ -0,0 +1,52 @@ +/* + * 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.protocol1_20_5to1_20_3.data; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.viaversion.viaversion.api.data.MappingDataBase; +import com.viaversion.viaversion.api.data.MappingDataLoader; +import java.util.ArrayList; +import java.util.List; + +public class MappingData extends MappingDataBase { + + private final List itemIds = new ArrayList<>(); + + public MappingData() { + super("1.20.3", "1.20.5"); + } + + @Override + protected void loadExtras(final CompoundTag data) { + super.loadExtras(data); + + final CompoundTag items = MappingDataLoader.loadNBT("itemIds-1.20.3.nbt"); + for (final StringTag tag : items.getListTag("items", StringTag.class)) { + itemIds.add(tag.getValue()); + } + } + + public int itemId(final String name) { + return itemIds.indexOf(name); + } + + public String itemName(final int id) { + return itemIds.get(id); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java index ea6c58eee..6ff00465a 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java @@ -40,6 +40,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimPattern; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifier; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers; 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.DyedColor; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; @@ -91,7 +92,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter { - private static final String[] MOB_TAGS = {"NoAI", "Silent", "NoGravity", "Glowing", "Invulnerable", "Health", "Age", "Variant", "HuntingCooldown", "BucketVariantTag"}; + public static final String[] MOB_TAGS = {"NoAI", "Silent", "NoGravity", "Glowing", "Invulnerable", "Health", "Age", "Variant", "HuntingCooldown", "BucketVariantTag"}; private static final GameProfile.Property[] EMPTY_PROPERTIES = new GameProfile.Property[0]; public BlockItemPacketRewriter1_20_5(final Protocol1_20_5To1_20_3 protocol) { @@ -395,18 +396,15 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter beesTag) { + final Bee[] bees = beesTag.stream().map(bee -> { + final CompoundTag entityData = bee.getCompoundTag("EntityData"); + final int ticksInHive = bee.getInt("TicksInHive"); + final int minOccupationTicks = bee.getInt("MinOccupationTicks"); + + return new Bee(entityData, ticksInHive, minOccupationTicks); + }).toArray(Bee[]::new); + + data.set(StructuredDataKey.BEES, bees); + } + private void updateProperties(final CompoundTag propertiesTag, final List properties) { for (final Map.Entry entry : propertiesTag.entrySet()) { if (!(entry.getValue() instanceof ListTag)) { @@ -810,9 +825,41 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter beesTag = tag.getListTag("Bees", CompoundTag.class); + if (beesTag != null) { + updateBees(data, beesTag); + } + + final ListTag sherdsTag = tag.getListTag("sherds", StringTag.class); + if (sherdsTag != null) { + final String sherd1 = sherdsTag.get(0).getValue(); + final String sherd2 = sherdsTag.get(1).getValue(); + final String sherd3 = sherdsTag.get(2).getValue(); + final String sherd4 = sherdsTag.get(3).getValue(); + + data.set(StructuredDataKey.POT_DECORATIONS, new int[]{toItemId(sherd1), toItemId(sherd2), toItemId(sherd3), toItemId(sherd4)}); + } + + final StringTag noteBlockSoundTag = tag.getStringTag("note_block_sound"); + if (noteBlockSoundTag != null) { + data.set(StructuredDataKey.NOTE_BLOCK_SOUND, noteBlockSoundTag.getValue()); + } + + final StringTag lootTableTag = tag.getStringTag("LootTable"); + if (lootTableTag != null) { + final long lootTableSeed = tag.getLong("LootTableSeed"); + + final CompoundTag containerLoot = new CompoundTag(); + containerLoot.putString("loot_table", lootTableTag.getValue()); + containerLoot.putLong("loot_table_seed", lootTableSeed); + data.set(StructuredDataKey.CONTAINER_LOOT, containerLoot); + } } final Tag skullOwnerTag = tag.remove("SkullOwner"); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/StructuredDataConverter.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/StructuredDataConverter.java index b5e903dfd..2a31be9cf 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/StructuredDataConverter.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/StructuredDataConverter.java @@ -27,15 +27,18 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifier; +import com.viaversion.viaversion.api.minecraft.item.data.Bee; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; 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.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Attributes1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Enchantments1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Instruments1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorations1_20_3; import com.viaversion.viaversion.util.ComponentUtil; +import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.UUIDUtil; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; @@ -220,6 +223,42 @@ final class StructuredDataConverter { tag.putString("instrument", identifier); } }); + register(StructuredDataKey.BEES, (data, tag) -> { + final ListTag bees = new ListTag<>(CompoundTag.class); + for (final Bee bee : data) { + final CompoundTag beeTag = new CompoundTag(); + beeTag.put("EntityData", bee.entityData()); + beeTag.putInt("TicksInHive", bee.ticksInHive()); + beeTag.putInt("MinOccupationTicks", bee.minTicksInHive()); + bees.add(beeTag); + } + getBlockEntityTag(tag).put("Bees", bees); + }); + register(StructuredDataKey.LOCK, (data, tag) -> getBlockEntityTag(tag).put("Lock", data)); + register(StructuredDataKey.NOTE_BLOCK_SOUND, (data, tag) -> getBlockEntityTag(tag).putString("note_block_sound", data)); + register(StructuredDataKey.POT_DECORATIONS, (data, tag) -> { + final ListTag sherds = new ListTag<>(StringTag.class); + for (final int id : data) { + final int oldId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id); + sherds.add(new StringTag(Protocol1_20_5To1_20_3.MAPPINGS.itemName(oldId))); + } + getBlockEntityTag(tag).put("sherds", sherds); + }); + register(StructuredDataKey.CREATIVE_SLOT_LOCK, (data, tag) -> tag.put("CustomCreativeLock", new CompoundTag())); + register(StructuredDataKey.DEBUG_STICK_STATE, (data, tag) -> tag.put("DebugProperty", data)); + register(StructuredDataKey.RECIPES, (data, tag) -> tag.put("Recipes", data)); + register(StructuredDataKey.ENTITY_DATA, (data, tag) -> tag.put("EntityTag", data)); + register(StructuredDataKey.BUCKET_ENTITY_DATA, (data, tag) -> { + for (final String mobTagName : BlockItemPacketRewriter1_20_5.MOB_TAGS) { + if (data.contains(mobTagName)) { + tag.put(mobTagName, data.get(mobTagName)); + } + } + }); + register(StructuredDataKey.BLOCK_ENTITY_DATA, (data, tag) -> { + // Handling of previously block entity tags is done using the getBlockEntityTag method + tag.put("BlockEntityTag", data); + }); //register(StructuredDataKey., (data, tag) -> ); //TODO @@ -228,25 +267,24 @@ final class StructuredDataConverter { // StructuredDataKey POTION_CONTENT // StructuredDataKey SUSPICIOUS_STEW_EFFECT // StructuredDataKey TRIM - // StructuredDataKey DEBUG_STICK_STATE - // StructuredDataKey ENTITY_DATA - // StructuredDataKey BUCKET_ENTITY_DATA - // StructuredDataKey BLOCK_ENTITY_DATA - // StructuredDataKey RECIPES // StructuredDataKey BANNER_PATTERNS // StructuredDataKey BLOCK_STATE - // StructuredDataKey POT_DECORATIONS - // StructuredDataKey NOTE_BLOCK_SOUND - // StructuredDataKey BEES - // StructuredDataKey LOCK // StructuredDataKey CONTAINER_LOOT // StructuredDataKey CONTAINER - // StructuredDataKey CREATIVE_SLOT_LOCK // StructuredDataKey ENCHANTMENT_GLINT_OVERRIDE // StructuredDataKey INTANGIBLE_PROJECTILE // StructuredDataKey MAP_POST_PROCESSING } + private static CompoundTag getBlockEntityTag(final CompoundTag tag) { + CompoundTag blockEntityTag = tag.getCompoundTag("BlockEntityTag"); + if (blockEntityTag == null) { + blockEntityTag = new CompoundTag(); + tag.put("BlockEntityTag", blockEntityTag); + } + return blockEntityTag; + } + private static CompoundTag convertExplosion(final FireworkExplosion explosion) { final CompoundTag explosionTag = new CompoundTag(); explosionTag.putInt("Type", explosion.shape()); @@ -260,8 +298,10 @@ final class StructuredDataConverter { private static void convertItemList(final Item[] items, final CompoundTag tag, final String key) { final ListTag itemsTag = new ListTag<>(CompoundTag.class); for (final Item item : items) { + final int oldId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(item.identifier()); + final CompoundTag savedItem = new CompoundTag(); - savedItem.putString("id", "stone"); // TODO + savedItem.putString("id", Protocol1_20_5To1_20_3.MAPPINGS.itemName(oldId)); savedItem.putByte("Count", (byte) item.amount()); final CompoundTag itemTag = new CompoundTag(); diff --git a/common/src/main/resources/assets/viaversion/data/itemIds-1.20.3.nbt b/common/src/main/resources/assets/viaversion/data/itemIds-1.20.3.nbt new file mode 100644 index 000000000..0f02d99b0 Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/itemIds-1.20.3.nbt differ