diff --git a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java index 3d43b066b..48d0e80e0 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/BlockStateValues.java @@ -38,6 +38,8 @@ import org.geysermc.geyser.util.collection.FixedInt2ByteMap; import org.geysermc.geyser.util.collection.FixedInt2IntMap; import org.geysermc.geyser.util.collection.LecternHasBookMap; +import java.util.Locale; + /** * Used for block entities if the Java block state contains Bedrock block information. */ @@ -47,6 +49,7 @@ public final class BlockStateValues { private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap(); private static final Int2ObjectMap DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); + private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet(); private static final LecternHasBookMap LECTERN_BOOK_STATES = new LecternHasBookMap(); private static final Int2IntMap NOTEBLOCK_PITCHES = new FixedInt2IntMap(); private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap(); @@ -170,12 +173,22 @@ public final class BlockStateValues { JsonNode shulkerDirection = blockData.get("shulker_direction"); if (shulkerDirection != null) { BlockStateValues.SHULKERBOX_DIRECTIONS.put(javaBlockState, (byte) shulkerDirection.intValue()); + return; } if (javaId.startsWith("minecraft:water")) { String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1); int level = Integer.parseInt(strLevel); WATER_LEVEL.put(javaBlockState, level); + return; + } + + if (javaId.startsWith("minecraft:jigsaw[orientation=")) { + String blockStateData = javaId.substring(javaId.indexOf("orientation=") + "orientation=".length(), javaId.lastIndexOf('_')); + Direction direction = Direction.valueOf(blockStateData.toUpperCase(Locale.ROOT)); + if (direction.isHorizontal()) { + HORIZONTAL_FACING_JIGSAWS.add(javaBlockState); + } } } @@ -230,6 +243,13 @@ public final class BlockStateValues { return FLOWER_POT_VALUES; } + /** + * @return a set of all forward-facing jigsaws, to use as a fallback if NBT is missing. + */ + public static IntSet getHorizontalFacingJigsaws() { + return HORIZONTAL_FACING_JIGSAWS; + } + /** * @return the lectern book state map pointing to book present state */ diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java index a1e990138..bb036a1b0 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/JigsawBlockBlockEntityTranslator.java @@ -28,16 +28,25 @@ package org.geysermc.geyser.translator.level.block.entity; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.nbt.NbtMapBuilder; +import org.geysermc.geyser.level.block.BlockStateValues; @BlockEntity(type = BlockEntityType.JIGSAW) -public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator { +public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - builder.put("joint", ((StringTag) tag.get("joint")).getValue()); - builder.put("name", ((StringTag) tag.get("name")).getValue()); - builder.put("target_pool", ((StringTag) tag.get("pool")).getValue()); + Tag jointTag = tag.get("joint"); + if (jointTag instanceof StringTag) { + builder.put("joint", ((StringTag) jointTag).getValue()); + } else { + // Tag is not present in at least 1.14.4 Paper + // Minecraft 1.18.1 deliberately has a fallback here, but not for any other value + builder.put("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); + } + builder.put("name", getOrDefault(tag.get("name"), "")); + builder.put("target_pool", getOrDefault(tag.get("pool"), "")); builder.put("final_state", ((StringTag) tag.get("final_state")).getValue()); - builder.put("target", ((StringTag) tag.get("target")).getValue()); + builder.put("target", getOrDefault(tag.get("target"), "")); } }