From d8e619a2d15afcc3e888fdc1ac170b0edb2c525d Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 12 Feb 2025 02:59:36 +0800 Subject: [PATCH] Optimize remove recipes --- .../resources/default/configuration/ores.yml | 10 ++--- .../default/configuration/templates.yml | 8 ++++ .../item/recipe/BukkitRecipeManager.java | 28 ++++++++++--- .../craftengine/bukkit/util/Reflections.java | 41 +++++++++++++++++++ .../core/pack/PackManagerImpl.java | 7 +++- 5 files changed, 81 insertions(+), 13 deletions(-) diff --git a/bukkit-loader/src/main/resources/resources/default/configuration/ores.yml b/bukkit-loader/src/main/resources/resources/default/configuration/ores.yml index f8d4b872b..cd61392c9 100644 --- a/bukkit-loader/src/main/resources/resources/default/configuration/ores.yml +++ b/bukkit-loader/src/main/resources/resources/default/configuration/ores.yml @@ -31,12 +31,10 @@ items: data: display-name: "Topaz" model: - type: "minecraft:model" - path: "minecraft:item/custom/topaz" - generation: - parent: "minecraft:item/generated" - textures: - "layer0": "minecraft:item/custom/topaz" + template: models:generated + arguments: + model_path: "minecraft:item/custom/topaz" + texture_path: "minecraft:item/custom/topaz" blocks: default:topaz_ore: diff --git a/bukkit-loader/src/main/resources/resources/default/configuration/templates.yml b/bukkit-loader/src/main/resources/resources/default/configuration/templates.yml index dec02c212..6d70a9ef7 100644 --- a/bukkit-loader/src/main/resources/resources/default/configuration/templates.yml +++ b/bukkit-loader/src/main/resources/resources/default/configuration/templates.yml @@ -1,5 +1,13 @@ # map-color: https://minecraft.wiki/w/Map_item_format templates: + # Models + models:generated: + type: "minecraft:model" + path: "{model_path}" + generation: + parent: "minecraft:item/generated" + textures: + "layer0": "{texture_path}" # Block Settings block_settings:surface_decoration: diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index d80e76bb2..fdf4b43e3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -128,14 +128,30 @@ public class BukkitRecipeManager implements RecipeManager { this.recipes.clear(); this.dataPackRecipes.clear(); this.customRecipes.clear(); - for (NamespacedKey key : this.injectedDataPackRecipes) { - Bukkit.removeRecipe(key); - } - this.injectedDataPackRecipes.clear(); - for (NamespacedKey key : this.registeredCustomRecipes) { - Bukkit.removeRecipe(key); + if (VersionHelper.isVersionNewerThan1_21_2()) { + try { + Object recipeManager = Reflections.method$MinecraftServer$getRecipeManager.invoke(Reflections.method$MinecraftServer$getServer.invoke(null)); + Object recipeMap = Reflections.field$RecipeManager$recipes.get(recipeManager); + for (NamespacedKey key : this.injectedDataPackRecipes) { + Reflections.method$RecipeMap$removeRecipe.invoke(recipeMap, Reflections.method$CraftRecipe$toMinecraft.invoke(null, key)); + } + for (NamespacedKey key : this.registeredCustomRecipes) { + Reflections.method$RecipeMap$removeRecipe.invoke(recipeMap, Reflections.method$CraftRecipe$toMinecraft.invoke(null, key)); + } + Reflections.method$RecipeManager$finalizeRecipeLoading.invoke(recipeManager); + } catch (ReflectiveOperationException e) { + plugin.logger().warn("Failed to unload custom recipes", e); + } + } else { + for (NamespacedKey key : this.injectedDataPackRecipes) { + Bukkit.removeRecipe(key); + } + for (NamespacedKey key : this.registeredCustomRecipes) { + Bukkit.removeRecipe(key); + } } this.registeredCustomRecipes.clear(); + this.injectedDataPackRecipes.clear(); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index bfb489c8d..04a8951df 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -10,6 +10,7 @@ import io.netty.handler.codec.MessageToByteEncoder; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Location; +import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; @@ -3796,4 +3797,44 @@ public class Reflections { clazz$InventoryView, HumanEntity.class ) ); + + public static final Class clazz$RecipeManager = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeManager"), + BukkitReflectionUtils.assembleMCClass("world.item.crafting.CraftingManager") + ) + ); + + public static final Method method$RecipeManager$finalizeRecipeLoading = + ReflectionUtils.getMethod( + clazz$RecipeManager, new String[]{"finalizeRecipeLoading"} + ); + + public static final Method method$MinecraftServer$getRecipeManager = requireNonNull( + ReflectionUtils.getMethod( + clazz$MinecraftServer, clazz$RecipeManager + ) + ); + + public static final Class clazz$RecipeMap = + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeMap") + ); + + public static final Field field$RecipeManager$recipes = Optional.ofNullable(clazz$RecipeMap) + .map(it -> ReflectionUtils.getDeclaredField(clazz$RecipeManager, it, 0)) + .orElse(null); + + public static final Method method$RecipeMap$removeRecipe = Optional.ofNullable(clazz$RecipeMap) + .map(it -> ReflectionUtils.getMethod(it, boolean.class, clazz$ResourceKey)) + .orElse(null); + + public static final Class clazz$CraftRecipe = + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleCBClass("inventory.CraftRecipe") + ); + + public static final Method method$CraftRecipe$toMinecraft = Optional.ofNullable(clazz$CraftRecipe) + .map(it -> ReflectionUtils.getStaticMethod(it, clazz$ResourceKey, NamespacedKey.class)) + .orElse(null); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/PackManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/pack/PackManagerImpl.java index 615ca9014..d41c2fa4e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/PackManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/PackManagerImpl.java @@ -169,6 +169,7 @@ public class PackManagerImpl implements PackManager { } private void loadConfigs() { + long o1 = System.nanoTime(); for (Pack pack : loadedPacks()) { List files = FileUtils.getConfigsDeeply(pack.configurationFolder()); for (Path path : files) { @@ -190,9 +191,11 @@ public class PackManagerImpl implements PackManager { } } } + long o2 = System.nanoTime(); + this.plugin.logger().info("Loaded packs. Took " + String.format("%.2f", ((o2 - o1) / 1_000_000.0)) + " ms"); for (Map.Entry> entry : this.cachedConfigs.entrySet()) { ConfigSectionParser parser = entry.getKey(); - this.plugin.logger().info("Loading config type: " + parser.sectionId()); + long t1 = System.nanoTime(); for (CachedConfig cached : entry.getValue()) { for (Map.Entry configEntry : cached.config().entrySet()) { String key = configEntry.getKey(); @@ -211,6 +214,8 @@ public class PackManagerImpl implements PackManager { } } } + long t2 = System.nanoTime(); + this.plugin.logger().info("Loaded config type: " + parser.sectionId() + ". Took " + String.format("%.2f", ((t2 - t1) / 1_000_000.0)) + " ms"); } }