From e537dbb024eec7284aabaddb97e8fb4a76f09779 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 30 Aug 2024 19:10:43 +0200 Subject: [PATCH 01/25] Clean up StructuredItemRewriter, also handle sound events --- .../viaversion/api/data/MappingData.java | 4 + .../viaversion/api/data/MappingDataBase.java | 12 +- .../viaversion/api/minecraft/Holder.java | 10 ++ .../viaversion/api/minecraft/HolderImpl.java | 17 +++ .../api/minecraft/HolderSetImpl.java | 2 +- .../item/data/AttributeModifiers1_21.java | 10 ++ .../api/minecraft/item/data/Instrument.java | 5 + .../minecraft/item/data/JukeboxPlayable.java | 20 +++ .../minecraft/item/data/MapDecorations.java | 56 --------- .../rewriter/StructuredItemRewriter.java | 115 +++++++++--------- 10 files changed, 134 insertions(+), 117 deletions(-) delete mode 100644 api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/MapDecorations.java diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java index b31d51fa5..b46fa9524 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java @@ -83,6 +83,10 @@ public interface MappingData { int getNewAttributeId(int id); + int getNewSoundId(int id); + + int getOldSoundId(int i); + /** * Returns a list of tags to send if present. * diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java index e0fed837d..06283302e 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java @@ -203,6 +203,16 @@ public class MappingDataBase implements MappingData { return checkValidity(id, attributeMappings.getNewId(id), "attributes"); } + @Override + public int getNewSoundId(final int id) { + return checkValidity(id, soundMappings.getNewId(id), "sound"); + } + + @Override + public int getOldSoundId(final int i) { + return soundMappings.getNewIdOrDefault(i, 0); + } + @Override public @Nullable List getTags(final RegistryType type) { return tags != null ? tags.get(type) : null; @@ -315,4 +325,4 @@ public class MappingDataBase implements MappingData { protected void loadExtras(final CompoundTag data) { } -} \ No newline at end of file +} 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 index 59bc32109..d597ba9ca 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/Holder.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/Holder.java @@ -22,6 +22,8 @@ */ package com.viaversion.viaversion.api.minecraft; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; + public interface Holder { /** @@ -79,4 +81,12 @@ public interface Holder { * @see #hasId() */ int id(); + + /** + * Returns a new holder with the id rewritten using the given function, or self if this is a direct holder or the id did not change. + * + * @param rewriteFunction the function to rewrite the id + * @return a new holder with the id rewritten, or self + */ + Holder updateId(final Int2IntFunction rewriteFunction); } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderImpl.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderImpl.java index 7020d968a..bcbaaf390 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderImpl.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderImpl.java @@ -23,6 +23,7 @@ package com.viaversion.viaversion.api.minecraft; import com.google.common.base.Preconditions; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; final class HolderImpl implements Holder { @@ -61,6 +62,22 @@ final class HolderImpl implements Holder { return id; } + @Override + public Holder updateId(final Int2IntFunction rewriteFunction) { + if (isDirect()) { + return this; + } + + final int rewrittenId = rewriteFunction.applyAsInt(id); + if (rewrittenId == id) { + return this; + } + if (rewrittenId == -1) { + throw new IllegalArgumentException("Received invalid id in updateId"); + } + return Holder.of(rewrittenId); + } + @Override public String toString() { return "HolderImpl{" + diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSetImpl.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSetImpl.java index 7d024799c..5557da917 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSetImpl.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/HolderSetImpl.java @@ -64,7 +64,7 @@ final class HolderSetImpl extends EitherImpl implements HolderSet final int[] ids = ids(); final int[] mappedIds = new int[ids.length]; for (int i = 0; i < mappedIds.length; i++) { - mappedIds[i] = idRewriter.apply(ids[i]); + mappedIds[i] = idRewriter.applyAsInt(ids[i]); } return new HolderSetImpl(mappedIds); } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/AttributeModifiers1_21.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/AttributeModifiers1_21.java index 8c095452c..ffcb7ce0a 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/AttributeModifiers1_21.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/AttributeModifiers1_21.java @@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.ArrayType; import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean showInTooltip) { @@ -44,6 +45,15 @@ public record AttributeModifiers1_21(AttributeModifier[] modifiers, boolean show } }; + public AttributeModifiers1_21 rewrite(final Int2IntFunction rewriteFunction) { + final AttributeModifier[] modifiers = new AttributeModifier[this.modifiers.length]; + for (int i = 0; i < this.modifiers.length; i++) { + final AttributeModifier modifier = this.modifiers[i]; + modifiers[i] = new AttributeModifier(rewriteFunction.applyAsInt(modifier.attribute()), modifier.modifier(), modifier.slotType()); + } + return new AttributeModifiers1_21(modifiers, showInTooltip); + } + public record AttributeModifier(int attribute, ModifierData modifier, int slotType) { public static final Type TYPE = new Type<>(AttributeModifier.class) { 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 index 21384c5a2..bb81c61cf 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/Instrument.java @@ -27,6 +27,7 @@ import com.viaversion.viaversion.api.minecraft.SoundEvent; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.misc.HolderType; import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; public record Instrument(Holder soundEvent, int useDuration, float range) { @@ -47,4 +48,8 @@ public record Instrument(Holder soundEvent, int useDuration, float r } }; + public Instrument rewrite(final Int2IntFunction soundIdRewriteFunction) { + final Holder soundEvent = this.soundEvent.updateId(soundIdRewriteFunction); + return soundEvent == this.soundEvent ? this : new Instrument(soundEvent, useDuration, range); + } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/JukeboxPlayable.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/JukeboxPlayable.java index e3a848a95..d485aca8b 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/JukeboxPlayable.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/JukeboxPlayable.java @@ -30,6 +30,7 @@ import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.misc.HolderType; import com.viaversion.viaversion.util.Either; import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2IntFunction; public record JukeboxPlayable(Either, String> song, boolean showInTooltip) { @@ -56,6 +57,20 @@ public record JukeboxPlayable(Either, String> song, boolean } }; + public JukeboxPlayable rewrite(final Int2IntFunction soundIdRewriteFunction) { + if (song.isRight()) { + return this; + } + + final Holder songHolder = this.song.left(); + if (songHolder.hasId()) { + return this; + } + + final JukeboxSong rewrittenSong = songHolder.value().rewrite(soundIdRewriteFunction); + return rewrittenSong == songHolder.value() ? this : new JukeboxPlayable(Holder.of(rewrittenSong), showInTooltip); + } + public record JukeboxSong(Holder soundEvent, Tag description, float lengthInSeconds, int comparatorOutput) { @@ -77,5 +92,10 @@ public record JukeboxPlayable(Either, String> song, boolean Types.VAR_INT.writePrimitive(buffer, value.comparatorOutput); } }; + + public JukeboxSong rewrite(final Int2IntFunction soundIdRewriteFunction) { + final Holder soundEvent = this.soundEvent.updateId(soundIdRewriteFunction); + return soundEvent == this.soundEvent ? this : new JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput); + } } } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/MapDecorations.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/MapDecorations.java deleted file mode 100644 index 047f4e106..000000000 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/MapDecorations.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.type.Type; -import com.viaversion.viaversion.api.type.Types; -import io.netty.buffer.ByteBuf; -import it.unimi.dsi.fastutil.objects.Object2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import java.util.Map; - -public record MapDecorations(Map decorations) { - - public static final Type TYPE = new Type<>(MapDecorations.class) { - @Override - public MapDecorations read(final ByteBuf buffer) { - final Object2ObjectMap decorations = new Object2ObjectOpenHashMap<>(); - final int size = Types.VAR_INT.readPrimitive(buffer); - for (int i = 0; i < size; i++) { - final String id = Types.STRING.read(buffer); - final MapDecoration decoration = MapDecoration.TYPE.read(buffer); - decorations.put(id, decoration); - } - return new MapDecorations(decorations); - } - - @Override - public void write(final ByteBuf buffer, final MapDecorations value) { - Types.VAR_INT.writePrimitive(buffer, value.decorations.size()); - for (final Map.Entry entry : value.decorations.entrySet()) { - Types.STRING.write(buffer, entry.getKey()); - MapDecoration.TYPE.write(buffer, entry.getValue()); - } - } - }; -} diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java index 65952fcd1..21eed2fd9 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java @@ -22,6 +22,7 @@ import com.viaversion.nbt.tag.Tag; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.data.FullMappings; import com.viaversion.viaversion.api.data.MappingData; +import com.viaversion.viaversion.api.minecraft.Holder; import com.viaversion.viaversion.api.minecraft.Particle; import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; @@ -30,7 +31,6 @@ import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; -import com.viaversion.viaversion.api.rewriter.ComponentRewriter; import com.viaversion.viaversion.api.type.Type; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.Map; @@ -63,40 +63,12 @@ public class StructuredItemRewriter loreData = dataContainer.getNonEmpty(StructuredDataKey.LORE); - if (loreData != null) { - for (final Tag tag : loreData.value()) { - componentRewriter.processTag(connection, tag); - } - } - } - - Int2IntFunction itemIdRewriter = null; - Int2IntFunction blockIdRewriter = null; - if (mappingData != null) { - itemIdRewriter = mappingData.getItemMappings() != null ? mappingData::getNewItemId : null; - blockIdRewriter = mappingData.getBlockMappings() != null ? mappingData::getNewBlockId : null; - } - updateItemComponents(connection, dataContainer, this::handleItemToClient, itemIdRewriter, blockIdRewriter); + updateItemDataComponentTypeIds(item.dataContainer(), true); + updateItemDataComponents(connection, item, true); return item; } @@ -107,44 +79,69 @@ public class StructuredItemRewriter dataComponentMappings.inverse().getNewId(id)); - } + if (mappingData != null && mappingData.getItemMappings() != null) { + item.setIdentifier(mappingData.getOldItemId(item.identifier())); } + updateItemDataComponentTypeIds(item.dataContainer(), false); + updateItemDataComponents(connection, item, false); restoreTextComponents(item); - - Int2IntFunction itemIdRewriter = null; - Int2IntFunction blockIdRewriter = null; - if (mappingData != null) { - itemIdRewriter = mappingData.getItemMappings() != null ? mappingData::getOldItemId : null; - blockIdRewriter = mappingData.getBlockMappings() != null ? mappingData::getOldBlockId : null; - } - updateItemComponents(connection, dataContainer, this::handleItemToServer, itemIdRewriter, blockIdRewriter); return item; } - protected void updateItemComponents(UserConnection connection, StructuredDataContainer container, ItemHandler itemHandler, @Nullable Int2IntFunction idRewriter, @Nullable Int2IntFunction blockIdRewriter) { - // Specific types that need deep handling - if (idRewriter != null) { - container.updateIfPresent(StructuredDataKey.TRIM, value -> value.rewrite(idRewriter)); - container.updateIfPresent(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(idRewriter)); + protected void updateItemDataComponentTypeIds(final StructuredDataContainer container, final boolean mappedNames) { + final MappingData mappingData = protocol.getMappingData(); + if (mappingData == null) { + return; } - if (blockIdRewriter != null) { + + FullMappings dataComponentMappings = mappingData.getDataComponentSerializerMappings(); + if (dataComponentMappings == null) { + return; + } + + if (!mappedNames) { + dataComponentMappings = dataComponentMappings.inverse(); + } + + container.setIdLookup(protocol, mappedNames); // Necessary to be set before trying to add values to the container + container.updateIds(protocol, dataComponentMappings::getNewId); + } + + protected void updateItemDataComponents(final UserConnection connection, final Item item, final boolean clientbound) { + // Specific types that need deep handling + final StructuredDataContainer container = item.dataContainer(); + final MappingData mappingData = protocol.getMappingData(); + if (mappingData.getItemMappings() != null) { + final Int2IntFunction itemIdRewriter = clientbound ? mappingData::getNewItemId : mappingData::getOldItemId; + container.updateIfPresent(StructuredDataKey.TRIM, value -> value.rewrite(itemIdRewriter)); + container.updateIfPresent(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter)); + } + if (mappingData.getBlockMappings() != null) { + final Int2IntFunction blockIdRewriter = clientbound ? mappingData::getNewBlockId : mappingData::getOldBlockId; container.updateIfPresent(StructuredDataKey.TOOL, value -> value.rewrite(blockIdRewriter)); container.updateIfPresent(StructuredDataKey.CAN_PLACE_ON, value -> value.rewrite(blockIdRewriter)); container.updateIfPresent(StructuredDataKey.CAN_BREAK, value -> value.rewrite(blockIdRewriter)); } + if (mappingData.getSoundMappings() != null) { + final Int2IntFunction soundIdRewriter = clientbound ? mappingData::getNewSoundId : mappingData::getOldSoundId; + container.updateIfPresent(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value); + container.updateIfPresent(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter)); + } + if (clientbound && protocol.getComponentRewriter() != null) { + updateComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name"); + updateComponent(connection, item, StructuredDataKey.CUSTOM_NAME, "custom_name"); + + final StructuredData loreData = container.getNonEmpty(StructuredDataKey.LORE); + if (loreData != null) { + for (final Tag tag : loreData.value()) { + protocol.getComponentRewriter().processTag(connection, tag); + } + } + } // Look for item types + final ItemHandler itemHandler = clientbound ? this::handleItemToClient : this::handleItemToServer; for (final Map.Entry, StructuredData> entry : container.data().entrySet()) { final StructuredData data = entry.getValue(); if (data.isEmpty()) { @@ -228,7 +225,7 @@ public class StructuredItemRewriter Date: Mon, 2 Sep 2024 23:21:29 +0200 Subject: [PATCH 02/25] Small cleanup to mapping file loading --- .../api/data/MappingDataLoader.java | 55 +++++++++---------- .../data/PotionColorMappings1_11.java | 2 +- .../data/AchievementTranslations1_12.java | 4 +- .../blockconnections/ConnectionData.java | 6 +- .../data/EntityIdMappings1_13.java | 4 +- .../rewriter/WorldPacketRewriter1_13.java | 2 +- .../v1_12_2to1_13/storage/BlockStorage.java | 2 +- .../rewriter/EntityPacketRewriter1_20.java | 4 +- .../v1_8to1_9/data/EffectIdMappings1_9.java | 2 +- .../v1_8to1_9/data/PotionIdMappings1_9.java | 2 +- 10 files changed, 39 insertions(+), 44 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java index e5b1ad257..27a12934f 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java @@ -30,7 +30,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import com.viaversion.nbt.io.NBTIO; import com.viaversion.nbt.io.TagReader; -import com.viaversion.nbt.tag.ByteTag; import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.nbt.tag.IntArrayTag; import com.viaversion.nbt.tag.IntTag; @@ -211,68 +210,64 @@ public class MappingDataLoader { return null; } - final ByteTag serializationStragetyTag = tag.getUnchecked("id"); - final IntTag mappedSizeTag = tag.getUnchecked("mappedSize"); - final byte strategy = serializationStragetyTag.asByte(); + final int mappedSize = tag.getIntTag("mappedSize").asInt(); + final byte strategy = tag.getByteTag("id").asByte(); final V mappings; if (strategy == DIRECT_ID) { final IntArrayTag valuesTag = tag.getIntArrayTag("val"); - return IntArrayMappings.of(valuesTag.getValue(), mappedSizeTag.asInt()); + return IntArrayMappings.of(valuesTag.getValue(), mappedSize); } else if (strategy == SHIFTS_ID) { - final IntArrayTag shiftsAtTag = tag.getIntArrayTag("at"); - final IntArrayTag shiftsTag = tag.getIntArrayTag("to"); - final IntTag sizeTag = tag.getUnchecked("size"); - final int[] shiftsAt = shiftsAtTag.getValue(); - final int[] shiftsTo = shiftsTag.getValue(); - final int size = sizeTag.asInt(); + final int[] shiftsAt = tag.getIntArrayTag("at").getValue(); + final int[] shiftsTo = tag.getIntArrayTag("to").getValue(); + final int size = tag.getIntTag("size").asInt(); mappings = holderSupplier.get(size); - // Handle values until first shift if (shiftsAt[0] != 0) { + // Add identity values before the first shift final int to = shiftsAt[0]; for (int id = 0; id < to; id++) { addConsumer.addTo(mappings, id, id); } } - // Handle shifts + // Read shifts for (int i = 0; i < shiftsAt.length; i++) { + final boolean isLast = i == shiftsAt.length - 1; final int from = shiftsAt[i]; - final int to = i == shiftsAt.length - 1 ? size : shiftsAt[i + 1]; + final int to = isLast ? size : shiftsAt[i + 1]; int mappedId = shiftsTo[i]; for (int id = from; id < to; id++) { addConsumer.addTo(mappings, id, mappedId++); } } } else if (strategy == CHANGES_ID) { - final IntArrayTag changesAtTag = tag.getIntArrayTag("at"); - final IntArrayTag valuesTag = tag.getIntArrayTag("val"); - final IntTag sizeTag = tag.getUnchecked("size"); + final int[] changesAt = tag.getIntArrayTag("at").getValue(); + final int[] values = tag.getIntArrayTag("val").getValue(); + final int size = tag.getIntTag("size").asInt(); final boolean fillBetween = tag.get("nofill") == null; - final int[] changesAt = changesAtTag.getValue(); - final int[] values = valuesTag.getValue(); - mappings = holderSupplier.get(sizeTag.asInt()); + mappings = holderSupplier.get(size); + int previousChangedId = 0; for (int i = 0; i < changesAt.length; i++) { - final int id = changesAt[i]; + final int changedId = changesAt[i]; if (fillBetween) { // Fill from after the last change to before this change with unchanged ids - final int previousId = i != 0 ? changesAt[i - 1] + 1 : 0; - for (int identity = previousId; identity < id; identity++) { - addConsumer.addTo(mappings, identity, identity); + for (int id = previousChangedId + 1; id < changedId; id++) { + addConsumer.addTo(mappings, id, id); } + previousChangedId = changedId; } // Assign the changed value - addConsumer.addTo(mappings, id, values[i]); + addConsumer.addTo(mappings, changedId, values[i]); } } else if (strategy == IDENTITY_ID) { - final IntTag sizeTag = tag.getUnchecked("size"); - return new IdentityMappings(sizeTag.asInt(), mappedSizeTag.asInt()); + final IntTag sizeTag = tag.getIntTag("size"); + return new IdentityMappings(sizeTag.asInt(), mappedSize); } else { throw new IllegalArgumentException("Unknown serialization strategy: " + strategy); } - return mappingsSupplier.create(mappings, mappedSizeTag.asInt()); + return mappingsSupplier.create(mappings, mappedSize); } public @Nullable List identifiersFromGlobalIds(final CompoundTag mappingsTag, final String key) { @@ -295,7 +290,7 @@ public class MappingDataLoader { * @return map with indexes hashed by their id value */ public Object2IntMap indexedObjectToMap(final JsonObject object) { - final Object2IntMap map = new Object2IntOpenHashMap<>(object.size(), .99F); + final Object2IntMap map = new Object2IntOpenHashMap<>(object.size()); map.defaultReturnValue(-1); for (final Map.Entry entry : object.entrySet()) { map.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey())); @@ -310,7 +305,7 @@ public class MappingDataLoader { * @return map with indexes hashed by their id value */ public Object2IntMap arrayToMap(final JsonArray array) { - final Object2IntMap map = new Object2IntOpenHashMap<>(array.size(), .99F); + final Object2IntMap map = new Object2IntOpenHashMap<>(array.size()); map.defaultReturnValue(-1); for (int i = 0; i < array.size(); i++) { map.put(array.get(i).getAsString(), i); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/data/PotionColorMappings1_11.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/data/PotionColorMappings1_11.java index f97951c5a..184974eb3 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/data/PotionColorMappings1_11.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/data/PotionColorMappings1_11.java @@ -24,7 +24,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; public class PotionColorMappings1_11 { // to mapping - private static final Int2ObjectMap> POTIONS = new Int2ObjectOpenHashMap<>(37, 0.99F); + private static final Int2ObjectMap> POTIONS = new Int2ObjectOpenHashMap<>(37); static { addRewrite(0, 3694022, false); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/data/AchievementTranslations1_12.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/data/AchievementTranslations1_12.java index 89439843c..12c4932f4 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/data/AchievementTranslations1_12.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/data/AchievementTranslations1_12.java @@ -23,7 +23,7 @@ import java.util.Set; public class AchievementTranslations1_12 { - private static final Object2ObjectOpenHashMap ACHIEVEMENTS = new Object2ObjectOpenHashMap<>(150, 0.99f); + private static final Object2ObjectOpenHashMap ACHIEVEMENTS = new Object2ObjectOpenHashMap<>(150); private static final Set SPECIAL_ACHIEVEMENTS = new HashSet<>(10); static { @@ -196,4 +196,4 @@ public class AchievementTranslations1_12 { return SPECIAL_ACHIEVEMENTS.contains(key); } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/blockconnections/ConnectionData.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/blockconnections/ConnectionData.java index 17bfe2da0..f8152b5e1 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/blockconnections/ConnectionData.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/blockconnections/ConnectionData.java @@ -54,8 +54,8 @@ import java.util.Map.Entry; public final class ConnectionData { public static BlockConnectionProvider blockConnectionProvider; - static final Object2IntMap KEY_TO_ID = new Object2IntOpenHashMap<>(8582, .99F); - static final IntSet OCCLUDING_STATES = new IntOpenHashSet(377, .99F); + static final Object2IntMap KEY_TO_ID = new Object2IntOpenHashMap<>(8582); + static final IntSet OCCLUDING_STATES = new IntOpenHashSet(377); static Int2ObjectMap connectionHandlerMap = new Int2ObjectOpenHashMap<>(); static Int2ObjectMap blockConnectionData = new Int2ObjectOpenHashMap<>(); private static final BlockChangeRecord1_8[] EMPTY_RECORDS = new BlockChangeRecord1_8[0]; @@ -173,7 +173,7 @@ public final class ConnectionData { KEY_TO_ID.put(key, id); } - connectionHandlerMap = new Int2ObjectOpenHashMap<>(3650, .99F); + connectionHandlerMap = new Int2ObjectOpenHashMap<>(3650); if (!Via.getConfig().isReduceBlockStorageMemory()) { blockConnectionData = new Int2ObjectOpenHashMap<>(2048); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/data/EntityIdMappings1_13.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/data/EntityIdMappings1_13.java index e3972c6a2..8cc9ec6b6 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/data/EntityIdMappings1_13.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/data/EntityIdMappings1_13.java @@ -21,7 +21,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class EntityIdMappings1_13 { - private static final Int2IntMap ENTITY_TYPES = new Int2IntOpenHashMap(83, .99F); + private static final Int2IntMap ENTITY_TYPES = new Int2IntOpenHashMap(83); static { ENTITY_TYPES.defaultReturnValue(-1); @@ -121,4 +121,4 @@ public class EntityIdMappings1_13 { public static Int2IntMap getEntityTypes() { return ENTITY_TYPES; } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/WorldPacketRewriter1_13.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/WorldPacketRewriter1_13.java index a4a710de1..a0f95d8d3 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/WorldPacketRewriter1_13.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/WorldPacketRewriter1_13.java @@ -53,7 +53,7 @@ import java.util.Iterator; import java.util.Optional; public class WorldPacketRewriter1_13 { - private static final IntSet VALID_BIOMES = new IntOpenHashSet(70, .99F); + private static final IntSet VALID_BIOMES = new IntOpenHashSet(70); static { // Client will crash if it receives an invalid biome id diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/storage/BlockStorage.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/storage/BlockStorage.java index c908a2976..87c2cfa07 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/storage/BlockStorage.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/storage/BlockStorage.java @@ -26,7 +26,7 @@ import java.util.Map; // TODO Fix memory leak lolz (only a smol one tho) public class BlockStorage implements StorableObject { - private static final IntSet WHITELIST = new IntOpenHashSet(46, .99F); + private static final IntSet WHITELIST = new IntOpenHashSet(46); private final Map blocks = new HashMap<>(); static { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_4to1_20/rewriter/EntityPacketRewriter1_20.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_4to1_20/rewriter/EntityPacketRewriter1_20.java index 65e4a623c..de9d57fa4 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_4to1_20/rewriter/EntityPacketRewriter1_20.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_19_4to1_20/rewriter/EntityPacketRewriter1_20.java @@ -79,8 +79,8 @@ public final class EntityPacketRewriter1_20 extends EntityRewriter damageTypes = TagUtil.getRegistryEntries(registry, "damage_type"); int highestId = -1; for (final CompoundTag damageType : damageTypes) { - final IntTag id = damageType.getUnchecked("id"); - highestId = Math.max(highestId, id.asInt()); + final int id = damageType.getInt("id"); + highestId = Math.max(highestId, id); } // AaaaAAAaa diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/EffectIdMappings1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/EffectIdMappings1_9.java index 9dc6d90fb..f2c3522fa 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/EffectIdMappings1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/EffectIdMappings1_9.java @@ -22,7 +22,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class EffectIdMappings1_9 { - private static final Int2IntMap EFFECTS = new Int2IntOpenHashMap(19, .99F); + private static final Int2IntMap EFFECTS = new Int2IntOpenHashMap(19); static { addRewrite(1005, 1010); //Play music disc diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIdMappings1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIdMappings1_9.java index 6a8dc9d60..2229aad67 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIdMappings1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/data/PotionIdMappings1_9.java @@ -27,7 +27,7 @@ public class PotionIdMappings1_9 { public static final Map POTION_NAME_TO_ID = new HashMap<>(); public static final Map POTION_ID_TO_NAME = new HashMap<>(); - public static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, .99F); + public static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36); static { register(-1, "empty"); From 369b076cad8299ed6d0b54c8cbe7600883139051 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Tue, 3 Sep 2024 16:43:55 +0200 Subject: [PATCH 03/25] Null check channel in player join listener Fixes #3390 --- .../viaversion/viaversion/bukkit/listeners/JoinListener.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bukkit/src/main/java/com/viaversion/viaversion/bukkit/listeners/JoinListener.java b/bukkit/src/main/java/com/viaversion/viaversion/bukkit/listeners/JoinListener.java index 959bd118a..4796a3ac2 100644 --- a/bukkit/src/main/java/com/viaversion/viaversion/bukkit/listeners/JoinListener.java +++ b/bukkit/src/main/java/com/viaversion/viaversion/bukkit/listeners/JoinListener.java @@ -112,7 +112,10 @@ public class JoinListener implements Listener { return; } // The connection has already closed, that was a quick leave - if (!channel.isOpen()) return; + // Channel may be null if a plugin is manually calling the event for a non-player... + if (channel == null || !channel.isOpen()) { + return; + } UserConnection user = getUserConnection(channel); if (user == null) { From d0b49009e5b45e39d210d4fda97e732dba3f3097 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Wed, 4 Sep 2024 20:27:38 +0200 Subject: [PATCH 04/25] Rewrite display name component in player info packet in 1.20.3->.5 (#4136) --- .../Protocol1_20_3To1_20_5.java | 1 + .../rewriter/ComponentRewriter.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) 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 75e4c4ccd..89e92006c 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 @@ -103,6 +103,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol { diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/ComponentRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/ComponentRewriter.java index 9428917a4..5aa31652b 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/ComponentRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/ComponentRewriter.java @@ -40,6 +40,7 @@ import com.viaversion.viaversion.util.ComponentUtil; import com.viaversion.viaversion.util.SerializerVersion; import com.viaversion.viaversion.util.TagUtil; import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.BitSet; /** * Handles json and tag components, containing methods to override certain parts of the handling. @@ -139,6 +140,43 @@ public class ComponentRewriter implements com.v }); } + public void registerPlayerInfoUpdate1_20_3(final C packetType) { + protocol.registerClientbound(packetType, wrapper -> { + final BitSet actions = wrapper.passthrough(Types.PROFILE_ACTIONS_ENUM); + if (!actions.get(5)) { // Update display name + return; + } + final int entries = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < entries; i++) { + wrapper.passthrough(Types.UUID); + if (actions.get(0)) { + wrapper.passthrough(Types.STRING); // Player Name + + final int properties = wrapper.passthrough(Types.VAR_INT); + for (int j = 0; j < properties; j++) { + wrapper.passthrough(Types.STRING); // Name + wrapper.passthrough(Types.STRING); // Value + wrapper.passthrough(Types.OPTIONAL_STRING); // Signature + } + } + if (actions.get(1) && wrapper.passthrough(Types.BOOLEAN)) { + wrapper.passthrough(Types.UUID); // Session UUID + wrapper.passthrough(Types.PROFILE_KEY); + } + if (actions.get(2)) { + wrapper.passthrough(Types.VAR_INT); // Gamemode + } + if (actions.get(3)) { + wrapper.passthrough(Types.BOOLEAN); // Listed + } + if (actions.get(4)) { + wrapper.passthrough(Types.VAR_INT); // Latency + } + processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); + } + }); + } + public void registerPlayerCombatKill(final C packetType) { protocol.registerClientbound(packetType, new PacketHandlers() { @Override From 95581a6fa5919f29f2a86fdf02fd4610444c09d0 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Thu, 5 Sep 2024 10:02:55 +0200 Subject: [PATCH 05/25] Fix mapping reading of changed_id type --- .../viaversion/viaversion/api/data/MappingDataLoader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java index 27a12934f..58ff10001 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java @@ -247,15 +247,15 @@ public class MappingDataLoader { final boolean fillBetween = tag.get("nofill") == null; mappings = holderSupplier.get(size); - int previousChangedId = 0; + int nextUnhandledId = 0; for (int i = 0; i < changesAt.length; i++) { final int changedId = changesAt[i]; if (fillBetween) { // Fill from after the last change to before this change with unchanged ids - for (int id = previousChangedId + 1; id < changedId; id++) { + for (int id = nextUnhandledId; id < changedId; id++) { addConsumer.addTo(mappings, id, id); } - previousChangedId = changedId; + nextUnhandledId = changedId + 1; } // Assign the changed value From ebc0e61be8538183f6bf50eb78cb9c1e36ca5554 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sat, 7 Sep 2024 10:45:10 +0200 Subject: [PATCH 06/25] Fix invalid book view not visible in 1.20.3->.5 (#4139) --- .../BlockItemPacketRewriter1_20_5.java | 70 ++++++++++++------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java index fde9af2f4..476d4e0e2 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java @@ -1163,47 +1163,63 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter pagesTag = tag.getListTag("pages", StringTag.class); - final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages"); - if (pagesTag == null) { - return; + + boolean valid = author != null && title != null && title.length() <= 32 && pagesTag != null; + if (valid) { + for (final StringTag page : pagesTag) { + if (page.getValue().length() > Short.MAX_VALUE) { + valid = false; + break; + } + } } final List pages = new ArrayList<>(); - for (int i = 0; i < pagesTag.size(); i++) { - final StringTag page = pagesTag.get(i); - Tag filtered = null; - if (filteredPagesTag != null) { - final StringTag filteredPage = filteredPagesTag.getStringTag(String.valueOf(i)); - if (filteredPage != null) { - try { - filtered = jsonToTag(connection, filteredPage); - } catch (final Exception e) { - // A 1.20.4 client would display the broken json raw, but a 1.20.5 client would die - continue; + if (valid) { + final CompoundTag filteredPagesTag = tag.getCompoundTag("filtered_pages"); + + for (int i = 0; i < pagesTag.size(); i++) { + final StringTag page = pagesTag.get(i); + Tag filtered = null; + if (filteredPagesTag != null) { + final StringTag filteredPage = filteredPagesTag.getStringTag(String.valueOf(i)); + if (filteredPage != null) { + try { + filtered = jsonToTag(connection, filteredPage); + } catch (final Exception e) { + // A 1.20.4 client would display the broken json raw, but a 1.20.5 client would die + continue; + } } } - } - final Tag parsedPage; - try { - parsedPage = jsonToTag(connection, page); - } catch (final Exception e) { - // Same as above - continue; - } + final Tag parsedPage; + try { + parsedPage = jsonToTag(connection, page); + } catch (final Exception e) { + // Same as above + continue; + } - pages.add(new FilterableComponent(parsedPage, filtered)); + pages.add(new FilterableComponent(parsedPage, filtered)); + } + } else { + final CompoundTag invalidPage = new CompoundTag(); + invalidPage.putString("text", "* Invalid book tag *"); + invalidPage.putString("color", "#AA0000"); // dark red + + pages.add(new FilterableComponent(invalidPage, null)); } - final String title = tag.getString("title", ""); final String filteredTitle = tag.getString("filtered_title"); // Nullable - final String author = tag.getString("author", ""); final int generation = tag.getInt("generation"); final boolean resolved = tag.getBoolean("resolved"); final WrittenBook writtenBook = new WrittenBook( - new FilterableString(limit(title, 32), limit(filteredTitle, 32)), - author, + new FilterableString(limit(title == null ? "" : title, 32), limit(filteredTitle, 32)), + author == null ? "" : author, clamp(generation, 0, 3), pages.toArray(new FilterableComponent[0]), resolved From e0ce8cc7152eb32f925203c30c1ff93ab5d3b7d8 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Thu, 12 Sep 2024 22:09:52 +0200 Subject: [PATCH 07/25] Make EntityTrackerBase#clearEntities call removeEntity for all entries (#4142) --- .../viaversion/viaversion/data/entity/EntityTrackerBase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 666e4d5d5..06a74bfd2 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -95,7 +95,10 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis @Override public void clearEntities() { - entities.clear(); + // Call wrapper function in case protocols need to do additional removals + for (final int id : entities.keySet().toIntArray()) { + removeEntity(id); + } } @Override From fcb472347ef7f871aefd43750ced1d0283cbd375 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sat, 14 Sep 2024 10:45:19 +0200 Subject: [PATCH 08/25] Add EntityTrackerBase#hasClientEntityId and don't use -1 as not set indicator (#4143) --- .../api/data/entity/EntityTracker.java | 14 +++++++++++--- .../data/entity/EntityTrackerBase.java | 18 +++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java index 11f194e49..8ba1feb81 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java @@ -102,11 +102,19 @@ public interface EntityTracker { @Nullable StoredEntityData entityDataIfPresent(int id); /** - * Returns the client entity id or -1 if unset. + * Returns whether the client entity id has been set. * - * @return client entity id or -1 if unset + * @return whether the client entity id has been set */ - int clientEntityId(); + boolean hasClientEntityId(); + + /** + * Returns the client entity id. Should be wrapped around {@link #hasClientEntityId()}. + * + * @return client entity id + * @throws IllegalStateException if the client entity id has not been set + */ + int clientEntityId() throws IllegalStateException; /** * Sets the client entity id. diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 06a74bfd2..110ca5ec8 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -37,7 +37,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis protected final Int2ObjectMap entities = new Int2ObjectOpenHashMap<>(); private final UserConnection connection; private final EntityType playerType; - private int clientEntityId = -1; + private Integer clientEntityId; private int currentWorldSectionHeight = -1; private int currentMinY; private String currentWorld; @@ -102,7 +102,15 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis } @Override - public int clientEntityId() { + public boolean hasClientEntityId() { + return clientEntityId != null; + } + + @Override + public int clientEntityId() throws IllegalStateException { + if (clientEntityId == null) { + throw new IllegalStateException("Client entity id not set"); + } return clientEntityId; } @@ -110,7 +118,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis public void setClientEntityId(int clientEntityId) { Preconditions.checkNotNull(playerType); final TrackedEntity oldEntity; - if (this.clientEntityId != -1 && (oldEntity = entities.remove(this.clientEntityId)) != null) { + if (this.clientEntityId != null && (oldEntity = entities.remove(this.clientEntityId.intValue())) != null) { entities.put(clientEntityId, oldEntity); } else { entities.put(clientEntityId, new TrackedEntityImpl(playerType)); @@ -121,8 +129,8 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis @Override public boolean trackClientEntity() { - if (clientEntityId != -1) { - entities.put(clientEntityId, new TrackedEntityImpl(playerType)); + if (clientEntityId != null) { + entities.put(clientEntityId.intValue(), new TrackedEntityImpl(playerType)); return true; } return false; From 723548580285eab39f65776ae0b3fefdb2271400 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sat, 14 Sep 2024 21:33:18 +0200 Subject: [PATCH 09/25] Cleanup enchantment conversion in 1.12->1.13 to match vanilla (#4147) Closes https://github.com/ViaVersion/ViaFabricPlus/issues/560 --- .../rewriter/ItemPacketRewriter1_13.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/ItemPacketRewriter1_13.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/ItemPacketRewriter1_13.java index 12cff0a94..26119ee83 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/ItemPacketRewriter1_13.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/rewriter/ItemPacketRewriter1_13.java @@ -304,23 +304,15 @@ public class ItemPacketRewriter1_13 extends ItemRewriter enchantments = new ListTag<>(CompoundTag.class); for (CompoundTag enchEntry : ench) { - NumberTag idTag = enchEntry.getNumberTag("id"); - if (idTag == null) { - continue; - } + short oldId = enchEntry.getShort("id", (short) 0); CompoundTag enchantmentEntry = new CompoundTag(); - short oldId = idTag.asShort(); String newId = Protocol1_12_2To1_13.MAPPINGS.getOldEnchantmentsIds().get(oldId); if (newId == null) { newId = "viaversion:legacy/" + oldId; } enchantmentEntry.putString("id", newId); - - NumberTag levelTag = enchEntry.getNumberTag("lvl"); - if (levelTag != null) { - enchantmentEntry.putShort("lvl", levelTag.asShort()); - } + enchantmentEntry.putShort("lvl", enchEntry.getShort("lvl", (short) 0)); enchantments.add(enchantmentEntry); } @@ -589,10 +581,7 @@ public class ItemPacketRewriter1_13 extends ItemRewriter Date: Sun, 15 Sep 2024 09:51:02 +0200 Subject: [PATCH 10/25] Update Gradle Wrapper from 8.10 to 8.10.1. (#4148) Signed-off-by: gradle-update-robot Co-authored-by: gradle-update-robot --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b189974c..8e876e1c5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 050a1dbacbd2c55c3ad596b624c89b629bda594b Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sun, 15 Sep 2024 19:14:42 +0200 Subject: [PATCH 11/25] Fix set equipment body slot in 1.20.3->.5 if value is not the last (#4149) --- .../rewriter/EntityPacketRewriter1_20_5.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/EntityPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/EntityPacketRewriter1_20_5.java index 1ffc81397..5c552b269 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/EntityPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/EntityPacketRewriter1_20_5.java @@ -83,13 +83,16 @@ public final class EntityPacketRewriter1_20_5 extends EntityRewriter { From e436bbe3754702ab2025165996d21c65a5933695 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sun, 15 Sep 2024 21:51:29 +0200 Subject: [PATCH 12/25] Refactor dimension switch handling across all protocols (#4146) --- .../api/connection/UserConnection.java | 24 ++++++++++- .../api/data/entity/EntityTracker.java | 10 +---- .../viaversion/api/minecraft/ClientWorld.java | 16 ++++++-- .../connection/UserConnectionImpl.java | 18 +++++++-- .../data/entity/EntityTrackerBase.java | 15 +++---- .../v1_10to1_11/Protocol1_10To1_11.java | 32 +-------------- .../rewriter/EntityPacketRewriter1_11.java | 29 ++++++++++++++ .../v1_11_1to1_12/Protocol1_11_1To1_12.java | 38 +----------------- .../rewriter/EntityPacketRewriter1_12.java | 38 ++++++++++++++++++ .../v1_12_2to1_13/Protocol1_12_2To1_13.java | 21 +--------- .../rewriter/EntityPacketRewriter1_13.java | 23 ++++++++++- .../rewriter/WorldPacketRewriter1_13.java | 2 +- .../v1_13_2to1_14/Protocol1_13_2To1_14.java | 6 +-- .../rewriter/EntityPacketRewriter1_14.java | 2 +- .../rewriter/WorldPacketRewriter1_14.java | 21 ++++++---- .../v1_13to1_13_1/Protocol1_13To1_13_1.java | 4 +- .../rewriter/EntityPacketRewriter1_13_1.java | 31 ++++++++++++++ .../rewriter/WorldPacketRewriter1_13_1.java | 33 +-------------- .../rewriter/EntityPacketRewriter1_15.java | 5 ++- .../rewriter/EntityPacketRewriter1_16.java | 5 ++- .../rewriter/EntityPacketRewriter1_16_2.java | 2 + .../rewriter/EntityPacketRewriter1_17.java | 2 + .../protocols/v1_8to1_9/Protocol1_8To1_9.java | 18 +++------ .../rewriter/PlayerPacketRewriter1_9.java | 40 +++++++++---------- .../rewriter/WorldPacketRewriter1_9.java | 22 +++++----- ...{ClientChunks.java => ClientWorld1_9.java} | 4 +- .../v1_9_1to1_9_3/Protocol1_9_1To1_9_3.java | 10 ++--- .../v1_9_3to1_10/Protocol1_9_3To1_10.java | 12 +++--- .../viaversion/rewriter/EntityRewriter.java | 8 ++-- 29 files changed, 259 insertions(+), 232 deletions(-) rename common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/{ClientChunks.java => ClientWorld1_9.java} (90%) diff --git a/api/src/main/java/com/viaversion/viaversion/api/connection/UserConnection.java b/api/src/main/java/com/viaversion/viaversion/api/connection/UserConnection.java index 2618ad59d..a4923e8a8 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/connection/UserConnection.java +++ b/api/src/main/java/com/viaversion/viaversion/api/connection/UserConnection.java @@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.connection; import com.viaversion.viaversion.api.configuration.ViaVersionConfig; import com.viaversion.viaversion.api.data.entity.EntityTracker; +import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.packet.PacketTracker; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; @@ -99,14 +100,33 @@ public interface UserConnection { void addEntityTracker(Class protocolClass, EntityTracker tracker); /** - * Clear stored objects and entity trackers. + * Returns the client world by the given protocol class if present. + * + * @param protocolClass protocol class + * @param client world type + * @return client world if present + */ + @Nullable + T getClientWorld(Class protocolClass); + + /** + * Adds a client world to the user connection. + * Does not override existing client worlds. + * + * @param protocolClass protocol class + * @param clientWorld client world + */ + void addClientWorld(Class protocolClass, ClientWorld clientWorld); + + /** + * Clear stored objects, entity trackers and client worlds. */ default void clearStoredObjects() { clearStoredObjects(false); } /** - * Clear stored objects and entity trackers. + * Clear stored objects, entity trackers and client worlds. * If cleared for a proxy server switch, some stored objects and tracker data will be retained. * * @param isServerSwitch whether the clear is due to a server switch diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java index 8ba1feb81..71ca92fe1 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java @@ -78,7 +78,7 @@ public interface EntityTracker { void removeEntity(int id); /** - * Clears stored entity types and data. + * Clears stored entity types and data, only leaving behind the client entity. */ void clearEntities(); @@ -177,12 +177,4 @@ public interface EntityTracker { @Nullable DimensionData dimensionData(int dimensionId); void setDimensions(Map dimensions); - - /** - * Adds the client player entity to the tracker. - * If the client entity has not been set yet, this will return false. - * - * @return whether the client has been tracked - */ - boolean trackClientEntity(); } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/ClientWorld.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/ClientWorld.java index e4e0809bb..ec8a7333b 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/ClientWorld.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/ClientWorld.java @@ -23,13 +23,12 @@ package com.viaversion.viaversion.api.minecraft; import com.viaversion.viaversion.api.connection.StorableObject; -import org.checkerframework.checker.nullness.qual.Nullable; /** * Stored up until 1.14 to be used in chunk sending. */ public class ClientWorld implements StorableObject { - private Environment environment; + private Environment environment = Environment.NORMAL; public ClientWorld() { } @@ -38,11 +37,20 @@ public class ClientWorld implements StorableObject { this.environment = environment; } - public @Nullable Environment getEnvironment() { + public Environment getEnvironment() { return environment; } - public void setEnvironment(final int environmentId) { + /** + * Sets the environment of the world and returns whether the environment was changed. + * + * @param environmentId the id of the environment to set + * @return whether the environment was changed + */ + public boolean setEnvironment(final int environmentId) { + final int previousEnvironmentId = environment.id(); this.environment = Environment.getEnvironmentById(environmentId); + + return previousEnvironmentId != environmentId; } } diff --git a/common/src/main/java/com/viaversion/viaversion/connection/UserConnectionImpl.java b/common/src/main/java/com/viaversion/viaversion/connection/UserConnectionImpl.java index 8ec84a0e7..4a7f82dc4 100644 --- a/common/src/main/java/com/viaversion/viaversion/connection/UserConnectionImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/connection/UserConnectionImpl.java @@ -23,6 +23,7 @@ import com.viaversion.viaversion.api.connection.ProtocolInfo; import com.viaversion.viaversion.api.connection.StorableObject; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.data.entity.EntityTracker; +import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.platform.ViaInjector; import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.packet.Direction; @@ -58,6 +59,7 @@ public class UserConnectionImpl implements UserConnection { private final long id = IDS.incrementAndGet(); private final Map, StorableObject> storedObjects = new ConcurrentHashMap<>(); private final Map, EntityTracker> entityTrackers = new HashMap<>(); + private final Map, ClientWorld> clientWorlds = new HashMap<>(); private final PacketTracker packetTracker = new PacketTracker(this); private final Set passthroughTokens = Collections.newSetFromMap(CacheBuilder.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) @@ -125,9 +127,17 @@ public class UserConnectionImpl implements UserConnection { @Override public void addEntityTracker(Class protocolClass, EntityTracker tracker) { - if (!entityTrackers.containsKey(protocolClass)) { - entityTrackers.put(protocolClass, tracker); - } + entityTrackers.putIfAbsent(protocolClass, tracker); + } + + @Override + public @Nullable T getClientWorld(final Class protocolClass) { + return (T) clientWorlds.get(protocolClass); + } + + @Override + public void addClientWorld(final Class protocolClass, final ClientWorld clientWorld) { + clientWorlds.putIfAbsent(protocolClass, clientWorld); } @Override @@ -142,7 +152,6 @@ public class UserConnectionImpl implements UserConnection { }); for (EntityTracker tracker : entityTrackers.values()) { tracker.clearEntities(); - tracker.trackClientEntity(); } } else { for (StorableObject object : storedObjects.values()) { @@ -150,6 +159,7 @@ public class UserConnectionImpl implements UserConnection { } storedObjects.clear(); entityTrackers.clear(); + clientWorlds.clear(); } } diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 110ca5ec8..f568bfded 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -87,7 +87,6 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis return entity != null && entity.hasData() ? entity.data() : null; } - //TODO Soft memory leak: Remove entities on respawn in protocols prior to 1.18 (1.16+ only when the worldname is different) @Override public void removeEntity(int id) { entities.remove(id); @@ -99,6 +98,11 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis for (final int id : entities.keySet().toIntArray()) { removeEntity(id); } + + // Re-add the client entity. Keep the call above to untrack attached data if necessary + if (clientEntityId != null) { + entities.put(clientEntityId.intValue(), new TrackedEntityImpl(playerType)); + } } @Override @@ -127,15 +131,6 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis this.clientEntityId = clientEntityId; } - @Override - public boolean trackClientEntity() { - if (clientEntityId != null) { - entities.put(clientEntityId.intValue(), new TrackedEntityImpl(playerType)); - return true; - } - return false; - } - @Override public int currentWorldSectionHeight() { return currentWorldSectionHeight; diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java index 2c0d5ce81..b2c2b779f 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/Protocol1_10To1_11.java @@ -99,7 +99,7 @@ public class Protocol1_10To1_11 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_10To1_11.class); Chunk chunk = wrapper.passthrough(ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment())); @@ -120,31 +120,6 @@ public class Protocol1_10To1_11 extends AbstractProtocol { - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 1); - clientChunks.setEnvironment(dimensionId); - }); - } - }); - registerClientbound(ClientboundPackets1_9_3.RESPAWN, new PacketHandlers() { - @Override - public void register() { - map(Types.INT); - handler(wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); - }); - } - }); - this.registerClientbound(ClientboundPackets1_9_3.LEVEL_EVENT, new PacketHandlers() { @Override public void register() { @@ -238,11 +213,8 @@ public class Protocol1_10To1_11 extends AbstractProtocol { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_10To1_11.class); + int dimensionId = wrapper.get(Types.INT, 1); + clientWorld.setEnvironment(dimensionId); + }); + } + }); + + protocol.registerClientbound(ClientboundPackets1_9_3.RESPAWN, new PacketHandlers() { + @Override + public void register() { + map(Types.INT); + handler(wrapper -> { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_10To1_11.class); + int dimensionId = wrapper.get(Types.INT, 0); + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + } + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_9_3.ADD_ENTITY, new PacketHandlers() { @Override public void register() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/Protocol1_11_1To1_12.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/Protocol1_11_1To1_12.java index 9b0f122ee..d7c913311 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/Protocol1_11_1To1_12.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_11_1to1_12/Protocol1_11_1To1_12.java @@ -72,7 +72,7 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_11_1To1_12.class); ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); Chunk chunk = wrapper.passthrough(type); @@ -101,38 +101,6 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol { - UserConnection user = wrapper.user(); - ClientWorld clientChunks = user.get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 1); - clientChunks.setEnvironment(dimensionId); - - // Reset recipes - if (user.getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_13)) { - wrapper.create(ClientboundPackets1_13.UPDATE_RECIPES, packetWrapper -> packetWrapper.write(Types.VAR_INT, 0)) - .scheduleSend(Protocol1_12_2To1_13.class); - } - }); - } - }); - registerClientbound(ClientboundPackets1_9_3.RESPAWN, new PacketHandlers() { - @Override - public void register() { - map(Types.INT); - handler(wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); - }); - } - }); - new SoundRewriter<>(this, this::getNewSoundId).registerSound(ClientboundPackets1_9_3.SOUND); @@ -205,9 +173,7 @@ public class Protocol1_11_1To1_12 extends AbstractProtocol { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_11_1To1_12.class); + int dimensionId = wrapper.get(Types.INT, 1); + clientWorld.setEnvironment(dimensionId); + + // Reset recipes + if (wrapper.user().getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_13)) { + wrapper.create(ClientboundPackets1_13.UPDATE_RECIPES, packetWrapper -> packetWrapper.write(Types.VAR_INT, 0)) + .scheduleSend(Protocol1_12_2To1_13.class); + } + }); + } + }); + + protocol.registerClientbound(ClientboundPackets1_9_3.RESPAWN, new PacketHandlers() { + @Override + public void register() { + map(Types.INT); + handler(wrapper -> { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_11_1To1_12.class); + int dimensionId = wrapper.get(Types.INT, 0); + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + } + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_9_3.ADD_ENTITY, new PacketHandlers() { @Override public void register() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java index 7d5c3cf42..d679f1849 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_12_2to1_13/Protocol1_12_2To1_13.java @@ -401,23 +401,6 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); - - if (Via.getConfig().isServersideBlockConnections()) { - ConnectionData.clearBlockStorage(wrapper.user()); - } - }); - handler(SEND_DECLARE_COMMANDS_AND_TAGS); - } - }); - registerClientbound(ClientboundPackets1_12_1.SET_OBJECTIVE, new PacketHandlers() { @Override public void register() { @@ -844,9 +827,9 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol { - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + ClientWorld clientChunks = wrapper.user().getClientWorld(Protocol1_12_2To1_13.class); int dimensionId = wrapper.get(Types.INT, 1); clientChunks.setEnvironment(dimensionId); }); @@ -141,6 +142,24 @@ public class EntityPacketRewriter1_13 extends EntityRewriter { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_12_2To1_13.class); + int dimensionId = wrapper.get(Types.INT, 0); + if (clientWorld.setEnvironment(dimensionId)) { + if (Via.getConfig().isServersideBlockConnections()) { + ConnectionData.clearBlockStorage(wrapper.user()); + } + tracker(wrapper.user()).clearEntities(); + } + }); + handler(Protocol1_12_2To1_13.SEND_DECLARE_COMMANDS_AND_TAGS); + } + }); + protocol.registerClientbound(ClientboundPackets1_12_1.UPDATE_MOB_EFFECT, new PacketHandlers() { @Override public void register() { @@ -235,4 +254,4 @@ public class EntityPacketRewriter1_13 extends EntityRewriter { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_12_2To1_13.class); BlockStorage storage = wrapper.user().get(BlockStorage.class); ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/Protocol1_13_2To1_14.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/Protocol1_13_2To1_14.java index 7efa794bd..f663cfaab 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/Protocol1_13_2To1_14.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/Protocol1_13_2To1_14.java @@ -121,9 +121,7 @@ public class Protocol1_13_2To1_14 extends AbstractProtocol getTagRewriter() { return tagRewriter; } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/EntityPacketRewriter1_14.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/EntityPacketRewriter1_14.java index 2a10716af..8d41df011 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/EntityPacketRewriter1_14.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/EntityPacketRewriter1_14.java @@ -204,7 +204,7 @@ public class EntityPacketRewriter1_14 extends EntityRewriter { // Store the player - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); + ClientWorld clientChunks = wrapper.user().getClientWorld(Protocol1_13_2To1_14.class); int dimensionId = wrapper.get(Types.INT, 1); clientChunks.setEnvironment(dimensionId); }); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/WorldPacketRewriter1_14.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/WorldPacketRewriter1_14.java index 6b3053701..7d8e0567c 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/WorldPacketRewriter1_14.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/rewriter/WorldPacketRewriter1_14.java @@ -125,7 +125,7 @@ public class WorldPacketRewriter1_14 { }); protocol.registerClientbound(ClientboundPackets1_13.LEVEL_CHUNK, wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13_2To1_14.class); Chunk chunk = wrapper.read(ChunkType1_13.forEnvironment(clientWorld.getEnvironment())); wrapper.write(ChunkType1_14.TYPE, chunk); @@ -282,21 +282,26 @@ public class WorldPacketRewriter1_14 { public void register() { map(Types.INT); // 0 - Dimension ID handler(wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + short difficulty = wrapper.read(Types.UNSIGNED_BYTE); // 19w11a removed difficulty from respawn + + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13_2To1_14.class); int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); + + if (!clientWorld.setEnvironment(dimensionId)) { + return; + } + EntityTracker1_14 entityTracker = wrapper.user().getEntityTracker(Protocol1_13_2To1_14.class); + entityTracker.clearEntities(); + // The client may reset the center chunk if dimension is changed entityTracker.setForceSendCenterChunk(true); - }); - handler(wrapper -> { - short difficulty = wrapper.read(Types.UNSIGNED_BYTE); // 19w11a removed difficulty from respawn + PacketWrapper difficultyPacket = wrapper.create(ClientboundPackets1_14.CHANGE_DIFFICULTY); difficultyPacket.write(Types.UNSIGNED_BYTE, difficulty); difficultyPacket.write(Types.BOOLEAN, false); // Unknown value added in 19w11a difficultyPacket.scheduleSend(protocol.getClass()); - }); - handler(wrapper -> { + // Manually send the packet and update the viewdistance after wrapper.send(Protocol1_13_2To1_14.class); wrapper.cancel(); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/Protocol1_13To1_13_1.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/Protocol1_13To1_13_1.java index d4710ef76..24cd8b7f0 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/Protocol1_13To1_13_1.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/Protocol1_13To1_13_1.java @@ -134,9 +134,7 @@ public class Protocol1_13To1_13_1 extends AbstractProtocol { + // Store the player + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_13_1.class); + int dimensionId = wrapper.get(Types.INT, 1); + clientWorld.setEnvironment(dimensionId); + }); + } + }); + + protocol.registerClientbound(ClientboundPackets1_13.RESPAWN, new PacketHandlers() { + @Override + public void register() { + map(Types.INT); // 0 - Dimension ID + handler(wrapper -> { + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_13_1.class); + int dimensionId = wrapper.get(Types.INT, 0); + if (clientWorld.setEnvironment(dimensionId)) { + tracker(wrapper.user()).clearEntities(); + } + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_13.ADD_ENTITY, new PacketHandlers() { @Override public void register() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/rewriter/WorldPacketRewriter1_13_1.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/rewriter/WorldPacketRewriter1_13_1.java index 8fa820fdc..dfe08d66b 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/rewriter/WorldPacketRewriter1_13_1.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_13to1_13_1/rewriter/WorldPacketRewriter1_13_1.java @@ -19,9 +19,6 @@ package com.viaversion.viaversion.protocols.v1_13to1_13_1.rewriter; import com.viaversion.viaversion.api.minecraft.ClientWorld; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; -import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; -import com.viaversion.viaversion.api.minecraft.chunks.DataPalette; -import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_13; @@ -35,7 +32,7 @@ public class WorldPacketRewriter1_13_1 { BlockRewriter blockRewriter = BlockRewriter.legacy(protocol); protocol.registerClientbound(ClientboundPackets1_13.LEVEL_CHUNK, wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_13To1_13_1.class); Chunk chunk = wrapper.passthrough(ChunkType1_13.forEnvironment(clientWorld.getEnvironment())); blockRewriter.handleChunk(chunk); @@ -84,33 +81,5 @@ public class WorldPacketRewriter1_13_1 { }); } }); - - protocol.registerClientbound(ClientboundPackets1_13.LOGIN, new PacketHandlers() { - @Override - public void register() { - map(Types.INT); // 0 - Entity ID - map(Types.UNSIGNED_BYTE); // 1 - Gamemode - map(Types.INT); // 2 - Dimension - - handler(wrapper -> { - // Store the player - ClientWorld clientChunks = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 1); - clientChunks.setEnvironment(dimensionId); - }); - } - }); - - protocol.registerClientbound(ClientboundPackets1_13.RESPAWN, new PacketHandlers() { - @Override - public void register() { - map(Types.INT); // 0 - Dimension ID - handler(wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); - }); - } - }); } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_4to1_15/rewriter/EntityPacketRewriter1_15.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_4to1_15/rewriter/EntityPacketRewriter1_15.java index a851eaebf..dd1ce1045 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_4to1_15/rewriter/EntityPacketRewriter1_15.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_4to1_15/rewriter/EntityPacketRewriter1_15.java @@ -86,7 +86,10 @@ public class EntityPacketRewriter1_15 extends EntityRewriter wrapper.write(Types.LONG, 0L)); // Level Seed + handler(wrapper -> { + tracker(wrapper.user()).clearEntities(); + wrapper.write(Types.LONG, 0L); // Level Seed + }); } }); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_15_2to1_16/rewriter/EntityPacketRewriter1_16.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_15_2to1_16/rewriter/EntityPacketRewriter1_16.java index f85c45f8a..c5a7786ea 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_15_2to1_16/rewriter/EntityPacketRewriter1_16.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_15_2to1_16/rewriter/EntityPacketRewriter1_16.java @@ -119,6 +119,8 @@ public class EntityPacketRewriter1_16 extends EntityRewriter { + tracker(wrapper.user()).clearEntities(); + wrapper.write(Types.BYTE, (byte) -1); // Previous gamemode, set to none // <= 1.14.4 didn't keep attributes on respawn and 1.15.x always kept them @@ -145,9 +147,8 @@ public class EntityPacketRewriter1_16 extends EntityRewriter { - wrapper.user().getEntityTracker(Protocol1_15_2To1_16.class).addEntity(wrapper.get(Types.INT, 0), EntityTypes1_16.PLAYER); - final String type = wrapper.read(Types.STRING);// level type wrapper.passthrough(Types.VAR_INT); // View distance wrapper.passthrough(Types.BOOLEAN); // Reduced debug info diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_1to1_16_2/rewriter/EntityPacketRewriter1_16_2.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_1to1_16_2/rewriter/EntityPacketRewriter1_16_2.java index d32776ec2..cb4cac5c3 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_1to1_16_2/rewriter/EntityPacketRewriter1_16_2.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_1to1_16_2/rewriter/EntityPacketRewriter1_16_2.java @@ -72,6 +72,8 @@ public class EntityPacketRewriter1_16_2 extends EntityRewriter { String dimensionType = wrapper.read(Types.STRING); wrapper.write(Types.NAMED_COMPOUND_TAG, getDimensionData(dimensionType)); + + tracker(wrapper.user()).clearEntities(); }); } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/rewriter/EntityPacketRewriter1_17.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/rewriter/EntityPacketRewriter1_17.java index e47f8795c..c7afdf27b 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/rewriter/EntityPacketRewriter1_17.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/rewriter/EntityPacketRewriter1_17.java @@ -116,6 +116,8 @@ public final class EntityPacketRewriter1_17 extends EntityRewriter { CompoundTag dimensionData = wrapper.passthrough(Types.NAMED_COMPOUND_TAG); addNewDimensionData(dimensionData); + + tracker(wrapper.user()).clearEntities(); }); protocol.registerClientbound(ClientboundPackets1_16_2.UPDATE_ATTRIBUTES, new PacketHandlers() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java index 1796fd814..8604ef723 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/Protocol1_8To1_9.java @@ -43,7 +43,7 @@ import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.ItemPacketRewriter import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.PlayerPacketRewriter1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.SpawnPacketRewriter1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.rewriter.WorldPacketRewriter1_9; -import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientChunks; +import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientWorld1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.CommandBlockStorage; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.InventoryTracker; @@ -104,20 +104,12 @@ public class Protocol1_8To1_9 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_8To1_9.class); int dimensionId = wrapper.get(Types.BYTE, 0); clientWorld.setEnvironment(dimensionId); }); @@ -295,27 +295,25 @@ public class PlayerPacketRewriter1_9 { map(Types.UNSIGNED_BYTE); // 2 - GameMode map(Types.STRING); // 3 - Level Type - // Track player's dimension - handler(wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - int dimensionId = wrapper.get(Types.INT, 0); - clientWorld.setEnvironment(dimensionId); - }); - - handler(wrapper -> { - // Client unloads chunks on respawn - wrapper.user().get(ClientChunks.class).getLoadedChunks().clear(); - - int gamemode = wrapper.get(Types.UNSIGNED_BYTE, 0); - EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); - tracker.setGameMode(GameMode.getById(gamemode)); - }); - - // Fake permissions to get Commandblocks working handler(wrapper -> { CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class); + // Fake permissions to get Commandblocks working provider.sendPermission(wrapper.user()); - provider.unloadChunks(wrapper.user()); + + EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class); + int gamemode = wrapper.get(Types.UNSIGNED_BYTE, 0); + tracker.setGameMode(GameMode.getById(gamemode)); + + ClientWorld1_9 clientWorld = wrapper.user().getClientWorld(Protocol1_8To1_9.class); + int dimensionId = wrapper.get(Types.INT, 0); + + // Track player's dimension + if (clientWorld.setEnvironment(dimensionId)) { + tracker.clearEntities(); + + clientWorld.getLoadedChunks().clear(); + provider.unloadChunks(wrapper.user()); + } }); } }); @@ -496,4 +494,4 @@ public class PlayerPacketRewriter1_9 { } }); } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java index ead2b6d1c..d0bb3c3a8 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/rewriter/WorldPacketRewriter1_9.java @@ -45,7 +45,7 @@ import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_ import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.provider.CommandBlockProvider; import com.viaversion.viaversion.protocols.v1_8to1_9.provider.HandItemProvider; -import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientChunks; +import com.viaversion.viaversion.protocols.v1_8to1_9.storage.ClientWorld1_9; import com.viaversion.viaversion.protocols.v1_8to1_9.storage.EntityTracker1_9; import com.viaversion.viaversion.util.ComponentUtil; import com.viaversion.viaversion.util.Key; @@ -130,11 +130,10 @@ public class WorldPacketRewriter1_9 { }); protocol.registerClientbound(ClientboundPackets1_8.LEVEL_CHUNK, wrapper -> { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); + ClientWorld1_9 clientWorld = wrapper.user().getClientWorld(Protocol1_8To1_9.class); Chunk chunk = wrapper.read(ChunkType1_8.forEnvironment(clientWorld.getEnvironment())); - long chunkHash = ClientChunks.toLong(chunk.getX(), chunk.getZ()); + long chunkHash = ClientWorld1_9.toLong(chunk.getX(), chunk.getZ()); // Check if the chunk should be handled as an unload packet if (chunk.isFullChunk() && chunk.getBitmask() == 0) { @@ -146,14 +145,14 @@ public class WorldPacketRewriter1_9 { CommandBlockProvider provider = Via.getManager().getProviders().get(CommandBlockProvider.class); provider.unloadChunk(wrapper.user(), chunk.getX(), chunk.getZ()); - clientChunks.getLoadedChunks().remove(chunkHash); + clientWorld.getLoadedChunks().remove(chunkHash); // Unload the empty chunks if (Via.getConfig().isChunkBorderFix()) { for (BlockFace face : BlockFace.HORIZONTAL) { int chunkX = chunk.getX() + face.modX(); int chunkZ = chunk.getZ() + face.modZ(); - if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) { + if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) { PacketWrapper unloadChunk = wrapper.create(ClientboundPackets1_9.FORGET_LEVEL_CHUNK); unloadChunk.write(Types.INT, chunkX); unloadChunk.write(Types.INT, chunkZ); @@ -165,14 +164,14 @@ public class WorldPacketRewriter1_9 { Type chunkType = ChunkType1_9_1.forEnvironment(clientWorld.getEnvironment()); wrapper.write(chunkType, chunk); - clientChunks.getLoadedChunks().add(chunkHash); + clientWorld.getLoadedChunks().add(chunkHash); // Send empty chunks surrounding the loaded chunk to force 1.9+ clients to render the new chunk if (Via.getConfig().isChunkBorderFix()) { for (BlockFace face : BlockFace.HORIZONTAL) { int chunkX = chunk.getX() + face.modX(); int chunkZ = chunk.getZ() + face.modZ(); - if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) { + if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) { PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.LEVEL_CHUNK); Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>()); emptyChunk.write(chunkType, c); @@ -185,8 +184,7 @@ public class WorldPacketRewriter1_9 { protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, null, wrapper -> { wrapper.cancel(); // Cancel the packet from being sent - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - ClientChunks clientChunks = wrapper.user().get(ClientChunks.class); + ClientWorld1_9 clientWorld = wrapper.user().getClientWorld(Protocol1_8To1_9.class); Chunk[] chunks = wrapper.read(BulkChunkType1_8.TYPE); Type chunkType = ChunkType1_9_1.forEnvironment(clientWorld.getEnvironment()); @@ -196,14 +194,14 @@ public class WorldPacketRewriter1_9 { chunkData.write(chunkType, chunk); chunkData.send(Protocol1_8To1_9.class); - clientChunks.getLoadedChunks().add(ClientChunks.toLong(chunk.getX(), chunk.getZ())); + clientWorld.getLoadedChunks().add(ClientWorld1_9.toLong(chunk.getX(), chunk.getZ())); // Send empty chunks surrounding the loaded chunk to force 1.9+ clients to render the new chunk if (Via.getConfig().isChunkBorderFix()) { for (BlockFace face : BlockFace.HORIZONTAL) { int chunkX = chunk.getX() + face.modX(); int chunkZ = chunk.getZ() + face.modZ(); - if (!clientChunks.getLoadedChunks().contains(ClientChunks.toLong(chunkX, chunkZ))) { + if (!clientWorld.getLoadedChunks().contains(ClientWorld1_9.toLong(chunkX, chunkZ))) { PacketWrapper emptyChunk = wrapper.create(ClientboundPackets1_9.LEVEL_CHUNK); Chunk c = new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], new int[256], new ArrayList<>()); emptyChunk.write(chunkType, c); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientChunks.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientWorld1_9.java similarity index 90% rename from common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientChunks.java rename to common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientWorld1_9.java index 561e56233..7defcd00e 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientChunks.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/storage/ClientWorld1_9.java @@ -18,10 +18,10 @@ package com.viaversion.viaversion.protocols.v1_8to1_9.storage; import com.google.common.collect.Sets; -import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.api.minecraft.ClientWorld; import java.util.Set; -public class ClientChunks implements StorableObject { +public class ClientWorld1_9 extends ClientWorld { private final Set loadedChunks = Sets.newConcurrentHashSet(); public static long toLong(int msw, int lsw) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_9_1to1_9_3/Protocol1_9_1To1_9_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_9_1to1_9_3/Protocol1_9_1To1_9_3.java index 0067e2ad9..6e7ddf529 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_9_1to1_9_3/Protocol1_9_1To1_9_3.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_9_1to1_9_3/Protocol1_9_1To1_9_3.java @@ -87,7 +87,7 @@ public class Protocol1_9_1To1_9_3 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_1To1_9_3.class); Chunk chunk = wrapper.read(ChunkType1_9_1.forEnvironment(clientWorld.getEnvironment())); wrapper.write(ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()), chunk); @@ -120,7 +120,7 @@ public class Protocol1_9_1To1_9_3 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_1To1_9_3.class); int dimensionId = wrapper.get(Types.INT, 1); clientWorld.setEnvironment(dimensionId); }); @@ -132,7 +132,7 @@ public class Protocol1_9_1To1_9_3 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_1To1_9_3.class); int dimensionId = wrapper.get(Types.INT, 0); clientWorld.setEnvironment(dimensionId); }); @@ -156,8 +156,6 @@ public class Protocol1_9_1To1_9_3 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_10.class); int dimensionId = wrapper.get(Types.INT, 1); clientWorld.setEnvironment(dimensionId); @@ -168,7 +168,7 @@ public class Protocol1_9_3To1_10 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_10.class); int dimensionId = wrapper.get(Types.INT, 0); clientWorld.setEnvironment(dimensionId); @@ -178,7 +178,7 @@ public class Protocol1_9_3To1_10 extends AbstractProtocol { - ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); + ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9_3To1_10.class); Chunk chunk = wrapper.passthrough(ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment())); if (Via.getConfig().isReplacePistons()) { @@ -234,11 +234,9 @@ public class Protocol1_9_3To1_10 extends AbstractProtocol Date: Sun, 15 Sep 2024 21:52:32 +0200 Subject: [PATCH 13/25] Remove transaction tracking (and cancelling) in 1.16.4->1.17 (#4140) --- .../v1_16_4to1_17/Protocol1_16_4To1_17.java | 2 -- .../rewriter/ItemPacketRewriter1_17.java | 4 +-- .../storage/InventoryAcknowledgements.java | 34 ------------------- 3 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/storage/InventoryAcknowledgements.java diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17.java index fe692871b..41004b37d 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/Protocol1_16_4To1_17.java @@ -37,7 +37,6 @@ import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPacke import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.EntityPacketRewriter1_17; import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.ItemPacketRewriter1_17; import com.viaversion.viaversion.protocols.v1_16_4to1_17.rewriter.WorldPacketRewriter1_17; -import com.viaversion.viaversion.protocols.v1_16_4to1_17.storage.InventoryAcknowledgements; import com.viaversion.viaversion.rewriter.SoundRewriter; import com.viaversion.viaversion.rewriter.StatisticsRewriter; import com.viaversion.viaversion.rewriter.TagRewriter; @@ -192,7 +191,6 @@ public final class Protocol1_16_4To1_17 extends AbstractProtocol { int id = wrapper.read(Types.INT); // Check extra bit for fast dismissal - if ((id & (1 << 30)) != 0 && wrapper.user().get(InventoryAcknowledgements.class).removeId(id)) { + if ((id & (1 << 30)) != 0) { // Decode our requested inventory acknowledgement short inventoryId = (short) ((id >> 16) & 0xFF); short confirmationId = (short) (id & 0xFFFF); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/storage/InventoryAcknowledgements.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/storage/InventoryAcknowledgements.java deleted file mode 100644 index b07d4dee7..000000000 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_16_4to1_17/storage/InventoryAcknowledgements.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion - * Copyright (C) 2016-2024 ViaVersion and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.viaversion.viaversion.protocols.v1_16_4to1_17.storage; - -import com.viaversion.viaversion.api.connection.StorableObject; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; - -public final class InventoryAcknowledgements implements StorableObject { - private final IntList ids = new IntArrayList(); - - public void addId(int id) { - ids.add(id); - } - - public boolean removeId(int id) { - return ids.rem(id); - } -} From 9e354e956e887f854bcbe0b5e7d66d1b3d6f32f4 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Fri, 20 Sep 2024 13:35:48 +0200 Subject: [PATCH 14/25] Update MCStructs (#4153) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bb415de83..3220e91ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ metadata.format.version = "1.1" gson = "2.10.1" fastutil = "8.5.12" vianbt = "5.0.0" -mcstructs = "5-2.5.1" +mcstructs = "5-2.5.2" # Common provided netty = "4.0.20.Final" From a0a27942919675ff7b9d924d61db82deee5b96c7 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Fri, 20 Sep 2024 13:35:58 +0200 Subject: [PATCH 15/25] Change player parent to living entity base in 1.9/1.12 entity enums (#4154) --- .../viaversion/api/minecraft/entities/EntityTypes1_12.java | 2 +- .../viaversion/api/minecraft/entities/EntityTypes1_9.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_12.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_12.java index 9a63fc145..6a2b140bb 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_12.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_12.java @@ -101,7 +101,7 @@ public class EntityTypes1_12 { LIVING_ENTITY_BASE(ENTITY), ARMOR_STAND(30, LIVING_ENTITY_BASE), - PLAYER(ENTITY), // Needed for entity (un)tracking + PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking // Living entities as a larger subclass LIVING_ENTITY(LIVING_ENTITY_BASE), diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_9.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_9.java index 81545ea6e..f32f53e43 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_9.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/entities/EntityTypes1_9.java @@ -99,7 +99,7 @@ public class EntityTypes1_9 { LIVING_ENTITY_BASE(ENTITY), ARMOR_STAND(30, LIVING_ENTITY_BASE), - PLAYER(ENTITY), // Needed for entity (un)tracking + PLAYER(LIVING_ENTITY_BASE), // Needed for entity (un)tracking // Living entities as a larger subclass LIVING_ENTITY(48, LIVING_ENTITY_BASE), From 5287d4fb4f69a1bedbad7d76e34dc49d163c35bb Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Mon, 23 Sep 2024 19:24:46 +0200 Subject: [PATCH 16/25] Fix enchantment glint behaviour in 1.10->1.11 (#4156) --- .../rewriter/ItemPacketRewriter1_11.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/rewriter/ItemPacketRewriter1_11.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/rewriter/ItemPacketRewriter1_11.java index f7dcd7075..587f7f448 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/rewriter/ItemPacketRewriter1_11.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_10to1_11/rewriter/ItemPacketRewriter1_11.java @@ -19,6 +19,7 @@ package com.viaversion.viaversion.protocols.v1_10to1_11.rewriter; import com.viaversion.nbt.tag.ByteTag; import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.nbt.tag.ListTag; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.type.Types; @@ -55,6 +56,22 @@ public class ItemPacketRewriter1_11 extends ItemRewriterremoveUnchecked(nbtTagName()).asByte()); - if (item.tag().isEmpty()) { - item.setTag(null); + CompoundTag tag = item.tag(); + if (tag != null) { + if (tag.contains(nbtTagName())) { + item.setAmount(tag.removeUnchecked(nbtTagName()).asByte()); + if (tag.isEmpty()) { + item.setTag(null); + } + } + if (tag.remove(nbtTagName("clearEnch")) != null) { + tag.put("ench", new ListTag()); } } EntityMappings1_11.toServerItem(item); @@ -78,4 +101,4 @@ public class ItemPacketRewriter1_11 extends ItemRewriter Date: Mon, 23 Sep 2024 19:44:27 +0200 Subject: [PATCH 17/25] Bump gradle-update/update-gradle-wrapper-action from 1 to 2 (#4157) Bumps [gradle-update/update-gradle-wrapper-action](https://github.com/gradle-update/update-gradle-wrapper-action) from 1 to 2. - [Release notes](https://github.com/gradle-update/update-gradle-wrapper-action/releases) - [Changelog](https://github.com/gradle-update/update-gradle-wrapper-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/gradle-update/update-gradle-wrapper-action/compare/v1...v2) --- updated-dependencies: - dependency-name: gradle-update/update-gradle-wrapper-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/update-gradle-wrapper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-gradle-wrapper.yml b/.github/workflows/update-gradle-wrapper.yml index 925038fa7..a6ed992bf 100644 --- a/.github/workflows/update-gradle-wrapper.yml +++ b/.github/workflows/update-gradle-wrapper.yml @@ -11,4 +11,4 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Update Gradle Wrapper - uses: gradle-update/update-gradle-wrapper-action@v1 + uses: gradle-update/update-gradle-wrapper-action@v2 From 6bae039d52913bbb365cda4a7264d2fc73c24f5a Mon Sep 17 00:00:00 2001 From: RK_01 <50594595+RaphiMC@users.noreply.github.com> Date: Tue, 24 Sep 2024 19:09:32 +0200 Subject: [PATCH 18/25] Update mcstructs (#4159) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3220e91ac..44c0992d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ metadata.format.version = "1.1" gson = "2.10.1" fastutil = "8.5.12" vianbt = "5.0.0" -mcstructs = "5-2.5.2" +mcstructs = "5-2.5.3" # Common provided netty = "4.0.20.Final" From 619eecacf8ec598ea2fa11748f7b7eff526421a8 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Thu, 26 Sep 2024 12:16:06 +0200 Subject: [PATCH 19/25] Don't add block entity tag if the id is missing --- .../rewriter/BlockItemPacketRewriter1_20_5.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java index 476d4e0e2..1e247371c 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java @@ -488,7 +488,11 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter Date: Sun, 29 Sep 2024 04:19:11 +0200 Subject: [PATCH 20/25] Update Gradle Wrapper from 8.10.1 to 8.10.2 (#4161) Signed-off-by: gradle-update-robot Co-authored-by: gradle-update-robot --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8e876e1c5..fb602ee2a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip +distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From c358c3902711eb5b091fa653538ffaa733ecdba2 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 29 Sep 2024 13:34:32 +0200 Subject: [PATCH 21/25] Make clearer distinction between filled and empty data component patch, simplify direct value getting --- .../api/minecraft/data/StructuredData.java | 8 +- .../data/StructuredDataContainer.java | 199 +++++++++++------- .../BlockItemPacketRewriter1_20_5.java | 2 +- .../rewriter/BlockItemPacketRewriter1_21.java | 11 +- .../rewriter/StructuredItemRewriter.java | 48 ++--- 5 files changed, 160 insertions(+), 108 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredData.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredData.java index 45e110e62..4bd08908a 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredData.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredData.java @@ -52,16 +52,14 @@ public interface StructuredData extends IdHolder { return new EmptyStructuredData<>(key, id); } - void setValue(final T value); + @Nullable T value(); - void write(final ByteBuf buffer); + void setValue(final T value); void setId(final int id); StructuredDataKey key(); - @Nullable T value(); - /** * Returns whether the structured data is present. Even if true, the value may be null. * @@ -77,4 +75,6 @@ public interface StructuredData extends IdHolder { * @return true if the structured data is empty */ boolean isEmpty(); + + void write(final ByteBuf buffer); } diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataContainer.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataContainer.java index 740994c3d..3907748d2 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataContainer.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/data/StructuredDataContainer.java @@ -33,6 +33,26 @@ import java.util.Map; import java.util.function.Function; import org.checkerframework.checker.nullness.qual.Nullable; +/** + * Loosely represents Minecraft's data component patch, but may also be used for an item's full data components. + *

+ * The most commonly used methods will ignore empty data (aka empty overrides that remove item defaults) since those will rarely be needed. + * These are: + *

    + *
  • {@link #get(StructuredDataKey)}
  • + *
  • {@link #set(StructuredDataKey, Object)}
  • + *
  • {@link #set(StructuredDataKey)}
  • + *
  • {@link #getNonEmptyData(StructuredDataKey)}
  • + *
  • {@link #hasValue(StructuredDataKey)}
  • + *
+ * + * To interact with empty patches specifically, use: + *
    + *
  • {@link #setEmpty(StructuredDataKey)}
  • + *
  • {@link #hasEmpty(StructuredDataKey)}
  • + *
+ * Other methods (e.g. {@link #getData(StructuredDataKey)} and {@link #has(StructuredDataKey)}) will handle both empty and non-empty data. + */ public final class StructuredDataContainer { private final Map, StructuredData> data; @@ -55,66 +75,45 @@ public final class StructuredDataContainer { } /** - * Returns structured data by id if present. + * Returns the non-empty value by id if present. + * + * @param key serializer id + * @param data type + * @return structured data + * @see #hasEmpty(StructuredDataKey) + */ + public @Nullable T get(final StructuredDataKey key) { + final StructuredData data = this.data.get(key); + if (data == null || data.isEmpty()) { + return null; + } + //noinspection unchecked + return ((StructuredData) data).value(); + } + + /** + * Returns structured data by id if present, either empty or non-empty. * * @param key serializer id * @param data type * @return structured data */ - public @Nullable StructuredData get(final StructuredDataKey key) { + public @Nullable StructuredData getData(final StructuredDataKey key) { //noinspection unchecked return (StructuredData) this.data.get(key); } /** - * Returns structured data by id if not empty. + * Returns non-empty structured data by id if present. * * @param key serializer id * @param data type - * @return structured data if not empty + * @return non-empty structured data */ - public @Nullable StructuredData getNonEmpty(final StructuredDataKey key) { + public @Nullable StructuredData getNonEmptyData(final StructuredDataKey key) { + final StructuredData data = this.data.get(key); //noinspection unchecked - final StructuredData data = (StructuredData) this.data.get(key); - return data != null && data.isPresent() ? data : null; - } - - /** - * Returns structured data by id if not empty, or creates it. - * - * @param key serializer id - * @param mappingFunction function to create structured data if not present - * @param data type - * @return structured data if not empty - */ - public StructuredData computeIfAbsent(final StructuredDataKey key, final Function, T> mappingFunction) { - final StructuredData data = this.getNonEmpty(key); - if (data != null) { - return data; - } - - final int id = serializerId(key); - final StructuredData empty = StructuredData.of(key, mappingFunction.apply(key), id); - this.data.put(key, empty); - return empty; - } - - /** - * Updates and returns the structured data by id if not empty. - * - * @param key serializer id - * @param mappingFunction function to update existing data - * @param data type - * @return updated structured data if not empty - */ - public @Nullable StructuredData updateIfPresent(final StructuredDataKey key, final Function mappingFunction) { - final StructuredData data = this.getNonEmpty(key); - if (data == null) { - return null; - } - - data.setValue(mappingFunction.apply(data.value())); - return data; + return data != null && data.isPresent() ? (StructuredData) data : null; } public void set(final StructuredDataKey key, final T value) { @@ -124,49 +123,105 @@ public final class StructuredDataContainer { } } - public void replaceKey(final StructuredDataKey key, final StructuredDataKey toKey) { - replace(key, toKey, Function.identity()); - } - - public void replace(final StructuredDataKey key, final StructuredDataKey toKey, final Function valueMapper) { - final StructuredData data = remove(key); - if (data == null) { - return; - } - - if (data.isPresent()) { - set(toKey, valueMapper.apply(data.value())); - } else { - addEmpty(toKey); - } - } - public void set(final StructuredDataKey key) { this.set(key, Unit.INSTANCE); } - public void addEmpty(final StructuredDataKey key) { + public void setEmpty(final StructuredDataKey key) { // Empty optional to override the Minecraft default this.data.put(key, StructuredData.empty(key, serializerId(key))); } /** - * Removes and returns structured data by the given key. + * Updates the structured data by id if not empty. * - * @param key serializer key - * @param data type - * @return removed structured data + * @param key serializer id + * @param valueMapper function to update existing data + * @param data type */ - public @Nullable StructuredData remove(final StructuredDataKey key) { - final StructuredData data = this.data.remove(key); - //noinspection unchecked - return data != null ? (StructuredData) data : null; + public void replace(final StructuredDataKey key, final Function valueMapper) { + final StructuredData data = this.getNonEmptyData(key); + if (data == null) { + return; + } + + final T replacement = valueMapper.apply(data.value()); + if (replacement != null) { + data.setValue(replacement); + } else { + this.data.remove(key); + } } - public boolean contains(final StructuredDataKey key) { + public void replaceKey(final StructuredDataKey key, final StructuredDataKey toKey) { + replace(key, toKey, Function.identity()); + } + + public void replace(final StructuredDataKey key, final StructuredDataKey toKey, final Function valueMapper) { + final StructuredData data = this.data.remove(key); + if (data == null) { + return; + } + + if (data.isPresent()) { + //noinspection unchecked + final T value = (T) data.value(); + final V replacement = valueMapper.apply(value); + if (replacement != null) { + set(toKey, replacement); + } + } else { + // Also replace the key for empty data + setEmpty(toKey); + } + } + + /** + * Removes data by the given key. + * + * @param key data key + * @see #replace(StructuredDataKey, Function) + * @see #replace(StructuredDataKey, StructuredDataKey, Function) + * @see #replaceKey(StructuredDataKey, StructuredDataKey) + */ + public void remove(final StructuredDataKey key) { + this.data.remove(key); + } + + /** + * Returns whether there is data for the given key, either empty or non-empty. + * + * @param key data key + * @return whether there data for the given key + * @see #hasEmpty(StructuredDataKey) + * @see #hasValue(StructuredDataKey) + */ + public boolean has(final StructuredDataKey key) { return this.data.containsKey(key); } + /** + * Returns whether there is non-empty data for the given key. + * + * @param key data key + * @return whether there is non-empty data for the given key + */ + public boolean hasValue(final StructuredDataKey key) { + final StructuredData data = this.data.get(key); + return data != null && data.isPresent(); + } + + /** + * Returns whether the structured data has an empty patch/override. + * + * @param key serializer id + * @return whether the structured data has an empty patch/override + */ + public boolean hasEmpty(final StructuredDataKey key) { + final StructuredData data = this.data.get(key); + return data != null && data.isEmpty(); + } + /** * Sets the lookup for serializer ids. Required to call most of the other methods. * diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java index 1e247371c..39204b2da 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java @@ -416,7 +416,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); + final StructuredData customData = data.getNonEmptyData(StructuredDataKey.CUSTOM_DATA); final CompoundTag tag = customData != null ? customData.value() : new CompoundTag(); final DataItem dataItem = new DataItem(item.identifier(), (byte) item.amount(), tag); if (!dataConverter.backupInconvertibleData() && customData != null && tag.remove(nbtTagName()) != null) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java index 803add1c2..b71695e51 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java @@ -20,7 +20,6 @@ package com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter; import com.viaversion.nbt.tag.ByteTag; import com.viaversion.nbt.tag.CompoundTag; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.minecraft.data.StructuredData; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; @@ -123,7 +122,7 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter customData = dataContainer.getNonEmpty(StructuredDataKey.CUSTOM_DATA); + final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA); if (customData == null) { return; } - if (customData.value().remove(tagName) != null) { + + if (customData.remove(tagName) != null) { dataContainer.remove(StructuredDataKey.RARITY); - if (customData.value().isEmpty()) { + if (customData.isEmpty()) { dataContainer.remove(StructuredDataKey.CUSTOM_DATA); } } diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java index 21eed2fd9..fe3b72e63 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/StructuredItemRewriter.java @@ -114,27 +114,27 @@ public class StructuredItemRewriter value.rewrite(itemIdRewriter)); - container.updateIfPresent(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter)); + container.replace(StructuredDataKey.TRIM, value -> value.rewrite(itemIdRewriter)); + container.replace(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter)); } if (mappingData.getBlockMappings() != null) { final Int2IntFunction blockIdRewriter = clientbound ? mappingData::getNewBlockId : mappingData::getOldBlockId; - container.updateIfPresent(StructuredDataKey.TOOL, value -> value.rewrite(blockIdRewriter)); - container.updateIfPresent(StructuredDataKey.CAN_PLACE_ON, value -> value.rewrite(blockIdRewriter)); - container.updateIfPresent(StructuredDataKey.CAN_BREAK, value -> value.rewrite(blockIdRewriter)); + container.replace(StructuredDataKey.TOOL, value -> value.rewrite(blockIdRewriter)); + container.replace(StructuredDataKey.CAN_PLACE_ON, value -> value.rewrite(blockIdRewriter)); + container.replace(StructuredDataKey.CAN_BREAK, value -> value.rewrite(blockIdRewriter)); } if (mappingData.getSoundMappings() != null) { final Int2IntFunction soundIdRewriter = clientbound ? mappingData::getNewSoundId : mappingData::getOldSoundId; - container.updateIfPresent(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value); - container.updateIfPresent(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter)); + container.replace(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value); + container.replace(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter)); } if (clientbound && protocol.getComponentRewriter() != null) { updateComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name"); updateComponent(connection, item, StructuredDataKey.CUSTOM_NAME, "custom_name"); - final StructuredData loreData = container.getNonEmpty(StructuredDataKey.LORE); - if (loreData != null) { - for (final Tag tag : loreData.value()) { + final Tag[] lore = container.get(StructuredDataKey.LORE); + if (lore != null) { + for (final Tag tag : lore) { protocol.getComponentRewriter().processTag(connection, tag); } } @@ -166,35 +166,35 @@ public class StructuredItemRewriter key, final String backupKey) { - final StructuredData name = item.dataContainer().getNonEmpty(key); + final Tag name = item.dataContainer().get(key); if (name == null) { return; } - final Tag originalName = name.value().copy(); - protocol.getComponentRewriter().processTag(connection, name.value()); - if (!name.value().equals(originalName)) { + final Tag originalName = name.copy(); + protocol.getComponentRewriter().processTag(connection, name); + if (!name.equals(originalName)) { saveTag(createCustomTag(item), originalName, backupKey); } } protected void restoreTextComponents(final Item item) { final StructuredDataContainer data = item.dataContainer(); - final StructuredData customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); + final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); if (customData == null) { return; } // Remove custom name - if (customData.value().remove(nbtTagName("added_custom_name")) != null) { + if (customData.remove(nbtTagName("added_custom_name")) != null) { data.remove(StructuredDataKey.CUSTOM_NAME); } else { - final Tag customName = removeBackupTag(customData.value(), "custom_name"); + final Tag customName = removeBackupTag(customData, "custom_name"); if (customName != null) { data.set(StructuredDataKey.CUSTOM_NAME, customName); } - final Tag itemName = removeBackupTag(customData.value(), "item_name"); + final Tag itemName = removeBackupTag(customData, "item_name"); if (itemName != null) { data.set(StructuredDataKey.ITEM_NAME, itemName); } @@ -203,14 +203,12 @@ public class StructuredItemRewriter customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); - if (customData != null) { - return customData.value(); + CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); + if (customData == null) { + customData = new CompoundTag(); + data.set(StructuredDataKey.CUSTOM_DATA, customData); } - - final CompoundTag tag = new CompoundTag(); - data.set(StructuredDataKey.CUSTOM_DATA, tag); - return tag; + return customData; } protected void saveTag(final CompoundTag customData, final Tag tag, final String name) { From c0821de2e206615dfb552e129ffcff8d21cf7ca9 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Wed, 2 Oct 2024 10:41:59 +0200 Subject: [PATCH 22/25] Define as Sponge plugin for ViaSponge (#4163) --- .../kotlin/via.base-conventions.gradle.kts | 2 +- settings.gradle.kts | 1 + .../resources/META-INF/sponge_plugins.json | 66 ++++++++++++++++++ .../assets/viaversion/textures/logo.png | Bin 0 -> 30715 bytes universal/build.gradle.kts | 1 + 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 sponge/src/main/resources/META-INF/sponge_plugins.json create mode 100644 sponge/src/main/resources/assets/viaversion/textures/logo.png diff --git a/build-logic/src/main/kotlin/via.base-conventions.gradle.kts b/build-logic/src/main/kotlin/via.base-conventions.gradle.kts index c67bf7a5a..d094aff73 100644 --- a/build-logic/src/main/kotlin/via.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/via.base-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { tasks { // Variable replacements processResources { - filesMatching(listOf("plugin.yml", "fabric.mod.json")) { + filesMatching(listOf("plugin.yml", "META-INF/sponge_plugins.json", "fabric.mod.json")) { expand("version" to project.version, "description" to project.description, "url" to "https://viaversion.com") } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 5f805ebcc..3f79ddd61 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,6 +29,7 @@ setupViaSubproject("common") setupViaSubproject("bukkit") setupViaSubproject("bukkit-legacy") setupViaSubproject("velocity") +setupViaSubproject("sponge") setupViaSubproject("fabric") setupSubproject("viaversion") { diff --git a/sponge/src/main/resources/META-INF/sponge_plugins.json b/sponge/src/main/resources/META-INF/sponge_plugins.json new file mode 100644 index 000000000..748394f77 --- /dev/null +++ b/sponge/src/main/resources/META-INF/sponge_plugins.json @@ -0,0 +1,66 @@ +{ + "loader": { + "name": "java_plain", + "version": "1.0" + }, + "license": "GNU GPLv3", + "global": { + "version": "${version}", + "links": { + "homepage": "https://viaversion.com/", + "source": "https://github.com/ViaVersion/ViaVersion", + "issues": "https://github.com/ViaVersion/ViaVersion/issues" + }, + "contributors": [ + { + "name": "_MylesC", + "description": "Maintainer" + }, + { + "name": "creeper123123321", + "description": "Contributor" + }, + { + "name": "Gerrygames", + "description": "Contributor" + }, + { + "name": "kennytv", + "description": "Maintainer" + }, + { + "name": "Matsv", + "description": "Contributor" + }, + { + "name": "EnZaXD", + "description": "Maintainer" + }, + { + "name": "RK_01", + "description": "Contributor" + } + ], + "dependencies": [ + { + "id": "spongeapi", + "version": "8.0.0" + }, + { + "id": "viasponge", + "version": "1.1.0" + } + ], + "branding": { + "logo": "assets/viaversion/textures/logo.png" + } + }, + "plugins": [ + { + "id": "viaversion", + "name": "ViaVersion", + "entrypoint": "com.viaversion.sponge.util.DummyEntrypoint", + "description": "${description}" + } + ] +} diff --git a/sponge/src/main/resources/assets/viaversion/textures/logo.png b/sponge/src/main/resources/assets/viaversion/textures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6cbc87e5368ad0899c4d83d1907819cefb1974 GIT binary patch literal 30715 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 literal 0 HcmV?d00001 diff --git a/universal/build.gradle.kts b/universal/build.gradle.kts index 3aec57adb..223746574 100644 --- a/universal/build.gradle.kts +++ b/universal/build.gradle.kts @@ -7,6 +7,7 @@ dependencies { api(projects.viaversionCommon) api(projects.viaversionBukkit) api(projects.viaversionVelocity) + api(projects.viaversionSponge) api(projects.viaversionFabric) } From 9df1704357db115bee15c5f726820fb90a2d9765 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sat, 5 Oct 2024 21:34:34 +0200 Subject: [PATCH 23/25] Fix holder set direct id conversion in 1.20.3->1.20.5 component rewriter (#4164) --- .../rewriter/ComponentRewriter1_20_5.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/ComponentRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/ComponentRewriter1_20_5.java index df6d52524..566a12887 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/ComponentRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/ComponentRewriter1_20_5.java @@ -396,6 +396,14 @@ public class ComponentRewriter1_20_5 extends Co } protected CompoundTag convertCanPlaceOn(final AdventureModePredicate value) { + return convertBlockPredicate(value); + } + + protected CompoundTag convertCanBreak(final AdventureModePredicate value) { + return convertBlockPredicate(value); + } + + protected CompoundTag convertBlockPredicate(final AdventureModePredicate value) { final CompoundTag tag = new CompoundTag(); final ListTag predicates = new ListTag<>(CompoundTag.class); for (final BlockPredicate predicate : value.predicates()) { @@ -404,8 +412,7 @@ public class ComponentRewriter1_20_5 extends Co convertHolderSet(predicateTag, "blocks", predicate.holderSet()); } if (predicate.propertyMatchers() != null) { - final CompoundTag state = convertPredicate(predicate); - predicateTag.put("state", state); + predicateTag.put("state", createState(predicate)); } if (predicate.tag() != null) { predicateTag.put("nbt", predicate.tag()); @@ -420,8 +427,10 @@ public class ComponentRewriter1_20_5 extends Co return tag; } - protected CompoundTag convertPredicate(final BlockPredicate predicate) { + // Not an own conversion method, just to avoid high nesting + protected CompoundTag createState(BlockPredicate predicate) { final CompoundTag state = new CompoundTag(); + for (final StatePropertyMatcher matcher : predicate.propertyMatchers()) { final Either match = matcher.matcher(); if (match.isLeft()) { @@ -441,10 +450,6 @@ public class ComponentRewriter1_20_5 extends Co return state; } - protected CompoundTag convertCanBreak(final AdventureModePredicate value) { - return convertCanPlaceOn(value); - } - protected CompoundTag convertAttributeModifiers(final AttributeModifiers1_20_5 value) { final CompoundTag tag = new CompoundTag(); final ListTag modifiers = new ListTag<>(CompoundTag.class); @@ -946,7 +951,17 @@ public class ComponentRewriter1_20_5 extends Co if (set.hasTagKey()) { tag.putString(name, set.tagKey()); } else { - tag.put(name, new IntArrayTag(set.ids())); + final ListTag identifiers = new ListTag<>(StringTag.class); + for (final int id : set.ids()) { + // Can use old block list because new ids are only at the end :tm: + final String identifier = Protocol1_20_3To1_20_5.MAPPINGS.blockName(id); + if (identifier == null) { + continue; + } + + identifiers.add(new StringTag(identifier)); + } + tag.put(name, identifiers); } } From 9674c617ca1cc399dc78b9f5114db97d1a3c2a00 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sun, 6 Oct 2024 15:19:05 +0200 Subject: [PATCH 24/25] Add option to fix wrong block placement rotation in 1.20.5->1.21 (#4166) --- .../api/configuration/ViaVersionConfig.java | 7 +++++++ .../configuration/AbstractViaConfig.java | 11 ++++++++-- .../rewriter/BlockItemPacketRewriter1_21.java | 20 +++++++++++++++++-- .../resources/assets/viaversion/config.yml | 5 ++++- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java b/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java index 16406afc3..23b844129 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java +++ b/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java @@ -471,4 +471,11 @@ public interface ViaVersionConfig extends Config { * @return true if enabled */ boolean hideScoreboardNumbers(); + + /** + * Fixes 1.21+ clients on 1.20.5 servers placing water/lava buckets at the wrong location when moving fast. + * + * @return true if enabled + */ + boolean fix1_21PlacementRotation(); } diff --git a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java index 3f32e31cc..8fa8488c3 100644 --- a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java +++ b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java @@ -25,14 +25,14 @@ import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.protocol.BlockedProtocolVersionsImpl; import com.viaversion.viaversion.util.Config; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; import java.io.File; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import it.unimi.dsi.fastutil.objects.ObjectSet; import org.checkerframework.checker.nullness.qual.Nullable; public abstract class AbstractViaConfig extends Config implements ViaVersionConfig { @@ -95,6 +95,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf private boolean handleInvalidItemCount; private boolean cancelBlockSounds; private boolean hideScoreboardNumbers; + private boolean fix1_21PlacementRotation; protected AbstractViaConfig(final File configFile, final Logger logger) { super(configFile, logger); @@ -163,6 +164,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf handleInvalidItemCount = getBoolean("handle-invalid-item-count", false); cancelBlockSounds = getBoolean("cancel-block-sounds", true); hideScoreboardNumbers = getBoolean("hide-scoreboard-numbers", false); + fix1_21PlacementRotation = getBoolean("fix-1_21-placement-rotation", false); } private BlockedProtocolVersions loadBlockedProtocolVersions() { @@ -549,4 +551,9 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf public boolean hideScoreboardNumbers() { return hideScoreboardNumbers; } + + @Override + public boolean fix1_21PlacementRotation() { + return fix1_21PlacementRotation; + } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java index b71695e51..d507ba5c5 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java @@ -19,12 +19,14 @@ package com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter; import com.viaversion.nbt.tag.ByteTag; import com.viaversion.nbt.tag.CompoundTag; +import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_20_5; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.version.Types1_20_5; @@ -105,8 +107,22 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter { wrapper.passthrough(Types.VAR_INT); // Hand wrapper.passthrough(Types.VAR_INT); // Sequence - wrapper.read(Types.FLOAT); // Y rotation - wrapper.read(Types.FLOAT); // X rotation + final float yaw = wrapper.read(Types.FLOAT); // Y rotation + final float pitch = wrapper.read(Types.FLOAT); // X rotation + + if (!Via.getConfig().fix1_21PlacementRotation()) { + return; + } + + // Not correct but *enough* for vanilla/normal servers to have block placement synchronized + final PacketWrapper playerRotation = wrapper.create(ServerboundPackets1_20_5.MOVE_PLAYER_ROT); + playerRotation.write(Types.FLOAT, yaw); + playerRotation.write(Types.FLOAT, pitch); + playerRotation.write(Types.BOOLEAN, true); // On Ground + + playerRotation.sendToServer(Protocol1_20_5To1_21.class); + wrapper.sendToServer(Protocol1_20_5To1_21.class); + wrapper.cancel(); }); new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_20_5.UPDATE_RECIPES); diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index 1a7e6ab9a..7476272f0 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -167,6 +167,9 @@ handle-invalid-item-count: false # Hides scoreboard numbers for 1.20.3+ clients on older server versions. hide-scoreboard-numbers: false # +# Fixes 1.21+ clients on 1.20.5 servers placing water/lava buckets at the wrong location when moving fast, NOTE: This may cause issues with anti-cheat plugins. +fix-1_21-placement-rotation: false +# #----------------------------------------------------------# # 1.9+ CLIENTS ON 1.8 SERVERS OPTIONS # #----------------------------------------------------------# @@ -211,4 +214,4 @@ chunk-border-fix: false # Allows 1.9+ left-handedness (main hand) on 1.8 servers left-handed-handling: true # Tries to cancel block break/place sounds sent by 1.8 servers to 1.9+ clients to prevent them from playing twice -cancel-block-sounds: true \ No newline at end of file +cancel-block-sounds: true From 9e5c541f79479d2d600ab452ac6cf846068d05bd Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Mon, 7 Oct 2024 21:43:20 +0200 Subject: [PATCH 25/25] Disable placement rotation fix for now Closes #4168 --- .../viaversion/viaversion/configuration/AbstractViaConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java index 8fa8488c3..7c4c81451 100644 --- a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java +++ b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java @@ -554,6 +554,6 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf @Override public boolean fix1_21PlacementRotation() { - return fix1_21PlacementRotation; + return false && fix1_21PlacementRotation; // TODO Can't always set onGround to true } }