From dd8997d1e34e8cd3103ee1b7f9bae640af0fbca5 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 28 Apr 2025 05:55:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 81 ++++++++++++++----- .../bukkit/item/BukkitItemManager.java | 24 ++++-- .../craftengine/core/item/ItemSettings.java | 4 +- .../item/recipe/AbstractRecipeFactory.java | 48 +++++++++++ .../item/recipe/AbstractRecipeManager.java | 7 +- .../item/recipe/CustomBlastingRecipe.java | 28 ++----- .../item/recipe/CustomCampfireRecipe.java | 28 ++----- .../core/item/recipe/CustomShapedRecipe.java | 19 +++-- .../item/recipe/CustomShapelessRecipe.java | 70 +++++++++++----- .../item/recipe/CustomSmeltingRecipe.java | 28 ++----- .../recipe/CustomSmithingTransformRecipe.java | 20 +++-- .../core/item/recipe/CustomSmokingRecipe.java | 28 ++----- .../item/recipe/CustomStoneCuttingRecipe.java | 23 +----- .../core/item/recipe/RecipeFactory.java | 8 +- .../core/item/recipe/RecipeTypes.java | 5 +- .../conflict/matcher/ExactPathMatcher.java | 3 +- .../conflict/matcher/FilenameMatcher.java | 3 +- .../matcher/ParentPathPrefixMatcher.java | 3 +- .../matcher/ParentPathSuffixMatcher.java | 3 +- .../conflict/matcher/PathContainsMatcher.java | 4 + .../pack/conflict/matcher/PathMatchers.java | 5 +- .../conflict/matcher/PathPatternMatcher.java | 3 +- .../pack/conflict/resolution/Resolutions.java | 5 +- .../core/pack/model/BaseItemModel.java | 1 - .../core/pack/model/CompositeItemModel.java | 1 - .../core/pack/model/ConditionItemModel.java | 1 - .../model/condition/ConditionProperties.java | 5 +- .../HasComponentConditionProperty.java | 7 +- .../KeyBindDownConditionProperty.java | 7 +- .../model/generation/ModelGeneration.java | 4 - .../CompassRangeDispatchProperty.java | 7 +- .../RangeDispatchProperties.java | 5 +- .../TimeRangeDispatchProperty.java | 7 +- .../select/BlockStateSelectProperty.java | 7 +- .../model/select/LocalTimeSelectProperty.java | 6 +- .../pack/model/select/SelectProperties.java | 5 +- .../core/pack/model/tint/ConstantTint.java | 4 + .../pack/model/tint/CustomModelDataTint.java | 3 +- .../core/pack/model/tint/GrassTint.java | 5 +- .../pack/model/tint/SimpleDefaultTint.java | 2 +- .../core/pack/model/tint/TintFactory.java | 29 ++++--- .../core/pack/model/tint/Tints.java | 5 +- .../core/plugin/config/Config.java | 6 +- .../core/sound/AbstractSoundManager.java | 3 + 44 files changed, 341 insertions(+), 229 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeFactory.java diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 546101339..6b387bd4d 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -75,11 +75,25 @@ 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.recipe.lack_type: "Issue found in file - The recipe '' is missing the required argument 'type'." +warning.config.recipe.invalid_type: "Issue found in file - The recipe '' is using an invalid recipe type ''." +warning.config.recipe.invalid_item: "Issue found in file - The recipe '' is using an invalid item ''." +warning.config.recipe.lack_ingredient: "Issue found in file - The cooking recipe '' is missing the required 'ingredient' argument." +warning.config.recipe.lack_result: "Issue found in file - The recipe '' is missing the required argument 'result'." +warning.config.recipe.result.lack_id: "Issue found in file - The recipe '' is missing the required argument 'id' for recipe result." +warning.config.recipe.shaped.lack_pattern: "Issue found in file - The shaped recipe '' is missing the required argument 'pattern'." +warning.config.recipe.shaped.invalid_pattern: "Issue found in file - The shaped recipe '' is using an invalid pattern ''." +warning.config.recipe.shaped.invalid_symbol: "Issue found in file - The shaped recipe '' is using an invalid symbol '' in pattern." +warning.config.recipe.smithing_transform.post_processor.lack_type: "Issue found in file - The smithing transform recipe '' is missing the required argument 'type' for one of the post-processors." +warning.config.recipe.smithing_transform.post_processor.invalid_type: "Issue found in file - The smithing transform recipe '' is using an invalid post processor type ''." +warning.config.recipe.smithing_transform.post_processor.keep_component.lack_components: "Issue found in file - The smithing transform recipe '' is missing the required argument 'components' for post-processors 'keep_components'" +warning.config.recipe.smithing_transform.post_processor.keep_component.lack_tags: "Issue found in file - The smithing transform recipe '' is missing the required argument 'tags' for post-processors 'keep_tags'" 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 ''." warning.config.sound.duplicated: "Issue found in file - Duplicated sound ''." +warning.config.sound.lack_sounds: "Issue found in file - The sound '' is missing the required argument 'sounds'." warning.config.jukebox_song.duplicated: "Issue found in file - Duplicated jukebox song ''." warning.config.jukebox_song.lack_sound: "Issue found in file - The jukebox song '' is missing the required 'sound' argument." warning.config.furniture.duplicated: "Issue found in file - Duplicated furniture ''." @@ -89,6 +103,7 @@ warning.config.furniture.settings.unknown: "Issue found in file warning.config.furniture.hitbox.invalid_type: "Issue found in file - The furniture '' is using an invalid hitbox type ''." warning.config.furniture.hitbox.custom.invalid_entity: "Issue found in file - The furniture '' is using a custom hitbox with invalid entity type ''." warning.config.item.duplicated: "Issue found in file - Duplicated item ''." +warning.config.item.settings.unknown: "Issue found in file - The item '' is using an unknown setting type ''." warning.config.item.lack_material: "Issue found in file - The item '' is missing the required 'material' argument." warning.config.item.invalid_material: "Issue found in file - The item '' is using an invalid material type ''." warning.config.item.bad_custom_model_data_value: "Issue found in file - The item '' is using a custom model data [] that is too large. It's recommended to use a value lower than 16,777,216." @@ -100,16 +115,34 @@ warning.config.item.behavior.block.lack_block: "Issue found in file Issue found in file - The item '' is missing the required 'furniture' argument for 'furniture_item' behavior." warning.config.item.behavior.liquid_collision_block.lack_block: "Issue found in file - The item '' is missing the required 'block' argument for 'liquid_collision_block_item' behavior." warning.config.item.model.invalid_type: "Issue found in file - The item '' is using an invalid model type ''." +warning.config.item.model.tint.lack_type: "Issue found in file - The item '' is missing the required 'type' argument for tint." +warning.config.item.model.tint.invalid_type: "Issue found in file - The item '' is using an invalid tint type ''." +warning.config.item.model.tint.constant.lack_value: "Issue found in file - The item '' is missing the required 'value' argument for constant tint." +warning.config.item.model.tint.grass.invalid_temperature: "Issue found in file - The item '' is using an invalid temperature '' for grass tint, which is expected to be between 0 and 1." +warning.config.item.model.tint.grass.invalid_downfall: "Issue found in file - The item '' is using an invalid downfall '' for grass tint, which is expected to be between 0 and 1." +warning.config.item.model.tint.invalid_value: "Issue found in file - The item '' is using an invalid tint ''." warning.config.item.model.base.lack_path: "Issue found in file - The item '' is missing the required 'path' argument for 'minecraft:model'." warning.config.item.model.base.invalid_resource_location: "Issue found in file - The item '' has an invalid 'path' argument [] for 'minecraft:model' which contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters." +warning.config.item.model.condition.lack_property: "Issue found in file - The item '' is missing the required 'property' argument for 'minecraft:condition'." +warning.config.item.model.condition.invalid_property: "Issue found in file - The item '' is using an invalid property '' for 'minecraft:condition'." warning.config.item.model.condition.lack_on_true: "Issue found in file - The item '' is missing the required 'on-true' argument for 'minecraft:condition'." warning.config.item.model.condition.lack_on_false: "Issue found in file - The item '' is missing the required 'on-false' argument for 'minecraft:condition'." +warning.config.item.model.condition.keybind_down.lack_keybind: "Issue found in file - The item '' is missing the required 'keybind' argument for 'minecraft:keybind_down'." +warning.config.item.model.condition.has_component.lack_component: "Issue found in file - The item '' is missing the required 'component' argument for 'minecraft:has_component'." warning.config.item.model.composite.lack_models: "Issue found in file - The item '' is missing the required 'models' argument for 'minecraft:composite'." +warning.config.item.model.range_dispatch.lack_property: "Issue found in file - The item '' is missing the required 'property' argument for 'minecraft:range_dispatch'." +warning.config.item.model.range_dispatch.invalid_property: "Issue found in file - The item '' is using an invalid property '' for 'minecraft:range_dispatch'." warning.config.item.model.range_dispatch.lack_entries: "Issue found in file - The item '' is missing the required 'entries' argument for 'minecraft:composite'." warning.config.item.model.range_dispatch.entry.lack_model: "Issue found in file - The item '' is missing the required 'model' argument for one of the entries in 'minecraft:composite'." +warning.config.item.model.range_dispatch.compass.lack_target: "Issue found in file - The item '' is missing the required 'target' argument for 'minecraft:compass'." +warning.config.item.model.range_dispatch.time.lack_source: "Issue found in file - The item '' is missing the required 'source' argument for 'minecraft:time'." +warning.config.item.model.select.lack_property: "Issue found in file - The item '' is missing the required 'property' argument for 'minecraft:select'." +warning.config.item.model.select.invalid_property: "Issue found in file - The item '' is using an invalid property '' for 'minecraft:select'." warning.config.item.model.select.lack_cases: "Issue found in file - The item '' is missing the required 'cases' argument for 'minecraft:select'." warning.config.item.model.select.case.lack_when: "Issue found in file - The item '' is missing the required 'when' argument for one of the cases in 'minecraft:select'." warning.config.item.model.select.case.lack_model: "Issue found in file - The item '' is missing the required 'model' argument for one of the cases in 'minecraft:select'." +warning.config.item.model.select.block_state.lack_block_state_property: "Issue found in file - The item '' is missing the required 'block-state-property' argument for 'minecraft:block_state'." +warning.config.item.model.select.local_time.lack_pattern: "Issue found in file - The item '' is missing the required 'pattern' argument for 'minecraft:local_time'." warning.config.block.duplicated: "Issue found in file - Duplicated block ''." warning.config.block.lack_state: "Issue found in file - The block '' is missing the required 'state' argument." warning.config.block.state.lack_real_id: "Issue found in file - The block '' is missing the required 'id' argument for 'state'." @@ -149,6 +182,25 @@ warning.config.emoji.lack_keywords: "Issue found in file - The e warning.config.emoji.duplicated: "Issue found in file - Duplicated emoji ''." warning.config.emoji.invalid_image: "Issue found in file - The emoji '' has an invalid 'image' argument ''." warning.config.advancement.duplicated: "Issue found in file - Duplicated advancement ''." +warning.config.loot_table.lack_pools: "Issue found in file - '' has a misconfigured loot table which is missing the required argument 'pools'." +warning.config.loot_table.wrong_pools_type: "Issue found in file - '' has a misconfigured loot table, 'pools' should be a string/map list, current type: ''." +warning.config.loot_table.wrong_conditions_type: "Issue found in file - '' has a misconfigured loot table, 'conditions' should be a map list, current type: ''." +warning.config.loot_table.wrong_functions_type: "Issue found in file - '' has a misconfigured loot table, 'functions' should be a map list, current type: ''." +warning.config.loot_table.wrong_entries_type: "Issue found in file - '' has a misconfigured loot table, 'entries' should be a map list, current type: ''." +warning.config.loot_table.function.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the functions is missing the required argument 'type'." +warning.config.loot_table.function.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the functions is using an invalid function type ''." +warning.config.loot_table.function.apply_bonus.lack_enchantment: "Issue found in file - '' has a misconfigured loot table, function 'apply_bonus' is missing the required argument 'enchantment'." +warning.config.loot_table.function.apply_bonus.lack_formula: "Issue found in file - '' has a misconfigured loot table, function 'apply_bonus' is missing the required argument 'formula'." +warning.config.loot_table.function.drop_exp.lack_count: "Issue found in file - '' has a misconfigured loot table, function 'drop_exp' is missing the required argument 'count'." +warning.config.loot_table.function.set_count.lack_count: "Issue found in file - '' has a misconfigured loot table, function 'set_count' is missing the required argument 'count'." +warning.config.loot_table.entry.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is missing the required argument 'type'." +warning.config.loot_table.entry.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is using an invalid entry type ''." +warning.config.loot_table.entry.exp.lack_count: "Issue found in file - '' has a misconfigured loot table, entry 'exp' is missing the required argument 'count'." +warning.config.loot_table.entry.item.lack_item: "Issue found in file - '' has a misconfigured loot table, entry 'item' is missing the required argument 'item'." +warning.config.loot_table.condition.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is missing the required argument 'type'." +warning.config.loot_table.condition.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is using an invalid condition type ''." +warning.config.loot_table.number.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is missing the required argument 'type'." +warning.config.loot_table.number.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is using an invalid number type ''." warning.config.host.lack_type: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required argument 'type' for host." warning.config.host.invalid_type: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Host 'type' [] is invalid. Please read https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host" warning.config.host.external.lack_url: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required argument 'url' for external host." @@ -175,22 +227,13 @@ warning.config.host.self.invalid_port: "Issue found in config.yml at 're warning.config.host.gitlab.lack_url: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required argument 'gitlab-url' for gitlab host." warning.config.host.gitlab.lack_access_token: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required argument 'access-token' for gitlab host." warning.config.host.gitlab.lack_project_id: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required argument 'project-id' for gitlab host." -warning.config.loot_table.lack_pools: "Issue found in file - '' has a misconfigured loot table which is missing the required argument 'pools'." -warning.config.loot_table.wrong_pools_type: "Issue found in file - '' has a misconfigured loot table, 'pools' should be a string/map list, current type: ''." -warning.config.loot_table.wrong_conditions_type: "Issue found in file - '' has a misconfigured loot table, 'conditions' should be a map list, current type: ''." -warning.config.loot_table.wrong_functions_type: "Issue found in file - '' has a misconfigured loot table, 'functions' should be a map list, current type: ''." -warning.config.loot_table.wrong_entries_type: "Issue found in file - '' has a misconfigured loot table, 'entries' should be a map list, current type: ''." -warning.config.loot_table.function.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the functions is missing the required argument 'type'." -warning.config.loot_table.function.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the functions is using an invalid function type ''." -warning.config.loot_table.function.apply_bonus.lack_enchantment: "Issue found in file - '' has a misconfigured loot table, function 'apply_bonus' is missing the required argument 'enchantment'." -warning.config.loot_table.function.apply_bonus.lack_formula: "Issue found in file - '' has a misconfigured loot table, function 'apply_bonus' is missing the required argument 'formula'." -warning.config.loot_table.function.drop_exp.lack_count: "Issue found in file - '' has a misconfigured loot table, function 'drop_exp' is missing the required argument 'count'." -warning.config.loot_table.function.set_count.lack_count: "Issue found in file - '' has a misconfigured loot table, function 'set_count' is missing the required argument 'count'." -warning.config.loot_table.entry.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is missing the required argument 'type'." -warning.config.loot_table.entry.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is using an invalid entry type ''." -warning.config.loot_table.entry.exp.lack_count: "Issue found in file - '' has a misconfigured loot table, entry 'exp' is missing the required argument 'count'." -warning.config.loot_table.entry.item.lack_item: "Issue found in file - '' has a misconfigured loot table, entry 'item' is missing the required argument 'item'." -warning.config.loot_table.condition.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is missing the required argument 'type'." -warning.config.loot_table.condition.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is using an invalid condition type ''." -warning.config.loot_table.number.lack_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is missing the required argument 'type'." -warning.config.loot_table.number.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is using an invalid number type ''." \ No newline at end of file +warning.config.conflict_matcher.lack_type: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'type' for one of the handlers." +warning.config.conflict_matcher.invalid_type: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - One of the terms is using the invalid type ''." +warning.config.conflict_matcher.exact.lack_path: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'path' for 'exact' matcher." +warning.config.conflict_matcher.contains.lack_path: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'path' for 'contains' matcher." +warning.config.conflict_matcher.filename.lack_name: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'path' for 'filename' matcher." +warning.config.conflict_matcher.pattern.lack_pattern: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'pattern' for 'pattern' matcher." +warning.config.conflict_matcher.parent_path_prefix.lack_prefix: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'prefix' for 'parent_path_prefix' matcher." +warning.config.conflict_matcher.parent_path_suffix.lack_suffix: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'suffix' for 'parent_path_suffix' matcher." +warning.config.conflict_resolution.lack_type: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - Missing required argument 'type' for one of the resolutions." +warning.config.conflict_resolution.invalid_type: "Issue found in config.yml at 'resource-pack.duplicated-files-handler' - One of the resolutions is using the invalid type ''." \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 477933c58..7ebecbf2f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -340,12 +340,14 @@ public class BukkitItemManager extends AbstractItemManager { } ItemSettings itemSettings; - if (section.containsKey("settings")) { - Map settings = MiscUtils.castToMap(section.get("settings"), false); - itemSettings = ItemSettings.fromMap(settings); - } else { - itemSettings = ItemSettings.of(); + try { + itemSettings = ItemSettings.fromMap(MiscUtils.castToMap(section.get("settings"), true)); + } catch (LocalizedResourceConfigException e) { + e.setPath(path); + e.setId(id); + throw e; } + if (isVanillaItem) { itemSettings.canPlaceRelatedVanillaBlock(true); } @@ -389,6 +391,15 @@ public class BukkitItemManager extends AbstractItemManager { return; } + ItemModel model; + try { + model = ItemModels.fromMap(modelSection); + } catch (LocalizedResourceConfigException e) { + e.setPath(path); + e.setId(id); + throw e; + } + boolean hasModel = false; if (customModelData != 0) { hasModel= true; @@ -406,7 +417,6 @@ public class BukkitItemManager extends AbstractItemManager { conflict.put(customModelData, id); // Parse models - ItemModel model = ItemModels.fromMap(modelSection); for (ModelGeneration generation : model.modelsToGenerate()) { prepareModelGeneration(path, id, generation); } @@ -425,8 +435,6 @@ public class BukkitItemManager extends AbstractItemManager { } if (itemModelKey != null) { hasModel = true; - // use components - ItemModel model = ItemModels.fromMap(modelSection); for (ModelGeneration generation : model.modelsToGenerate()) { prepareModelGeneration(path, id, generation); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index 2e02df698..8b646436a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.item.modifier.EquippableModifier; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.VersionHelper; @@ -35,6 +36,7 @@ public class ItemSettings { } public static ItemSettings fromMap(Map map) { + if (map == null) return ItemSettings.of(); return applyModifiers(ItemSettings.of(), map); } @@ -56,7 +58,7 @@ public class ItemSettings { if (factory != null) { factory.createModifier(entry.getValue()).apply(settings); } else { - throw new IllegalArgumentException("Unknown item settings key: " + entry.getKey()); + throw new LocalizedResourceConfigException("warning.config.item.settings.unknown", new IllegalArgumentException("Unknown item settings key: " + entry.getKey()), entry.getKey()); } } return settings; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeFactory.java new file mode 100644 index 000000000..bfb72ec03 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeFactory.java @@ -0,0 +1,48 @@ +package net.momirealms.craftengine.core.item.recipe; + +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Holder; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public abstract class AbstractRecipeFactory implements RecipeFactory { + + protected List ingredients(Map arguments) { + return MiscUtils.getAsStringList(getIngredientOrThrow(arguments)); + } + + protected Map ingredientMap(Map arguments) { + return MiscUtils.castToMap(getIngredientOrThrow(arguments), true); + } + + protected Set> ingredientHolders(Map arguments) { + Set> holders = new HashSet<>(); + for (String item : ingredients(arguments)) { + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); + } + } + return holders; + } + + protected Object getIngredientOrThrow(Map arguments) { + Object ingredient = arguments.get("ingredient"); + if (ingredient == null) { + ingredient = arguments.get("ingredients"); + } + if (ingredient == null) { + throw new LocalizedResourceConfigException("warning.config.recipe.lack_ingredient", new NullPointerException("'ingredient' should not be null")); + } + return ingredient; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java index 1c13e04db..f12d49c16 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java @@ -162,9 +162,10 @@ public abstract class AbstractRecipeManager implements RecipeManager { Recipe recipe; try { recipe = RecipeTypes.fromMap(id, section); - } catch (Exception e) { - CraftEngine.instance().logger().warn(path, "Failed to create recipe: " + id, e); - return; + } catch (LocalizedResourceConfigException e) { + e.setPath(path); + e.setId(id); + throw e; } try { markAsCustomRecipe(id); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java index 8d80181ec..c5d68e2c1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBlastingRecipe.java @@ -1,13 +1,13 @@ package net.momirealms.craftengine.core.item.recipe; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Set; public class CustomBlastingRecipe extends CustomCookingRecipe { public static final Factory FACTORY = new Factory<>(); @@ -21,7 +21,7 @@ public class CustomBlastingRecipe extends CustomCookingRecipe { return RecipeTypes.BLASTING; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override @@ -30,24 +30,8 @@ public class CustomBlastingRecipe extends CustomCookingRecipe { String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); float experience = MiscUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f)); - List items = MiscUtils.getAsStringList(arguments.get("ingredient")); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); - } - } - return new CustomBlastingRecipe( - id, - recipeCategory, - group, - Ingredient.of(holders), - cookingTime, - experience, - parseResult(arguments) - ); + Set> holders = ingredientHolders(arguments); + return new CustomBlastingRecipe(id, recipeCategory, group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java index fd3220981..96a983fec 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomCampfireRecipe.java @@ -1,13 +1,13 @@ package net.momirealms.craftengine.core.item.recipe; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Set; public class CustomCampfireRecipe extends CustomCookingRecipe { public static final Factory FACTORY = new Factory<>(); @@ -21,7 +21,7 @@ public class CustomCampfireRecipe extends CustomCookingRecipe { return RecipeTypes.CAMPFIRE_COOKING; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override @@ -30,24 +30,8 @@ public class CustomCampfireRecipe extends CustomCookingRecipe { String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); float experience = MiscUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f)); - List items = MiscUtils.getAsStringList(arguments.get("ingredient")); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); - } - } - return new CustomCampfireRecipe( - id, - recipeCategory, - group, - Ingredient.of(holders), - cookingTime, - experience, - parseResult(arguments) - ); + Set> holders = ingredientHolders(arguments); + return new CustomCampfireRecipe(id, recipeCategory, group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java index d5e4b7877..4000cde6c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapedRecipe.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.recipe.input.CraftingInput; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; @@ -133,29 +134,26 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { } } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override public Recipe create(Key id, Map arguments) { List pattern = MiscUtils.getAsStringList(arguments.get("pattern")); if (pattern.isEmpty()) { - throw new IllegalArgumentException("pattern cannot be empty"); + throw new LocalizedResourceConfigException("warning.config.recipe.shaped.lack_pattern", new NullPointerException("'pattern' cannot be empty")); } if (!validatePattern(pattern)) { - throw new IllegalArgumentException("Invalid pattern: " + pattern); - } - Map ingredientMap = MiscUtils.castToMap(arguments.get("ingredients"), true); - if (ingredientMap == null) { - throw new IllegalArgumentException("ingredients cannot be empty"); + throw new LocalizedResourceConfigException("warning.config.recipe.shaped.invalid_pattern", new IllegalArgumentException("Invalid pattern: " + pattern), pattern.toString()); } + Object ingredientObj = getIngredientOrThrow(arguments); CraftingRecipeCategory recipeCategory = arguments.containsKey("category") ? CraftingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; Map> ingredients = new HashMap<>(); - for (Map.Entry entry : ingredientMap.entrySet()) { + for (Map.Entry entry : MiscUtils.castToMap(ingredientObj, false).entrySet()) { String key = entry.getKey(); if (key.length() != 1) { - throw new IllegalArgumentException("Invalid key: " + key); + throw new LocalizedResourceConfigException("warning.config.recipe.shaped.invalid_symbol", new IllegalArgumentException("Invalid symbol: " + key), key); } char ch = key.charAt(0); List items = MiscUtils.getAsStringList(entry.getValue()); @@ -164,7 +162,8 @@ public class CustomShapedRecipe extends CustomCraftingTableRecipe { if (item.charAt(0) == '#') { holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); } } ingredients.put(ch, Ingredient.of(holders)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java index f0bb3cc87..7668a13bc 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomShapelessRecipe.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.recipe.input.CraftingInput; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; @@ -52,37 +53,66 @@ public class CustomShapelessRecipe extends CustomCraftingTableRecipe { return RecipeTypes.SHAPELESS; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override public Recipe create(Key id, Map arguments) { - Map ingredientMap = MiscUtils.castToMap(arguments.get("ingredients"), true); - if (ingredientMap == null) { - throw new IllegalArgumentException("ingredients cannot be empty"); - } CraftingRecipeCategory recipeCategory = arguments.containsKey("category") ? CraftingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null; String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; List> ingredients = new ArrayList<>(); - for (Map.Entry entry : ingredientMap.entrySet()) { - List items = MiscUtils.getAsStringList(entry.getValue()); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); + Object ingredientsObject = getIngredientOrThrow(arguments); + if (ingredientsObject instanceof Map map) { + for (Map.Entry entry : (MiscUtils.castToMap(map, false)).entrySet()) { + List items = MiscUtils.getAsStringList(entry.getValue()); + Set> holders = new HashSet<>(); + for (String item : items) { + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); + } } + ingredients.add(Ingredient.of(holders)); + } + } else if (ingredientsObject instanceof List list) { + for (Object obj : list) { + if (obj instanceof List inner) { + Set> holders = new HashSet<>(); + for (String item : MiscUtils.getAsStringList(inner)) { + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); + } + } + ingredients.add(Ingredient.of(holders)); + } else { + String item = obj.toString(); + Set> holders = new HashSet<>(); + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); + } + ingredients.add(Ingredient.of(holders)); + } + } + } else { + String item = ingredientsObject.toString(); + Set> holders = new HashSet<>(); + if (item.charAt(0) == '#') { + holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); + } else { + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); } ingredients.add(Ingredient.of(holders)); } - return new CustomShapelessRecipe( - id, - recipeCategory, - group, - ingredients, - parseResult(arguments) - ); + return new CustomShapelessRecipe(id, recipeCategory, group, ingredients, parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java index 7f4fed503..b08089f7b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmeltingRecipe.java @@ -1,13 +1,13 @@ package net.momirealms.craftengine.core.item.recipe; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Set; public class CustomSmeltingRecipe extends CustomCookingRecipe { public static final Factory FACTORY = new Factory<>(); @@ -21,7 +21,7 @@ public class CustomSmeltingRecipe extends CustomCookingRecipe { return RecipeTypes.SMELTING; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override @@ -30,24 +30,8 @@ public class CustomSmeltingRecipe extends CustomCookingRecipe { String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); float experience = MiscUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f)); - List items = MiscUtils.getAsStringList(arguments.get("ingredient")); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); - } - } - return new CustomSmeltingRecipe( - id, - recipeCategory, - group, - Ingredient.of(holders), - cookingTime, - experience, - parseResult(arguments) - ); + Set> holders = ingredientHolders(arguments); + return new CustomSmeltingRecipe(id, recipeCategory, group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java index 51dabc68d..7f2c7d2f5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java @@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.item.recipe.input.SmithingInput; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -149,7 +150,8 @@ public class CustomSmithingTransformRecipe implements Recipe { if (item.charAt(0) == '#') { holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); + holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Invalid vanilla/custom item: " + item), item))); } } return holders.isEmpty() ? null : Ingredient.of(holders); @@ -180,12 +182,12 @@ public class CustomSmithingTransformRecipe implements Recipe { public static ItemDataProcessor fromMap(Map map) { String type = (String) map.get("type"); if (type == null) { - throw new NullPointerException("processor type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.lack_type", new NullPointerException("Missing required parameter 'type' for post processor")); } Key key = Key.withDefaultNamespace(type, "craftengine"); ItemDataProcessor.Factory factory = BuiltInRegistries.SMITHING_RESULT_PROCESSOR_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown processor type: " + type); + throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.invalid_type", new IllegalArgumentException("Unknown processor type: " + type), type); } return factory.create(map); } @@ -233,7 +235,11 @@ public class CustomSmithingTransformRecipe implements Recipe { @Override public ItemDataProcessor create(Map arguments) { - List components = MiscUtils.getAsStringList(arguments.get("components")); + Object componentsObj = arguments.get("components"); + if (componentsObj == null) { + throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.keep_component.lack_components", new NullPointerException("Missing required parameter 'components' for post processor")); + } + List components = MiscUtils.getAsStringList(componentsObj); return new KeepComponents(components.stream().map(Key::of).toList()); } } @@ -266,7 +272,11 @@ public class CustomSmithingTransformRecipe implements Recipe { @Override public ItemDataProcessor create(Map arguments) { - List tags = MiscUtils.getAsStringList(arguments.get("tags")); + Object tagsObj = arguments.get("tags"); + if (tagsObj == null) { + throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.post_processor.keep_component.lack_tags", new NullPointerException("Missing required parameter 'tags' for post processor")); + } + List tags = MiscUtils.getAsStringList(tagsObj); return new KeepTags(tags.stream().map(it -> it.split("\\.")).toList()); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java index 2976836e0..df5e02007 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmokingRecipe.java @@ -1,13 +1,13 @@ package net.momirealms.craftengine.core.item.recipe; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Set; public class CustomSmokingRecipe extends CustomCookingRecipe { public static final Factory FACTORY = new Factory<>(); @@ -21,7 +21,7 @@ public class CustomSmokingRecipe extends CustomCookingRecipe { return RecipeTypes.SMOKING; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"}) @Override @@ -30,24 +30,8 @@ public class CustomSmokingRecipe extends CustomCookingRecipe { String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80)); float experience = MiscUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f)); - List items = MiscUtils.getAsStringList(arguments.get("ingredient")); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); - } - } - return new CustomSmokingRecipe( - id, - recipeCategory, - group, - Ingredient.of(holders), - cookingTime, - experience, - parseResult(arguments) - ); + Set> holders = ingredientHolders(arguments); + return new CustomSmokingRecipe(id, recipeCategory, group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java index bc0cbc901..1d9b4b528 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomStoneCuttingRecipe.java @@ -2,14 +2,10 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -43,27 +39,14 @@ public class CustomStoneCuttingRecipe extends AbstractGroupedRecipe { return ingredient; } - public static class Factory implements RecipeFactory { + public static class Factory extends AbstractRecipeFactory { @SuppressWarnings({"DuplicatedCode"}) @Override public Recipe create(Key id, Map arguments) { String group = arguments.containsKey("group") ? arguments.get("group").toString() : null; - List items = MiscUtils.getAsStringList(arguments.get("ingredient")); - Set> holders = new HashSet<>(); - for (String item : items) { - if (item.charAt(0) == '#') { - holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1)))); - } else { - holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(() -> new IllegalArgumentException("Invalid vanilla/custom item: " + item))); - } - } - return new CustomStoneCuttingRecipe<>( - id, - group, - Ingredient.of(holders), - parseResult(arguments) - ); + Set> holders = ingredientHolders(arguments); + return new CustomStoneCuttingRecipe<>(id, group, Ingredient.of(holders), parseResult(arguments)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java index e6092042f..517a04f35 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; @@ -14,15 +15,16 @@ public interface RecipeFactory { default CustomRecipeResult parseResult(Map arguments) { Map resultMap = MiscUtils.castToMap(arguments.get("result"), true); if (resultMap == null) { - throw new IllegalArgumentException("result cannot be empty"); + throw new LocalizedResourceConfigException("warning.config.recipe.lack_result", new IllegalArgumentException("result cannot be empty for recipe")); } String id = (String) resultMap.get("id"); if (id == null) { - throw new IllegalArgumentException("result.id cannot be empty"); + throw new LocalizedResourceConfigException("warning.config.recipe.result.lack_id", new IllegalArgumentException("id cannot be empty for result")); } int count = MiscUtils.getAsInt(resultMap.getOrDefault("count", 1)); return new CustomRecipeResult( - CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new IllegalArgumentException("Unknown recipe result item id: " + id)), + CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow( + () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", new IllegalArgumentException("Unknown recipe result item id: " + id), id)), count ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java index 4f9b7a047..12918f6bf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeTypes.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.item.recipe; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -41,12 +42,12 @@ public class RecipeTypes { public static Recipe fromMap(Key id, Map map) { String type = (String) map.get("type"); if (type == null) { - throw new NullPointerException("recipe type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.recipe.lack_type", new NullPointerException("recipe type cannot be null")); } Key key = Key.withDefaultNamespace(type, "minecraft"); RecipeFactory factory = (RecipeFactory) BuiltInRegistries.RECIPE_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown recipe type: " + type); + throw new LocalizedResourceConfigException("warning.config.recipe.invalid_type", new IllegalArgumentException("Unknown recipe type: " + type), type); } return factory.create(id, map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ExactPathMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ExactPathMatcher.java index fdff56bcd..760e843e6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ExactPathMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ExactPathMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -30,7 +31,7 @@ public class ExactPathMatcher implements PathMatcher { public PathMatcher create(Map arguments) { String path = (String) arguments.get("path"); if (path == null) { - throw new IllegalArgumentException("The 'path' argument must not be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.exact.lack_path", new IllegalArgumentException("The 'path' argument must not be null")); } return new ExactPathMatcher(path); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/FilenameMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/FilenameMatcher.java index e52d8a590..81680e45f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/FilenameMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/FilenameMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -30,7 +31,7 @@ public class FilenameMatcher implements PathMatcher { public PathMatcher create(Map arguments) { String name = (String) arguments.get("name"); if (name == null) { - throw new IllegalArgumentException("The 'name' argument must not be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.filename.lack_name", new IllegalArgumentException("The 'name' argument must not be null")); } return new FilenameMatcher(name); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathPrefixMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathPrefixMatcher.java index 49d45fa5d..3322f27ff 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathPrefixMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathPrefixMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -32,7 +33,7 @@ public class ParentPathPrefixMatcher implements PathMatcher { public PathMatcher create(Map arguments) { String prefix = (String) arguments.get("prefix"); if (prefix == null) { - throw new IllegalArgumentException("The prefix argument must not be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.parent_path_prefix.lack_prefix", new IllegalArgumentException("The prefix argument must not be null")); } return new ParentPathPrefixMatcher(prefix); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathSuffixMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathSuffixMatcher.java index b5728bd52..4aec62815 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathSuffixMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/ParentPathSuffixMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -32,7 +33,7 @@ public class ParentPathSuffixMatcher implements PathMatcher { public PathMatcher create(Map arguments) { String suffix = (String) arguments.get("suffix"); if (suffix == null) { - throw new IllegalArgumentException("The suffix argument must not be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.parent_path_suffix.lack_suffix", new IllegalArgumentException("The suffix argument must not be null")); } return new ParentPathSuffixMatcher(suffix); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathContainsMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathContainsMatcher.java index 2a138c0d9..ea3d986bd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathContainsMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathContainsMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -29,6 +30,9 @@ public class PathContainsMatcher implements PathMatcher { @Override public PathMatcher create(Map arguments) { String path = (String) arguments.get("path"); + if (path == null) { + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.contains.lack_path", new NullPointerException("path should not be null")); + } return new PathContainsMatcher(path); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathMatchers.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathMatchers.java index 55d6ba56d..781a0e16c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathMatchers.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathMatchers.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -50,12 +51,12 @@ public class PathMatchers { public static PathMatcher fromMap(Map map) { String type = (String) map.getOrDefault("type", "empty"); if (type == null) { - throw new NullPointerException("path matcher type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.lack_type", new NullPointerException("path matcher type cannot be null")); } Key key = Key.withDefaultNamespace(type, "craftengine"); PathMatcherFactory factory = BuiltInRegistries.PATH_MATCHER_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown matcher type: " + type); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.invalid_type", new IllegalArgumentException("Unknown matcher type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathPatternMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathPatternMatcher.java index 30c9e958f..5ec39b080 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathPatternMatcher.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/matcher/PathPatternMatcher.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.matcher; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.nio.file.Path; @@ -30,7 +31,7 @@ public class PathPatternMatcher implements PathMatcher { public PathMatcher create(Map arguments) { String pattern = (String) arguments.get("pattern"); if (pattern == null) { - throw new IllegalArgumentException("The pattern argument must not be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_matcher.pattern.lack_pattern", new IllegalArgumentException("The pattern argument must not be null")); } return new PathPatternMatcher(pattern); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java index 9d65cf9cc..24d2e33f5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.conflict.resolution; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -32,12 +33,12 @@ public class Resolutions { public static Resolution fromMap(Map map) { String type = (String) map.getOrDefault("type", "empty"); if (type == null) { - throw new NullPointerException("path matcher type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.conflict_resolution.lack_type", new NullPointerException("path matcher type cannot be null")); } Key key = Key.withDefaultNamespace(type, "craftengine"); ResolutionFactory factory = BuiltInRegistries.RESOLUTION_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown matcher type: " + type); + throw new LocalizedResourceConfigException("warning.config.conflict_resolution.invalid_type", new IllegalArgumentException("Unknown matcher type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java index 07cee9b30..1a6deb312 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java @@ -14,7 +14,6 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; public class BaseItemModel implements ItemModel { public static final Factory FACTORY = new Factory(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/CompositeItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/CompositeItemModel.java index bed90211b..92d043472 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/CompositeItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/CompositeItemModel.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.pack.model; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; -import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/ConditionItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/ConditionItemModel.java index 514f0e4af..f1ebff144 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/ConditionItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/ConditionItemModel.java @@ -11,7 +11,6 @@ import net.momirealms.craftengine.core.util.MiscUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; public class ConditionItemModel implements ItemModel { public static final Factory FACTORY = new Factory(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/ConditionProperties.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/ConditionProperties.java index c0e1e83e6..8c5ab2fae 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/ConditionProperties.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/ConditionProperties.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.model.condition; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -47,12 +48,12 @@ public class ConditionProperties { public static ConditionProperty fromMap(Map map) { String type = (String) map.get("property"); if (type == null) { - throw new NullPointerException("property type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.item.model.condition.lack_property", new NullPointerException("property type cannot be null")); } Key key = Key.withDefaultNamespace(type, "minecraft"); ConditionPropertyFactory factory = BuiltInRegistries.CONDITION_PROPERTY_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown property type: " + type); + throw new LocalizedResourceConfigException("warning.config.item.model.condition.invalid_property", new IllegalArgumentException("Unknown property type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/HasComponentConditionProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/HasComponentConditionProperty.java index 790e8b87d..3842ecf57 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/HasComponentConditionProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/HasComponentConditionProperty.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.condition; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -35,7 +36,11 @@ public class HasComponentConditionProperty implements ConditionProperty { @Override public ConditionProperty create(Map arguments) { boolean ignoreDefault = (boolean) arguments.getOrDefault("ignore-default", false); - String component = Objects.requireNonNull(arguments.get("component"), "component").toString(); + Object componentObj = arguments.get("component"); + if (componentObj == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.condition.has_component.lack_component", new NullPointerException("component should not be null")); + } + String component = componentObj.toString(); return new HasComponentConditionProperty(component, ignoreDefault); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/KeyBindDownConditionProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/KeyBindDownConditionProperty.java index 19df014e9..9482c4b5f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/KeyBindDownConditionProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/condition/KeyBindDownConditionProperty.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.condition; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -29,7 +30,11 @@ public class KeyBindDownConditionProperty implements ConditionProperty { @Override public ConditionProperty create(Map arguments) { - String keybind = Objects.requireNonNull(arguments.get("keybind"), "keybind").toString(); + Object keybindObj = arguments.get("keybind"); + if (keybindObj == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.condition.keybind_down.lack_keybind", new NullPointerException("keybind should not be null")); + } + String keybind = keybindObj.toString(); return new KeyBindDownConditionProperty(keybind); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java index 29e49801e..2c00d885c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java @@ -1,13 +1,9 @@ package net.momirealms.craftengine.core.pack.model.generation; import com.google.gson.JsonObject; -import dev.dejvokep.boostedyaml.block.implementation.Section; -import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; -import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; -import software.amazon.awssdk.services.s3.endpoints.internal.Value; import java.util.Collections; import java.util.LinkedHashMap; diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/CompassRangeDispatchProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/CompassRangeDispatchProperty.java index 0481ace29..1a3d0c2a2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/CompassRangeDispatchProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/CompassRangeDispatchProperty.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.rangedisptach; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -29,7 +30,11 @@ public class CompassRangeDispatchProperty implements RangeDispatchProperty { @Override public RangeDispatchProperty create(Map arguments) { - String target = Objects.requireNonNull(arguments.get("target")).toString(); + Object targetObj = arguments.get("target"); + if (targetObj == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.range_dispatch.compass.lack_target", new NullPointerException("target should not be null")); + } + String target = targetObj.toString(); return new CompassRangeDispatchProperty(target); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/RangeDispatchProperties.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/RangeDispatchProperties.java index 087a3acaa..6c9f57fcd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/RangeDispatchProperties.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/RangeDispatchProperties.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.model.rangedisptach; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -43,12 +44,12 @@ public class RangeDispatchProperties { public static RangeDispatchProperty fromMap(Map map) { String type = (String) map.get("property"); if (type == null) { - throw new NullPointerException("property type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.item.model.range_dispatch.lack_property", new NullPointerException("property type cannot be null")); } Key key = Key.withDefaultNamespace(type, "minecraft"); RangeDispatchPropertyFactory factory = BuiltInRegistries.RANGE_DISPATCH_PROPERTY_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown property type: " + type); + throw new LocalizedResourceConfigException("warning.config.item.model.range_dispatch.invalid_property", new IllegalArgumentException("Unknown property type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/TimeRangeDispatchProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/TimeRangeDispatchProperty.java index de8bc007f..df8f38d99 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/TimeRangeDispatchProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/rangedisptach/TimeRangeDispatchProperty.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.rangedisptach; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -34,7 +35,11 @@ public class TimeRangeDispatchProperty implements RangeDispatchProperty { @Override public RangeDispatchProperty create(Map arguments) { - String source = Objects.requireNonNull(arguments.get("source")).toString(); + Object sourceObj = arguments.get("source"); + if (sourceObj == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.range_dispatch.time.lack_source", new NullPointerException("source should not be null")); + } + String source = sourceObj.toString(); boolean wobble = (boolean) arguments.getOrDefault("wobble", true); return new TimeRangeDispatchProperty(source, wobble); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/BlockStateSelectProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/BlockStateSelectProperty.java index 92c67a2a2..e4e187e2b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/BlockStateSelectProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/BlockStateSelectProperty.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.select; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -29,7 +30,11 @@ public class BlockStateSelectProperty implements SelectProperty { @Override public SelectProperty create(Map arguments) { - String blockStateProperty = Objects.requireNonNull(arguments.get("block-state-property")).toString(); + Object property = arguments.get("block-state-property"); + if (property == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.select.block_state.lack_block_state_property", new NullPointerException("block-state-property should not be null")); + } + String blockStateProperty = property.toString(); return new BlockStateSelectProperty(blockStateProperty); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/LocalTimeSelectProperty.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/LocalTimeSelectProperty.java index e89314e55..d557d882c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/LocalTimeSelectProperty.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/LocalTimeSelectProperty.java @@ -43,7 +43,11 @@ public class LocalTimeSelectProperty implements SelectProperty { @Override public SelectProperty create(Map arguments) { - String pattern = Objects.requireNonNull(arguments.get("pattern")).toString(); + Object patternObj = arguments.get("pattern"); + if (patternObj == null) { + throw new IllegalArgumentException("warning.config.item.model.select.local_time.lack_pattern", new NullPointerException("pattern should not be null")); + } + String pattern = patternObj.toString(); String locale = (String) arguments.get("locale"); String timeZone = (String) arguments.get("time-zone"); return new LocalTimeSelectProperty(pattern, locale, timeZone); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/SelectProperties.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/SelectProperties.java index bd01a1d6a..1c9b62a17 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/SelectProperties.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/select/SelectProperties.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.model.select; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -41,12 +42,12 @@ public class SelectProperties { public static SelectProperty fromMap(Map map) { String type = (String) map.get("property"); if (type == null) { - throw new NullPointerException("property type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.item.model.select.lack_property", new NullPointerException("property type cannot be null")); } Key key = Key.withDefaultNamespace(type, "minecraft"); SelectPropertyFactory factory = BuiltInRegistries.SELECT_PROPERTY_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown property type: " + type); + throw new LocalizedResourceConfigException("warning.config.item.model.select.invalid_property", new IllegalArgumentException("Unknown property type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java index a34494783..469ce3655 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.tint; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import org.incendo.cloud.type.Either; @@ -33,6 +34,9 @@ public class ConstantTint implements Tint { @Override public Tint create(Map arguments) { Object value = arguments.get("value"); + if (value == null) { + throw new LocalizedResourceConfigException("warning.config.item.model.tint.constant.lack_value", new NullPointerException("value should not be null")); + } return new ConstantTint(parseTintValue(value)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java index f524bd1af..a031e2690 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.tint; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.incendo.cloud.type.Either; @@ -37,7 +38,7 @@ public class CustomModelDataTint implements Tint { @Override public Tint create(Map arguments) { - Object value = arguments.get("default"); + Object value = arguments.getOrDefault("default", 0); int index = MiscUtils.getAsInt(arguments.getOrDefault("index", 0)); return new CustomModelDataTint(parseTintValue(value), index); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/GrassTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/GrassTint.java index 562b351e4..a5f6752ba 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/GrassTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/GrassTint.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.tint; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; @@ -37,10 +38,10 @@ public class GrassTint implements Tint { float temperature = MiscUtils.getAsFloat(arguments.getOrDefault("temperature", 0)); float downfall = MiscUtils.getAsFloat(arguments.getOrDefault("downfall", 0)); if (temperature > 1 || temperature < 0) { - throw new IllegalArgumentException("Invalid temperature: " + temperature + ". Valid range 0~1"); + throw new LocalizedResourceConfigException("warning.config.item.model.tint.grass.invalid_temperature", new IllegalArgumentException("Invalid temperature: " + temperature + ". Valid range 0~1"), String.valueOf(temperature)); } if (downfall > 1 || downfall < 0) { - throw new IllegalArgumentException("Invalid downfall: " + downfall + ". Valid range 0~1"); + throw new LocalizedResourceConfigException("warning.config.item.model.tint.grass.invalid_downfall", new IllegalArgumentException("Invalid downfall: " + downfall + ". Valid range 0~1"), String.valueOf(downfall)); } return new GrassTint(temperature, downfall); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java index 1b055abe3..a08c0daec 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java @@ -34,7 +34,7 @@ public class SimpleDefaultTint implements Tint { @Override public Tint create(Map arguments) { - Object value = arguments.get("default"); + Object value = arguments.getOrDefault("default", 0); Key type = Key.of(arguments.get("type").toString()); return new SimpleDefaultTint(parseTintValue(value), type); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java index e7dd6c16e..324fce58d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.model.tint; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import org.incendo.cloud.type.Either; import java.util.ArrayList; @@ -14,25 +15,23 @@ public interface TintFactory { if (value instanceof Number i) { return Either.ofPrimary(i.intValue()); } else if (value instanceof List list) { - if (list.size() != 3) { - throw new IllegalArgumentException("Invalid tint value list size: " + list.size() + " which is expected to be 3"); + if (list.size() == 3) { + List intList = new ArrayList<>(); + for (Object o : list) { + intList.add(Integer.parseInt(o.toString())); + } + return Either.ofFallback(intList); } - List intList = new ArrayList<>(); - for (Object o : list) { - intList.add(Integer.parseInt(o.toString())); - } - return Either.ofFallback(intList); } else if (value instanceof String s) { String[] split = s.split(","); - if (split.length != 3) { - throw new IllegalArgumentException("Invalid tint value list size: " + split.length + " which is expected to be 3"); + if (split.length == 3) { + List intList = new ArrayList<>(); + for (String string : split) { + intList.add(Integer.parseInt(string)); + } + return Either.ofFallback(intList); } - List intList = new ArrayList<>(); - for (String string : split) { - intList.add(Integer.parseInt(string)); - } - return Either.ofFallback(intList); } - throw new IllegalArgumentException("Invalid tint value: " + value); + throw new LocalizedResourceConfigException("warning.config.item.model.tint.invalid_value", new IllegalArgumentException("Invalid tint value: " + value), value.toString()); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tints.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tints.java index 24e0f3cda..2aa65e8e3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tints.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tints.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.pack.model.tint; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.Registries; @@ -39,12 +40,12 @@ public class Tints { public static Tint fromMap(Map map) { String type = (String) map.get("type"); if (type == null) { - throw new NullPointerException("tint type cannot be null"); + throw new LocalizedResourceConfigException("warning.config.item.model.tint.lack_type", new NullPointerException("'type' cannot be null for tint")); } Key key = Key.withDefaultNamespace(type, "minecraft"); TintFactory factory = BuiltInRegistries.TINT_FACTORY.getValue(key); if (factory == null) { - throw new IllegalArgumentException("Unknown tint type: " + type); + throw new LocalizedResourceConfigException("warning.config.item.model.tint.invalid_type", new IllegalArgumentException("Unknown tint type: " + type), type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index a1020c555..a3a733518 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -16,6 +16,7 @@ import net.momirealms.craftengine.core.entity.furniture.ColliderType; import net.momirealms.craftengine.core.pack.conflict.resolution.ConditionalResolution; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.PluginProperties; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.plugin.logger.filter.DisconnectLogFilter; import net.momirealms.craftengine.core.util.AdventureHelper; @@ -245,8 +246,11 @@ public class Config { Map args = MiscUtils.castToMap(it, false); return ConditionalResolution.FACTORY.create(args); }).toList(); + } catch (LocalizedResourceConfigException e) { + TranslationManager.instance().log(e.node(), e.arguments()); + resource_pack$duplicated_files_handler = List.of(); } catch (Exception e) { - this.plugin.logger().warn("Failed to load resource pack duplicated files handler", e); + this.plugin.logger().warn("Failed to load resource-pack.duplicated-files-handler", e); resource_pack$duplicated_files_handler = List.of(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java index d89413f9c..6a0826695 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java @@ -113,6 +113,9 @@ public abstract class AbstractSoundManager implements SoundManager { boolean replace = (boolean) section.getOrDefault("replace", false); String subtitle = (String) section.get("subtitle"); List soundList = (List) section.get("sounds"); + if (soundList == null) { + throw new LocalizedResourceConfigException("warning.config.sound.lack_sounds", path, id); + } List sounds = new ArrayList<>(); for (Object sound : soundList) { if (sound instanceof String soundPath) {