From b52638f44403d60042b2492204081ec4b128a945 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 21:25:21 +0800 Subject: [PATCH] Convert NBT tags between 1.20.1 <-> 1.20.2 --- .../axiom/packet/HelloPacketListener.java | 5 +- .../ManipulateEntityPacketListener.java | 7 +- .../packet/SetBlockBufferPacketListener.java | 3 +- .../packet/SpawnEntityPacketListener.java | 11 ++- .../axiom/viaversion/ViaVersionHelper.java | 69 +++++++++++++++++++ 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index f30707c..77bcf31 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -12,12 +12,15 @@ import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.*; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.api.type.ByteBufReader; +import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; +import net.minecraft.nbt.NbtIo; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; @@ -53,7 +56,7 @@ public class HelloPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); int apiVersion = friendlyByteBuf.readVarInt(); int dataVersion = friendlyByteBuf.readVarInt(); - friendlyByteBuf.readNbt(); // Discard + ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player); int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); if (dataVersion != serverDataVersion) { diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index 63d7f31..8db9526 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -46,7 +47,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { public record ManipulateEntry(UUID uuid, @Nullable Set relativeMovementSet, @Nullable Vec3 position, float yaw, float pitch, CompoundTag merge, PassengerManipulation passengerManipulation, List passengers) { - public static ManipulateEntry read(FriendlyByteBuf friendlyByteBuf) { + public static ManipulateEntry read(FriendlyByteBuf friendlyByteBuf, Player player) { UUID uuid = friendlyByteBuf.readUUID(); int flags = friendlyByteBuf.readByte(); @@ -61,7 +62,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { pitch = friendlyByteBuf.readFloat(); } - CompoundTag nbt = friendlyByteBuf.readNbt(); + CompoundTag nbt = ViaVersionHelper.readTagUnknown(friendlyByteBuf, player); PassengerManipulation passengerManipulation = friendlyByteBuf.readEnum(PassengerManipulation.class); List passengers = List.of(); @@ -93,7 +94,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), - ManipulateEntry::read); + buf -> ManipulateEntry.read(buf, player)); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 8497706..aaf85f7 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -9,6 +9,7 @@ import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.SectionPermissionChecker; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import net.minecraft.ChatFormatting; @@ -77,7 +78,7 @@ public class SetBlockBufferPacketListener { boolean continuation = friendlyByteBuf.readBoolean(); if (!continuation) { - friendlyByteBuf.readNbt(); // Discard sourceInfo + ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player.getBukkitEntity()); } RateLimiter rateLimiter = this.plugin.getBlockBufferRateLimiter(player.getUUID()); diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index bf8ea46..ebfbaf1 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -38,11 +39,6 @@ public class SpawnEntityPacketListener implements PluginMessageListener { private record SpawnEntry(UUID newUuid, double x, double y, double z, float yaw, float pitch, @Nullable UUID copyFrom, CompoundTag tag) { - public SpawnEntry(FriendlyByteBuf friendlyByteBuf) { - this(friendlyByteBuf.readUUID(), friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble(), - friendlyByteBuf.readDouble(), friendlyByteBuf.readFloat(), friendlyByteBuf.readFloat(), - friendlyByteBuf.readNullable(FriendlyByteBuf::readUUID), friendlyByteBuf.readNbt()); - } } private static final Rotation[] ROTATION_VALUES = Rotation.values(); @@ -62,7 +58,10 @@ public class SpawnEntityPacketListener implements PluginMessageListener { } FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), SpawnEntry::new); + List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), + buf -> new SpawnEntry(buf.readUUID(), buf.readDouble(), buf.readDouble(), + buf.readDouble(), buf.readFloat(), buf.readFloat(), + buf.readNullable(FriendlyByteBuf::readUUID), ViaVersionHelper.readTagUnknown(buf, player))); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index 7730fa3..53d03be 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -6,13 +6,22 @@ import com.viaversion.viaversion.api.data.BiMappings; import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.Mappings; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -92,4 +101,64 @@ public class ViaVersionHelper { return newBlockRegistry; } + private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = ProtocolVersion.v1_20_2.getVersion(); + + public static void skipTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + try { + ViaVersionHelper.skipTagViaVersion(friendlyByteBuf, playerVersion); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + friendlyByteBuf.readNbt(); // Discard + } + } + + public static CompoundTag readTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + try { + return ViaVersionHelper.readTagViaVersion(friendlyByteBuf, playerVersion); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return friendlyByteBuf.readNbt(); + } + } + + public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { + getTagType(playerVersion).read(friendlyByteBuf); + } + + public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { + Type from = getTagType(playerVersion); + Type to = getTagType(SharedConstants.getProtocolVersion()); + + return readTagViaVersion(friendlyByteBuf, from, to); + } + + private static Type getTagType(int version) { + if (version < UNNAMED_COMPOUND_TAG_CHANGE_VERSION) { + return Type.NAMED_COMPOUND_TAG; + } else { + return Type.COMPOUND_TAG; + } + } + + private static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, + Type from, + Type to) throws Exception { + if (from == to) { + return friendlyByteBuf.readNbt(); + } + + com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag tag = from.read(friendlyByteBuf); + ByteBuf buffer = Unpooled.buffer(); + to.write(buffer, tag); + return new FriendlyByteBuf(buffer).readNbt(); + } + }