From aca6cd42f3fca3d57946627237892d6c73728fba Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Tue, 31 Oct 2023 23:39:27 -0700 Subject: [PATCH] Final touches Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../geyser/level/block/BlockStateValues.java | 20 +++++++++++ .../entity/CauldronBlockEntityTranslator.java | 22 +++---------- .../DoubleChestBlockEntityTranslator.java | 2 +- .../FlowerPotBlockEntityTranslator.java | 33 +++---------------- .../entity/PistonBlockEntityTranslator.java | 18 +++++++--- .../entity/SignBlockEntityTranslator.java | 4 +++ ...java => SimpleBedrockOnlyBlockEntity.java} | 2 +- .../level/JavaBlockEntityDataTranslator.java | 1 + .../JavaLevelChunkWithLightTranslator.java | 2 +- .../org/geysermc/geyser/util/ChunkUtils.java | 10 +++--- core/src/main/resources/mappings | 2 +- 11 files changed, 57 insertions(+), 59 deletions(-) rename core/src/main/java/org/geysermc/geyser/translator/level/block/entity/{BedrockOnlyBlockEntity.java => SimpleBedrockOnlyBlockEntity.java} (95%) 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 9ba48b895db..97d35d929b3 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 @@ -58,7 +58,9 @@ public final class BlockStateValues { private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap(); private static final IntSet STICKY_PISTONS = new IntOpenHashSet(); private static final Object2IntMap PISTON_HEADS = new Object2IntOpenHashMap<>(); + private static final Object2IntMap ALL_STICKY_PISTON_HEADS = new Object2IntOpenHashMap<>(); private static final Int2ObjectMap PISTON_ORIENTATION = new Int2ObjectOpenHashMap<>(); + private static final Int2ObjectMap PISTON_HEAD_ORIENTATION = new Int2ObjectOpenHashMap<>(); private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet(); private static final IntSet MOVING_PISTONS = new IntOpenHashSet(); private static final Int2ByteMap SKULL_VARIANTS = new FixedInt2ByteMap(); @@ -156,6 +158,10 @@ public static void storeBlockStateValues(String javaId, int javaBlockState, Json return; } else if (javaId.startsWith("minecraft:piston_head")) { ALL_PISTON_HEADS.add(javaBlockState); + PISTON_HEAD_ORIENTATION.put(javaBlockState, getBlockDirection(javaId)); + if (javaId.contains("sticky")) { + ALL_STICKY_PISTON_HEADS.put(getBlockDirection(javaId), javaBlockState); + } if (javaId.contains("short=false")) { PISTON_HEADS.put(getBlockDirection(javaId), javaBlockState); } @@ -335,6 +341,10 @@ public static boolean isPistonHead(int state) { return ALL_PISTON_HEADS.contains(state); } + public static boolean isStickyPistonHead(int state) { + return ALL_STICKY_PISTON_HEADS.containsValue(state); + } + /** * Get the Java Block State for a piston head for a specific direction * This is used in PistonBlockEntity to get the BlockCollision for the piston head. @@ -369,6 +379,16 @@ public static Direction getPistonOrientation(int state) { return PISTON_ORIENTATION.get(state); } + /** + * This is used in PistonBlockEntityTranslator.java and accepts minecraft:piston_head + * + * @param state The block state of the piston head + * @return The direction in which the piston head faces + */ + public static Direction getPistonHeadOrientation(int state) { + return PISTON_HEAD_ORIENTATION.get(state); + } + /** * Checks if a block sticks to other blocks * (Slime and honey blocks) diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CauldronBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CauldronBlockEntityTranslator.java index 95a159f2fd0..880fb8a0d53 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CauldronBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/CauldronBlockEntityTranslator.java @@ -3,31 +3,19 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtList; -import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtType; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.util.BlockEntityUtils; @BlockEntity(type = "Cauldron") -public class CauldronBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity { +public class CauldronBlockEntityTranslator extends BlockEntityTranslator implements SimpleBedrockOnlyBlockEntity { @Override public void updateBlock(GeyserSession session, int blockState, Vector3i position) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateBlock'"); - } - - public static NbtMap getTag(Vector3i position) { - return NbtMap.builder() - .putString("id", "Cauldron") - .putByte("isMovable", (byte) 0) - .putShort("PotionId", (short) -1) - .putShort("PotionType", (short) -1) - .putList("Items", NbtType.END, NbtList.EMPTY) - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) - .build(); + NbtMapBuilder builder = getConstantBedrockTag("Cauldron", position.getX(), position.getY(), position.getZ()); + translateTag(session, builder, null, blockState); + BlockEntityUtils.updateBlockEntity(session, builder.build(), position); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java index dc3e95e7fff..41e614b55f7 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/DoubleChestBlockEntityTranslator.java @@ -38,7 +38,7 @@ * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity */ @BlockEntity(type = "Chest") -public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity { +public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements SimpleBedrockOnlyBlockEntity { @Override public void updateBlock(GeyserSession session, int blockState, Vector3i position) { NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java index bbf72c321fb..9eb26edc05a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/FlowerPotBlockEntityTranslator.java @@ -35,37 +35,12 @@ import org.geysermc.geyser.util.BlockEntityUtils; @BlockEntity(type = "FlowerPot") -public class FlowerPotBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity { - /** - * Get the Nukkit CompoundTag of the flower pot. - * - * @param blockState Java block state of flower pot. - * @param position Bedrock position of flower pot. - * @return Bedrock tag of flower pot. - */ - public static NbtMap getTag(GeyserSession session, int blockState, Vector3i position) { - NbtMapBuilder builder = NbtMap.builder() - .putInt("x", position.getX()) - .putInt("y", position.getY()) - .putInt("z", position.getZ()) - .putByte("isMovable", (byte) 1) - .putString("id", "FlowerPot"); - // Get the Java name of the plant inside. e.g. minecraft:oak_sapling - String name = BlockStateValues.getFlowerPotValues().get(blockState); - if (name != null) { - // Get the Bedrock CompoundTag of the block. - // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. - NbtMap plant = session.getBlockMappings().getFlowerPotBlocks().get(name); - if (plant != null) { - builder.put("PlantBlock", plant.toBuilder().build()); - } - } - return builder.build(); - } - +public class FlowerPotBlockEntityTranslator extends BlockEntityTranslator implements SimpleBedrockOnlyBlockEntity { @Override public void updateBlock(GeyserSession session, int blockState, Vector3i position) { - NbtMap tag = getTag(session, blockState, position); + NbtMapBuilder builder = getConstantBedrockTag("FlowerPot", position.getX(), position.getY(), position.getZ()); + translateTag(session, builder, null, blockState); + NbtMap tag = builder.build(); BlockEntityUtils.updateBlockEntity(session, tag, position); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java index 14fa804f138..2014879b138 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/PistonBlockEntityTranslator.java @@ -30,13 +30,14 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.geysermc.geyser.level.block.BlockStateValues; +import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.session.GeyserSession; /** * Pistons are a special case where they are only a block entity on Bedrock. */ @BlockEntity(type = "PistonArm") -public class PistonBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity { +public class PistonBlockEntityTranslator extends BlockEntityTranslator { /** * Used in ChunkUtils to determine if the block is a piston. * @@ -61,12 +62,21 @@ public static NbtMap getTag(int blockState, Vector3i position) { } @Override - public void updateBlock(GeyserSession session, int blockState, Vector3i position) { - + public NbtMap getBlockEntityTag(GeyserSession session, String type, int x, int y, int z, CompoundTag tag, int blockState) { + Direction direction = BlockStateValues.getPistonHeadOrientation(blockState); + Vector3i position = Vector3i.from(x, y, z).sub(direction.getUnitVector()); // Piston arm is one block away from the head + NbtMapBuilder tagBuilder = getConstantBedrockTag(type, position.getX(), position.getY(), position.getZ()); + translateTag(session, tagBuilder, tag, blockState); + return tagBuilder.build(); } @Override public void translateTag(GeyserSession session, NbtMapBuilder builder, CompoundTag tag, int blockState) { - + builder.putBoolean("Sticky", BlockStateValues.isStickyPistonHead(blockState)) + .putFloat("Progress", 1.0f) // We wouldn't be here if this wasn't extended + .putFloat("LastProgress", 1.0f) + .putByte("NewState", (byte) 2) + .putByte("State", (byte) 2) + .putBoolean("isMovable", false); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java index f30fdb688b6..851382a388b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SignBlockEntityTranslator.java @@ -73,6 +73,10 @@ public int signWidthMax() { @Override public void translateTag(GeyserSession session, NbtMapBuilder builder, CompoundTag tag, int blockState) { + if (tag == null) { + return; + } + builder.putCompound("FrontText", translateSide(tag.get("front_text"))); builder.putCompound("BackText", translateSide(tag.get("back_text"))); var waxed = tag.get("is_waxed"); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SimpleBedrockOnlyBlockEntity.java similarity index 95% rename from core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java rename to core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SimpleBedrockOnlyBlockEntity.java index d3bb7f2acb1..4ee749a7a0f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/BedrockOnlyBlockEntity.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/block/entity/SimpleBedrockOnlyBlockEntity.java @@ -31,7 +31,7 @@ /** * Implemented only if a block is a block entity in Bedrock and not Java Edition. */ -public interface BedrockOnlyBlockEntity extends RequiresBlockState { +public interface SimpleBedrockOnlyBlockEntity extends RequiresBlockState { /** * Update the block on Bedrock Edition. * @param session GeyserConnection. diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java index 8233c1297e1..857fc781128 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaBlockEntityDataTranslator.java @@ -52,6 +52,7 @@ public void translate(GeyserSession session, ClientboundBlockEntityDataPacket pa return; } + // Only translate block entities that are supported by bedrock String bedrockType = BlockEntityUtils.getBedrockBlockEntityId(type); if (bedrockType == null) { 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 605d94f41b5..3c2cb084429 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 @@ -273,7 +273,7 @@ public void translate(GeyserSession session, ClientboundLevelChunkWithLightPacke } } - if (BlockRegistries.JAVA_BLOCKS.getOrDefault(javaId, BlockMapping.DEFAULT).isJavaBlockEntity()) { + if (BlockRegistries.JAVA_BLOCKS.getOrDefault(javaId, BlockMapping.DEFAULT).isBedrockBlockEntity()) { blockEntityPaletteIds.set(i); } } diff --git a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java index 4377b9eba9d..918d8bf8bc2 100644 --- a/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/ChunkUtils.java @@ -48,7 +48,7 @@ import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity; +import org.geysermc.geyser.translator.level.block.entity.SimpleBedrockOnlyBlockEntity; import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator; import static org.geysermc.geyser.level.block.BlockStateValues.JAVA_AIR_ID; @@ -193,12 +193,12 @@ public static void updateBlockClientSide(GeyserSession session, int blockState, BlockStateValues.getLecternBookStates().handleBlockChange(session, blockState, position); - if (BlockRegistries.JAVA_BLOCKS.getOrDefault(blockState, BlockMapping.DEFAULT).isBedrockBlockEntity()) { + if (BlockRegistries.JAVA_BLOCKS.getOrDefault(blockState, BlockMapping.DEFAULT).isBedrockOnlyBlockEntity()) { String blockEntity = BlockRegistries.JAVA_BLOCKS.getOrDefault(blockState, BlockMapping.DEFAULT).getBedrockBlockEntity(); - BedrockOnlyBlockEntity blockEntityTranslator = (BedrockOnlyBlockEntity) BlockEntityUtils.getBlockEntityTranslator(blockEntity); - if (blockEntityTranslator != null) { - blockEntityTranslator.updateBlock(session, blockState, position); + BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(blockEntity); + if (blockEntityTranslator instanceof SimpleBedrockOnlyBlockEntity) { + ((SimpleBedrockOnlyBlockEntity) blockEntityTranslator).updateBlock(session, blockState, position); } } } diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings index c0844e6bb6c..ed859d79fce 160000 --- a/core/src/main/resources/mappings +++ b/core/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit c0844e6bb6cc77f7178f86a185677a31643af827 +Subproject commit ed859d79fcef212a4c074dac1f11f7e36247c777