From 1db45877981f43fda4b004d2059b48f5b7fae397 Mon Sep 17 00:00:00 2001 From: MrJoshuaT Date: Sat, 10 Jan 2026 22:38:29 +0000 Subject: [PATCH] Fix: 1.21.9 and 1.21.11 adapters throw invalid bit count when calling "unpack" --- .../v1_21_11/PaperweightPlatformAdapter.java | 47 +++++++++---------- .../v1_21_9/PaperweightPlatformAdapter.java | 47 +++++++++---------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java index 52be60c424..6d89402ef7 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java @@ -40,7 +40,6 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; @@ -449,35 +448,35 @@ public static LevelChunkSection newChunkSection( bitArray.fromRaw(blocksCopy); } - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); + // Create empty container and populate it manually + // This avoids unpack() validation issues with global palettes + PalettedContainerFactory factory = PalettedContainerFactory.create(registryAccess); + final PalettedContainer blockStatePalettedContainer = + factory.createForBlockStates(); + + // Populate the container by setting each block position + for (int i = 0; i < 4096; i++) { + int x = i & 15; + int y = i >> 8; + int z = (i >> 4) & 15; + + char ordinal = set[i]; + ordinal = (char) Math.max(ordinal, BlockTypesCache.ReservedIDs.AIR); + final BlockState state = BlockTypesCache.states[ordinal]; + net.minecraft.world.level.block.state.BlockState nmsState = + ((PaperweightBlockMaterial) state.getMaterial()).getState(); + + blockStatePalettedContainer.set(x, y, z, nmsState); } - // Create palette with data - var strategy = Strategy.createForBlockStates(Block.BLOCK_STATE_REGISTRY); - var packedData = new PalettedContainerRO.PackedData<>(palette, Optional.of(LongStream.of(bits)), bitsPerEntry); - DataResult> result; - if (PaperLib.isPaper()) { - result = PalettedContainer.unpack(strategy, packedData, Blocks.AIR.defaultBlockState(), null); - } else { - //noinspection unchecked - result = (DataResult>) - palettedContainerUnpackSpigot.invokeExact(strategy, packedData); + for (int i = 0; i < num_palette; i++) { + blockToPalette[paletteToBlock[i]] = Integer.MAX_VALUE; } + if (biomes == null) { biomes = PalettedContainerFactory.create(registryAccess).createForBiomes(); } - return new LevelChunkSection(result.getOrThrow(), biomes); + return new LevelChunkSection(blockStatePalettedContainer, biomes); } catch (Throwable e) { throw new RuntimeException("Failed to create block palette", e); } finally { diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java index 5da8b3cec5..7a4264e34d 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java @@ -41,7 +41,6 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; @@ -460,35 +459,35 @@ public static LevelChunkSection newChunkSection( bitArray.fromRaw(blocksCopy); } - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); + // Create empty container and populate it manually + // This avoids unpack() validation issues with global palettes + PalettedContainerFactory factory = PalettedContainerFactory.create(registryAccess); + final PalettedContainer blockStatePalettedContainer = + factory.createForBlockStates(); + + // Populate the container by setting each block position + for (int i = 0; i < 4096; i++) { + int x = i & 15; + int y = i >> 8; + int z = (i >> 4) & 15; + + char ordinal = set[i]; + ordinal = (char) Math.max(ordinal, BlockTypesCache.ReservedIDs.AIR); + final BlockState state = BlockTypesCache.states[ordinal]; + net.minecraft.world.level.block.state.BlockState nmsState = + ((PaperweightBlockMaterial) state.getMaterial()).getState(); + + blockStatePalettedContainer.set(x, y, z, nmsState); } - // Create palette with data - var strategy = Strategy.createForBlockStates(Block.BLOCK_STATE_REGISTRY); - var packedData = new PalettedContainerRO.PackedData<>(palette, Optional.of(LongStream.of(bits)), bitsPerEntry); - DataResult> result; - if (PaperLib.isPaper()) { - result = PalettedContainer.unpack(strategy, packedData, Blocks.AIR.defaultBlockState(), null); - } else { - //noinspection unchecked - result = (DataResult>) - palettedContainerUnpackSpigot.invokeExact(strategy, packedData); + for (int i = 0; i < num_palette; i++) { + blockToPalette[paletteToBlock[i]] = Integer.MAX_VALUE; } + if (biomes == null) { biomes = PalettedContainerFactory.create(registryAccess).createForBiomes(); } - return new LevelChunkSection(result.getOrThrow(), biomes); + return new LevelChunkSection(blockStatePalettedContainer, biomes); } catch (Throwable e) { throw new RuntimeException("Failed to create block palette", e); } finally {