Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.21.3 - RecipeBook click ignores ExactChoice (Spigot bug) #4108

Closed
LoneDev6 opened this issue Nov 7, 2024 · 4 comments
Closed

1.21.3 - RecipeBook click ignores ExactChoice (Spigot bug) #4108

LoneDev6 opened this issue Nov 7, 2024 · 4 comments
Labels
compat: new minecraft update type: bug Something isn't working type: spigot bug A bug of Spigot. verdict: workaround implemented A workaround is implemented to mitigate the issue.
Milestone

Comments

@LoneDev6
Copy link
Collaborator

LoneDev6 commented Nov 7, 2024

image

image

@LoneDev6
Copy link
Collaborator Author

LoneDev6 commented Nov 7, 2024

Notes:

Citation from the Spigot forum.

Minecraft recipe book doesn't actually support exact choices. While at server and protocol level you can indeed use the full itemstack as a choice, the client code that handles recipe search only compares the itemstack material (See ShapedRecipe#checkMatch and Ingredient#test).

Example code:

{
    org.bukkit.inventory.ShapedRecipe recipe = new org.bukkit.inventory.ShapedRecipe(new NamespacedKey("test", "test"), new org.bukkit.inventory.ItemStack(Material.BARRIER));
    recipe.shape( "ccc",  "xix",  "xix");
    org.bukkit.inventory.ItemStack exact = new org.bukkit.inventory.ItemStack(Material.DIAMOND);
    ItemMeta meta = exact.getItemMeta();
    meta.setDisplayName("test item");
    exact.setItemMeta(meta);
    recipe.setIngredient('c', new RecipeChoice.ExactChoice(exact));
    recipe.setIngredient('i', new RecipeChoice.MaterialChoice(Material.STICK));

    org.bukkit.inventory.ItemStack aaa = exact.clone();
    aaa.setAmount(32);
    Bukkit.getPlayer("LoneDev").getInventory().addItem(aaa);

    try
    {
        Bukkit.addRecipe(recipe);
    }
    catch(IllegalStateException e) // The recipe already exists, so I remove it and re-add it.
    {
        Bukkit.removeRecipe(recipe.getKey());
        Bukkit.addRecipe(recipe);
    }
}

If you click on the recipe button you clearly see vanilla items added instead of the renamed Diamond.
This causes the recipe to not be selected correctly, instead the vanilla overlapping recipe gets used.

image

image

If you manually put the correct renamed Diamond it works as intended. You can craft the Barrier.

image


Because of this I have to do some magic stuff on the packet level.
This seems mainly caused by how the server code checks for recipe matching.

Even if you provide the correct recipe to handlePlacement, you will get the wrong matrix, of another recipe.

RecipeBookMenu.PostPlaceAction postPlaceAction = bookMenu.handlePlacement(...)
// ServerGamePacketListenerImpl#handlePlaceRecipe(...)

ServerPlayer serverPlayer = ((CraftPlayer) e.getPlayer()).getHandle();
AbstractContainerMenu containerMenu = serverPlayer.containerMenu;
if (containerMenu instanceof RecipeBookMenu bookMenu)
{
    ServerLevel serverLevel = ((CraftWorld) e.getPlayer().getWorld()).getHandle();
    Scheduler.sync(() -> {
        RecipeBookMenu.PostPlaceAction postPlaceAction = bookMenu.handlePlacement(handle.useMaxItems(), false, recipeHolder, serverLevel, serverPlayer.getInventory());
        if (postPlaceAction == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE)
        {
            serverPlayer.connection.send(new ClientboundPlaceGhostRecipePacket(serverPlayer.containerMenu.containerId, recipeFromDisplay.display().display()));
        }
    });
}

@LoneDev6
Copy link
Collaborator Author

LoneDev6 commented Nov 8, 2024

After some tests seems:

  • spigot 1.21.1: doesn't work
  • spigot 1.21.3: doesn't work
  • paper 1.21.1: works correctly
  • paper 1.21.3: doesn't work

Paper has some patches for ExactChoice correct matching on 1.21.1 here.

Anyway seems 1.21.3 client changed some stuff so this might not be fixable completely like it was on 1.21.1.

In the meantime I opened an [issue report on the Spigot Jira, as I think this should be fixed also on Spigot.

I opened an issue also on Paper GitHub, maybe they will fix it before Spigot:

1.21.1

Minecraft.1.21.1.-.Multiplayer.3rd-party.Server.2024-11-08.11-03-35.2.mp4

1.21.3

Minecraft.1.21.3.-.Multiplayer.3rd-party.Server.2024-11-08.11-03-15.2.1.mp4

@LoneDev6 LoneDev6 changed the title 1.21.3 - recipes issues 1.21.3 - RecipeBook click ignores ExactChoice (Spigot bug) Nov 8, 2024
@LoneDev6 LoneDev6 added type: spigot bug A bug of Spigot. type: bug Something isn't working labels Nov 8, 2024
@LoneDev6 LoneDev6 moved this to In Progress in ItemsAdder Nov 8, 2024
@LoneDev6
Copy link
Collaborator Author

LoneDev6 commented Nov 8, 2024

Note:
My workaround of handling that intercepting the ServerboundPlaceRecipePacket packet works only for the first click, the client seems not to send any ServerboundPlaceRecipePacket if the recipe is not craftable due to a clientside check.
The check seems to be this:

// net.minecraft.client.gui.screens.recipebook.RecipeBookComponent
// handlePlaceRecipe calls ServerboundPlaceRecipePacket
   private boolean tryPlaceRecipe(RecipeCollection recipeCollection, RecipeDisplayId recipeDisplayId) {
      if (!recipeCollection.isCraftable(recipeDisplayId) && recipeDisplayId.equals(this.lastPlacedRecipe)) {
         return false;
      } else {
         this.lastPlacedRecipe = recipeDisplayId;
         this.ghostSlots.clear();
         this.minecraft.gameMode.handlePlaceRecipe(this.minecraft.player.containerMenu.containerId, recipeDisplayId, Screen.hasShiftDown());
         return true;
      }
   }

Attaching a debugger to the client shows that 1.21.3 doesn't send the [play:serverbound/minecraft:place_recipe] packet, so my assumption is confirmed, while 1.21.1 client always sends it on click.
This might not be fixable and might actually be a bug of the client.

@LoneDev6 LoneDev6 added the verdict: workaround implemented A workaround is implemented to mitigate the issue. label Nov 8, 2024
@LoneDev6
Copy link
Collaborator Author

LoneDev6 commented Nov 8, 2024

Workaround implemented, but sadly doesn't completely fix the issue.

Known issues:

You can't increment the number of crafted items by clicking or shift-clicking on the recipe.
You have to manually put more ingredients.

  • In order to craft one item you have to click one time.
  • In order to craft multiple items you have to remove all elements from the grid manually and then shift-click, but this will setup the grid to craft the max possible amount of items.

Check the video to understand more.

Minecraft.1.21.3.-.Multiplayer.3rd-party.Server.2024-11-08.17-27-07.2.mp4

@LoneDev6 LoneDev6 moved this from In Progress to Done in ItemsAdder Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compat: new minecraft update type: bug Something isn't working type: spigot bug A bug of Spigot. verdict: workaround implemented A workaround is implemented to mitigate the issue.
Projects
Status: Done
Development

No branches or pull requests

1 participant