From cd533b26359642bdec95a3361c014ad35ae5b14b Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Tue, 28 Oct 2025 10:37:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96visual=5Fblock=5Fstate?= =?UTF-8?q?=E7=9A=84=E7=BC=96=E8=A7=A3=E7=A0=81=E5=99=A8=E4=BB=A5=E8=8A=82?= =?UTF-8?q?=E7=BA=A6=E5=B8=A6=E5=AE=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../protocol/VisualBlockStatePacket.java | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/VisualBlockStatePacket.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/VisualBlockStatePacket.java index 42a626a9e..bed116f3e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/VisualBlockStatePacket.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/VisualBlockStatePacket.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.network.payload.protocol; +import io.netty.handler.codec.DecoderException; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.core.block.ImmutableBlockState; @@ -19,13 +20,75 @@ public record VisualBlockStatePacket(int[] data) implements ModPacket { VisualBlockStatePacket::encode, VisualBlockStatePacket::new ); + private static final int RLE_THRESHOLD = 3; + private static final int RLE_TAG = 0; + private static final int DELTA_TAG = 1; private VisualBlockStatePacket(FriendlyByteBuf buf) { - this(buf.readVarIntArray()); + this(decode(buf)); } private void encode(FriendlyByteBuf buf) { - buf.writeVarIntArray(this.data); + encode(buf, this.data); + } + + private static void encode(FriendlyByteBuf buf, int[] data) { + if (data.length == 0) { + buf.writeVarInt(0); + return; + } + buf.writeVarInt(data.length); + int i = 0; + int previousValue = 0; + while (i < data.length) { + int currentValue = data[i]; + int repeatCount = 1; + int j = i + 1; + while (j < data.length && data[j] == currentValue) { + repeatCount++; + j++; + } + if (repeatCount >= RLE_THRESHOLD) { + buf.writeVarInt(RLE_TAG); + buf.writeVarInt(currentValue); + buf.writeVarInt(repeatCount); + i += repeatCount; + previousValue = currentValue; + } else { + buf.writeVarInt(DELTA_TAG); + int delta = currentValue - previousValue; + buf.writeVarInt(delta); + previousValue = currentValue; + i++; + } + } + } + + private static int[] decode(FriendlyByteBuf buf) { + int length = buf.readVarInt(); + if (length == 0) return new int[0]; + int[] data = new int[length]; + int previousValue = 0; + int i = 0; + while (i < length) { + int tag = buf.readVarInt(); + if (tag == RLE_TAG) { + int value = buf.readVarInt(); + int count = buf.readVarInt(); + if (i + count > length) throw new DecoderException("RLE count exceeds array bounds"); + for (int j = 0; j < count; j++) data[i++] = value; + previousValue = value; + } else if (tag == DELTA_TAG) { + int delta = buf.readVarInt(); + int currentValue = previousValue + delta; + data[i++] = currentValue; + previousValue = currentValue; + } else { + throw new DecoderException("Unknown encoding tag: " + tag); + } + } + if (i != length) throw new DecoderException("Decoded length mismatch"); + return data; } @Override