diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java index 0df961076..70a73be39 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java @@ -34,11 +34,7 @@ import com.github.steveice10.mc.protocol.data.game.window.WindowType; import com.nukkitx.protocol.bedrock.data.ContainerType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.network.translators.block.entity.BannerBlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; -import org.geysermc.connector.network.translators.block.entity.CampfireBlockEntityTranslator; -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.AnvilInventoryTranslator; import org.geysermc.connector.network.translators.inventory.BlockInventoryTranslator; import org.geysermc.connector.network.translators.inventory.BrewingInventoryTranslator; @@ -132,6 +128,7 @@ public class Translators { blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator()); blockEntityTranslators.put("Banner", new BannerBlockEntityTranslator()); + blockEntityTranslators.put("EndGateway", new EndGatewayBlockEntityTranslator()); } private static void registerInventoryTranslators() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java new file mode 100644 index 000000000..e66a0bcda --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019-2020 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.LongTag; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.IntTag; +import com.nukkitx.nbt.tag.Tag; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { + @Override + public List> translateTag(CompoundTag tag) { + List> tags = new ArrayList<>(); + tags.add(new IntTag("Age", (int) (long) tag.get("Age").getValue())); + // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist + // Linked coordinates + List tagsList = new ArrayList<>(); + // Yes, the axis letters are capitalized + tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "X"))); + tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "Y"))); + tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "Z"))); + com.nukkitx.nbt.tag.ListTag exitPortal = + new com.nukkitx.nbt.tag.ListTag<>("ExitPortal", IntTag.class, tagsList); + tags.add(exitPortal); + return tags; + } + + @Override + public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + CompoundTag tag = getConstantJavaTag(javaId, x, y, z); + tag.put(new LongTag("Age")); + return tag; + } + + @Override + public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); + List tagsList = new ArrayList<>(); + tagsList.add(new IntTag("", 0)); + tagsList.add(new IntTag("", 0)); + tagsList.add(new IntTag("", 0)); + tagBuilder.listTag("ExitPortal", IntTag.class, tagsList); + return tagBuilder.buildRootTag(); + } + + private int getExitPortalCoordinate(CompoundTag tag, String axis) { + // Return 0 if it doesn't exist, otherwise give proper value + if (tag.get("ExitPortal") != null) { + LinkedHashMap compoundTag = (LinkedHashMap) tag.get("ExitPortal").getValue(); + com.github.steveice10.opennbt.tag.builtin.IntTag intTag = (com.github.steveice10.opennbt.tag.builtin.IntTag) compoundTag.get(axis); + return intTag.getValue(); + } return 0; + } +} 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 5d17e0e07..4f6d1bc6b 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 @@ -110,10 +110,18 @@ public class JavaChunkDataTranslator extends PacketTranslator blockEntityEntry : chunkData.gateways.object2IntEntrySet()) { + int x = blockEntityEntry.getKey().getInt("x"); + int y = blockEntityEntry.getKey().getInt("y"); + int z = blockEntityEntry.getKey().getInt("z"); + ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntValue()), new Position(x, y, z)); + } + for (Map.Entry blockEntityEntry: chunkData.beds.entrySet()) { ChunkUtils.updateBlock(session, blockEntityEntry.getValue(), blockEntityEntry.getKey()); } chunkData.signs.clear(); + chunkData.gateways.clear(); chunkData.beds.clear(); } catch (Exception ex) { ex.printStackTrace(); 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 b7bcb7197..c6851770c 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -78,6 +78,9 @@ public class ChunkUtils { if (BlockTranslator.getBlockEntityString(blockState) != null && BlockTranslator.getBlockEntityString(blockState).contains("sign[")) { Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); chunkData.signs.put(Translators.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag("Sign", pos.getX(), pos.getY(), pos.getZ()), blockState.getId()); + } else if (BlockTranslator.getBlockEntityString(blockState) != null && BlockTranslator.getBlockEntityString(blockState).contains("end_gateway")) { + Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); + chunkData.gateways.put(Translators.getBlockEntityTranslators().get("EndGateway").getDefaultBedrockTag("EndGateway", pos.getX(), pos.getY(), pos.getZ()), blockState.getId()); } else if (BlockTranslator.getBedColor(blockState) > -1) { Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); // Beds need to be updated separately to add the bed color tag @@ -189,6 +192,7 @@ public class ChunkUtils { public com.nukkitx.nbt.tag.CompoundTag[] blockEntities = new com.nukkitx.nbt.tag.CompoundTag[0]; public Object2IntMap signs = new Object2IntOpenHashMap<>(); + public Object2IntMap gateways = new Object2IntOpenHashMap<>(); public Map beds = new HashMap<>(); } }