diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/Holder.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/Holder.java new file mode 100644 index 000000000..919761b0c --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/Holder.java @@ -0,0 +1,69 @@ +/* + * 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; + +import com.viaversion.viaversion.util.Either; + +public final class Holder implements Either { + + private final T value; + private final int id; + + public Holder(final int id) { + this.value = null; + this.id = id; + } + + public Holder(final T value) { + this.value = value; + this.id = -1; + } + + public boolean isDirect() { + return id != -1; + } + + @Override + public boolean isLeft() { + return value != null; + } + + @Override + public boolean isRight() { + return value == null; + } + + @Override + public Integer left() { + return id; + } + + @Override + public T right() { + return value; + } + + public int id() { + return id; + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSet.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSet.java index b9288956d..59f09922a 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSet.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSet.java @@ -22,21 +22,15 @@ */ package com.viaversion.viaversion.api.minecraft; -import com.viaversion.viaversion.util.Either; +import com.viaversion.viaversion.util.EitherImpl; -public final class HolderSet { - - private final Either values; +public final class HolderSet extends EitherImpl { public HolderSet(final String tagKey) { - this.values = Either.left(tagKey); + super(tagKey, null); } public HolderSet(final int[] ids) { - this.values = Either.right(ids); - } - - public Either values() { - return values; + super(null, ids); } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/SoundEvent.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/SoundEvent.java new file mode 100644 index 000000000..a9bcdd8ee --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/SoundEvent.java @@ -0,0 +1,44 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.minecraft; + +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class SoundEvent { + + private final String resourceLocation; + private final Float fixedRange; + + public SoundEvent(final String resourceLocation, @Nullable final Float fixedRange) { + this.resourceLocation = resourceLocation; + this.fixedRange = fixedRange; + } + + public String resourceLocation() { + return resourceLocation; + } + + public @Nullable Float fixedRange() { + return fixedRange; + } +} 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 c4e34f233..37fe3bbc5 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 @@ -25,16 +25,19 @@ package com.viaversion.viaversion.api.minecraft.data; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import com.viaversion.viaversion.api.minecraft.GameProfile; +import com.viaversion.viaversion.api.minecraft.Holder; 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; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers; import com.viaversion.viaversion.api.minecraft.item.data.BannerPattern; 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.AdventureModePredicate; 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.FireworkExplosion; import com.viaversion.viaversion.api.minecraft.item.data.Fireworks; +import com.viaversion.viaversion.api.minecraft.item.data.Instrument; import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTarget; import com.viaversion.viaversion.api.minecraft.item.data.PotionContents; import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect; @@ -72,12 +75,12 @@ public final class StructuredDataKey { 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", Type.STRING_ARRAY); public static final StructuredDataKey WRITTEN_BOOK_CONTENT = new StructuredDataKey<>("written_book_content", WrittenBook.TYPE); - public static final StructuredDataKey TRIM = new StructuredDataKey<>("trim", Type.EMPTY); // TODO + public static final StructuredDataKey TRIM = new StructuredDataKey<>("trim", ArmorTrim.TYPE); public static final StructuredDataKey DEBUG_STICK_STATE = new StructuredDataKey<>("debug_stick_state", Type.COMPOUND_TAG); public static final StructuredDataKey ENTITY_DATA = new StructuredDataKey<>("entity_data", Type.COMPOUND_TAG); public static final StructuredDataKey BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Type.COMPOUND_TAG); public static final StructuredDataKey BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Type.COMPOUND_TAG); - public static final StructuredDataKey INSTRUMENT = new StructuredDataKey<>("instrument", Type.EMPTY); // TODO + public static final StructuredDataKey> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE); public static final StructuredDataKey RECIPES = new StructuredDataKey<>("recipes", Type.STRING_ARRAY); public static final StructuredDataKey LODESTONE_TARGET = new StructuredDataKey<>("lodestone_target", LodestoneTarget.TYPE); public static final StructuredDataKey FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE); diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrim.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrim.java new file mode 100644 index 000000000..c09da1072 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrim.java @@ -0,0 +1,69 @@ +/* + * 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.type.Type; +import io.netty.buffer.ByteBuf; + +public final class ArmorTrim { + + public static final Type TYPE = new Type(ArmorTrim.class) { + @Override + public ArmorTrim read(final ByteBuf buffer) throws Exception { + final Holder material = ArmorTrimMaterial.TYPE.read(buffer); + final Holder pattern = ArmorTrimPattern.TYPE.read(buffer); + final boolean showInTooltip = buffer.readBoolean(); + return new ArmorTrim(material, pattern, showInTooltip); + } + + @Override + public void write(final ByteBuf buffer, final ArmorTrim value) throws Exception { + ArmorTrimMaterial.TYPE.write(buffer, value.material); + ArmorTrimPattern.TYPE.write(buffer, value.pattern); + buffer.writeBoolean(value.showInTooltip); + } + }; + + private final Holder material; + private final Holder pattern; + private final boolean showInTooltip; + + public ArmorTrim(final Holder material, final Holder pattern, final boolean showInTooltip) { + this.material = material; + this.pattern = pattern; + this.showInTooltip = showInTooltip; + } + + public Holder material() { + return material; + } + + public Holder pattern() { + return pattern; + } + + public boolean showInTooltip() { + return showInTooltip; + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimMaterial.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimMaterial.java new file mode 100644 index 000000000..d5e7c971c --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimMaterial.java @@ -0,0 +1,102 @@ +/* + * 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.github.steveice10.opennbt.tag.builtin.Tag; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +public final class ArmorTrimMaterial { + + public static final HolderType TYPE = new HolderType() { + @Override + public ArmorTrimMaterial readDirect(final ByteBuf buffer) throws Exception { + final String assetName = Type.STRING.read(buffer); + final int item = Type.VAR_INT.readPrimitive(buffer); + final float itemModelIndex = buffer.readFloat(); + + final int overrideArmorMaterialsSize = Type.VAR_INT.readPrimitive(buffer); + final Int2ObjectMap overrideArmorMaterials = new Int2ObjectOpenHashMap<>(overrideArmorMaterialsSize); + for (int i = 0; i < overrideArmorMaterialsSize; i++) { + final int key = Type.VAR_INT.readPrimitive(buffer); + final String value = Type.STRING.read(buffer); + overrideArmorMaterials.put(key, value); + } + + final Tag description = Type.TAG.read(buffer); + return new ArmorTrimMaterial(assetName, item, itemModelIndex, overrideArmorMaterials, description); + } + + @Override + public void writeDirect(final ByteBuf buffer, final ArmorTrimMaterial value) throws Exception { + Type.STRING.write(buffer, value.assetName()); + Type.VAR_INT.writePrimitive(buffer, value.itemId()); + buffer.writeFloat(value.itemModelIndex()); + + Type.VAR_INT.writePrimitive(buffer, value.overrideArmorMaterials().size()); + for (final Int2ObjectMap.Entry entry : value.overrideArmorMaterials().int2ObjectEntrySet()) { + Type.VAR_INT.writePrimitive(buffer, entry.getIntKey()); + Type.STRING.write(buffer, entry.getValue()); + } + + Type.TAG.write(buffer, value.description()); + } + }; + + private final String assetName; + private final int itemId; + private final float itemModelIndex; + private final Int2ObjectMap overrideArmorMaterials; + private final Tag description; + + public ArmorTrimMaterial(final String assetName, final int itemId, final float itemModelIndex, final Int2ObjectMap overrideArmorMaterials, final Tag description) { + this.assetName = assetName; + this.itemId = itemId; + this.itemModelIndex = itemModelIndex; + this.overrideArmorMaterials = overrideArmorMaterials; + this.description = description; + } + + public String assetName() { + return assetName; + } + + public int itemId() { + return itemId; + } + + public float itemModelIndex() { + return itemModelIndex; + } + + public Int2ObjectMap overrideArmorMaterials() { + return overrideArmorMaterials; + } + + public Tag description() { + return description; + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimPattern.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimPattern.java new file mode 100644 index 000000000..b6a0cafae --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ArmorTrimPattern.java @@ -0,0 +1,78 @@ +/* + * 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.github.steveice10.opennbt.tag.builtin.Tag; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import io.netty.buffer.ByteBuf; + +public final class ArmorTrimPattern { + + public static final HolderType TYPE = new HolderType() { + @Override + public ArmorTrimPattern readDirect(final ByteBuf buffer) throws Exception { + final String assetName = Type.STRING.read(buffer); + final int itemId = Type.VAR_INT.readPrimitive(buffer); + final Tag description = Type.TAG.read(buffer); + final boolean decal = buffer.readBoolean(); + return new ArmorTrimPattern(assetName, itemId, description, decal); + } + + @Override + public void writeDirect(final ByteBuf buffer, final ArmorTrimPattern value) throws Exception { + Type.STRING.write(buffer, value.assetName()); + Type.VAR_INT.writePrimitive(buffer, value.itemId()); + Type.TAG.write(buffer, value.description()); + buffer.writeBoolean(value.decal()); + } + }; + + private final String assetName; + private final int itemId; + private final Tag description; + private final boolean decal; + + public ArmorTrimPattern(final String assetName, final int itemId, final Tag description, final boolean decal) { + this.assetName = assetName; + this.itemId = itemId; + this.description = description; + this.decal = decal; + } + + public String assetName() { + return assetName; + } + + public int itemId() { + return itemId; + } + + public Tag description() { + return description; + } + + public boolean decal() { + return decal; + } +} 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/Instrument.java new file mode 100644 index 000000000..eae31a242 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java @@ -0,0 +1,71 @@ +/* + * 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.SoundEvent; +import com.viaversion.viaversion.api.type.Type; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import io.netty.buffer.ByteBuf; + +public final class Instrument { + + public static final HolderType TYPE = new HolderType() { + @Override + public Instrument readDirect(final ByteBuf buffer) throws Exception { + final Holder soundEvent = Type.SOUND_EVENT.read(buffer); + final int useDuration = Type.VAR_INT.readPrimitive(buffer); + final float range = buffer.readFloat(); + return new Instrument(soundEvent, useDuration, range); + } + + @Override + public void writeDirect(final ByteBuf buffer, final Instrument value) throws Exception { + Type.SOUND_EVENT.write(buffer, value.soundEvent()); + Type.VAR_INT.writePrimitive(buffer, value.useDuration()); + buffer.writeFloat(value.range()); + } + }; + + private final Holder soundEvent; + private final int useDuration; + private final float range; + + public Instrument(final Holder soundEvent, final int useDuration, final float range) { + this.soundEvent = soundEvent; + this.useDuration = useDuration; + this.range = range; + } + + public Holder soundEvent() { + return soundEvent; + } + + public int useDuration() { + return useDuration; + } + + public float range() { + return range; + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/Type.java b/api/src/main/java/com/viaversion/viaversion/api/type/Type.java index 821f368a2..f1831e197 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/Type.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/Type.java @@ -35,6 +35,7 @@ import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.ProfileKey; import com.viaversion.viaversion.api.minecraft.Quaternion; import com.viaversion.viaversion.api.minecraft.RegistryEntry; +import com.viaversion.viaversion.api.minecraft.SoundEvent; import com.viaversion.viaversion.api.minecraft.Vector; import com.viaversion.viaversion.api.minecraft.Vector3f; import com.viaversion.viaversion.api.minecraft.VillagerData; @@ -48,18 +49,19 @@ import com.viaversion.viaversion.api.type.types.ByteArrayType; import com.viaversion.viaversion.api.type.types.ByteType; import com.viaversion.viaversion.api.type.types.ComponentType; import com.viaversion.viaversion.api.type.types.DoubleType; +import com.viaversion.viaversion.api.type.types.EmptyType; import com.viaversion.viaversion.api.type.types.FloatType; import com.viaversion.viaversion.api.type.types.IntArrayType; import com.viaversion.viaversion.api.type.types.IntType; import com.viaversion.viaversion.api.type.types.LongArrayType; import com.viaversion.viaversion.api.type.types.LongType; +import com.viaversion.viaversion.api.type.types.OptionalVarIntType; import com.viaversion.viaversion.api.type.types.RegistryEntryType; import com.viaversion.viaversion.api.type.types.RemainingBytesType; import com.viaversion.viaversion.api.type.types.ShortByteArrayType; import com.viaversion.viaversion.api.type.types.ShortType; import com.viaversion.viaversion.api.type.types.StringType; import com.viaversion.viaversion.api.type.types.UUIDType; -import com.viaversion.viaversion.api.type.types.EmptyType; import com.viaversion.viaversion.api.type.types.UnsignedByteType; import com.viaversion.viaversion.api.type.types.UnsignedShortType; import com.viaversion.viaversion.api.type.types.VarIntArrayType; @@ -68,30 +70,31 @@ import com.viaversion.viaversion.api.type.types.VarLongType; import com.viaversion.viaversion.api.type.types.block.BlockChangeRecordType; import com.viaversion.viaversion.api.type.types.block.BlockEntityType1_18; import com.viaversion.viaversion.api.type.types.block.BlockEntityType1_20_2; -import com.viaversion.viaversion.api.type.types.math.ChunkPositionType; -import com.viaversion.viaversion.api.type.types.misc.CompoundTagType; -import com.viaversion.viaversion.api.type.types.math.EulerAngleType; +import com.viaversion.viaversion.api.type.types.block.VarLongBlockChangeRecordType; import com.viaversion.viaversion.api.type.types.item.ItemShortArrayType1_13; -import com.viaversion.viaversion.api.type.types.item.ItemType1_13; import com.viaversion.viaversion.api.type.types.item.ItemShortArrayType1_13_2; -import com.viaversion.viaversion.api.type.types.item.ItemType1_13_2; -import com.viaversion.viaversion.api.type.types.math.GlobalPositionType; -import com.viaversion.viaversion.api.type.types.item.ItemType1_20_2; import com.viaversion.viaversion.api.type.types.item.ItemShortArrayType1_8; +import com.viaversion.viaversion.api.type.types.item.ItemType1_13; +import com.viaversion.viaversion.api.type.types.item.ItemType1_13_2; +import com.viaversion.viaversion.api.type.types.item.ItemType1_20_2; import com.viaversion.viaversion.api.type.types.item.ItemType1_8; -import com.viaversion.viaversion.api.type.types.misc.GameProfileType; -import com.viaversion.viaversion.api.type.types.misc.HolderSetType; -import com.viaversion.viaversion.api.type.types.misc.NamedCompoundTagType; -import com.viaversion.viaversion.api.type.types.OptionalVarIntType; -import com.viaversion.viaversion.api.type.types.misc.PlayerMessageSignatureType; +import com.viaversion.viaversion.api.type.types.math.ChunkPositionType; +import com.viaversion.viaversion.api.type.types.math.EulerAngleType; +import com.viaversion.viaversion.api.type.types.math.GlobalPositionType; import com.viaversion.viaversion.api.type.types.math.PositionType1_14; import com.viaversion.viaversion.api.type.types.math.PositionType1_8; -import com.viaversion.viaversion.api.type.types.misc.ProfileKeyType; import com.viaversion.viaversion.api.type.types.math.QuaternionType; -import com.viaversion.viaversion.api.type.types.misc.TagType; -import com.viaversion.viaversion.api.type.types.block.VarLongBlockChangeRecordType; import com.viaversion.viaversion.api.type.types.math.Vector3fType; import com.viaversion.viaversion.api.type.types.math.VectorType; +import com.viaversion.viaversion.api.type.types.misc.CompoundTagType; +import com.viaversion.viaversion.api.type.types.misc.GameProfileType; +import com.viaversion.viaversion.api.type.types.misc.HolderSetType; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import com.viaversion.viaversion.api.type.types.misc.NamedCompoundTagType; +import com.viaversion.viaversion.api.type.types.misc.PlayerMessageSignatureType; +import com.viaversion.viaversion.api.type.types.misc.ProfileKeyType; +import com.viaversion.viaversion.api.type.types.misc.SoundEventType; +import com.viaversion.viaversion.api.type.types.misc.TagType; import com.viaversion.viaversion.api.type.types.misc.VillagerDataType; import com.viaversion.viaversion.util.Unit; import java.util.UUID; @@ -198,6 +201,8 @@ public abstract class Type implements ByteBufReader, ByteBufWriter { public static final Type HOLDER_SET = new HolderSetType(); public static final Type OPTIONAL_HOLDER_SET = new HolderSetType.OptionalHolderSetType(); + public static final HolderType SOUND_EVENT = new SoundEventType(); + public static final Type ITEM1_8 = new ItemType1_8(); public static final Type ITEM1_13 = new ItemType1_13(); public static final Type ITEM1_13_2 = new ItemType1_13_2(); diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderSetType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderSetType.java index f9a65e0ac..aec86254b 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderSetType.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderSetType.java @@ -35,7 +35,7 @@ public class HolderSetType extends Type { @Override public HolderSet read(final ByteBuf buffer) throws Exception { - final int size = Type.VAR_INT.readPrimitive(buffer); + final int size = Type.VAR_INT.readPrimitive(buffer) - 1; if (size == -1) { final String tag = Type.STRING.read(buffer); return new HolderSet(tag); @@ -50,12 +50,12 @@ public class HolderSetType extends Type { @Override public void write(final ByteBuf buffer, final HolderSet object) throws Exception { - if (object.values().isLeft()) { - Type.VAR_INT.writePrimitive(buffer, -1); - Type.STRING.write(buffer, object.values().left()); + if (object.isLeft()) { + Type.VAR_INT.writePrimitive(buffer, 0); + Type.STRING.write(buffer, object.left()); } else { - final int[] values = object.values().right(); - Type.VAR_INT.writePrimitive(buffer, values.length); + final int[] values = object.right(); + Type.VAR_INT.writePrimitive(buffer, values.length + 1); for (final int value : values) { Type.VAR_INT.writePrimitive(buffer, value); } diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderType.java new file mode 100644 index 000000000..a8a337f3e --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/HolderType.java @@ -0,0 +1,57 @@ +/* + * 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.misc; + +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; + +public abstract class HolderType extends Type> { + + protected HolderType() { + super(Holder.class); + } + + @Override + public Holder read(final ByteBuf buffer) throws Exception { + final int id = Type.VAR_INT.readPrimitive(buffer) - 1; // Normalize id + if (id == -1) { + return new Holder<>(readDirect(buffer)); + } + return new Holder<>(id); + } + + @Override + public void write(final ByteBuf buffer, final Holder object) throws Exception { + if (object.isLeft()) { + Type.VAR_INT.writePrimitive(buffer, object.id() + 1); // Normalize id + } else { + Type.VAR_INT.writePrimitive(buffer, 0); + writeDirect(buffer, object.right()); + } + } + + public abstract T readDirect(final ByteBuf buffer) throws Exception; + + public abstract void writeDirect(final ByteBuf buffer, final T object) throws Exception; +} diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/SoundEventType.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/SoundEventType.java new file mode 100644 index 000000000..ec7e49330 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/misc/SoundEventType.java @@ -0,0 +1,43 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.api.type.types.misc; + +import com.viaversion.viaversion.api.minecraft.SoundEvent; +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; + +public final class SoundEventType extends HolderType { + + @Override + public SoundEvent readDirect(final ByteBuf buffer) throws Exception { + final String resourceLocation = Type.STRING.read(buffer); + final Float fixedRange = Type.OPTIONAL_FLOAT.read(buffer); + return new SoundEvent(resourceLocation, fixedRange); + } + + @Override + public void writeDirect(final ByteBuf buffer, final SoundEvent value) throws Exception { + Type.STRING.write(buffer, value.resourceLocation()); + Type.OPTIONAL_FLOAT.write(buffer, value.fixedRange()); + } +} diff --git a/api/src/main/java/com/viaversion/viaversion/util/Either.java b/api/src/main/java/com/viaversion/viaversion/util/Either.java index 55a2d4e9f..1a19c091a 100644 --- a/api/src/main/java/com/viaversion/viaversion/util/Either.java +++ b/api/src/main/java/com/viaversion/viaversion/util/Either.java @@ -23,63 +23,24 @@ package com.viaversion.viaversion.util; import com.google.common.base.Preconditions; -import java.util.Objects; -import org.checkerframework.checker.nullness.qual.Nullable; -public final class Either { - private final X left; - private final Y right; +public interface Either { - private Either(final X left, final Y value) { - this.left = left; - this.right = value; - Preconditions.checkArgument(left == null || value == null, "Either.left and Either.right are both present"); - } - - public static Either left(final X left) { + static Either left(final X left) { Preconditions.checkNotNull(left); - return new Either<>(left, null); + return new EitherImpl<>(left, null); } - public static Either right(final Y right) { + static Either right(final Y right) { Preconditions.checkNotNull(right); - return new Either<>(null, right); + return new EitherImpl<>(null, right); } - public boolean isLeft() { - return left != null; - } + boolean isLeft(); - public boolean isRight() { - return right != null; - } + boolean isRight(); - public @Nullable X left() { - return left; - } + X left(); - public @Nullable Y right() { - return right; - } - - @Override - public String toString() { - return "Either{" + left + ", " + right + '}'; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final Either pair = (Either) o; - if (!Objects.equals(left, pair.left)) return false; - return Objects.equals(right, pair.right); - } - - @Override - public int hashCode() { - int result = left != null ? left.hashCode() : 0; - result = 31 * result + (right != null ? right.hashCode() : 0); - return result; - } + Y right(); } diff --git a/api/src/main/java/com/viaversion/viaversion/util/EitherImpl.java b/api/src/main/java/com/viaversion/viaversion/util/EitherImpl.java new file mode 100644 index 000000000..2c3715c03 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/util/EitherImpl.java @@ -0,0 +1,79 @@ +/* + * 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.util; + +import com.google.common.base.Preconditions; +import java.util.Objects; + +public class EitherImpl implements Either { + private final X left; + private final Y right; + + protected EitherImpl(final X left, final Y value) { + this.left = left; + this.right = value; + Preconditions.checkArgument(left == null || value == null, "Either.left and Either.right are both present"); + Preconditions.checkArgument(left != null || value != null, "Either.left and Either.right are both null"); + } + + @Override + public boolean isLeft() { + return left != null; + } + + @Override + public boolean isRight() { + return right != null; + } + + @Override + public X left() { + return left; + } + + @Override + public Y right() { + return right; + } + + @Override + public String toString() { + return "Either{" + left + ", " + right + '}'; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final EitherImpl pair = (EitherImpl) o; + if (!Objects.equals(left, pair.left)) return false; + return Objects.equals(right, pair.right); + } + + @Override + public int hashCode() { + int result = left != null ? left.hashCode() : 0; + result = 31 * result + (right != null ? right.hashCode() : 0); + return result; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11_1to1_11/packets/InventoryPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11_1to1_11/packets/InventoryPackets.java index 22633016b..be4520e65 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11_1to1_11/packets/InventoryPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11_1to1_11/packets/InventoryPackets.java @@ -43,6 +43,6 @@ public class InventoryPackets extends ItemRewriter soundRewriter = new SoundRewriter<>(this); - registerClientbound(ClientboundPackets1_19_1.ENTITY_SOUND, new PacketHandlers() { - @Override - public void register() { - map(Type.VAR_INT); // Sound id - handler(soundRewriter.getSoundHandler()); - handler(wrapper -> { - // 0 means a resource location will be written - final int soundId = wrapper.get(Type.VAR_INT, 0); - wrapper.set(Type.VAR_INT, 0, soundId + 1); - }); + // Rewrite sounds as holders + final PacketHandler soundHandler = wrapper -> { + int soundId = wrapper.read(Type.VAR_INT); + soundId = MAPPINGS.getSoundMappings().getNewId(soundId); + if (soundId == -1) { + wrapper.cancel(); + return; } - }); - registerClientbound(ClientboundPackets1_19_1.SOUND, new PacketHandlers() { - @Override - public void register() { - map(Type.VAR_INT); // Sound id - handler(soundRewriter.getSoundHandler()); - handler(wrapper -> { - // 0 means a resource location will be written - final int soundId = wrapper.get(Type.VAR_INT, 0); - wrapper.set(Type.VAR_INT, 0, soundId + 1); - }); - } - }); + + wrapper.write(Type.SOUND_EVENT, new Holder<>(soundId)); + }; + registerClientbound(ClientboundPackets1_19_1.ENTITY_SOUND, soundHandler); + registerClientbound(ClientboundPackets1_19_1.SOUND, soundHandler); registerClientbound(ClientboundPackets1_19_1.NAMED_SOUND, ClientboundPackets1_19_3.SOUND, wrapper -> { - wrapper.write(Type.VAR_INT, 0); - wrapper.passthrough(Type.STRING); // Sound identifier - wrapper.write(Type.OPTIONAL_FLOAT, null); // No fixed range + final String soundIdentifier = wrapper.read(Type.STRING); + wrapper.write(Type.SOUND_EVENT, new Holder<>(new SoundEvent(soundIdentifier, null))); }); new StatisticsRewriter<>(this).register(ClientboundPackets1_19_1.STATISTICS); diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/SoundRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/SoundRewriter.java index 987fb762f..52a25326f 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/SoundRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/SoundRewriter.java @@ -17,6 +17,8 @@ */ package com.viaversion.viaversion.rewriter; +import com.viaversion.viaversion.api.minecraft.Holder; +import com.viaversion.viaversion.api.minecraft.SoundEvent; import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; @@ -53,20 +55,24 @@ public class SoundRewriter { public PacketHandler soundHolderHandler() { return wrapper -> { - final int soundId = wrapper.read(Type.VAR_INT); - if (soundId == 0) { + Holder soundEventHolder = wrapper.read(Type.SOUND_EVENT); + if (soundEventHolder.isDirect()) { // Is followed by the resource loation - wrapper.write(Type.VAR_INT, 0); + wrapper.write(Type.SOUND_EVENT, soundEventHolder); return; } - final int mappedId = idRewriter.rewrite(soundId - 1); // Normalize sound id + final int mappedId = idRewriter.rewrite(soundEventHolder.id()); if (mappedId == -1) { wrapper.cancel(); return; } - wrapper.write(Type.VAR_INT, mappedId + 1); + if (mappedId != soundEventHolder.id()) { + soundEventHolder = new Holder<>(mappedId); + } + + wrapper.write(Type.SOUND_EVENT, soundEventHolder); }; }