From 4e945f2af2083183feddb5fb20edab35474bf22a Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 4 Apr 2025 03:57:55 +0800 Subject: [PATCH] refactor vanilla loots --- .../src/main/resources/translations/en.yml | 5 +- .../bukkit/loot/BukkitVanillaLootManager.java | 105 ++++++++++-------- .../core/loot/AbstractVanillaLootManager.java | 30 +++++ .../core/loot/VanillaLootManager.java | 17 +-- .../craftengine/core/plugin/CraftEngine.java | 4 +- .../config/template/TemplateManagerImpl.java | 10 +- 6 files changed, 105 insertions(+), 66 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 3c2e1dbed..b926499ff 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -64,4 +64,7 @@ warning.config.image.codepoint_in_use: "Issue found in file - Th warning.config.image.invalid_codepoint_grid: "Issue found in file - Image '' has an invalid 'chars' codepoint grind." warning.config.image.file_not_exist: "Issue found in file - PNG file not found for image ''." warning.config.recipe.duplicated: "Issue found in file - Duplicated recipe ''." -warning.config.i18n.unknown_locale: "Issue found in file - Unknown locale ''." \ No newline at end of file +warning.config.i18n.unknown_locale: "Issue found in file - Unknown locale ''." +warning.config.template.duplicated: "Issue found in file - Duplicated template ''." +warning.config.vanilla_loot.type_not_exist: "Issue found in file - 'type' not set for vanilla loot ''." +warning.config.vanilla_loot.block.invalid_target: "Issue found in file - Invalid block target [] in vanilla loot ''." \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java index 9a47edb92..93dd5d2d8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java @@ -8,11 +8,15 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.entity.player.InteractionHand; import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.loot.AbstractVanillaLootManager; import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.loot.VanillaLoot; import net.momirealms.craftengine.core.loot.VanillaLootManager; import net.momirealms.craftengine.core.loot.parameter.LootParameters; +import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.PreConditions; @@ -33,15 +37,13 @@ import java.nio.file.Path; import java.util.*; // note: block listeners are in BlockEventListener to reduce performance cost -public class BukkitVanillaLootManager implements VanillaLootManager, Listener { +public class BukkitVanillaLootManager extends AbstractVanillaLootManager implements Listener { private final BukkitCraftEngine plugin; - private final Map blockLoots; - private final Map entityLoots; + private final VanillaLootParser vanillaLootParser; public BukkitVanillaLootManager(BukkitCraftEngine plugin) { this.plugin = plugin; - this.blockLoots = new HashMap<>(); - this.entityLoots = new HashMap<>(); + this.vanillaLootParser = new VanillaLootParser(); } @Override @@ -54,17 +56,6 @@ public class BukkitVanillaLootManager implements VanillaLootManager, Listener { HandlerList.unregisterAll(this); } - @Override - public void unload() { - this.blockLoots.clear(); - this.entityLoots.clear(); - } - - @Override - public Optional getBlockLoot(int vanillaBlockState) { - return Optional.ofNullable(this.blockLoots.get(vanillaBlockState)); - } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onEntityDeath(EntityDeathEvent event) { Entity entity = event.getEntity(); @@ -97,45 +88,65 @@ public class BukkitVanillaLootManager implements VanillaLootManager, Listener { } @Override - public void parseSection(Pack pack, Path path, Key id, Map section) { - String type = (String) section.get("type"); - if (PreConditions.isNull(type, () -> this.plugin.logger().warn(path, "`type` option is required for vanilla-loot " + id))) { - return; + public ConfigSectionParser parser() { + return this.vanillaLootParser; + } + + public class VanillaLootParser implements ConfigSectionParser { + public static final String[] CONFIG_SECTION_NAME = new String[] {"vanilla-loots", "vanilla-loot", "loots", "loot"}; + + @Override + public int loadingSequence() { + return LoadingSequence.VANILLA_LOOTS; } - VanillaLoot.Type typeEnum = VanillaLoot.Type.valueOf(type.toUpperCase(Locale.ENGLISH)); - boolean override = (boolean) section.getOrDefault("override", false); - List targets = MiscUtils.getAsStringList(section.getOrDefault("target", List.of())); - LootTable lootTable = LootTable.fromMap(MiscUtils.castToMap(section.get("loot"), false)); - switch (typeEnum) { - case BLOCK -> { - for (String target : targets) { - if (target.endsWith("]") && target.contains("[")) { - java.lang.Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(target)); - if (blockState == Reflections.instance$Blocks$AIR$defaultState) { - this.plugin.logger().warn(path, "Failed to load " + id + ". Invalid target " + target); - return; - } - VanillaLoot vanillaLoot = this.blockLoots.computeIfAbsent(BlockStateUtils.blockStateToId(blockState), k -> new VanillaLoot(VanillaLoot.Type.BLOCK)); - vanillaLoot.addLootTable(lootTable); - } else { - for (Object blockState : BlockStateUtils.getAllVanillaBlockStates(Key.of(target))) { + + @Override + public String[] sectionId() { + return CONFIG_SECTION_NAME; + } + + @Override + public void parseSection(Pack pack, Path path, Key id, Map section) { + String type = (String) section.get("type"); + if (type == null) { + TranslationManager.instance().log("warning.config.vanilla_loot.type_not_exist", path.toString(), id.toString()); + return; + } + VanillaLoot.Type typeEnum = VanillaLoot.Type.valueOf(type.toUpperCase(Locale.ENGLISH)); + boolean override = (boolean) section.getOrDefault("override", false); + List targets = MiscUtils.getAsStringList(section.getOrDefault("target", List.of())); + LootTable lootTable = LootTable.fromMap(MiscUtils.castToMap(section.get("loot"), false)); + switch (typeEnum) { + case BLOCK -> { + for (String target : targets) { + if (target.endsWith("]") && target.contains("[")) { + java.lang.Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(target)); if (blockState == Reflections.instance$Blocks$AIR$defaultState) { - this.plugin.logger().warn(path, "Failed to load " + id + ". Invalid target " + target); + TranslationManager.instance().log("warning.config.vanilla_loot.block.invalid_target", path.toString(), id.toString(), target); return; } - VanillaLoot vanillaLoot = this.blockLoots.computeIfAbsent(BlockStateUtils.blockStateToId(blockState), k -> new VanillaLoot(VanillaLoot.Type.BLOCK)); - if (override) vanillaLoot.override(true); + VanillaLoot vanillaLoot = blockLoots.computeIfAbsent(BlockStateUtils.blockStateToId(blockState), k -> new VanillaLoot(VanillaLoot.Type.BLOCK)); vanillaLoot.addLootTable(lootTable); + } else { + for (Object blockState : BlockStateUtils.getAllVanillaBlockStates(Key.of(target))) { + if (blockState == Reflections.instance$Blocks$AIR$defaultState) { + TranslationManager.instance().log("warning.config.vanilla_loot.block.invalid_target", path.toString(), id.toString(), target); + return; + } + VanillaLoot vanillaLoot = blockLoots.computeIfAbsent(BlockStateUtils.blockStateToId(blockState), k -> new VanillaLoot(VanillaLoot.Type.BLOCK)); + if (override) vanillaLoot.override(true); + vanillaLoot.addLootTable(lootTable); + } } } } - } - case ENTITY -> { - for (String target : targets) { - Key key = Key.of(target); - VanillaLoot vanillaLoot = this.entityLoots.computeIfAbsent(key, k -> new VanillaLoot(VanillaLoot.Type.ENTITY)); - vanillaLoot.addLootTable(lootTable); - if (override) vanillaLoot.override(true); + case ENTITY -> { + for (String target : targets) { + Key key = Key.of(target); + VanillaLoot vanillaLoot = entityLoots.computeIfAbsent(key, k -> new VanillaLoot(VanillaLoot.Type.ENTITY)); + vanillaLoot.addLootTable(lootTable); + if (override) vanillaLoot.override(true); + } } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java b/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java new file mode 100644 index 000000000..ae9b199d9 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/AbstractVanillaLootManager.java @@ -0,0 +1,30 @@ +package net.momirealms.craftengine.core.loot; + +import net.momirealms.craftengine.core.util.Key; + +import java.util.*; + +public abstract class AbstractVanillaLootManager implements VanillaLootManager { + protected final Map blockLoots = new HashMap<>(); + // TODO More entity NBT + protected final Map entityLoots = new HashMap<>(); + + public AbstractVanillaLootManager() { + } + + @Override + public void unload() { + this.blockLoots.clear(); + this.entityLoots.clear(); + } + + @Override + public Optional getBlockLoot(int vanillaBlockState) { + return Optional.ofNullable(this.blockLoots.get(vanillaBlockState)); + } + + @Override + public Optional getEntityLoot(Key entity) { + return Optional.ofNullable(this.entityLoots.get(entity)); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java b/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java index b1d672f65..5e301e286 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java @@ -1,23 +1,16 @@ package net.momirealms.craftengine.core.loot; -import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.plugin.Reloadable; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.util.Key; import java.util.Optional; -public interface VanillaLootManager extends ConfigSectionParser, Reloadable { - String[] CONFIG_SECTION_NAME = new String[] {"vanilla-loots", "vanilla-loot", "loots", "loot"}; +public interface VanillaLootManager extends Reloadable { - @Override - default int loadingSequence() { - return LoadingSequence.VANILLA_LOOTS; - } - - @Override - default String[] sectionId() { - return CONFIG_SECTION_NAME; - } + ConfigSectionParser parser(); Optional getBlockLoot(int blockState); + + Optional getEntityLoot(Key entity); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index c38b79ff6..020145b62 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -142,7 +142,7 @@ public abstract class CraftEngine implements Plugin { @Override public void enable() { this.networkManager.enable(); - this.templateManager = new TemplateManagerImpl(this); + this.templateManager = new TemplateManagerImpl(); this.itemBrowserManager = new ItemBrowserManagerImpl(this); this.commandManager.registerDefaultFeatures(); // delay the reload so other plugins can register some parsers @@ -205,7 +205,7 @@ public abstract class CraftEngine implements Plugin { this.packManager.registerConfigSectionParser(this.soundManager); this.packManager.registerConfigSectionParser(this.soundManager.jukeboxSongManager()); // register vanilla loot parser - this.packManager.registerConfigSectionParser(this.vanillaLootManager); + this.packManager.registerConfigSectionParser(this.vanillaLootManager.parser()); } protected abstract void delayedEnable(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index 9f577e83c..5b7560860 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; @@ -19,13 +20,11 @@ import java.util.regex.Matcher; import static net.momirealms.craftengine.core.util.MiscUtils.castToMap; public class TemplateManagerImpl implements TemplateManager { - private final CraftEngine plugin; private final Map templates = new HashMap<>(); private final static Set NON_TEMPLATE_KEY = new HashSet<>(Set.of(TEMPLATE, ARGUMENTS, OVERRIDES)); private final TemplateParser templateParser; - public TemplateManagerImpl(CraftEngine plugin) { - this.plugin = plugin; + public TemplateManagerImpl() { this.templateParser = new TemplateParser(); } @@ -60,7 +59,10 @@ public class TemplateManagerImpl implements TemplateManager { @Override public void addTemplate(Pack pack, Path path, Key id, Object obj) { - if (PreConditions.runIfTrue(this.templates.containsKey(id), () -> this.plugin.logger().warn(path, "Template duplicates: " + id))) return; + if (this.templates.containsKey(id)) { + TranslationManager.instance().log("warning.config.template.duplicated", path.toString(), id.toString()); + return; + } this.templates.put(id, obj); }