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 f2829dda1..1de87af3b 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 @@ -38,6 +38,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties; import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2; import com.viaversion.viaversion.api.minecraft.item.data.DyedColor; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; +import com.viaversion.viaversion.api.minecraft.item.data.Equippable; 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; @@ -70,6 +71,7 @@ public record StructuredDataKey(String identifier, Type type) { public static final StructuredDataKey UNBREAKABLE = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE); public static final StructuredDataKey CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG); public static final StructuredDataKey ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG); + public static final StructuredDataKey ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING); public static final StructuredDataKey LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY); public static final StructuredDataKey RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT); public static final StructuredDataKey ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE); @@ -93,7 +95,10 @@ public record StructuredDataKey(String identifier, Type type) { 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 EQUIPPABLE = new StructuredDataKey<>("equippable", Equippable.TYPE); public static final StructuredDataKey REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET); + public static final StructuredDataKey GLIDER = new StructuredDataKey<>("glider", Types.EMPTY); + public static final StructuredDataKey TOOLTIP_STYLE = new StructuredDataKey<>("tooltip_style", Types.STRING); public static final StructuredDataKey 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); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java new file mode 100644 index 000000000..5b3eb58a7 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Equippable.java @@ -0,0 +1,62 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.minecraft.item.data; + +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.HolderSet; +import com.viaversion.viaversion.api.minecraft.SoundEvent; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.Types; +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; +import org.checkerframework.checker.nullness.qual.Nullable; + +public record Equippable(int equipmentSlot, Holder soundEvent, @Nullable String model, + @Nullable HolderSet allowedEntities, boolean dispensable) { + + public static final Type TYPE = new Type<>(Equippable.class) { + @Override + public Equippable read(final ByteBuf buffer) { + final int equipmentSlot = Types.VAR_INT.readPrimitive(buffer); + final Holder soundEvent = Types.SOUND_EVENT.read(buffer); + final String model = Types.STRING.read(buffer); + final HolderSet allowedEntities = Types.HOLDER_SET.read(buffer); + final boolean dispensable = buffer.readBoolean(); + return new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable); + } + + @Override + public void write(final ByteBuf buffer, final Equippable value) { + Types.VAR_INT.writePrimitive(buffer, value.equipmentSlot()); + Types.SOUND_EVENT.write(buffer, value.soundEvent()); + Types.STRING.write(buffer, value.model()); + Types.HOLDER_SET.write(buffer, value.allowedEntities()); + buffer.writeBoolean(value.dispensable()); + } + }; + + public Equippable rewrite(final Int2IntFunction soundIdRewriter) { + final Holder soundEvent = this.soundEvent.updateId(soundIdRewriter); + return soundEvent == this.soundEvent ? this : new Equippable(equipmentSlot, soundEvent, model, allowedEntities, dispensable); + } +} 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 ca9aed825..a82ddee97 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java @@ -86,7 +86,7 @@ public class ProtocolVersion implements Comparable { public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4)); public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6)); public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1)); - public static final ProtocolVersion v1_21_2 = register(768, 207, "1.21.2"); + public static final ProtocolVersion v1_21_2 = register(768, 208, "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/item/StructuredDataType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/item/StructuredDataType.java index a1a297fbd..90186aa3b 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/item/StructuredDataType.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/item/StructuredDataType.java @@ -87,5 +87,12 @@ public class StructuredDataType extends Type> { types[id] = key; return this; } + + public DataFiller add(final StructuredDataKey... keys) { + for (final StructuredDataKey key : keys) { + add(key); + } + return this; + } } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/Protocol1_21To1_21_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/Protocol1_21To1_21_2.java index 0e2d6dd5c..0620ce5c3 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/Protocol1_21To1_21_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_21to1_21_2/Protocol1_21To1_21_2.java @@ -108,30 +108,26 @@ public final class Protocol1_21To1_21_2 extends AbstractProtocol { + protocol.registerClientbound(ClientboundPackets1_21.PLAYER_POSITION, wrapper -> { + wrapper.write(Types.VAR_INT, 0); // Teleport id, set at the end + + wrapper.passthrough(Types.DOUBLE); // X + wrapper.passthrough(Types.DOUBLE); // Y + wrapper.passthrough(Types.DOUBLE); // Z + + wrapper.write(Types.DOUBLE, 0D); // Delta movement X + wrapper.write(Types.DOUBLE, 0D); // Delta movement Y + wrapper.write(Types.DOUBLE, 0D); // Delta movement Z + + // Pack y and x rot + final float yaw = wrapper.read(Types.FLOAT); + final float pitch = wrapper.read(Types.FLOAT); + wrapper.write(Types.BYTE, (byte) Math.floor(yaw * 256F / 360F)); + wrapper.write(Types.BYTE, (byte) Math.floor(pitch * 256F / 360F)); + + // Add new delta movement flags so their current veloticy is kept + int relativeArguments = wrapper.read(Types.BYTE); + relativeArguments |= 1 << 5; + relativeArguments |= 1 << 6; + relativeArguments |= 1 << 7; + wrapper.write(Types.INT, relativeArguments); + + final int teleportId = wrapper.read(Types.VAR_INT); + wrapper.set(Types.VAR_INT, 0, teleportId); + }); + + // Previously only used while in a vehicle, now always sent. + // The server will ignore it if not in a vehicle, so we can always pass it through + protocol.registerServerbound(ServerboundPackets1_21_2.PLAYER_INPUT, wrapper -> { + final byte flags = wrapper.read(Types.BYTE); + final boolean left = (flags & 4) != 0; + final boolean right = (flags & 8) != 0; + wrapper.write(Types.FLOAT, left ? 1F : (right ? -1F : 0F)); + + final boolean forward = (flags & 1) != 0; + final boolean backward = (flags & 2) != 0; + wrapper.write(Types.FLOAT, forward ? 1F : (backward ? -1F : 0F)); + + byte updatedFlags = 0; + if ((flags & 1) != 0) { + updatedFlags |= 1; + } else if ((flags & 2) != 0) { + updatedFlags |= 2; + } + wrapper.write(Types.BYTE, updatedFlags); + }); + + protocol.registerServerbound(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 -> { + protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS_ROT, wrapper -> { wrapper.passthrough(Types.DOUBLE); // X wrapper.passthrough(Types.DOUBLE); // Y wrapper.passthrough(Types.DOUBLE); // Z @@ -134,12 +183,12 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter { + protocol.registerServerbound(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); + protocol.registerServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround); } public static void updateEnchantmentAttributes(final RegistryEntry[] entries, final FullMappings mappings) { 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 b3b72fc76..c3a77a755 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 index 7c40bbfbc..c62857d28 100644 Binary files a/common/src/main/resources/assets/viaversion/data/identifiers-1.21.2.nbt 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 index 3feade9f1..1330ffa6d 100644 Binary files a/common/src/main/resources/assets/viaversion/data/mappings-1.21to1.21.2.nbt and b/common/src/main/resources/assets/viaversion/data/mappings-1.21to1.21.2.nbt differ