diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java index 45981377c0c..6df7781bedc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.session.GeyserSession; @@ -40,9 +41,13 @@ protected BlockEntityTranslator() { public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState); - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); - translateTag(session, tagBuilder, javaNbt, blockState); + if (javaNbt != null || this instanceof RequiresBlockState) { + // Always process tags if the block state is part of the tag. + // See: banner base colors. + translateTag(session, tagBuilder, javaNbt, blockState); + } return tagBuilder.build(); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java index 05b763e6b21..edf71d3841c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SpawnerBlockEntityTranslator.java @@ -40,7 +40,10 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Fixes https://github.com/GeyserMC/Geyser/issues/4214 NbtMap spawnData = javaNbt.getCompound("SpawnData"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java index aefd97dd5e7..4bb9c5676f6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/StructureBlockBlockEntityTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.level.block.entity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -39,7 +40,10 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { @Override - public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) { + public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) { + if (javaNbt == null) { + return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState); + } // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ int xStructureSize = javaNbt.getInt("sizeX"); int yStructureSize = javaNbt.getInt("sizeY"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java index c3a39986392..29db95e3f58 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaLevelChunkWithLightTranslator.java @@ -412,13 +412,10 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke continue; } - if (tag != null) { - BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(type); - bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(session, type, x + chunkBlockX, y, z + chunkBlockZ, tag, blockState)); - } else { - // Since 1.20.5, tags can be null, but Bedrock still needs a default tag to render the item - bedrockBlockEntities.add(BlockEntityTranslator.getConstantBedrockTag(type, x + chunkBlockX, y, z + chunkBlockZ).build()); - } + // Note that, since 1.20.5, tags can be null, but Bedrock still needs a default tag to render the item + // Also, some properties - like banner base colors - are part of the tag and is processed here. + BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(type); + bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(session, type, x + chunkBlockX, y, z + chunkBlockZ, tag, blockState)); // Check for custom skulls if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.containsKey("profile")) {