diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8001187ca..7a1fdba58 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -31,10 +31,10 @@ assignees: '' **Geyser Version** - + **Minecraft: Bedrock Edition Version** **Additional Context** - + diff --git a/connector/pom.xml b/connector/pom.xml index a0142efb7..c9740ea44 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -33,7 +33,7 @@ com.nukkitx.protocol bedrock-v390 - 2.5.5-SNAPSHOT + 2.5.6-SNAPSHOT compile @@ -117,7 +117,7 @@ com.github.steveice10 mcauthlib - 1.1-SNAPSHOT + 1.3-SNAPSHOT compile @@ -145,5 +145,23 @@ reflections 0.9.12 + + net.kyori + text-api + 3.0.3 + compile + + + net.kyori + text-serializer-gson + 3.0.3 + compile + + + net.kyori + text-serializer-legacy + 3.0.3 + compile + diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java index 24ce37a66..7b1b4d69b 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -28,10 +28,7 @@ package org.geysermc.connector.command; import lombok.Getter; import org.geysermc.common.command.ICommandManager; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.command.defaults.HelpCommand; -import org.geysermc.connector.command.defaults.ListCommand; -import org.geysermc.connector.command.defaults.ReloadCommand; -import org.geysermc.connector.command.defaults.StopCommand; +import org.geysermc.connector.command.defaults.*; import java.util.Collections; import java.util.HashMap; @@ -51,6 +48,7 @@ public abstract class CommandManager implements ICommandManager { registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list")); registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload")); registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop")); + registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand")); } public void registerCommand(GeyserCommand command) { diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java new file mode 100644 index 000000000..d181d07e2 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java @@ -0,0 +1,61 @@ +/* + * 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.command.defaults; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; +import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; +import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; + +public class OffhandCommand extends GeyserCommand { + + private GeyserConnector connector; + + public OffhandCommand(GeyserConnector connector, String name, String description, String permission) { + super(name, description, permission); + + this.connector = connector; + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (sender.isConsole()) { + return; + } + + // Make sure the sender is a Bedrock edition client + if (sender instanceof GeyserSession) { + GeyserSession session = (GeyserSession) sender; + ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), + BlockFace.DOWN); + session.getDownstream().getSession().send(releaseItemPacket); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java index bd8444c79..c38a0c23d 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java @@ -48,7 +48,7 @@ public class ReloadCommand extends GeyserCommand { } sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked."); for (GeyserSession session : connector.getPlayers().values()) { - session.getUpstream().disconnect("Geyser has been reloaded... sorry for the inconvenience!"); + session.disconnect("Geyser has been reloaded... sorry for the inconvenience!"); } connector.reload(); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index dcd2475a7..5596ca7ae 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -27,12 +27,15 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; +import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; import com.github.steveice10.mc.protocol.data.message.TextMessage; +import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; +import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityDataMap; -import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.data.EntityFlags; +import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -45,6 +48,7 @@ import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.MessageUtils; @@ -199,6 +203,28 @@ public class Entity { metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); + + // Shield code + if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) { + if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) || + (session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemTranslator.SHIELD)) { + ClientPlayerUseItemPacket useItemPacket; + metadata.getFlags().setFlag(EntityFlag.BLOCKING, true); + if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) { + useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); + } + // Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent + else { + useItemPacket = new ClientPlayerUseItemPacket(Hand.OFF_HAND); + } + session.getDownstream().getSession().send(useItemPacket); + } + } else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) { + metadata.getFlags().setFlag(EntityFlag.BLOCKING, false); + metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true); + ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN); + session.getDownstream().getSession().send(releaseItemPacket); + } // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); if ((xd & 0x20) == 0x20) metadata.put(EntityData.SCALE, 0.0f); @@ -221,6 +247,12 @@ public class Entity { case 5: // no gravity metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); break; + case 7: // blocking + if (entityMetadata.getType() == MetadataType.BYTE) { + byte xd = (byte) entityMetadata.getValue(); + metadata.getFlags().setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01); + } + break; } updateBedrockMetadata(session); diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index 4ad4deffa..7e41fca8b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -47,10 +47,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(LoginPacket loginPacket) { if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { - session.getUpstream().disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); + session.disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); return true; } else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { - session.getUpstream().disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); + session.disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); return true; } @@ -80,7 +80,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { session.getUpstream().sendPacket(stack); break; default: - session.getUpstream().disconnect("disconnectionScreen.resourcePack"); + session.disconnect("disconnectionScreen.resourcePack"); break; } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index bb0878b67..cc5b6d230 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -340,10 +340,16 @@ public class GeyserSession implements CommandSender { downstream.getSession().disconnect(reason); } if (upstream != null && !upstream.isClosed()) { + connector.getPlayers().remove(this.upstream.getAddress()); upstream.disconnect(reason); } } + this.entityCache.getEntities().clear(); + this.scoreboardCache.removeScoreboard(); + this.inventoryCache.getInventories().clear(); + this.windowCache.getWindows().clear(); + closed = true; } diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/InventoryCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/InventoryCache.java index 8734c710a..032f64024 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/InventoryCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/InventoryCache.java @@ -25,14 +25,13 @@ package org.geysermc.connector.network.session.cache; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; -import java.util.HashMap; -import java.util.Map; - public class InventoryCache { private GeyserSession session; @@ -42,7 +41,7 @@ public class InventoryCache { private Inventory openInventory; @Getter - private Map inventories = new HashMap(); + private Int2ObjectMap inventories = new Int2ObjectOpenHashMap<>(); public InventoryCache(GeyserSession session) { this.session = session; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java index 012ef90ea..0d1c08b22 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java @@ -34,6 +34,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.nukkitx.protocol.bedrock.packet.InteractPacket; +import org.geysermc.connector.network.translators.item.ItemTranslator; @Translator(packet = InteractPacket.class) public class BedrockInteractTranslator extends PacketTranslator { @@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator switch (packet.getAction()) { case INTERACT: + if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) { + break; + } ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), InteractAction.INTERACT, Hand.MAIN_HAND); session.getDownstream().getSession().send(interactPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java index f17df09b2..7eb051c50 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java @@ -46,6 +46,7 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.utils.InventoryUtils; @Translator(packet = InventoryTransactionPacket.class) @@ -104,6 +105,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator= 1 && slot <= 44) { @@ -164,6 +187,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator { //crafting grid is not visible in creative mode in java edition for (InventoryActionData action : actions) { if (action.getSource().getContainerId() == ContainerId.CURSOR && (action.getSlot() >= 28 && 31 >= action.getSlot())) { + if (!HAS_RECEIVED_MESSAGE.contains(session.getPlayerEntity().getEntityId())) { + // TODO: Allow the crafting table to be used with non-standalone versions + session.sendMessage("The creative crafting table cannot be used as it's incompatible with Minecraft: Java Edition."); + HAS_RECEIVED_MESSAGE.add(session.getPlayerEntity().getEntityId()); + } updateInventory(session, inventory); InventoryUtils.updateCursor(session); return; 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 79dae31fd..5e0361c06 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 @@ -45,6 +45,9 @@ public class ItemTranslator { private Int2ObjectMap itemTranslators = new Int2ObjectOpenHashMap(); private List nbtItemTranslators; private Map javaIdentifierMap = new HashMap<>(); + + // Shield ID, used in Entity.java + public static final int SHIELD = 829; public void init() { Reflections ref = new Reflections("org.geysermc.connector.network.translators.item"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java new file mode 100644 index 000000000..f29f16fea --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java @@ -0,0 +1,84 @@ +/* + * 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.item.translators.nbt; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import org.geysermc.connector.network.translators.ItemRemapper; +import org.geysermc.connector.network.translators.NbtItemStackTranslator; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.utils.MessageUtils; + +import java.util.ArrayList; +import java.util.List; + +@ItemRemapper +public class BookPagesTranslator extends NbtItemStackTranslator { + + @Override + public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + if (itemTag.contains("pages")) { + List pages = new ArrayList<>(); + ListTag pagesTag = itemTag.get("pages"); + for (Tag tag : pagesTag.getValue()) { + if (!(tag instanceof StringTag)) + continue; + + StringTag textTag = (StringTag) tag; + + CompoundTag pageTag = new CompoundTag(""); + pageTag.put(new StringTag("photoname", "")); + pageTag.put(new StringTag("text", MessageUtils.getBedrockMessage(textTag.getValue()))); + pages.add(pageTag); + } + + itemTag.remove("pages"); + itemTag.put(new ListTag("pages", pages)); + } + } + + @Override + public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) { + if (itemTag.contains("pages")) { + List pages = new ArrayList<>(); + ListTag pagesTag = itemTag.get("pages"); + for (Tag tag : pagesTag.getValue()) { + if (!(tag instanceof CompoundTag)) + continue; + + CompoundTag pageTag = (CompoundTag) tag; + + StringTag textTag = pageTag.get("text"); + pages.add(new StringTag(MessageUtils.getJavaMessage(textTag.getValue()))); + } + + itemTag.remove("pages"); + itemTag.put(new ListTag("pages", pages)); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index fba206668..41e1ae36a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -58,8 +58,10 @@ public class EnchantmentTranslator extends NbtItemStackTranslator { if (!(tag instanceof CompoundTag)) continue; CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag); - bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0)); - newTags.add(bedrockTag); + if (bedrockTag != null) { + bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0)); + newTags.add(bedrockTag); + } } itemTag.remove("StoredEnchantments"); } @@ -117,11 +119,11 @@ public class EnchantmentTranslator extends NbtItemStackTranslator { private CompoundTag remapEnchantment(CompoundTag tag) { - Tag javaEnchLvl = ((CompoundTag) tag).get("lvl"); + Tag javaEnchLvl = tag.get("lvl"); if (!(javaEnchLvl instanceof ShortTag)) return null; - Tag javaEnchId = ((CompoundTag) tag).get("id"); + Tag javaEnchId = tag.get("id"); if (!(javaEnchId instanceof StringTag)) return null; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java index edc20a648..d57b89487 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaServerDeclareCommandsTranslator.java @@ -32,6 +32,8 @@ import com.nukkitx.protocol.bedrock.data.CommandData; import com.nukkitx.protocol.bedrock.data.CommandEnumData; import com.nukkitx.protocol.bedrock.data.CommandParamData; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.Getter; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; @@ -45,8 +47,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator commandData = new ArrayList<>(); - Map commands = new HashMap<>(); - Map> commandArgs = new HashMap<>(); + Int2ObjectMap commands = new Int2ObjectOpenHashMap<>(); + Int2ObjectMap> commandArgs = new Int2ObjectOpenHashMap<>(); // Get the first node, it should be a root node CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java index 28022c16d..78681f8fb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java @@ -51,13 +51,12 @@ public class JavaMapDataTranslator extends PacketTranslator mapItemDataPacket.setWidth(data.getColumns()); mapItemDataPacket.setHeight(data.getRows()); - // Every int entry is an ARGB color + // Every int entry is an ABGR color int[] colors = new int[data.getData().length]; int idx = 0; for (byte colorId : data.getData()) { - colors[idx] = MapColor.fromId(colorId).toARGB(); - idx++; + colors[idx++] = MapColor.fromId(colorId & 0xFF).toABGR(); } mapItemDataPacket.setColors(colors); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java index 6c7eeaf92..3c11d87b6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java @@ -25,14 +25,6 @@ package org.geysermc.connector.network.translators.java.world; -import java.util.Set; -import java.util.concurrent.ThreadLocalRandom; - -import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.PacketTranslator; -import org.geysermc.connector.network.translators.Translator; - import com.github.steveice10.mc.protocol.data.game.ClientRequest; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue; @@ -43,13 +35,16 @@ import com.nukkitx.protocol.bedrock.data.EntityDataMap; import com.nukkitx.protocol.bedrock.data.EntityFlag; import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.PlayerPermission; -import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; -import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; -import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; -import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; -import com.nukkitx.protocol.bedrock.packet.ShowCreditsPacket; - +import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.network.translators.inventory.PlayerInventoryTranslator; + +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ServerNotifyClientPacket.class) public class JavaNotifyClientTranslator extends PacketTranslator { @@ -110,6 +105,10 @@ public class JavaNotifyClientTranslator extends PacketTranslator " + session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " -> " + soundMapping + (soundMapping == null ? "[not found]" : "") + " - " + packet.toString()); - if(soundMapping == null) { + if (soundMapping == null) { return; } LevelSoundEventPacket soundPacket = new LevelSoundEventPacket(); SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); - if(sound == null) { + if (sound == null) { sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); - if(sound == null) { - sound = SoundUtils.toSoundEvent(packetSound); - if(sound == null) { - session.getConnector().getLogger() - .debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket - + " was not a playable level sound, or has yet to be mapped to an enum in " + - "NukkitX SoundEvent "); - } else { - session.getConnector().getLogger() - .debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket - + " was not found in NukkitX SoundEvent, but original packet sound name was."); - } - return; - } + } + if (sound == null) { + sound = SoundUtils.toSoundEvent(packetSound); + } + if (sound == null) { + session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket + + " was not a playable level sound, or has yet to be mapped to an enum in " + + "NukkitX SoundEvent "); + + } else { + session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket + + " was not found in NukkitX SoundEvent, but original packet sound name was."); } soundPacket.setSound(sound); diff --git a/connector/src/main/java/org/geysermc/connector/utils/MapColor.java b/connector/src/main/java/org/geysermc/connector/utils/MapColor.java index 2db144648..b011edc71 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MapColor.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MapColor.java @@ -1,7 +1,5 @@ package org.geysermc.connector.utils; -import java.util.Arrays; - public enum MapColor { COLOR_0(-1, -1, -1), COLOR_1(-1, -1, -1), @@ -212,6 +210,8 @@ public enum MapColor { COLOR_206(37, 22, 16), COLOR_207(19, 11, 8); + private static final MapColor[] VALUES = values(); + private final int red; private final int green; private final int blue; @@ -222,23 +222,18 @@ public enum MapColor { this.blue = blue; } - int getId() { - return ordinal(); - } - public static MapColor fromId(int id) { - return Arrays.stream(values()).filter(color -> color.getId() == id).findFirst().orElse(COLOR_0); + return id >= 0 && id < VALUES.length ? VALUES[id] : COLOR_0; } - public int toARGB() { + public int toABGR() { int alpha = 255; if (red == -1 && green == -1 && blue == -1) alpha = 0; // transparent - long result = red & 0xff; - result |= (green & 0xff) << 8; - result |= (blue & 0xff) << 16; - result |= (alpha & 0xff) << 24; - return (int) (result & 0xFFFFFFFFL); + return ((alpha & 0xFF) << 24) | + ((blue & 0xFF) << 16) | + ((green & 0xFF) << 8) | + ((red & 0xFF) << 0); } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index c00d4bd5b..ac111c71e 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -32,6 +32,9 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; +import net.kyori.text.Component; +import net.kyori.text.serializer.gson.GsonComponentSerializer; +import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.network.session.GeyserSession; import java.util.*; @@ -62,7 +65,7 @@ public class MessageUtils { List furtherParams = getTranslationParams(translation.getTranslationParams(), locale); if (locale != null) { strings.add(insertParams(LocaleUtils.getLocaleString(translation.getTranslationKey(), locale), furtherParams)); - }else{ + } else { strings.addAll(furtherParams); } } else { @@ -118,14 +121,30 @@ public class MessageUtils { } public static String getBedrockMessage(Message message) { - return getTranslatedBedrockMessage(message, null, false); + Component component; + if (isMessage(message.getText())) { + component = GsonComponentSerializer.INSTANCE.deserialize(message.getText()); + } else { + component = GsonComponentSerializer.INSTANCE.deserialize(message.toJsonString()); + } + return LegacyComponentSerializer.legacy().serialize(component); + } + + public static String getBedrockMessage(String message) { + Component component = GsonComponentSerializer.INSTANCE.deserialize(message); + return LegacyComponentSerializer.legacy().serialize(component); + } + + public static String getJavaMessage(String message) { + Component component = LegacyComponentSerializer.legacy().deserialize(message); + return GsonComponentSerializer.INSTANCE.serialize(component); } /** * Inserts the given parameters into the given message both in sequence and as requested * * @param message Message containing possible parameter replacement strings - * @param params A list of parameter strings + * @param params A list of parameter strings * @return Parsed message with all params inserted as needed */ public static String insertParams(String message, List params) { @@ -135,7 +154,7 @@ public class MessageUtils { Matcher m = p.matcher(message); while (m.find()) { try { - newMessage = newMessage.replaceFirst("%" + m.group(1) + "\\$s" , params.get(Integer.parseInt(m.group(1)) - 1)); + newMessage = newMessage.replaceFirst("%" + m.group(1) + "\\$s", params.get(Integer.parseInt(m.group(1)) - 1)); } catch (Exception e) { // Couldn't find the param to replace } diff --git a/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java index 0ff75a21a..874f94d38 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java @@ -84,7 +84,7 @@ public class SoundUtils { public static SoundEvent toSoundEvent(String sound) { try { return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_")); - } catch (IllegalArgumentException ex) { + } catch (Exception ex) { return null; } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java index 46bcebd1f..0df9b4170 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java +++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java @@ -55,7 +55,7 @@ public class Toolbox { public static final Int2ObjectMap ITEM_ENTRIES = new Int2ObjectOpenHashMap<>(); - public static final Map> LOCALE_MAPPINGS = new HashMap<>(); + public static int BARRIER_INDEX = 0; static { /* Load biomes */ @@ -129,6 +129,10 @@ public class Toolbox { entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("is_block").booleanValue())); } + if (entry.getKey().equals("minecraft:barrier")) { + BARRIER_INDEX = itemIndex; + } + itemIndex++; }