diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/ShulkerInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/ShulkerInventoryTranslator.java index 4f28d0e4e..7dafb862a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/ShulkerInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/ShulkerInventoryTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.connector.network.translators.inventory.translators; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMapBuilder; @@ -42,7 +43,7 @@ import org.geysermc.connector.registry.Registries; public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator { public ShulkerInventoryTranslator() { super(27, new BlockInventoryHolder("minecraft:shulker_box[facing=north]", ContainerType.CONTAINER) { - private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get("ShulkerBox"); + private final BlockEntityTranslator shulkerBoxTranslator = Registries.BLOCK_ENTITIES.get(BlockEntityType.SHULKER_BOX); @Override protected boolean isValidBlock(String[] javaBlockString) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaBlockEntityDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaBlockEntityDataTranslator.java index 95f70f3c9..8f33742c6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaBlockEntityDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaBlockEntityDataTranslator.java @@ -30,7 +30,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import org.geysermc.connector.network.session.GeyserSession; @@ -47,13 +46,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator= 2 && - session.getGameMode() == GameMode.CREATIVE && packet.getNbt().size() > 5) { + session.getGameMode() == GameMode.CREATIVE && packet.getNbt() != null && packet.getNbt().size() > 5) { ContainerOpenPacket openPacket = new ContainerOpenPacket(); openPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); openPacket.setId((byte) 1); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaLevelChunkWithLightTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaLevelChunkWithLightTranslator.java index 3ac2e5646..69950be97 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaLevelChunkWithLightTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/level/JavaLevelChunkWithLightTranslator.java @@ -31,10 +31,9 @@ import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket; 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.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.stream.StreamNetInput; import com.nukkitx.math.vector.Vector3i; @@ -48,7 +47,6 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -227,41 +225,16 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator> 4) - yOffset]; + DataPalette section = javaChunks[(y >> 4) - yOffset]; int blockState = section.get(x & 0xF, y & 0xF, z & 0xF); - if (tagName.equals("minecraft:lectern") && BlockStateValues.getLecternBookStates().get(blockState)) { + if (type == BlockEntityType.LECTERN && BlockStateValues.getLecternBookStates().get(blockState)) { // If getLecternBookStates is false, let's just treat it like a normal block entity bedrockBlockEntities[blockEntityCount] = session.getConnector().getWorldManager().getLecternDataAt( session, blockEntity.getX(), blockEntity.getY(), blockEntity.getZ(), true); @@ -269,8 +242,8 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.world.block.entity.BlockEntity", BlockEntityRegistryLoader::new); + public static final SimpleMappedRegistry BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.world.block.entity.BlockEntity", BlockEntityRegistryLoader::new); /** * A mapped registry containing which holds block IDs to its {@link BlockCollision}. diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java index a58cca7ca..5e9d156a1 100644 --- a/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java +++ b/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java @@ -25,14 +25,38 @@ package org.geysermc.connector.registry.loader; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.connector.network.translators.world.block.entity.BlockEntity; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.world.block.entity.EmptyBlockEntityTranslator; +import org.geysermc.connector.utils.FileUtils; + +import java.lang.reflect.InvocationTargetException; +import java.util.Map; /** * Loads block entities from the given classpath. */ -public class BlockEntityRegistryLoader extends AnnotatedRegistryLoader { - public BlockEntityRegistryLoader() { - super(BlockEntity.class, BlockEntity::name); +public class BlockEntityRegistryLoader implements RegistryLoader> { + + @Override + public Map load(String input) { + // Overridden so one translator can be applied to multiple block entity types + Object2ObjectMap entries = new Object2ObjectOpenHashMap<>(); + entries.defaultReturnValue(new EmptyBlockEntityTranslator()); + for (Class clazz : FileUtils.getGeneratedClassesForAnnotation(input)) { + try { + BlockEntity annotation = clazz.getAnnotation(BlockEntity.class); + BlockEntityTranslator translator = (BlockEntityTranslator) clazz.getConstructor().newInstance(); + for (BlockEntityType type : annotation.type()) { + entries.put(type, translator); + } + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) { + ex.printStackTrace(); + } + } + return entries; } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java index 500c0d723..38ffa80f5 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -26,6 +26,7 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; @@ -50,41 +51,33 @@ public class BlockEntityUtils { /** * Contains a list of irregular block entity name translations that can't be fit into the regex */ - public static final Map BLOCK_ENTITY_TRANSLATIONS = new HashMap() { + public static final Map BLOCK_ENTITY_TRANSLATIONS = new HashMap<>() { { // Bedrock/Java differences - put("minecraft:enchanting_table", "EnchantTable"); - put("minecraft:jigsaw", "JigsawBlock"); - put("minecraft:piston_head", "PistonArm"); - put("minecraft:trapped_chest", "Chest"); + put(BlockEntityType.ENCHANTING_TABLE, "EnchantTable"); + put(BlockEntityType.JIGSAW, "JigsawBlock"); + put(BlockEntityType.PISTON, "PistonArm"); + put(BlockEntityType.TRAPPED_CHEST, "Chest"); // There are some legacy IDs sent but as far as I can tell they are not needed for things to work properly } }; - private static final BlockEntityTranslator EMPTY_TRANSLATOR = Registries.BLOCK_ENTITIES.get("Empty"); - static { // Seeing as there are only two - and, hopefully, will only ever be two - we can hardcode this - BEDROCK_ONLY_BLOCK_ENTITIES.add((BedrockOnlyBlockEntity) Registries.BLOCK_ENTITIES.get().get("Chest")); + BEDROCK_ONLY_BLOCK_ENTITIES.add((BedrockOnlyBlockEntity) Registries.BLOCK_ENTITIES.get().get(BlockEntityType.CHEST)); BEDROCK_ONLY_BLOCK_ENTITIES.add(new FlowerPotBlockEntityTranslator()); } - public static String getBedrockBlockEntityId(String id) { + public static String getBedrockBlockEntityId(BlockEntityType type) { // These are the only exceptions when it comes to block entity ids - String value = BLOCK_ENTITY_TRANSLATIONS.get(id); + String value = BLOCK_ENTITY_TRANSLATIONS.get(type); if (value != null) { return value; } - id = id.replace("minecraft:", "") - .replace("_", " "); + String id = type.name(); // Split at every space or capital letter - for the latter, some legacy Java block entity tags are the correct format already - String[] words; - if (!id.toUpperCase().equals(id)) { // Otherwise we get [S, K, U, L, L] - words = id.split("(?=[A-Z])| "); // Split at every space or note or before every capital letter - } else { - words = id.split(" "); - } + String[] words = id.split("_");; for (int i = 0; i < words.length; i++) { words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase(); } @@ -92,12 +85,8 @@ public class BlockEntityUtils { return String.join("", words); } - public static BlockEntityTranslator getBlockEntityTranslator(String name) { - BlockEntityTranslator blockEntityTranslator = Registries.BLOCK_ENTITIES.get(name); - if (blockEntityTranslator != null) { - return blockEntityTranslator; - } - return EMPTY_TRANSLATOR; + public static BlockEntityTranslator getBlockEntityTranslator(BlockEntityType type) { + return Registries.BLOCK_ENTITIES.get(type); } public static void updateBlockEntity(GeyserSession session, @Nonnull NbtMap blockEntity, Position position) {