Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-5128

recipe iterator missing recipes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • None
    • None
    • macOS 10.14.5

      java version "1.8.0_201"

      Java(TM) SE Runtime Environment (build 1.8.0_201-b09)

      Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

    • CraftBukkit version git-Spigot-935adb3-a0e4747 (MC: 1.14.3)
    • Just my test plugin RecipeTest
    • Yes

      The issue:

      The api does not have a proper way to remove single recipes. I was suggested to iterate thru all the recipes, save backups, clear all the servers recipes, then add back the ones from the saved backup.

      In a previous issue (SPIGOT-4842) I mentioned when doing this, it was adding back recipes to the recipe book that would show up as air. md_5 fixed that. The issue now is that when using this method, (for instance lets say I want to remove just 2 recipes) it appears to remove all recipes that don't show up in the recipe book (ie: dyed leather armor)

      I wrote a little plugin just to test the the issue. Without the plugin, the player can dye armor normally. When using the recipe iterator and removing WOODEN_HOE and WOODEN_AXE, these 2 recipes are removed just fine, all other recipe book recipes seem to show just fine. The issue now is that hidden recipes (recipes that don't ever show up in the recipe book) seem to no longer work, such as dying leather armor.

       

      The test code:

      private void removeRecipes() {
          List<Recipe> backup = new ArrayList<>();
      
          Iterator<Recipe> iterator = getServer().recipeIterator();
      
          while (iterator.hasNext()) {
              Recipe recipe = iterator.next();
              backup.add(recipe);
          }
      
          Iterator<Recipe> backupIterator = backup.iterator();
      
          while (backupIterator.hasNext()) {
              Recipe recipe = backupIterator.next();
              if (recipe != null) {
                  switch (recipe.getResult().getType()) {
                      case WOODEN_HOE:
                      case WOODEN_AXE:
                          backupIterator.remove();
                  }
              }
          }
      
          getServer().clearRecipes();
      
          for (Recipe r : backup) {
              getServer().addRecipe(r);
          }
      }
      

      The solution:

      I cant think of a proper solution that might suit everyone, but one idea I had was if possible, maybe implement another clearRecipe method that would only clear recipes from the server that are included in the recipeIterator method? Or if at all possible, add a method for just removing a single recipe vs having to use this whole iteration system to backup/remove/clear/restore recipes.

       

      More info:

      Tested on Vanilla? no, not possible

      Tested on 1.13.2? yes, same outcome. Leather armor dying recipes are removed.

      Tested on CraftBukkit? yes, same outcome.

      Included sample jar? yes

       

            Unassigned Unassigned
            ShaneBee Shane Bee
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: