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 58f78d5e4..cdba22f1d 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 @@ -84,6 +84,7 @@ public class ProtocolVersion implements Comparable { public static final ProtocolVersion v1_20_2 = register(764, "1.20.2"); 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, 193, "1.21"); 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/misc/ParticleType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/ParticleType.java index b3485b581..f02573c07 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/ParticleType.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/ParticleType.java @@ -71,8 +71,6 @@ public class ParticleType extends DynamicType { }; public static final DataReader ITEM1_13 = itemHandler(Types.ITEM1_13); public static final DataReader ITEM1_13_2 = itemHandler(Types.ITEM1_13_2); - public static final DataReader ITEM1_20_2 = itemHandler(Types.ITEM1_20_2); - public static final DataReader ITEM1_20_5 = itemHandler(Types1_20_5.ITEM); public static final DataReader DUST = (buf, particle) -> { particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Red 0-1 particle.add(Types.FLOAT, Types.FLOAT.readPrimitive(buf)); // Green 0-1 @@ -139,5 +137,9 @@ public class ParticleType extends DynamicType { particle.add(Types.VAR_INT, Types.VAR_INT.readPrimitive(buf)); // Delay }; public static final DataReader COLOR = (buf, particle) -> particle.add(Types.INT, buf.readInt()); + + public static DataReader item(Type item) { + return (buf, particle) -> particle.add(item, item.read(buf)); + } } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21.java new file mode 100644 index 000000000..39b2ba473 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/Types1_21.java @@ -0,0 +1,55 @@ +/* + * 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.item.Item; +import com.viaversion.viaversion.api.minecraft.metadata.Metadata; +import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_20_5; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.ArrayType; +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.metadata.MetaListType; +import com.viaversion.viaversion.api.type.types.metadata.MetadataType; +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 { + + public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType(); + public static final Type[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA); + public static final Type ITEM = new ItemType1_20_5(STRUCTURED_DATA); + 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 MetaTypes1_20_5 META_TYPES = new MetaTypes1_20_5(PARTICLE, PARTICLES); + public static final Type METADATA = new MetadataType(META_TYPES); + public static final Type> METADATA_LIST = new MetaListType(METADATA); +} 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 a12e19ccf..6b7725b24 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolManagerImpl.java @@ -187,6 +187,8 @@ public class ProtocolManagerImpl implements ProtocolManager { registerProtocol(new Protocol1_20To1_20_2(), ProtocolVersion.v1_20_2, ProtocolVersion.v1_20); registerProtocol(new Protocol1_20_2To1_20_3(), ProtocolVersion.v1_20_3, ProtocolVersion.v1_20_2); registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3); + + registerProtocol(new Protocol1_21To1_20_5(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5); } @Override diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/Protocol1_21To1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/Protocol1_21To1_20_5.java new file mode 100644 index 000000000..1b2c3ff6f --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/Protocol1_21To1_20_5.java @@ -0,0 +1,145 @@ +/* + * 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_21to1_20_5; + +import com.viaversion.viaversion.api.connection.UserConnection; +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.provider.PacketTypesProvider; +import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; +import com.viaversion.viaversion.api.type.types.misc.ParticleType; +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.data.entity.EntityTrackerBase; +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; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundConfigurationPackets1_20_5; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.data.MappingData; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.rewriter.BlockItemPacketRewriter1_21; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.rewriter.EntityPacketRewriter1_21; +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_20_5 extends AbstractProtocol { + + public static final MappingData MAPPINGS = new MappingData(); + private final EntityPacketRewriter1_21 entityRewriter = new EntityPacketRewriter1_21(this); + private final BlockItemPacketRewriter1_21 itemRewriter = new BlockItemPacketRewriter1_21(this); + private final TagRewriter tagRewriter = new TagRewriter<>(this); + + public Protocol1_21To1_20_5() { + super(ClientboundPacket1_20_5.class, ClientboundPacket1_20_5.class, ServerboundPacket1_20_5.class, ServerboundPacket1_20_5.class); + } + + @Override + protected void registerPackets() { + super.registerPackets(); + + tagRewriter.registerGeneric(ClientboundPackets1_20_5.TAGS); + tagRewriter.registerGeneric(ClientboundConfigurationPackets1_20_5.UPDATE_TAGS); + + final SoundRewriter soundRewriter = new SoundRewriter<>(this); + soundRewriter.register1_19_3Sound(ClientboundPackets1_20_5.SOUND); + soundRewriter.register1_19_3Sound(ClientboundPackets1_20_5.ENTITY_SOUND); + + new StatisticsRewriter<>(this).register(ClientboundPackets1_20_5.STATISTICS); + new AttributeRewriter<>(this).register1_20_5(ClientboundPackets1_20_5.ENTITY_PROPERTIES); + } + + @Override + protected void onMappingDataLoaded() { + super.onMappingDataLoaded(); + + // Added preemptively TODO Check if there are actual changes before release + Types1_21.PARTICLE.filler(this) + .reader("block", ParticleType.Readers.BLOCK) + .reader("block_marker", ParticleType.Readers.BLOCK) + .reader("dust", ParticleType.Readers.DUST) + .reader("dust_pillar", ParticleType.Readers.BLOCK) + .reader("falling_dust", ParticleType.Readers.BLOCK) + .reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION) + .reader("item", ParticleType.Readers.item(Types1_20_5.ITEM)) + .reader("vibration", ParticleType.Readers.VIBRATION1_20_3) + .reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE) + .reader("shriek", ParticleType.Readers.SHRIEK) + .reader("entity_effect", ParticleType.Readers.COLOR); + Types1_21.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.FOOD).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.ATTRIBUTE_MODIFIERS) + .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_PROJECTILES).add(StructuredDataKey.BUNDLE_CONTENTS).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.INSTRUMENT) + .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.CONTAINER).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); + } + + @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 getEntityRewriter() { + return entityRewriter; + } + + @Override + public BlockItemPacketRewriter1_21 getItemRewriter() { + return itemRewriter; + } + + @Override + public TagRewriter getTagRewriter() { + return tagRewriter; + } + + @Override + protected PacketTypesProvider createPacketTypesProvider() { + return new SimplePacketTypesProvider<>( + packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_20_5.class, ClientboundConfigurationPackets1_20_5.class), + packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_20_5.class, ClientboundConfigurationPackets1_20_5.class), + packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class), + packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class) + ); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/MappingData.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/MappingData.java new file mode 100644 index 000000000..f0d6faa49 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/MappingData.java @@ -0,0 +1,42 @@ +/* + * 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_21to1_20_5.data; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.viaversion.viaversion.api.data.MappingDataBase; +import com.viaversion.viaversion.api.data.MappingDataLoader; + +public final class MappingData extends MappingDataBase { + + private ListTag enchantments; + + public MappingData() { + super("1.20.5", "1.21"); + } + + @Override + protected void loadExtras(final CompoundTag data) { + final CompoundTag extraMappings = MappingDataLoader.INSTANCE.loadNBT("enchantments-1.21.nbt"); + enchantments = extraMappings.getListTag("entries", CompoundTag.class); + } + + public CompoundTag enchantment(final int id) { + return enchantments.get(id).copy(); + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/Paintings1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/Paintings1_20_5.java new file mode 100644 index 000000000..7d83316d0 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/data/Paintings1_20_5.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.protocol1_21to1_20_5.data; + +public final class Paintings1_20_5 { + + public static final PaintingVariant[] PAINTINGS = { + new PaintingVariant("kebab", 1, 1), + new PaintingVariant("aztec", 1, 1), + new PaintingVariant("alban", 1, 1), + new PaintingVariant("aztec2", 1, 1), + new PaintingVariant("bomb", 1, 1), + new PaintingVariant("plant", 1, 1), + new PaintingVariant("wasteland", 1, 1), + new PaintingVariant("pool", 2, 1), + new PaintingVariant("courbet", 2, 1), + new PaintingVariant("sea", 2, 1), + new PaintingVariant("sunset", 2, 1), + new PaintingVariant("creebet", 2, 1), + new PaintingVariant("wanderer", 1, 2), + new PaintingVariant("graham", 1, 2), + new PaintingVariant("match", 2, 2), + new PaintingVariant("bust", 2, 2), + new PaintingVariant("stage", 2, 2), + new PaintingVariant("void", 2, 2), + new PaintingVariant("skull_and_roses", 2, 2), + new PaintingVariant("wither", 2, 2), + new PaintingVariant("fighters", 4, 2), + new PaintingVariant("pointer", 4, 4), + new PaintingVariant("pigscene", 4, 4), + new PaintingVariant("burning_skull", 4, 4), + new PaintingVariant("skeleton", 4, 3), + new PaintingVariant("earth", 2, 2), + new PaintingVariant("wind", 2, 2), + new PaintingVariant("water", 2, 2), + new PaintingVariant("fire", 2, 2), + new PaintingVariant("donkey_kong", 4, 3) + }; + + public static final class PaintingVariant { + private final String key; + private final int width; + private final int height; + + public PaintingVariant(final String key, final int width, final int height) { + this.key = key; + this.width = width; + this.height = height; + } + + public String key() { + return key; + } + + public int width() { + return width; + } + + public int height() { + return height; + } + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java new file mode 100644 index 000000000..bdbeb477c --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/BlockItemPacketRewriter1_21.java @@ -0,0 +1,62 @@ +/* + * 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_21to1_20_5.rewriter; + +import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; +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.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3; +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; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5; +import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.Protocol1_21To1_20_5; +import com.viaversion.viaversion.rewriter.BlockRewriter; +import com.viaversion.viaversion.rewriter.StructuredItemRewriter; + +public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter { + + public BlockItemPacketRewriter1_21(final Protocol1_21To1_20_5 protocol) { + super(protocol, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, Types1_21.ITEM, Types1_21.ITEM_ARRAY); + } + + @Override + public void registerPackets() { + final BlockRewriter blockRewriter = BlockRewriter.for1_20_2(protocol); + blockRewriter.registerBlockAction(ClientboundPackets1_20_5.BLOCK_ACTION); + blockRewriter.registerBlockChange(ClientboundPackets1_20_5.BLOCK_CHANGE); + blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_20_5.MULTI_BLOCK_CHANGE); + blockRewriter.registerEffect(ClientboundPackets1_20_5.EFFECT, 1010, 2001); + blockRewriter.registerChunkData1_19(ClientboundPackets1_20_5.CHUNK_DATA, ChunkType1_20_2::new); + blockRewriter.registerBlockEntityData(ClientboundPackets1_20_5.BLOCK_ENTITY_DATA); + + registerSetCooldown(ClientboundPackets1_20_5.COOLDOWN); + registerWindowItems1_17_1(ClientboundPackets1_20_5.WINDOW_ITEMS); + registerSetSlot1_17_1(ClientboundPackets1_20_5.SET_SLOT); + registerAdvancements1_20_3(ClientboundPackets1_20_5.ADVANCEMENTS); + registerEntityEquipmentArray(ClientboundPackets1_20_5.ENTITY_EQUIPMENT); + registerClickWindow1_17_1(ServerboundPackets1_20_5.CLICK_WINDOW); + registerTradeList1_20_5(ClientboundPackets1_20_5.TRADE_LIST, Types1_20_5.ITEM_COST, Types1_20_5.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21.OPTIONAL_ITEM_COST); + registerCreativeInvAction(ServerboundPackets1_20_5.CREATIVE_INVENTORY_ACTION); + registerWindowPropertyEnchantmentHandler(ClientboundPackets1_20_5.WINDOW_PROPERTY); + registerSpawnParticle1_20_5(ClientboundPackets1_20_5.SPAWN_PARTICLE, Types1_20_5.PARTICLE, Types1_21.PARTICLE); + registerExplosion(ClientboundPackets1_20_5.EXPLOSION, Types1_20_5.PARTICLE, Types1_21.PARTICLE); // Rewrites the included sound and particles + + new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_20_5.DECLARE_RECIPES); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java new file mode 100644 index 000000000..8dd39ed38 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_21to1_20_5/rewriter/EntityPacketRewriter1_21.java @@ -0,0 +1,150 @@ +/* + * 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_21to1_20_5.rewriter; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +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.Type; +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.protocols.protocol1_20_5to1_20_3.data.Enchantments1_20_5; +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; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.Protocol1_21To1_20_5; +import com.viaversion.viaversion.protocols.protocol1_21to1_20_5.data.Paintings1_20_5; +import com.viaversion.viaversion.rewriter.EntityRewriter; +import com.viaversion.viaversion.util.Key; + +public final class EntityPacketRewriter1_21 extends EntityRewriter { + + public EntityPacketRewriter1_21(final Protocol1_21To1_20_5 protocol) { + super(protocol); + } + + @Override + public void registerPackets() { + registerTrackerWithData1_19(ClientboundPackets1_20_5.SPAWN_ENTITY, EntityTypes1_20_5.FALLING_BLOCK); + registerMetadataRewriter(ClientboundPackets1_20_5.ENTITY_METADATA, Types1_20_5.METADATA_LIST, Types1_21.METADATA_LIST); + registerRemoveEntities(ClientboundPackets1_20_5.REMOVE_ENTITIES); + + protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA, new PacketHandlers() { + @Override + protected void register() { + map(Type.STRING); // Registry + map(Type.REGISTRY_ENTRY_ARRAY); // Data + handler(registryDataHandler1_20_5()); + handler(wrapper -> { + // Add required damage type + final String type = wrapper.get(Type.STRING, 0); + final RegistryEntry[] entries = wrapper.get(Type.REGISTRY_ENTRY_ARRAY, 0); + if (Key.stripMinecraftNamespace(type).equals("damage_type")) { + final CompoundTag campfireDamageType = new CompoundTag(); + campfireDamageType.putString("scaling", "when_caused_by_living_non_player"); + campfireDamageType.putString("message_id", "inFire"); + campfireDamageType.putFloat("exhaustion", 0.1F); + wrapper.set(Type.REGISTRY_ENTRY_ARRAY, 0, addRegistryEnties(entries, new RegistryEntry("minecraft:campfire", campfireDamageType))); + } + }); + } + }); + + protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.FINISH_CONFIGURATION, wrapper -> { + // Add new registries + final PacketWrapper paintingRegistryPacket = wrapper.create(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA); + paintingRegistryPacket.write(Type.STRING, "minecraft:painting_variant"); + final RegistryEntry[] paintingsRegistry = new RegistryEntry[Paintings1_20_5.PAINTINGS.length]; + for (int i = 0; i < Paintings1_20_5.PAINTINGS.length; i++) { + final Paintings1_20_5.PaintingVariant painting = Paintings1_20_5.PAINTINGS[i]; + final CompoundTag tag = new CompoundTag(); + tag.putInt("width", painting.width()); + tag.putInt("height", painting.height()); + tag.putString("asset_id", painting.key()); + paintingsRegistry[i] = new RegistryEntry(painting.key(), tag); + } + paintingRegistryPacket.write(Type.REGISTRY_ENTRY_ARRAY, paintingsRegistry); + paintingRegistryPacket.send(Protocol1_21To1_20_5.class); + + final PacketWrapper enchantmentRegistryPacket = wrapper.create(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA); + enchantmentRegistryPacket.write(Type.STRING, "minecraft:enchantment"); + final RegistryEntry[] enchantmentRegistry = new RegistryEntry[Enchantments1_20_5.ENCHANTMENTS.size()]; + for (int i = 0; i < Enchantments1_20_5.ENCHANTMENTS.size(); i++) { + final String key = Enchantments1_20_5.idToKey(i); + final CompoundTag tag = protocol.getMappingData().enchantment(i); + enchantmentRegistry[i] = new RegistryEntry(key, tag); + } + enchantmentRegistryPacket.write(Type.REGISTRY_ENTRY_ARRAY, enchantmentRegistry); + enchantmentRegistryPacket.send(Protocol1_21To1_20_5.class); + }); + + protocol.registerClientbound(ClientboundPackets1_20_5.JOIN_GAME, new PacketHandlers() { + @Override + public void register() { + map(Type.INT); // Entity id + map(Type.BOOLEAN); // Hardcore + map(Type.STRING_ARRAY); // World List + map(Type.VAR_INT); // Max players + map(Type.VAR_INT); // View distance + map(Type.VAR_INT); // Simulation distance + map(Type.BOOLEAN); // Reduced debug info + map(Type.BOOLEAN); // Show death screen + map(Type.BOOLEAN); // Limited crafting + map(Type.VAR_INT); // Dimension id + map(Type.STRING); // World + handler(worldDataTrackerHandlerByKey1_20_5(3)); + handler(playerTrackerHandler()); + } + }); + + protocol.registerClientbound(ClientboundPackets1_20_5.RESPAWN, new PacketHandlers() { + @Override + public void register() { + map(Type.VAR_INT); // Dimension + map(Type.STRING); // World + handler(worldDataTrackerHandlerByKey1_20_5(0)); // Tracks world height and name for chunk data and entity (un)tracking + } + }); + } + + @Override + protected void registerRewrites() { + filter().mapMetaType(Types1_21.META_TYPES::byId); + + registerMetaTypeHandler( + Types1_21.META_TYPES.itemType, + Types1_21.META_TYPES.blockStateType, + Types1_21.META_TYPES.optionalBlockStateType, + Types1_21.META_TYPES.particleType, + Types1_21.META_TYPES.particlesType + ); + + filter().type(EntityTypes1_20_5.MINECART_ABSTRACT).index(11).handler((event, meta) -> { + final int blockState = meta.value(); + meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState)); + }); + } + + @Override + public EntityType typeFromId(final int type) { + return EntityTypes1_20_5.getTypeFromId(type); + } +} \ 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 dc7752d1c..997413b5b 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 @@ -253,7 +253,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol { private final Protocol protocol; @@ -33,10 +33,24 @@ public class AttributeRewriter { wrapper.passthrough(Types.VAR_INT); // Entity ID final int size = wrapper.passthrough(Types.VAR_INT); + int newSize = size; for (int i = 0; i < size; i++) { final int attributeId = wrapper.read(Types.VAR_INT); - wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewAttributeId(attributeId)); + final int mappedId = protocol.getMappingData().getNewAttributeId(attributeId); + if (mappedId == -1) { + newSize--; + wrapper.read(Types.DOUBLE); // Base + final int modifierSize = wrapper.read(Types.VAR_INT); + for (int j = 0; j < modifierSize; j++) { + wrapper.read(Types.UUID); // ID + wrapper.read(Types.DOUBLE); // Amount + wrapper.read(Types.BYTE); // Operation + } + continue; + } + + wrapper.write(Types.VAR_INT, mappedId); wrapper.passthrough(Types.DOUBLE); // Base final int modifierSize = wrapper.passthrough(Types.VAR_INT); for (int j = 0; j < modifierSize; j++) { @@ -45,6 +59,10 @@ public class AttributeRewriter { wrapper.passthrough(Types.BYTE); // Operation } } + + if (size != newSize) { + wrapper.set(Types.VAR_INT, 1, newSize); + } }); } } diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java index f70dd480f..6257f593f 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java @@ -51,6 +51,7 @@ import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEventImpl; import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.TagUtil; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -579,6 +580,13 @@ public abstract class EntityRewriter { } public void handleRecipeType(PacketWrapper wrapper, String type) { - RecipeConsumer handler = recipeHandlers.get(type); + RecipeConsumer handler = recipeHandlers.get(Key.stripMinecraftNamespace(type)); if (handler != null) { handler.accept(wrapper); } @@ -73,7 +73,7 @@ public class RecipeRewriter { for (int i = 0; i < size; i++) { String type = wrapper.passthrough(Types.STRING); wrapper.passthrough(Types.STRING); // Recipe Identifier - handleRecipeType(wrapper, Key.stripMinecraftNamespace(type)); + handleRecipeType(wrapper, type); } }); } @@ -82,7 +82,7 @@ public class RecipeRewriter { protocol.registerClientbound(packetType, wrapper -> { int size = wrapper.passthrough(Types.VAR_INT); for (int i = 0; i < size; i++) { - wrapper.passthrough(Types.STRING);// Recipe Identifier + wrapper.passthrough(Types.STRING); // Recipe Identifier final int typeId = wrapper.passthrough(Types.VAR_INT); final String type = protocol.getMappingData().getRecipeSerializerMappings().identifier(typeId); diff --git a/common/src/main/resources/assets/viaversion/data/enchantments-1.21.nbt b/common/src/main/resources/assets/viaversion/data/enchantments-1.21.nbt new file mode 100644 index 000000000..2c613fe55 Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/enchantments-1.21.nbt differ 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 045d153ad..32aa5c473 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.nbt b/common/src/main/resources/assets/viaversion/data/identifiers-1.21.nbt new file mode 100644 index 000000000..36189349a Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/identifiers-1.21.nbt differ diff --git a/common/src/main/resources/assets/viaversion/data/mappings-1.20.5to1.21.nbt b/common/src/main/resources/assets/viaversion/data/mappings-1.20.5to1.21.nbt new file mode 100644 index 000000000..54faa5422 Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/mappings-1.20.5to1.21.nbt differ diff --git a/gradle.properties b/gradle.properties index 981c064fc..de83ae393 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Project properties - we put these here so they can be modified without causing a recompile of the build scripts -projectVersion=5.0.0-SNAPSHOT +projectVersion=5.0.0-24w18a-SNAPSHOT # Smile emoji mcVersions=1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9 diff --git a/template/src/main/java/com/viaversion/viaversion/template/protocols/Protocol1_99To_98.java b/template/src/main/java/com/viaversion/viaversion/template/protocols/Protocol1_99To_98.java index 5240c8264..4617443cd 100644 --- a/template/src/main/java/com/viaversion/viaversion/template/protocols/Protocol1_99To_98.java +++ b/template/src/main/java/com/viaversion/viaversion/template/protocols/Protocol1_99To_98.java @@ -22,6 +22,8 @@ import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.MappingDataBase; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; import com.viaversion.viaversion.api.protocol.AbstractProtocol; +import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; +import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundConfigurationPackets1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPacket1_20_5; @@ -34,6 +36,8 @@ import com.viaversion.viaversion.rewriter.TagRewriter; import com.viaversion.viaversion.template.protocols.rewriter.BlockItemPacketRewriter1_99; import com.viaversion.viaversion.template.protocols.rewriter.EntityPacketRewriter1_99; +import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap; + // Placeholders to replace (in the entire package): // Protocol1_99To_98, EntityPacketRewriter1_99, BlockItemPacketRewriter1_99 // ClientboundPacket1_20_5 @@ -130,4 +134,14 @@ public final class Protocol1_99To_98 extends AbstractProtocol getTagRewriter() { return tagRewriter; } + + @Override + protected PacketTypesProvider createPacketTypesProvider() { + return new SimplePacketTypesProvider<>( + packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_20_5.class, ClientboundConfigurationPackets1_20_5.class), + packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_20_5.class, ClientboundConfigurationPackets1_20_5.class), + packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class), + packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class) + ); + } } \ No newline at end of file