From da11cd298c294d5431ee498ba89fac0c6c825a5a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:57:31 -0500 Subject: [PATCH] Address requests --- .../platform/spigot/GeyserSpigotPlugin.java | 2 +- .../GeyserSpigot1_11CraftingListener.java | 21 +++++++++++++------ ...BedrockInventoryTransactionTranslator.java | 7 +++---- .../LecternInventoryTranslator.java | 2 ++ .../translators/LoomInventoryTranslator.java | 3 +++ .../PlayerInventoryTranslator.java | 2 +- .../StonecutterInventoryTranslator.java | 3 +++ .../java/JavaDeclareRecipesTranslator.java | 7 +++++-- .../java/window/JavaSetSlotTranslator.java | 5 ++--- .../java/world/JavaTradeListTranslator.java | 6 ++++++ 10 files changed, 41 insertions(+), 17 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index 5296af1b0..671ad18cf 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -205,7 +205,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { if (isPre1_12) { // Register events needed to send all recipes to the client - Bukkit.getServer().getPluginManager().registerEvents(new GeyserSpigot1_11CraftingListener(this, connector), this); + Bukkit.getServer().getPluginManager().registerEvents(new GeyserSpigot1_11CraftingListener(connector), this); } this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector)); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigot1_11CraftingListener.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigot1_11CraftingListener.java index 66fbb0163..2ee6457ac 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigot1_11CraftingListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigot1_11CraftingListener.java @@ -45,7 +45,6 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.RecipeRegistry; -import org.geysermc.platform.spigot.GeyserSpigotPlugin; import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.data.MappingData; import us.myles.ViaVersion.api.protocol.Protocol; @@ -70,14 +69,12 @@ public class GeyserSpigot1_11CraftingListener implements Listener { * The list of all protocols from the client's version to 1.13. */ private final List> protocolList; - private final ProtocolVersion version; - public GeyserSpigot1_11CraftingListener(GeyserSpigotPlugin plugin, GeyserConnector connector) { + public GeyserSpigot1_11CraftingListener(GeyserConnector connector) { this.connector = connector; this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData(); this.protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION, ProtocolVersion.v1_13.getVersion()); - this.version = plugin.getServerProtocolVersion(); } @EventHandler @@ -101,13 +98,16 @@ public class GeyserSpigot1_11CraftingListener implements Listener { CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); craftingDataPacket.setCleanRecipes(true); + Iterator recipeIterator = Bukkit.getServer().recipeIterator(); while (recipeIterator.hasNext()) { Recipe recipe = recipeIterator.next(); + Pair outputs = translateToBedrock(session, recipe.getResult()); ItemStack javaOutput = outputs.getKey(); ItemData output = outputs.getValue(); if (output.getId() == 0) continue; // If items make air we don't want that + boolean isNotAllAir = false; // Check for all-air recipes if (recipe instanceof ShapedRecipe) { ShapedRecipe shapedRecipe = (ShapedRecipe) recipe; @@ -119,8 +119,9 @@ public class GeyserSpigot1_11CraftingListener implements Listener { Pair result = translateToBedrock(session, shapedRecipe.getIngredientMap().get((char) ('a' + i))); ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()}); input[i] = result.getValue(); - isNotAllAir = isNotAllAir || input[i].getId() != 0; + isNotAllAir |= input[i].getId() != 0; } + if (!isNotAllAir) continue; UUID uuid = UUID.randomUUID(); // Add recipe to our internal cache @@ -128,6 +129,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener { "", ingredients, javaOutput); session.getCraftingRecipes().put(netId, new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPED, uuid.toString(), data)); + // Add recipe for Bedrock craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(), shapedRecipe.getShape()[0].length(), shapedRecipe.getShape().length, Arrays.asList(input), @@ -136,18 +138,21 @@ public class GeyserSpigot1_11CraftingListener implements Listener { ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe; Ingredient[] ingredients = new Ingredient[shapelessRecipe.getIngredientList().size()]; ItemData[] input = new ItemData[shapelessRecipe.getIngredientList().size()]; + for (int i = 0; i < input.length; i++) { Pair result = translateToBedrock(session, shapelessRecipe.getIngredientList().get(i)); ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()}); input[i] = result.getValue(); - isNotAllAir = isNotAllAir || input[i].getId() != 0; + isNotAllAir |= input[i].getId() != 0; } + if (!isNotAllAir) continue; UUID uuid = UUID.randomUUID(); // Add recipe to our internal cache ShapelessRecipeData data = new ShapelessRecipeData("", ingredients, javaOutput); session.getCraftingRecipes().put(netId, new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPELESS, uuid.toString(), data)); + // Add recipe for Bedrock craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(), Arrays.asList(input), Collections.singletonList(output), uuid, "crafting_table", 0, netId++)); @@ -163,10 +168,13 @@ public class GeyserSpigot1_11CraftingListener implements Listener { if (itemStack.getType().getId() == 0) { return new Pair<>(null, ItemData.AIR); } + int legacyId = (itemStack.getType().getId() << 4) | (itemStack.getData().getData() & 0xFFFF); + if (itemStack.getType().getId() == 355 && itemStack.getData().getData() == (byte) 0) { // Handle bed color since the server will always be pre-1.12 legacyId = (itemStack.getType().getId() << 4) | ((byte) 14 & 0xFFFF); } + // old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 and so on int itemId; if (mappingData1_12to1_13.getItemMappings().containsKey(legacyId)) { @@ -189,6 +197,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener { ItemData finalData = ItemTranslator.translateToBedrock(session, mcItemStack); return new Pair<>(mcItemStack, finalData); } + // Empty slot, most likely return new Pair<>(null, ItemData.AIR); } 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 440dff571..0f08e4e84 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 @@ -48,7 +48,6 @@ import com.nukkitx.protocol.bedrock.packet.*; import org.geysermc.connector.entity.CommandBlockMinecartEntity; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.ItemFrameEntity; -import org.geysermc.connector.entity.living.merchant.AbstractMerchantEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.inventory.GeyserItemStack; import org.geysermc.connector.network.session.GeyserSession; @@ -87,10 +86,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { - if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot()) - return; - if (session.getPlayerInventory().getItemInHand().isEmpty()) + if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot() || + session.getPlayerInventory().getItemInHand().isEmpty()) { return; + } boolean dropAll = worldAction.getToItem().getCount() > 1; ClientPlayerActionPacket dropAllPacket = new ClientPlayerActionPacket( diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LecternInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LecternInventoryTranslator.java index c1a623ab6..dbbc418ba 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LecternInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LecternInventoryTranslator.java @@ -103,6 +103,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { Vector3i position = session.getLastInteractionBlockPosition(); // shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet boolean shouldRefresh = !session.getConnector().getWorldManager().shouldExpectLecternHandled() && !session.getLecternCache().contains(position); + NbtMap blockEntityTag; if (tag != null) { int pagesSize = ((ListTag) tag.get("pages")).size(); @@ -132,6 +133,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator { blockEntityTag = lecternTag.putCompound("book", bookTag.build()).build(); } + // Even with serverside access to lecterns, we don't easily know which lectern this is, so we need to rebuild // the block entity tag lecternContainer.setBlockEntityTag(blockEntityTag); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LoomInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LoomInventoryTranslator.java index befe9ff30..38758c5f8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LoomInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/LoomInventoryTranslator.java @@ -128,6 +128,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { return rejectRequest(request); } CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data; + // Get the patterns compound tag List newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND); // Get the pattern that the Bedrock client requests - the last pattern in the Patterns list @@ -151,6 +152,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { } CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); CompoundTag javaBannerPattern = BannerTranslator.getJavaBannerPattern(pattern); + if (blockEntityTag != null) { ListTag patternsList = blockEntityTag.get("Patterns"); if (patternsList != null) { @@ -165,6 +167,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator { blockEntityTag.put(patternsList); inputCopy.getNbt().put(blockEntityTag); } + // Set the new item as the output inventory.setItem(3, inputCopy, session); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/PlayerInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/PlayerInventoryTranslator.java index 50a0ae2c7..e3dbec507 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/PlayerInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/PlayerInventoryTranslator.java @@ -107,7 +107,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (session.getGameMode() == GameMode.CREATIVE) { slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK); - }else{ + } else { slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(i).getItemStack())); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/StonecutterInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/StonecutterInventoryTranslator.java index 4bb5748dc..2acce3a9b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/StonecutterInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/translators/StonecutterInventoryTranslator.java @@ -65,6 +65,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl return rejectRequest(request); } CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data; + StonecutterContainer container = (StonecutterContainer) inventory; // Get the ID of the item we are cutting int id = inventory.getItem(0).getJavaId(); @@ -73,6 +74,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl if (results == null) { return rejectRequest(request); } + ItemStack javaOutput = ItemTranslator.translateToJava(craftData.getResultItems()[0]); int button = results.indexOf(javaOutput.getId()); // If we've already pressed the button with this item, no need to press it again! @@ -86,6 +88,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl inventory.setItem(1, GeyserItemStack.from(javaOutput), session); } } + return translateRequest(session, inventory, request); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java index ee8f03306..bf78d52c6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java @@ -163,10 +163,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator stonecutterRecipeMap = new Int2ObjectOpenHashMap<>(); for (Int2ObjectMap.Entry> data : unsortedStonecutterData.int2ObjectEntrySet()) { + // Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore + // We can get the correct order for button pressing data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData -> - // Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore - // We can get the correct order for button pressing ItemRegistry.getItem(stoneCuttingRecipeData.getResult()).getJavaIdentifier()))); + // Now that it's sorted, let's translate these recipes for (StoneCuttingRecipeData stoneCuttingData : data.getValue()) { // As of 1.16.4, all stonecutter recipes have one ingredient option @@ -174,9 +175,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator } } - if (Arrays.equals(ingredients, mirroredIngredients)) { - continue; - } else if (!testShapedRecipe(mirroredIngredients, inventory, gridDimensions, firstRow, height, firstCol, width)) { + if (Arrays.equals(ingredients, mirroredIngredients) || + !testShapedRecipe(mirroredIngredients, inventory, gridDimensions, firstRow, height, firstCol, width)) { continue; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java index ac194eca7..1432a06e1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java @@ -77,6 +77,7 @@ public class JavaTradeListTranslator extends PacketTranslator tags = new ArrayList<>(addExtraTrade ? packet.getTrades().length + 1 : packet.getTrades().length); @@ -119,6 +120,7 @@ public class JavaTradeListTranslator extends PacketTranslator expTags = new ArrayList<>(5); expTags.add(NbtMap.builder().putInt("0", 0).build()); expTags.add(NbtMap.builder().putInt("1", 10).build()); @@ -126,6 +128,7 @@ public class JavaTradeListTranslator extends PacketTranslator