Update to new block entity changes

This commit is contained in:
Camotoy 2021-11-14 12:06:07 -05:00
parent 4bbea1de68
commit 15f26999dd
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
23 changed files with 117 additions and 121 deletions

View file

@ -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) {

View file

@ -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<ClientboundB
@Override
public void translate(GeyserSession session, ClientboundBlockEntityDataPacket packet) {
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
if (packet.getNbt().isEmpty()) { // Fixes errors in servers sending empty NBT
BlockEntityUtils.updateBlockEntity(session, NbtMap.EMPTY, packet.getPosition());
return;
}
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id);
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(packet.getType());
// The Java block state is used in BlockEntityTranslator.translateTag() to make up for some inconsistencies
// between Java block states and Bedrock block entity data
int blockState;
@ -62,17 +55,19 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
} else {
blockState = BlockStateValues.JAVA_AIR_ID;
}
Position position = packet.getPosition();
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, position.getX(), position.getY(), position.getZ(),
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getType(), position.getX(), position.getY(), position.getZ(),
packet.getNbt(), blockState), packet.getPosition());
// Check for custom skulls.
if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt().contains("SkullOwner")) {
if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt() != null && packet.getNbt().contains("SkullOwner")) {
SkullBlockEntityTranslator.spawnPlayer(session, packet.getNbt(), blockState);
}
// If block entity is command block, OP permission level is appropriate, player is in creative mode and the NBT is not empty
// TODO 1.18 re-test
if (packet.getType() == BlockEntityType.COMMAND_BLOCK && session.getOpPermissionLevel() >= 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);

View file

@ -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<Clientbo
while (blockEntityCount < blockEntities.length) {
BlockEntityInfo blockEntity = blockEntities[blockEntityCount];
CompoundTag tag = blockEntity.getNbt();
// TODO use the actual name
String tagName;
if (tag != null) {
Tag idTag = tag.get("id");
if (idTag != null) {
tagName = (String) idTag.getValue();
} else {
tagName = "Empty";
// Sometimes legacy tags have their ID be a StringTag with empty value
for (Tag subTag : tag) {
if (subTag instanceof StringTag stringTag) {
if (stringTag.getValue().isEmpty()) {
tagName = stringTag.getName();
break;
}
}
}
if (tagName.equals("Empty")) {
GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue());
}
}
} else {
tagName = "Empty";
}
String id = BlockEntityUtils.getBedrockBlockEntityId(tagName);
BlockEntityType type = blockEntity.getType();
int x = blockEntity.getX();
int y = blockEntity.getY();
int z = blockEntity.getZ();
// Get the Java block state ID from block entity position
DataPalette section = javaChunks[(blockEntity.getY() >> 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<Clientbo
continue;
}
BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id);
bedrockBlockEntities[blockEntityCount] = blockEntityTranslator.getBlockEntityTag(tagName, x, y, z, tag, blockState);
BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(type);
bedrockBlockEntities[blockEntityCount] = blockEntityTranslator.getBlockEntityTag(type, x, y, z, tag, blockState);
// Check for custom skulls
if (session.getPreferencesCache().showCustomSkulls() && tag != null && tag.contains("SkullOwner")) {

View file

@ -40,7 +40,7 @@ import org.geysermc.connector.utils.collections.LecternHasBookMap;
/**
* Used for block entities if the Java block state contains Bedrock block information.
*/
public class BlockStateValues {
public final class BlockStateValues {
private static final Int2IntMap BANNER_COLORS = new FixedInt2IntMap();
private static final Int2ByteMap BED_COLORS = new FixedInt2ByteMap();
private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap();
@ -422,4 +422,7 @@ public class BlockStateValues {
}
throw new IllegalStateException();
}
private BlockStateValues() {
}
}

View file

@ -25,27 +25,21 @@
package org.geysermc.connector.network.translators.world.block;
import lombok.AllArgsConstructor;
/**
* This stores all values of double chests that are part of the Java block state.
*/
@AllArgsConstructor
public class DoubleChestValue {
/**
* If true, then chest is facing east/west; if false, south/north
*/
public boolean isFacingEast;
/**
* If true, direction is positive (east/south); if false, direction is negative (west/north)
*/
public boolean isDirectionPositive;
/**
* If true, chest is the left of a pair; if false, chest is the right of a pair.
*/
public boolean isLeft;
public record DoubleChestValue(
/**
* If true, then chest is facing east/west; if false, south/north
*/
boolean isFacingEast,
/**
* If true, direction is positive (east/south); if false, direction is negative (west/north)
*/
boolean isDirectionPositive,
/**
* If true, chest is the left of a pair; if false, chest is the right of a pair.
*/
boolean isLeft) {
}

View file

@ -25,13 +25,14 @@
package org.geysermc.connector.network.translators.world.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.ListTag;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.item.translators.BannerTranslator;
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
@BlockEntity(name = "Banner")
@BlockEntity(type = BlockEntityType.BANNER)
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,10 +25,11 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.nbt.NbtMapBuilder;
@BlockEntity(name = "Beacon")
@BlockEntity(type = BlockEntityType.BEACON)
public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,11 +25,12 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
@BlockEntity(name = "Bed")
@BlockEntity(type = BlockEntityType.BED)
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,6 +25,8 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -32,8 +34,8 @@ import java.lang.annotation.RetentionPolicy;
public @interface BlockEntity {
/**
* The block entity name
* @return the name of the block entity
* The Java block entity type
* @return the type of the block entity
*/
String name();
BlockEntityType[] type();
}

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.world.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.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -42,8 +43,8 @@ public abstract class BlockEntityTranslator {
public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState);
public NbtMap getBlockEntityTag(String id, int x, int y, int z, CompoundTag tag, int blockState) {
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(id), x, y, z);
public NbtMap getBlockEntityTag(BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) {
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(type), x, y, z);
translateTag(tagBuilder, tag, blockState);
return tagBuilder.build();
}

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.world.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.ListTag;
import com.nukkitx.nbt.NbtMap;
@ -33,7 +34,7 @@ import org.geysermc.connector.network.MinecraftProtocol;
import org.geysermc.connector.registry.Registries;
import org.geysermc.connector.registry.type.ItemMapping;
@BlockEntity(name = "Campfire")
@BlockEntity(type = BlockEntityType.CAMPFIRE)
public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,12 +25,13 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import org.geysermc.connector.network.translators.chat.MessageTranslator;
@BlockEntity(name = "CommandBlock")
@BlockEntity(type = BlockEntityType.COMMAND_BLOCK)
public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMapBuilder;
@ -36,7 +37,7 @@ import org.geysermc.connector.utils.BlockEntityUtils;
/**
* Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity
*/
@BlockEntity(name = "Chest")
@BlockEntity(type = { BlockEntityType.CHEST, BlockEntityType.TRAPPED_CHEST })
public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity {
@Override
public boolean isBlock(int blockState) {
@ -46,7 +47,7 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
@Override
public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
CompoundTag javaTag = getConstantJavaTag("chest", position.getX(), position.getY(), position.getZ());
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId("chest"), position.getX(), position.getY(), position.getZ());
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ());
translateTag(tagBuilder, javaTag, blockState);
BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position);
}
@ -71,26 +72,26 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
*/
public static void translateChestValue(NbtMapBuilder builder, DoubleChestValue chestValues, int x, int z) {
// Calculate the position of the other chest based on the Java block state
if (chestValues.isFacingEast) {
if (chestValues.isDirectionPositive) {
if (chestValues.isFacingEast()) {
if (chestValues.isDirectionPositive()) {
// East
z = z + (chestValues.isLeft ? 1 : -1);
z = z + (chestValues.isLeft() ? 1 : -1);
} else {
// West
z = z + (chestValues.isLeft ? -1 : 1);
z = z + (chestValues.isLeft() ? -1 : 1);
}
} else {
if (chestValues.isDirectionPositive) {
if (chestValues.isDirectionPositive()) {
// South
x = x + (chestValues.isLeft ? -1 : 1);
x = x + (chestValues.isLeft() ? -1 : 1);
} else {
// North
x = x + (chestValues.isLeft ? 1 : -1);
x = x + (chestValues.isLeft() ? 1 : -1);
}
}
builder.put("pairx", x);
builder.put("pairz", z);
if (!chestValues.isLeft) {
if (!chestValues.isLeft()) {
builder.put("pairlead", (byte) 1);
}
}

View file

@ -28,7 +28,6 @@ package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.nbt.NbtMapBuilder;
@BlockEntity(name = "Empty")
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators.world.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.IntTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
@ -37,7 +38,7 @@ import it.unimi.dsi.fastutil.ints.IntList;
import java.util.LinkedHashMap;
@BlockEntity(name = "EndGateway")
@BlockEntity(type = BlockEntityType.END_GATEWAY)
public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,11 +25,12 @@
package org.geysermc.connector.network.translators.world.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.nukkitx.nbt.NbtMapBuilder;
@BlockEntity(name = "JigsawBlock")
@BlockEntity(type = BlockEntityType.JIGSAW)
public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {

View file

@ -25,13 +25,14 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import javax.annotation.Nullable;
@BlockEntity(name = "ShulkerBox")
@BlockEntity(type = BlockEntityType.SHULKER_BOX)
public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
/**
* Also used in {@link org.geysermc.connector.network.translators.inventory.translators.ShulkerInventoryTranslator}

View file

@ -25,13 +25,14 @@
package org.geysermc.connector.network.translators.world.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.Tag;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.chat.MessageTranslator;
import org.geysermc.connector.utils.SignUtils;
@BlockEntity(name = "Sign")
@BlockEntity(type = BlockEntityType.SIGN)
public class SignBlockEntityTranslator extends BlockEntityTranslator {
/**
* Maps a color stored in a sign's Color tag to its ARGB value.

View file

@ -26,6 +26,7 @@
package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.mc.auth.data.GameProfile;
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.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -46,7 +47,7 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@BlockEntity(name = "Skull")
@BlockEntity(type = BlockEntityType.SKULL)
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
public static boolean ALLOW_CUSTOM_SKULLS;

View file

@ -25,12 +25,13 @@
package org.geysermc.connector.network.translators.world.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.Tag;
import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.entity.type.EntityType;
@BlockEntity(name = "MobSpawner")
@BlockEntity(type = BlockEntityType.MOB_SPAWNER)
public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
@Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
@ -66,7 +67,9 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
CompoundTag spawnData = tag.get("SpawnData");
if (spawnData != null) {
String entityID = (String) spawnData.get("id").getValue();
String entityID = (String) ((CompoundTag) spawnData.get("entity"))
.get("id")
.getValue();
builder.put("EntityIdentifier", entityID);
EntityType type = EntityType.getFromIdentifier(entityID);

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.registry;
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.mc.protocol.data.game.level.event.SoundEvent;
import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
@ -69,7 +70,7 @@ public class Registries {
/**
* A mapped registry which stores a block entity identifier to its {@link BlockEntityTranslator}.
*/
public static final SimpleMappedRegistry<String, BlockEntityTranslator> BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.connector.network.translators.world.block.entity.BlockEntity", BlockEntityRegistryLoader::new);
public static final SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> 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}.

View file

@ -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<String, BlockEntity, BlockEntityTranslator> {
public BlockEntityRegistryLoader() {
super(BlockEntity.class, BlockEntity::name);
public class BlockEntityRegistryLoader implements RegistryLoader<String, Map<BlockEntityType, BlockEntityTranslator>> {
@Override
public Map<BlockEntityType, BlockEntityTranslator> load(String input) {
// Overridden so one translator can be applied to multiple block entity types
Object2ObjectMap<BlockEntityType, BlockEntityTranslator> 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;
}
}

View file

@ -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<String, String> BLOCK_ENTITY_TRANSLATIONS = new HashMap<String, String>() {
public static final Map<BlockEntityType, String> 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) {