From ce68e1442a4f233dd0287084d2b1bb2051af97ac Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Wed, 27 Nov 2019 18:14:38 -0600 Subject: [PATCH 1/8] Start work on block entities (partially-functioning) Most block entities should now *show up*. Some like signs will not as of yet, however when another player places one, they will display. Block entities are not yet fully functional and may only just be visible for the time being. --- .../network/translators/TranslatorsInit.java | 15 ++++ .../block/entity/BlockEntityTranslator.java | 73 ++++++++++++++++++ .../entity/EmptyBlockEntityTranslator.java | 50 ++++++++++++ .../entity/SignBlockEntityTranslator.java | 77 +++++++++++++++++++ .../java/world/JavaChunkDataTranslator.java | 12 +++ .../world/JavaUpdateTileEntityTranslator.java | 51 ++++++++++++ .../connector/utils/BlockEntityUtils.java | 32 ++++++++ .../geysermc/connector/utils/ChunkUtils.java | 34 +++++++- 8 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 6539fb05..8e3728e6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -48,6 +48,9 @@ import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import org.geysermc.connector.network.translators.bedrock.*; import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.EmptyBlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; @@ -67,6 +70,8 @@ import org.geysermc.connector.network.translators.java.world.*; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; public class TranslatorsInit { @@ -79,6 +84,9 @@ public class TranslatorsInit { @Getter private static InventoryTranslator inventoryTranslator = new GenericInventoryTranslator(); + @Getter + private static Map blockEntityTranslators = new HashMap<>(); + private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); public static final byte[] EMPTY_LEVEL_CHUNK_DATA; @@ -143,6 +151,7 @@ public class TranslatorsInit { Registry.registerJava(ServerBlockChangePacket.class, new JavaBlockChangeTranslator()); Registry.registerJava(ServerMultiBlockChangePacket.class, new JavaMultiBlockChangeTranslator()); Registry.registerJava(ServerUnloadChunkPacket.class, new JavaUnloadChunkTranslator()); + Registry.registerJava(ServerUpdateTileEntityPacket.class, new JavaUpdateTileEntityTranslator()); Registry.registerJava(ServerOpenWindowPacket.class, new OpenWindowPacketTranslator()); @@ -159,9 +168,15 @@ public class TranslatorsInit { itemTranslator = new ItemTranslator(); blockTranslator = new BlockTranslator(); + registerBlockEntityTranslators(); registerInventoryTranslators(); } + private static void registerBlockEntityTranslators() { + blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator()); + blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); + } + private static void registerInventoryTranslators() { /*inventoryTranslators.put(WindowType.GENERIC_9X1, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X2, new GenericInventoryTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java new file mode 100644 index 00000000..4913a300 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.utils.BlockEntityUtils; + +import java.util.List; + +public abstract class BlockEntityTranslator { + + public abstract List> translateTag(CompoundTag tag); + + public abstract CompoundTag getDefaultJavaTag(int x, int y, int z); + + public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z); + + public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) { + String id = BlockEntityUtils.getBedrockBlockEntityId((String) tag.get("id").getValue()); + int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); + int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); + int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); + + CompoundTagBuilder tagBuilder = getConstantBedrockTag(id, x, y, z).toBuilder(); + translateTag(tag).forEach(tagBuilder::tag); + return tagBuilder.buildRootTag(); + } + + protected CompoundTag getConstantJavaTag(String id, int x, int y, int z) { + CompoundTag tag = new CompoundTag(""); + tag.put(new IntTag("x", x)); + tag.put(new IntTag("y", y)); + tag.put(new IntTag("z", z)); + tag.put(new StringTag("id", id)); + return tag; + } + + protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String id, int x, int y, int z) { + CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() + .intTag("x", x) + .intTag("y", y) + .intTag("z", z) + .stringTag("id", id); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java new file mode 100644 index 00000000..927337bc --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.tag.Tag; + +import java.util.ArrayList; +import java.util.List; + +public class EmptyBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public List> translateTag(CompoundTag tag) { + return new ArrayList<>(); + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + return getConstantJavaTag("empty", x, y, z); + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + return getConstantBedrockTag("Empty", x, y, z); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java new file mode 100644 index 00000000..414455c7 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.ByteTag; +import com.nukkitx.nbt.tag.StringTag; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.utils.MessageUtils; + +import java.util.ArrayList; +import java.util.List; + +public class SignBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + + String line1 = (String) tag.getValue().get("Text1").getValue(); + String line2 = (String) tag.getValue().get("Text2").getValue(); + String line3 = (String) tag.getValue().get("Text3").getValue(); + String line4 = (String) tag.getValue().get("Text4").getValue(); + + tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(line1)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line2)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line3)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4)) + )); + + tags.add(new ByteTag("isMovable", (byte) 0)); + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + CompoundTag tag = getConstantJavaTag("minecraft:sign", x, y, z); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text4", "\"text\":\"\"")); + return tag; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag("Sign", x, y, z).toBuilder(); + tagBuilder.stringTag("Text", ""); + tagBuilder.byteTag("isMovable", (byte) 0); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index a620197e..1c83579a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -3,10 +3,14 @@ package org.geysermc.connector.network.translators.java.world; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket; import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.nbt.NbtUtils; +import com.nukkitx.nbt.stream.NBTOutputStream; +import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import org.geysermc.api.Geyser; import org.geysermc.connector.network.session.GeyserSession; @@ -53,6 +57,14 @@ public class JavaChunkDataTranslator extends PacketTranslator { + + @Override + public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) { + BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); + blockEntityPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), + packet.getPosition().getY(), + packet.getPosition().getZ()) + ); + + String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name()); + BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id); + blockEntityPacket.setData(translator.getBlockEntityTag(packet.getNbt())); + session.getUpstream().sendPacket(blockEntityPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java new file mode 100644 index 00000000..6fb62b55 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -0,0 +1,32 @@ +package org.geysermc.connector.utils; + +import org.geysermc.connector.network.translators.TranslatorsInit; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; + +public class BlockEntityUtils { + + public static String getBedrockBlockEntityId(String id) { + // This is the only exception when it comes to block entity ids + if (id.contains("piston_head")) + return "PistonArm"; + + id = id.replace("minecraft:", ""); + id = id.replace("_", " "); + 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(); + } + + id = String.join(" ", words); + return id.replace(" ", ""); + } + + public static BlockEntityTranslator getBlockEntityTranslator(String name) { + BlockEntityTranslator blockEntityTranslator = TranslatorsInit.getBlockEntityTranslators().get(name); + if (blockEntityTranslator == null) { + return TranslatorsInit.getBlockEntityTranslators().get("Empty"); + } + + return blockEntityTranslator; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index 6f2b6d3c..59a5fe84 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -3,10 +3,19 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.block.BlockEntry; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; import org.geysermc.connector.world.chunk.ChunkSection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class ChunkUtils { public static ChunkData translateToBedrock(Column column) { @@ -16,6 +25,7 @@ public class ChunkUtils { int chunkSectionCount = chunks.length; chunkData.sections = new ChunkSection[chunkSectionCount]; + List blockEntities = new ArrayList<>(Arrays.asList(column.getTileEntities())); for (int chunkY = 0; chunkY < chunkSectionCount; chunkY++) { chunkData.sections[chunkY] = new ChunkSection(); Chunk chunk = chunks[chunkY]; @@ -38,10 +48,32 @@ public class ChunkUtils { section.getBlockStorageArray()[1].setFullBlock(ChunkSection.blockPosition(x, y, z), 9 << 4); // water id } + + // Block entity data for signs is not sent in this packet, which is needed + // for bedrock, so we need to check the block itself + if (block.getJavaIdentifier().contains("sign")) { + SignBlockEntityTranslator sign = (SignBlockEntityTranslator) BlockEntityUtils.getBlockEntityTranslator("Sign"); + blockEntities.add(sign.getDefaultJavaTag(x, y, z)); + } } } } } + + List bedrockBlockEntities = new ArrayList<>(); + for (CompoundTag tag : blockEntities) { + Tag idTag = tag.get("id"); + if (idTag == null) { + GeyserLogger.DEFAULT.debug("Got tag with no id: " + tag.getValue()); + continue; + } + + String id = BlockEntityUtils.getBedrockBlockEntityId((String) tag.get("id").getValue()); + BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id); + bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(tag)); + } + + chunkData.blockEntities = bedrockBlockEntities; return chunkData; } @@ -49,6 +81,6 @@ public class ChunkUtils { public ChunkSection[] sections; public byte[] biomes = new byte[256]; - public byte[] blockEntities = new byte[0]; + public List blockEntities = new ArrayList<>(); } } From ebf6050d44f5ae1fcf03bb3fdd289ec02dfd4e81 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Wed, 27 Nov 2019 18:14:38 -0600 Subject: [PATCH 2/8] Start work on block entities (partially-functioning) Most block entities should now *show up*. Some like signs will not as of yet, however when another player places one, they will display. Block entities are not yet fully functional and may only just be visible for the time being. --- .../network/translators/TranslatorsInit.java | 15 ++++ .../block/entity/BlockEntityTranslator.java | 73 ++++++++++++++++++ .../entity/EmptyBlockEntityTranslator.java | 50 ++++++++++++ .../entity/SignBlockEntityTranslator.java | 77 +++++++++++++++++++ .../java/world/JavaChunkDataTranslator.java | 12 +++ .../world/JavaUpdateTileEntityTranslator.java | 51 ++++++++++++ .../connector/utils/BlockEntityUtils.java | 32 ++++++++ .../geysermc/connector/utils/ChunkUtils.java | 34 +++++++- 8 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index a19de3f2..072b7aed 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -45,6 +45,9 @@ import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import org.geysermc.connector.network.translators.bedrock.*; import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.EmptyBlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; @@ -64,6 +67,8 @@ import org.geysermc.connector.network.translators.java.world.*; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; public class TranslatorsInit { @@ -76,6 +81,9 @@ public class TranslatorsInit { @Getter private static InventoryTranslator inventoryTranslator = new GenericInventoryTranslator(); + @Getter + private static Map blockEntityTranslators = new HashMap<>(); + private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); public static final byte[] EMPTY_LEVEL_CHUNK_DATA; @@ -144,6 +152,7 @@ public class TranslatorsInit { Registry.registerJava(ServerBlockChangePacket.class, new JavaBlockChangeTranslator()); Registry.registerJava(ServerMultiBlockChangePacket.class, new JavaMultiBlockChangeTranslator()); Registry.registerJava(ServerUnloadChunkPacket.class, new JavaUnloadChunkTranslator()); + Registry.registerJava(ServerUpdateTileEntityPacket.class, new JavaUpdateTileEntityTranslator()); Registry.registerJava(ServerOpenWindowPacket.class, new OpenWindowPacketTranslator()); @@ -160,9 +169,15 @@ public class TranslatorsInit { itemTranslator = new ItemTranslator(); blockTranslator = new BlockTranslator(); + registerBlockEntityTranslators(); registerInventoryTranslators(); } + private static void registerBlockEntityTranslators() { + blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator()); + blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); + } + private static void registerInventoryTranslators() { /*inventoryTranslators.put(WindowType.GENERIC_9X1, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X2, new GenericInventoryTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java new file mode 100644 index 00000000..4913a300 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.utils.BlockEntityUtils; + +import java.util.List; + +public abstract class BlockEntityTranslator { + + public abstract List> translateTag(CompoundTag tag); + + public abstract CompoundTag getDefaultJavaTag(int x, int y, int z); + + public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z); + + public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) { + String id = BlockEntityUtils.getBedrockBlockEntityId((String) tag.get("id").getValue()); + int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); + int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); + int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); + + CompoundTagBuilder tagBuilder = getConstantBedrockTag(id, x, y, z).toBuilder(); + translateTag(tag).forEach(tagBuilder::tag); + return tagBuilder.buildRootTag(); + } + + protected CompoundTag getConstantJavaTag(String id, int x, int y, int z) { + CompoundTag tag = new CompoundTag(""); + tag.put(new IntTag("x", x)); + tag.put(new IntTag("y", y)); + tag.put(new IntTag("z", z)); + tag.put(new StringTag("id", id)); + return tag; + } + + protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String id, int x, int y, int z) { + CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() + .intTag("x", x) + .intTag("y", y) + .intTag("z", z) + .stringTag("id", id); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java new file mode 100644 index 00000000..927337bc --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.tag.Tag; + +import java.util.ArrayList; +import java.util.List; + +public class EmptyBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public List> translateTag(CompoundTag tag) { + return new ArrayList<>(); + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + return getConstantJavaTag("empty", x, y, z); + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + return getConstantBedrockTag("Empty", x, y, z); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java new file mode 100644 index 00000000..414455c7 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.ByteTag; +import com.nukkitx.nbt.tag.StringTag; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.utils.MessageUtils; + +import java.util.ArrayList; +import java.util.List; + +public class SignBlockEntityTranslator extends BlockEntityTranslator { + + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + + String line1 = (String) tag.getValue().get("Text1").getValue(); + String line2 = (String) tag.getValue().get("Text2").getValue(); + String line3 = (String) tag.getValue().get("Text3").getValue(); + String line4 = (String) tag.getValue().get("Text4").getValue(); + + tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(line1)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line2)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line3)) + + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4)) + )); + + tags.add(new ByteTag("isMovable", (byte) 0)); + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + CompoundTag tag = getConstantJavaTag("minecraft:sign", x, y, z); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "\"text\":\"\"")); + tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text4", "\"text\":\"\"")); + return tag; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag("Sign", x, y, z).toBuilder(); + tagBuilder.stringTag("Text", ""); + tagBuilder.byteTag("isMovable", (byte) 0); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index a620197e..1c83579a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -3,10 +3,14 @@ package org.geysermc.connector.network.translators.java.world; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket; import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.nbt.NbtUtils; +import com.nukkitx.nbt.stream.NBTOutputStream; +import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import org.geysermc.api.Geyser; import org.geysermc.connector.network.session.GeyserSession; @@ -53,6 +57,14 @@ public class JavaChunkDataTranslator extends PacketTranslator { + + @Override + public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) { + BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); + blockEntityPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), + packet.getPosition().getY(), + packet.getPosition().getZ()) + ); + + String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name()); + BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id); + blockEntityPacket.setData(translator.getBlockEntityTag(packet.getNbt())); + session.getUpstream().sendPacket(blockEntityPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java new file mode 100644 index 00000000..6fb62b55 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -0,0 +1,32 @@ +package org.geysermc.connector.utils; + +import org.geysermc.connector.network.translators.TranslatorsInit; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; + +public class BlockEntityUtils { + + public static String getBedrockBlockEntityId(String id) { + // This is the only exception when it comes to block entity ids + if (id.contains("piston_head")) + return "PistonArm"; + + id = id.replace("minecraft:", ""); + id = id.replace("_", " "); + 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(); + } + + id = String.join(" ", words); + return id.replace(" ", ""); + } + + public static BlockEntityTranslator getBlockEntityTranslator(String name) { + BlockEntityTranslator blockEntityTranslator = TranslatorsInit.getBlockEntityTranslators().get(name); + if (blockEntityTranslator == null) { + return TranslatorsInit.getBlockEntityTranslators().get("Empty"); + } + + return blockEntityTranslator; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index 6f2b6d3c..59a5fe84 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -3,10 +3,19 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.block.BlockEntry; +import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; import org.geysermc.connector.world.chunk.ChunkSection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class ChunkUtils { public static ChunkData translateToBedrock(Column column) { @@ -16,6 +25,7 @@ public class ChunkUtils { int chunkSectionCount = chunks.length; chunkData.sections = new ChunkSection[chunkSectionCount]; + List blockEntities = new ArrayList<>(Arrays.asList(column.getTileEntities())); for (int chunkY = 0; chunkY < chunkSectionCount; chunkY++) { chunkData.sections[chunkY] = new ChunkSection(); Chunk chunk = chunks[chunkY]; @@ -38,10 +48,32 @@ public class ChunkUtils { section.getBlockStorageArray()[1].setFullBlock(ChunkSection.blockPosition(x, y, z), 9 << 4); // water id } + + // Block entity data for signs is not sent in this packet, which is needed + // for bedrock, so we need to check the block itself + if (block.getJavaIdentifier().contains("sign")) { + SignBlockEntityTranslator sign = (SignBlockEntityTranslator) BlockEntityUtils.getBlockEntityTranslator("Sign"); + blockEntities.add(sign.getDefaultJavaTag(x, y, z)); + } } } } } + + List bedrockBlockEntities = new ArrayList<>(); + for (CompoundTag tag : blockEntities) { + Tag idTag = tag.get("id"); + if (idTag == null) { + GeyserLogger.DEFAULT.debug("Got tag with no id: " + tag.getValue()); + continue; + } + + String id = BlockEntityUtils.getBedrockBlockEntityId((String) tag.get("id").getValue()); + BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id); + bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(tag)); + } + + chunkData.blockEntities = bedrockBlockEntities; return chunkData; } @@ -49,6 +81,6 @@ public class ChunkUtils { public ChunkSection[] sections; public byte[] biomes = new byte[256]; - public byte[] blockEntities = new byte[0]; + public List blockEntities = new ArrayList<>(); } } From da8bd8a6599bd6d945c903da03bb37c07ef5d053 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Mon, 30 Dec 2019 21:55:17 -0600 Subject: [PATCH 3/8] Actually fix signs and start on campfire/container translators Since signs are not sent as block (tile) entities in chunks when it comes to later Minecraft versions, caching and sending the signs after the chunk packet has been sent was the only way to fix this. Sign data sending has intentionally been delayed in JavaUpdateTileEntityTranslator in the event that a chunk takes a long time to send and the block entity data is sent first. --- .../network/translators/TranslatorsInit.java | 6 +- .../block/entity/BlockEntityTranslator.java | 19 ++-- .../ContainerBlockEntityTranslator.java | 92 +++++++++++++++++++ .../entity/EmptyBlockEntityTranslator.java | 8 +- .../entity/SignBlockEntityTranslator.java | 12 ++- .../translators/item/ItemTranslator.java | 8 ++ .../java/world/JavaChunkDataTranslator.java | 18 +++- .../world/JavaUpdateTileEntityTranslator.java | 23 +++-- .../connector/utils/BlockEntityUtils.java | 17 +++- .../geysermc/connector/utils/ChunkUtils.java | 53 ++++++----- .../connector/world/chunk/ChunkPosition.java | 14 +-- 11 files changed, 204 insertions(+), 66 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 072b7aed..477734d8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -46,6 +46,7 @@ import lombok.Getter; import org.geysermc.connector.network.translators.bedrock.*; import org.geysermc.connector.network.translators.block.BlockTranslator; import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.ContainerBlockEntityTranslator; import org.geysermc.connector.network.translators.block.entity.EmptyBlockEntityTranslator; import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator; @@ -174,8 +175,9 @@ public class TranslatorsInit { } private static void registerBlockEntityTranslators() { - blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator()); - blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); + blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator("empty", "Empty")); + blockEntityTranslators.put("Sign", new SignBlockEntityTranslator("minecraft:sign", "Sign")); + blockEntityTranslators.put("Campfire", new ContainerBlockEntityTranslator("minecraft:campfire", "Campfire")); } private static void registerInventoryTranslators() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java index 61d3fd08..e5e3a50d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java @@ -30,43 +30,48 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.utils.BlockEntityUtils; + +import lombok.AllArgsConstructor; import java.util.List; +@AllArgsConstructor public abstract class BlockEntityTranslator { + protected String javaId; + protected String bedrockId; + public abstract List> translateTag(CompoundTag tag); public abstract CompoundTag getDefaultJavaTag(int x, int y, int z); public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z); - public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag, String id) { + public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) { int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); - CompoundTagBuilder tagBuilder = getConstantBedrockTag(id, x, y, z).toBuilder(); + CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); translateTag(tag).forEach(tagBuilder::tag); return tagBuilder.buildRootTag(); } - protected CompoundTag getConstantJavaTag(String id, int x, int y, int z) { + protected CompoundTag getConstantJavaTag(int x, int y, int z) { CompoundTag tag = new CompoundTag(""); tag.put(new IntTag("x", x)); tag.put(new IntTag("y", y)); tag.put(new IntTag("z", z)); - tag.put(new StringTag("id", id)); + tag.put(new StringTag("id", javaId)); return tag; } - protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String id, int x, int y, int z) { + protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(int x, int y, int z) { CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() .intTag("x", x) .intTag("y", y) .intTag("z", z) - .stringTag("id", id); + .stringTag("id", bedrockId); return tagBuilder.buildRootTag(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java new file mode 100644 index 00000000..18168348 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.IntArrayTag; +import com.nukkitx.nbt.tag.Tag; + +import org.geysermc.connector.network.translators.TranslatorsInit; +import org.geysermc.connector.network.translators.item.ItemEntry; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ContainerBlockEntityTranslator extends BlockEntityTranslator { + + public ContainerBlockEntityTranslator(String javaId, String bedrockId) { + super(javaId, bedrockId); + } + + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + ListTag items = tag.get("Items"); + List tagsList = new ArrayList<>(); + for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) { + tagsList.add(getItem((CompoundTag) itemTag)); + } + + int[] fakeCookingTime = new int[4]; + Arrays.fill(fakeCookingTime, 3); + + com.nukkitx.nbt.tag.ListTag bedrockItems = + new com.nukkitx.nbt.tag.ListTag<>("Items", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); + tags.add(bedrockItems); + + tags.add(new IntArrayTag("CookingTimes", fakeCookingTime)); + tags.add(new IntArrayTag("CookingTotalTimes", fakeCookingTime)); + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(x, y, z); + tag.put(new ListTag("Items")); + return tag; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + tagBuilder.listTag("Items", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); + return tagBuilder.buildRootTag(); + } + + protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { + ItemEntry entry = TranslatorsInit.getItemTranslator().getItemEntry((String) tag.get("id").getValue()); + CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() + .shortTag("id", (short) entry.getBedrockId()) + .byteTag("Count", (byte) tag.get("Count").getValue()) + .shortTag("Damage", (short) entry.getBedrockData()) + .byteTag("Slot", (byte) tag.get("Slot").getValue()) + .tag(CompoundTagBuilder.builder().build("tag")); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java index 927337bc..700b50db 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java @@ -33,6 +33,10 @@ import java.util.List; public class EmptyBlockEntityTranslator extends BlockEntityTranslator { + public EmptyBlockEntityTranslator(String javaId, String bedrockId) { + super(javaId, bedrockId); + } + @Override public List> translateTag(CompoundTag tag) { return new ArrayList<>(); @@ -40,11 +44,11 @@ public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override public CompoundTag getDefaultJavaTag(int x, int y, int z) { - return getConstantJavaTag("empty", x, y, z); + return getConstantJavaTag(x, y, z); } @Override public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - return getConstantBedrockTag("Empty", x, y, z); + return getConstantBedrockTag(x, y, z); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java index 182eedd9..7029143b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java @@ -28,9 +28,9 @@ package org.geysermc.connector.network.translators.block.entity; import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.Tag; + import org.geysermc.connector.utils.MessageUtils; import java.util.ArrayList; @@ -38,6 +38,10 @@ import java.util.List; public class SignBlockEntityTranslator extends BlockEntityTranslator { + public SignBlockEntityTranslator(String javaId, String bedrockId) { + super(javaId, bedrockId); + } + @Override public List> translateTag(CompoundTag tag) { List> tags = new ArrayList<>(); @@ -53,13 +57,12 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4)) )); - tags.add(new ByteTag("isMovable", (byte) 0)); return tags; } @Override public CompoundTag getDefaultJavaTag(int x, int y, int z) { - CompoundTag tag = getConstantJavaTag("minecraft:sign", x, y, z); + CompoundTag tag = getConstantJavaTag(x, y, z); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "{\"text\":\"\"}")); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "{\"text\":\"\"}")); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "{\"text\":\"\"}")); @@ -69,9 +72,8 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { @Override public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag("Sign", x, y, z).toBuilder(); + CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); tagBuilder.stringTag("Text", ""); - tagBuilder.byteTag("isMovable", (byte) 0); return tagBuilder.buildRootTag(); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 20421059..22f2c9f1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -41,6 +41,7 @@ import com.github.steveice10.opennbt.tag.builtin.ShortTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.protocol.bedrock.data.ItemData; + import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.Toolbox; @@ -52,6 +53,8 @@ import java.util.Map; public class ItemTranslator { + private Map javaIdentifierMap = new HashMap<>(); + public ItemStack translateToJava(ItemData data) { ItemEntry javaItem = getItem(data); @@ -89,6 +92,11 @@ public class ItemTranslator { return ItemEntry.AIR; } + public ItemEntry getItemEntry(String javaIdentifier) { + return javaIdentifierMap.computeIfAbsent(javaIdentifier, key -> Toolbox.ITEM_ENTRIES.values() + .stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null)); + } + private CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) { CompoundTag javaTag = new CompoundTag(tag.getName()); Map javaValue = javaTag.getValue(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index 1c83579a..c7c9af5b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -1,5 +1,7 @@ package org.geysermc.connector.network.translators.java.world; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket; import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; @@ -9,9 +11,13 @@ import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket; + import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; + import org.geysermc.api.Geyser; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -22,7 +28,6 @@ public class JavaChunkDataTranslator extends PacketTranslator { Vector2i chunkPos = session.getLastChunkPosition(); Vector3f position = session.getPlayerEntity().getPosition(); @@ -33,7 +38,6 @@ public class JavaChunkDataTranslator extends PacketTranslator blockEntityEntry : chunkData.signs.int2ObjectEntrySet()) { + int x = blockEntityEntry.getValue().getAsInt("x"); + int y = blockEntityEntry.getValue().getAsInt("y"); + int z = blockEntityEntry.getValue().getAsInt("z"); + + ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); + } + chunkData.signs.clear(); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java index 2b55e27e..20601104 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java @@ -26,26 +26,29 @@ package org.geysermc.connector.network.translators.java.world; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket; -import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; + import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; import org.geysermc.connector.utils.BlockEntityUtils; +import java.util.concurrent.TimeUnit; + public class JavaUpdateTileEntityTranslator extends PacketTranslator { @Override public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) { - BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); - blockEntityPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), - packet.getPosition().getY(), - packet.getPosition().getZ()) - ); - String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name()); BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id); - blockEntityPacket.setData(translator.getBlockEntityTag(packet.getNbt(), id)); - session.getUpstream().sendPacket(blockEntityPacket); + if (id.equalsIgnoreCase("Sign")) { + // Delay so chunks can finish sending + session.getConnector().getGeneralThreadPool().schedule(() -> + BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition()), + 5, + TimeUnit.SECONDS + ); + } else { + BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition()); + } } } 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 6fb62b55..f610f271 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -1,5 +1,10 @@ package org.geysermc.connector.utils; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; + +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; @@ -10,8 +15,9 @@ public class BlockEntityUtils { if (id.contains("piston_head")) return "PistonArm"; - id = id.replace("minecraft:", ""); - id = id.replace("_", " "); + id = id.toLowerCase() + .replace("minecraft:", "") + .replace("_", " "); 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(); @@ -29,4 +35,11 @@ public class BlockEntityUtils { return blockEntityTranslator; } + + public static void updateBlockEntity(GeyserSession session, com.nukkitx.nbt.tag.CompoundTag blockEntity, Position position) { + BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); + blockEntityPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ())); + blockEntityPacket.setData(blockEntity); + session.getUpstream().sendPacket(blockEntityPacket); + } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index cf214625..0059b523 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -3,35 +3,31 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.opennbt.tag.builtin.Tag; -import org.geysermc.connector.console.GeyserLogger; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.block.BlockEntry; import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; +import org.geysermc.connector.world.chunk.ChunkPosition; import org.geysermc.connector.world.chunk.ChunkSection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - public class ChunkUtils { public static ChunkData translateToBedrock(Column column) { ChunkData chunkData = new ChunkData(); - Chunk[] chunks = column.getChunks(); - int chunkSectionCount = chunks.length; - chunkData.sections = new ChunkSection[chunkSectionCount]; + chunkData.sections = new ChunkSection[chunks.length]; - List blockEntities = new ArrayList<>(Arrays.asList(column.getTileEntities())); - for (int chunkY = 0; chunkY < chunkSectionCount; chunkY++) { + CompoundTag[] blockEntities = column.getTileEntities(); + for (int chunkY = 0; chunkY < chunks.length; chunkY++) { chunkData.sections[chunkY] = new ChunkSection(); Chunk chunk = chunks[chunkY]; @@ -39,15 +35,17 @@ public class ChunkUtils { continue; ChunkSection section = chunkData.sections[chunkY]; - for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { BlockState blockState = chunk.get(x, y, z); BlockEntry block = TranslatorsInit.getBlockTranslator().getBlockEntry(blockState); - - section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), - block.getBedrockRuntimeId()); + if (block.getJavaIdentifier().contains("sign[")) { + Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); + chunkData.signs.put(block.getJavaId(), TranslatorsInit.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag(pos.getX(), pos.getY(), pos.getZ())); + } else { + section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), block.getBedrockRuntimeId()); + } if (block.isWaterlogged()) { BlockEntry water = TranslatorsInit.getBlockTranslator().getBlockEntry("minecraft:water[level=0]"); @@ -58,17 +56,20 @@ public class ChunkUtils { } } - List bedrockBlockEntities = new ArrayList<>(); - for (CompoundTag tag : blockEntities) { - Tag idTag = tag.get("id"); - if (idTag == null && !tag.contains("Sign")) { + com.nukkitx.nbt.tag.CompoundTag[] bedrockBlockEntities = new com.nukkitx.nbt.tag.CompoundTag[blockEntities.length]; + for (int i = 0; i < bedrockBlockEntities.length; i++) { + CompoundTag tag = blockEntities[i]; + String tagName; + if (!tag.contains("id")) { GeyserLogger.DEFAULT.debug("Got tag with no id: " + tag.getValue()); - continue; + tagName = "Empty"; + } else { + tagName = (String) tag.get("id").getValue(); } - String id = idTag == null ? "Sign" : BlockEntityUtils.getBedrockBlockEntityId((String) idTag.getValue()); + String id = BlockEntityUtils.getBedrockBlockEntityId(tagName); BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id); - bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(tag, id)); + bedrockBlockEntities[i] = blockEntityTranslator.getBlockEntityTag(tag); } chunkData.blockEntities = bedrockBlockEntities; @@ -102,6 +103,8 @@ public class ChunkUtils { public ChunkSection[] sections; public byte[] biomes = new byte[256]; - public List blockEntities = new ArrayList<>(); + public com.nukkitx.nbt.tag.CompoundTag[] blockEntities = new com.nukkitx.nbt.tag.CompoundTag[0]; + + public Int2ObjectMap signs = new Int2ObjectOpenHashMap<>(); } } diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java b/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java index 86da2da4..4af2bcc2 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java +++ b/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java @@ -18,17 +18,9 @@ public class ChunkPosition { } public Position getChunkBlock(int x, int y, int z) { - int chunkX = x % 16; - int chunkY = y % 16; - int chunkZ = z % 16; - - if (chunkX < 0) - chunkX = -chunkX; - if (chunkY < 0) - chunkY = -chunkY; - if (chunkZ < 0) - chunkZ = -chunkZ; - + int chunkX = x & 15; + int chunkY = y & 15; + int chunkZ = z & 15; return new Position(chunkX, chunkY, chunkZ); } } From bc2df705ef9b3a3d1526aa8d8ecd37cebb159bc9 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 31 Dec 2019 11:53:42 -0600 Subject: [PATCH 4/8] Fix campfires --- .../network/translators/TranslatorsInit.java | 7 +- .../entity/CampfireBlockEntityTranslator.java | 76 +++++++++++++++++++ .../ContainerBlockEntityTranslator.java | 8 -- 3 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 477734d8..268d443f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -45,10 +45,7 @@ import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import org.geysermc.connector.network.translators.bedrock.*; import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.ContainerBlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.EmptyBlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator; +import org.geysermc.connector.network.translators.block.entity.*; import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; @@ -177,7 +174,7 @@ public class TranslatorsInit { private static void registerBlockEntityTranslators() { blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator("empty", "Empty")); blockEntityTranslators.put("Sign", new SignBlockEntityTranslator("minecraft:sign", "Sign")); - blockEntityTranslators.put("Campfire", new ContainerBlockEntityTranslator("minecraft:campfire", "Campfire")); + blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator("minecraft:campfire", "Campfire")); } private static void registerInventoryTranslators() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java new file mode 100644 index 00000000..f2776213 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.Tag; + +import org.geysermc.connector.network.translators.TranslatorsInit; +import org.geysermc.connector.network.translators.item.ItemEntry; + +import java.util.ArrayList; +import java.util.List; + +public class CampfireBlockEntityTranslator extends BlockEntityTranslator { + + public CampfireBlockEntityTranslator(String javaId, String bedrockId) { + super(javaId, bedrockId); + } + + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + ListTag items = tag.get("Items"); + int i = 1; + for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) { + tags.add(getItem((CompoundTag) itemTag).toBuilder().build("Item" + i)); + i++; + } + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + return null; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + return null; + } + + protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { + ItemEntry entry = TranslatorsInit.getItemTranslator().getItemEntry((String) tag.get("id").getValue()); + CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() + .shortTag("id", (short) entry.getBedrockId()) + .byteTag("Count", (byte) tag.get("Count").getValue()) + .shortTag("Damage", (short) entry.getBedrockData()) + .tag(CompoundTagBuilder.builder().build("tag")); + return tagBuilder.buildRootTag(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java index 18168348..78566d60 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java @@ -28,14 +28,12 @@ package org.geysermc.connector.network.translators.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.IntArrayTag; import com.nukkitx.nbt.tag.Tag; import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.item.ItemEntry; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class ContainerBlockEntityTranslator extends BlockEntityTranslator { @@ -53,15 +51,9 @@ public class ContainerBlockEntityTranslator extends BlockEntityTranslator { tagsList.add(getItem((CompoundTag) itemTag)); } - int[] fakeCookingTime = new int[4]; - Arrays.fill(fakeCookingTime, 3); - com.nukkitx.nbt.tag.ListTag bedrockItems = new com.nukkitx.nbt.tag.ListTag<>("Items", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); tags.add(bedrockItems); - - tags.add(new IntArrayTag("CookingTimes", fakeCookingTime)); - tags.add(new IntArrayTag("CookingTotalTimes", fakeCookingTime)); return tags; } From da645abec432699862f6b46dfaab0fea605802ac Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 31 Dec 2019 12:31:04 -0600 Subject: [PATCH 5/8] Add support for banner block entities Colored banners still need to be implemented. The color for banners themselves is set as part of the block entity on bedrock meanwhile in java edition its set as part of the block state. --- .../network/translators/TranslatorsInit.java | 1 + .../entity/BannerBlockEntityTranslator.java | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 268d443f..90a2b742 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -175,6 +175,7 @@ public class TranslatorsInit { blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator("empty", "Empty")); blockEntityTranslators.put("Sign", new SignBlockEntityTranslator("minecraft:sign", "Sign")); blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator("minecraft:campfire", "Campfire")); + blockEntityTranslators.put("Banner", new BannerBlockEntityTranslator("minecraft:banner", "Banner")); } private static void registerInventoryTranslators() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java new file mode 100644 index 00000000..22c68843 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.block.entity; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.StringTag; +import com.nukkitx.nbt.tag.Tag; + +import java.util.ArrayList; +import java.util.List; + +public class BannerBlockEntityTranslator extends BlockEntityTranslator { + + public BannerBlockEntityTranslator(String javaId, String bedrockId) { + super(javaId, bedrockId); + } + + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + ListTag patterns = tag.get("Patterns"); + List tagsList = new ArrayList<>(); + for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) { + tagsList.add(getPattern((CompoundTag) patternTag)); + } + com.nukkitx.nbt.tag.ListTag bedrockPatterns = + new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); + tags.add(bedrockPatterns); + + if (tag.contains("CustomName")) { + tags.add(new StringTag("CustomName", (String) tag.get("CustomName").getValue())); + } + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(x, y, z); + tag.put(new ListTag("Patterns")); + return tag; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + tagBuilder.listTag("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); + return tagBuilder.buildRootTag(); + } + + protected com.nukkitx.nbt.tag.CompoundTag getPattern(CompoundTag pattern) { + return CompoundTagBuilder.builder() + .intTag("Color", (int) pattern.get("Color").getValue()) + .stringTag("Pattern", (String) pattern.get("Pattern").getValue()) + .buildRootTag(); + } +} From a59e330db9a1c0a54efbadabe492de01c600068d Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 31 Dec 2019 12:33:42 -0600 Subject: [PATCH 6/8] Add default tags for campfire block entity --- .../block/entity/CampfireBlockEntityTranslator.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java index f2776213..ee1c1275 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java @@ -34,6 +34,7 @@ import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.item.ItemEntry; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @@ -56,12 +57,19 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override public CompoundTag getDefaultJavaTag(int x, int y, int z) { - return null; + CompoundTag tag = getConstantJavaTag(x, y, z); + tag.put(new ListTag("Items")); + return tag; } @Override public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - return null; + CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item1", new HashMap<>())); + tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item2", new HashMap<>())); + tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item3", new HashMap<>())); + tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item4", new HashMap<>())); + return tagBuilder.buildRootTag(); } protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { From 0eb182d0da1bd5d3a8d910d0ed73f74ba2559495 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 31 Dec 2019 13:24:59 -0600 Subject: [PATCH 7/8] Add block value translator You can now see chest opening/closing animations :) --- .../network/translators/TranslatorsInit.java | 1 + .../java/world/JavaBlockValueTranslator.java | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 90a2b742..a08a0c81 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -151,6 +151,7 @@ public class TranslatorsInit { Registry.registerJava(ServerMultiBlockChangePacket.class, new JavaMultiBlockChangeTranslator()); Registry.registerJava(ServerUnloadChunkPacket.class, new JavaUnloadChunkTranslator()); Registry.registerJava(ServerUpdateTileEntityPacket.class, new JavaUpdateTileEntityTranslator()); + Registry.registerJava(ServerBlockValuePacket.class, new JavaBlockValueTranslator()); Registry.registerJava(ServerOpenWindowPacket.class, new OpenWindowPacketTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java new file mode 100644 index 00000000..ac699fd9 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.data.game.world.block.value.ChestValue; +import com.github.steveice10.mc.protocol.data.game.world.block.value.EndGatewayValue; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockValuePacket; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.packet.BlockEventPacket; + +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; + +public class JavaBlockValueTranslator extends PacketTranslator { + + @Override + public void translate(ServerBlockValuePacket packet, GeyserSession session) { + BlockEventPacket blockEventPacket = new BlockEventPacket(); + blockEventPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), + packet.getPosition().getY(), packet.getPosition().getZ())); + if (packet.getValue() instanceof ChestValue) { + ChestValue value = (ChestValue) packet.getValue() ; + blockEventPacket.setEventType(1); + blockEventPacket.setEventData(value.getViewers() > 0 ? 1 : 0); + session.getUpstream().sendPacket(blockEventPacket); + } + if (packet.getValue() instanceof EndGatewayValue) { + blockEventPacket.setEventType(1); + session.getUpstream().sendPacket(blockEventPacket); + } + } +} From e0f6c8a1700fa0df130cc884f84e5ac91eace754 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sat, 25 Jan 2020 23:51:29 -0600 Subject: [PATCH 8/8] Fix chests and potentially other block entities --- .../network/translators/TranslatorsInit.java | 8 ++++---- .../entity/BannerBlockEntityTranslator.java | 12 ++++-------- .../block/entity/BlockEntityTranslator.java | 16 +++++++--------- .../entity/CampfireBlockEntityTranslator.java | 12 ++++-------- .../entity/ContainerBlockEntityTranslator.java | 12 ++++-------- .../block/entity/EmptyBlockEntityTranslator.java | 12 ++++-------- .../block/entity/SignBlockEntityTranslator.java | 12 ++++-------- .../connector/utils/BlockEntityUtils.java | 4 +++- .../org/geysermc/connector/utils/ChunkUtils.java | 2 +- 9 files changed, 35 insertions(+), 55 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 6d5a1efa..21b57b25 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -176,10 +176,10 @@ public class TranslatorsInit { } private static void registerBlockEntityTranslators() { - blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator("empty", "Empty")); - blockEntityTranslators.put("Sign", new SignBlockEntityTranslator("minecraft:sign", "Sign")); - blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator("minecraft:campfire", "Campfire")); - blockEntityTranslators.put("Banner", new BannerBlockEntityTranslator("minecraft:banner", "Banner")); + blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator()); + blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); + blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator()); + blockEntityTranslators.put("Banner", new BannerBlockEntityTranslator()); } private static void registerInventoryTranslators() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java index 22c68843..a5ed5994 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java @@ -36,10 +36,6 @@ import java.util.List; public class BannerBlockEntityTranslator extends BlockEntityTranslator { - public BannerBlockEntityTranslator(String javaId, String bedrockId) { - super(javaId, bedrockId); - } - @Override public List> translateTag(CompoundTag tag) { List> tags = new ArrayList<>(); @@ -59,15 +55,15 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator { } @Override - public CompoundTag getDefaultJavaTag(int x, int y, int z) { - CompoundTag tag = getConstantJavaTag(x, y, z); + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(javaId, x, y, z); tag.put(new ListTag("Patterns")); return tag; } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); tagBuilder.listTag("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); return tagBuilder.buildRootTag(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java index e5e3a50d..71b83d59 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java @@ -32,32 +32,30 @@ import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.Tag; import lombok.AllArgsConstructor; +import org.geysermc.connector.utils.BlockEntityUtils; import java.util.List; -@AllArgsConstructor public abstract class BlockEntityTranslator { - protected String javaId; - protected String bedrockId; - public abstract List> translateTag(CompoundTag tag); - public abstract CompoundTag getDefaultJavaTag(int x, int y, int z); + public abstract CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z); - public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z); + public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z); public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) { int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); - CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + CompoundTagBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId( + String.valueOf(tag.get("id").getValue())), x, y, z).toBuilder(); translateTag(tag).forEach(tagBuilder::tag); return tagBuilder.buildRootTag(); } - protected CompoundTag getConstantJavaTag(int x, int y, int z) { + protected CompoundTag getConstantJavaTag(String javaId, int x, int y, int z) { CompoundTag tag = new CompoundTag(""); tag.put(new IntTag("x", x)); tag.put(new IntTag("y", y)); @@ -66,7 +64,7 @@ public abstract class BlockEntityTranslator { return tag; } - protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(int x, int y, int z) { + protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String bedrockId, int x, int y, int z) { CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() .intTag("x", x) .intTag("y", y) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java index ee1c1275..b40626dc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java @@ -39,10 +39,6 @@ import java.util.List; public class CampfireBlockEntityTranslator extends BlockEntityTranslator { - public CampfireBlockEntityTranslator(String javaId, String bedrockId) { - super(javaId, bedrockId); - } - @Override public List> translateTag(CompoundTag tag) { List> tags = new ArrayList<>(); @@ -56,15 +52,15 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator { } @Override - public CompoundTag getDefaultJavaTag(int x, int y, int z) { - CompoundTag tag = getConstantJavaTag(x, y, z); + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(javaId, x, y, z); tag.put(new ListTag("Items")); return tag; } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item1", new HashMap<>())); tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item2", new HashMap<>())); tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item3", new HashMap<>())); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java index 78566d60..123290db 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ContainerBlockEntityTranslator.java @@ -38,10 +38,6 @@ import java.util.List; public class ContainerBlockEntityTranslator extends BlockEntityTranslator { - public ContainerBlockEntityTranslator(String javaId, String bedrockId) { - super(javaId, bedrockId); - } - @Override public List> translateTag(CompoundTag tag) { List> tags = new ArrayList<>(); @@ -58,15 +54,15 @@ public class ContainerBlockEntityTranslator extends BlockEntityTranslator { } @Override - public CompoundTag getDefaultJavaTag(int x, int y, int z) { - CompoundTag tag = getConstantJavaTag(x, y, z); + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(javaId, x, y, z); tag.put(new ListTag("Items")); return tag; } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); tagBuilder.listTag("Items", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); return tagBuilder.buildRootTag(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java index 700b50db..16bc4d7a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java @@ -33,22 +33,18 @@ import java.util.List; public class EmptyBlockEntityTranslator extends BlockEntityTranslator { - public EmptyBlockEntityTranslator(String javaId, String bedrockId) { - super(javaId, bedrockId); - } - @Override public List> translateTag(CompoundTag tag) { return new ArrayList<>(); } @Override - public CompoundTag getDefaultJavaTag(int x, int y, int z) { - return getConstantJavaTag(x, y, z); + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + return getConstantJavaTag(javaId, x, y, z); } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - return getConstantBedrockTag(x, y, z); + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java index 7029143b..3d9a4a7a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java @@ -38,10 +38,6 @@ import java.util.List; public class SignBlockEntityTranslator extends BlockEntityTranslator { - public SignBlockEntityTranslator(String javaId, String bedrockId) { - super(javaId, bedrockId); - } - @Override public List> translateTag(CompoundTag tag) { List> tags = new ArrayList<>(); @@ -61,8 +57,8 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public CompoundTag getDefaultJavaTag(int x, int y, int z) { - CompoundTag tag = getConstantJavaTag(x, y, z); + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(javaId, x, y, z); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "{\"text\":\"\"}")); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "{\"text\":\"\"}")); tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "{\"text\":\"\"}")); @@ -71,8 +67,8 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder(); + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); tagBuilder.stringTag("Text", ""); return tagBuilder.buildRootTag(); } 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 f610f271..58eadb1b 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -10,6 +10,8 @@ import org.geysermc.connector.network.translators.block.entity.BlockEntityTransl public class BlockEntityUtils { + private static final BlockEntityTranslator EMPTY_TRANSLATOR = TranslatorsInit.getBlockEntityTranslators().get("Empty"); + public static String getBedrockBlockEntityId(String id) { // This is the only exception when it comes to block entity ids if (id.contains("piston_head")) @@ -30,7 +32,7 @@ public class BlockEntityUtils { public static BlockEntityTranslator getBlockEntityTranslator(String name) { BlockEntityTranslator blockEntityTranslator = TranslatorsInit.getBlockEntityTranslators().get(name); if (blockEntityTranslator == null) { - return TranslatorsInit.getBlockEntityTranslators().get("Empty"); + return EMPTY_TRANSLATOR; } return blockEntityTranslator; diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index fba9e788..4e0b6826 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -69,7 +69,7 @@ public class ChunkUtils { BlockEntry block = TranslatorsInit.getBlockTranslator().getBlockEntry(blockState); if (block.getJavaIdentifier().contains("sign[")) { Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); - chunkData.signs.put(block.getJavaId(), TranslatorsInit.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag(pos.getX(), pos.getY(), pos.getZ())); + chunkData.signs.put(block.getJavaId(), TranslatorsInit.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag("Sign", pos.getX(), pos.getY(), pos.getZ())); } else { section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), block.getBedrockRuntimeId()); }