From 344d40dd1f0dc6a39f840e6ab6c4127298359a04 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:58:37 -0400 Subject: [PATCH] Smithing recipes mostly work --- .../geyser/session/cache/InputCache.java | 26 +++++- .../BedrockPlayerAuthInputTranslator.java | 6 +- .../java/JavaRecipeBookAddTranslator.java | 26 ++---- .../java/JavaUpdateRecipesTranslator.java | 84 +++++++++++++------ .../player/JavaPlayerPositionTranslator.java | 1 + .../inventory/JavaOpenScreenTranslator.java | 5 +- .../org/geysermc/geyser/util/MathUtils.java | 11 --- 7 files changed, 95 insertions(+), 64 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java index c666ded64..79c37a5a8 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java @@ -27,6 +27,8 @@ package org.geysermc.geyser.session.cache; import lombok.Getter; import lombok.Setter; +import org.cloudburstmc.math.vector.Vector2f; +import org.cloudburstmc.protocol.bedrock.data.InputMode; import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData; import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; import org.geysermc.geyser.session.GeyserSession; @@ -52,12 +54,28 @@ public final class InputCache { // Input is sent to the server before packet positions, as of 1.21.2 Set bedrockInput = packet.getInputData(); var oldInputPacket = this.inputPacket; + + boolean up, down, left, right; + if (packet.getInputMode() == InputMode.MOUSE) { + up = bedrockInput.contains(PlayerAuthInputData.UP); + down = bedrockInput.contains(PlayerAuthInputData.DOWN); + left = bedrockInput.contains(PlayerAuthInputData.LEFT); + right = bedrockInput.contains(PlayerAuthInputData.RIGHT); + } else { + // The above flags don't fire TODO test console + Vector2f analogMovement = packet.getAnalogMoveVector(); + up = analogMovement.getY() > 0; + down = analogMovement.getY() < 0; + left = analogMovement.getX() > 0; + right = analogMovement.getX() < 0; + } + // TODO when is UP_LEFT, etc. used? this.inputPacket = this.inputPacket - .withForward(bedrockInput.contains(PlayerAuthInputData.UP)) - .withBackward(bedrockInput.contains(PlayerAuthInputData.DOWN)) - .withLeft(bedrockInput.contains(PlayerAuthInputData.LEFT)) - .withRight(bedrockInput.contains(PlayerAuthInputData.RIGHT)) + .withForward(up) + .withBackward(down) + .withLeft(left) + .withRight(right) .withJump(bedrockInput.contains(PlayerAuthInputData.JUMPING)) // Looks like this only triggers when the JUMP key input is being pressed. There's also JUMP_DOWN? .withShift(bedrockInput.contains(PlayerAuthInputData.SNEAKING)) .withSprint(bedrockInput.contains(PlayerAuthInputData.SPRINTING)); // SPRINTING will trigger even if the player isn't moving diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java index 93e4cb92a..a366a5b69 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; +import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.vector.Vector2f; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; @@ -50,7 +51,6 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator; import org.geysermc.geyser.util.CooldownUtils; -import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; @@ -71,7 +71,7 @@ public final class BedrockPlayerAuthInputTranslator extends PacketTranslator> javaToBedrockRecipeIds = session.getJavaToBedrockRecipeIds(); CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); @@ -131,8 +132,8 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator { - if (true) { - System.out.println(display); + if (display.result() instanceof SmithingTrimDemoSlotDisplay) { + // Skip these - Bedrock already knows about them from the TrimDataPacket continue; } SmithingRecipeDisplay smithingRecipe = (SmithingRecipeDisplay) display; @@ -169,7 +170,7 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator { -// String molang = "q.is_item_name_any('', " -// + Arrays.stream(items).mapToObj(item -> { -// ItemMapping mapping = session.getItemMappings().getMapping(item); -// return "'" + mapping.getBedrockIdentifier() + "'"; -// }).collect(Collectors.joining(", ")) -// + ")"; -// String molang = Arrays.stream(items).mapToObj(item -> { -// ItemMapping mapping = session.getItemMappings().getMapping(item); -// return "q.identifier == '" + mapping.getBedrockIdentifier() + "'"; -// }).collect(Collectors.joining(" || ")); -// if ("minecraft:planks".equals(tag.toString())) { -// String molang = "q.any_tag('minecraft:planks')"; -// return Collections.singletonList(new ItemDescriptorWithCount(new MolangDescriptor(molang, 10), 1)); -// } - Set itemDescriptors = new HashSet<>(); for (int item : key) { itemDescriptors.add(fromItem(session, item)); } - return new ArrayList<>(itemDescriptors); // This, or a list from the start with contains -> add? + return List.copyOf(itemDescriptors); // This, or a list from the start with contains -> add? }); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java index 693b451ba..9f53a9af4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateRecipesTranslator.java @@ -28,13 +28,20 @@ package org.geysermc.geyser.translator.protocol.java; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.kyori.adventure.key.Key; +import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement; +import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData; +import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData; +import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTrimRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; +import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; +import org.geysermc.geyser.inventory.recipe.TrimRecipe; import org.geysermc.geyser.item.Items; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.ItemMapping; @@ -50,11 +57,14 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.Clientbound import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket.SelectableRecipe; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * Used to send all valid recipes from Java to Bedrock. @@ -94,6 +104,34 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator Registries.JAVA_ITEMS.get(i).javaIdentifier()).collect(Collectors.joining(" "))); + System.out.println(Arrays.stream(smithingAddition).mapToObj(i -> Registries.JAVA_ITEMS.get(i).javaIdentifier()).collect(Collectors.joining(" "))); + oldSmithingTable = false; + // BDS sends armor trim templates and materials before the CraftingDataPacket + TrimDataPacket trimDataPacket = new TrimDataPacket(); + trimDataPacket.getPatterns().addAll(session.getRegistryCache().trimPatterns().values()); + trimDataPacket.getMaterials().addAll(session.getRegistryCache().trimMaterials().values()); + session.sendUpstreamPacket(trimDataPacket); + + // Identical smithing_trim recipe sent by BDS that uses tag-descriptors, as the client seems to ignore the + // approach of using many default-descriptors (which we do for smithing_transform) + craftingDataPacket.getCraftingData().add(SmithingTrimRecipeData.of(TrimRecipe.ID, + TrimRecipe.BASE, TrimRecipe.ADDITION, TrimRecipe.TEMPLATE, "smithing_table", netId++)); + } + session.getGeyser().getLogger().debug("Using old smithing table workaround? " + oldSmithingTable); + session.setOldSmithingTable(oldSmithingTable); + Int2ObjectMap> unsortedStonecutterData = new Int2ObjectOpenHashMap<>(); List stonecutterRecipes = packet.getStonecutterRecipes(); @@ -433,30 +471,28 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator getSmithingTransformRecipes(GeyserSession session) { -// List recipes = new ArrayList<>(); -// ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate(); -// -// for (String identifier : NETHERITE_UPGRADES) { -// recipes.add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData.of(identifier + "_smithing", -// getDescriptorFromId(session, template.getBedrockIdentifier()), -// getDescriptorFromId(session, identifier.replace("netherite", "diamond")), -// getDescriptorFromId(session, "minecraft:netherite_ingot"), -// ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(), -// "smithing_table", -// session.getLastRecipeNetId().getAndIncrement())); -// } -// return recipes; -// } -// -// private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) { -// ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId); -// if (bedrockDefinition != null) { -// return ItemDescriptorWithCount.fromItem(ItemData.builder().definition(bedrockDefinition).count(1).build()); -// } -// GeyserImpl.getInstance().getLogger().debug("Unable to find item with identifier " + bedrockId); -// return ItemDescriptorWithCount.EMPTY; -// } + private void addSmithingTransformRecipes(GeyserSession session, List recipes) { + ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate(); + + for (String identifier : NETHERITE_UPGRADES) { + recipes.add(SmithingTransformRecipeData.of(identifier + "_smithing", + getDescriptorFromId(session, template.getBedrockIdentifier()), + getDescriptorFromId(session, identifier.replace("netherite", "diamond")), + getDescriptorFromId(session, "minecraft:netherite_ingot"), + ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(), + "smithing_table", + session.getLastRecipeNetId().getAndIncrement())); + } + } + + private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) { + ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId); + if (bedrockDefinition != null) { + return ItemDescriptorWithCount.fromItem(ItemData.builder().definition(bedrockDefinition).count(1).build()); + } + GeyserImpl.getInstance().getLogger().debug("Unable to find item with identifier " + bedrockId); + return ItemDescriptorWithCount.EMPTY; + } // // @EqualsAndHashCode // @AllArgsConstructor diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java index ca1b95997..89e8eff82 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java @@ -47,6 +47,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator truncated ? truncated + 1 : truncated; } - /** - * Round the given float to the previous whole number - * - * @param floatNumber Float to round - * @return Rounded number - */ - public static int floor(float floatNumber) { - int truncated = (int) floatNumber; - return floatNumber < truncated ? truncated - 1 : truncated; - } - /** * If number is greater than the max, set it to max, and if number is lower than low, set it to low. *