diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index 1e959b731..125d3e971 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -69,12 +69,12 @@ search_recipe_admin: - /craftengine item search-recipe - /ce item search-recipe -totem: +totem_animation: enable: true - permission: ce.command.admin.totem + permission: ce.command.admin.totem_animation usage: - - /craftengine totem - - /ce totem + - /craftengine feature totem-animation + - /ce feature totem-animation # Debug commands debug_set_block: diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 5624e7bd8..9fededa9d 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -152,7 +152,14 @@ image: sign: true recipe: + # Enable the plugin's recipe system enable: true + # Disable vanilla recipes + disable-vanilla-recipes: + # Disable all vanilla recipes + all: false + # Disable the recipes in list + list: [] gui: browser: diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 760faf424..d2c95dfb1 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -53,7 +53,7 @@ command.search_recipe.not_found: "No recipe found for this item" command.search_usage.not_found: "No usage found for this item" command.search_recipe.no_item: "Please hold an item before running this command" command.search_usage.no_item: "Please hold an item before running this command" -command.totem.not_totem: "'' is not type of totem_of_undying" +command.totem_animation.failure.not_totem: "Item '' is not minecraft:totem_of_undying" warning.config.image.duplicated: "Issue found in file - Duplicated image ''." warning.config.image.lack_height: "Issue found in file - The image '' is missing the required 'height' argument." warning.config.image.height_smaller_than_ascent: "Issue found in file - The image '' violates the bitmap image rule: 'height' should be no lower than 'ascent'." @@ -63,7 +63,7 @@ warning.config.image.invalid_font_name: "Issue found in file - T warning.config.image.lack_char: "Issue found in file - The image '' is missing the required 'char' argument." warning.config.image.codepoint_in_use: "Issue found in file - The image '' is using a character[()] in font that has been used by another image ''." 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.image.file_not_exist: "Issue found in file - PNG file '' not found for image ''." warning.config.recipe.duplicated: "Issue found in file - Duplicated recipe ''." warning.config.i18n.unknown_locale: "Issue found in file - Unknown locale ''." warning.config.template.duplicated: "Issue found in file - Duplicated template ''." @@ -93,8 +93,13 @@ warning.config.block.state.invalid_state: "Issue found in file - warning.config.block.state.unavailable_state: "Issue found in file - The block '' is using an unavailable vanilla block state ''." warning.config.block.state.invalid_vanilla_state_id: "Issue found in file - The block '' is using a vanilla block state '' that exceeds the available slot range '0~'." warning.config.block.state.conflict: "Issue found in file - The block '' is using a vanilla block state '' that has been occupied by ''." -warning.config.block.bind_real_state: "Issue found in file - The block '' failed to bind real block state for '' as the state has been occupied by ''." +warning.config.block.state.bind_real_state: "Issue found in file - The block '' failed to bind real block state for '' as the state has been occupied by ''." warning.config.block.state.invalid_property_structure: "Issue found in file - The block '' has an invalid property structure ''." warning.config.block.state.invalid_property: "Issue found in file - Failed to create property '' for block '': ." warning.config.block.state.no_model_set: "Issue found in file - The block '' is missing the required 'model' or 'models' argument." -warning.config.block.state.invalid_real_state_id: "Issue found in file - The block '' is using a real block state '' that exceeds the available slot range '0~'. Consider adding more real states in 'additional-real-blocks.yml' if the slots are used up." \ No newline at end of file +warning.config.block.state.invalid_real_state_id: "Issue found in file - The block '' is using a real block state '' that exceeds the available slot range '0~'. Consider adding more real states in 'additional-real-blocks.yml' if the slots are used up." +warning.config.block.state.model.lack_path: "Issue found in file - The block '' is missing the required 'path' option for 'model'." +warning.config.block.state.model.invalid_resource_location: "Issue found in file - The block '' has a 'path' argument [] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters" +warning.config.model.generation.conflict: "Issue found in file - Failed to generate model for '' as two or more configurations attempt to generate different json models with the same path: ''" +warning.config.model.generation.texture.invalid_resource_location: "Issue found in file - The config '' has a '' texture argument [] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters" +warning.config.model.generation.parent.invalid_resource_location: "Issue found in file - The config '' has a parent argument [] that contains legal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters" \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/translations/es.yml b/bukkit/loader/src/main/resources/translations/es.yml index f04f051a0..eda313eaf 100644 --- a/bukkit/loader/src/main/resources/translations/es.yml +++ b/bukkit/loader/src/main/resources/translations/es.yml @@ -53,4 +53,4 @@ command.search_recipe.not_found: "No se encontró ninguna receta para este command.search_usage.not_found: "No se encontró ningún uso para este objeto" command.search_recipe.no_item: "Por favor, sostén un objeto antes de ejecutar este comando" command.search_usage.no_item: "Por favor, sostén un objeto antes de ejecutar este comando" -command.totem.not_totem: "'' no es del tipo totem_of_undying" \ No newline at end of file +command.totem_animation.failure.not_totem: "'' no es del tipo totem_of_undying" \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index 0cab6ac5d..822f32e54 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -53,7 +53,7 @@ command.search_recipe.not_found: "找不到此物品的配方" command.search_usage.not_found: "找不到此物品的用途" command.search_recipe.no_item: "请手持物品后再执行此命令" command.search_usage.no_item: "请手持物品后再执行此命令" -command.totem.not_totem: "'' 不是 totem_of_undying 类型" +command.totem_animation.failure.not_totem: "'' 不是 totem_of_undying 类型" warning.config.image.duplicated: "在文件 中发现问题 - 图片 '' 重复定义" warning.config.image.lack_height: "在文件 中发现问题 - 图片 '' 缺少必要的 'height' 高度参数" warning.config.image.height_smaller_than_ascent: "在文件 中发现问题 - 图片 '' 违反位图规则:'height' 高度值不应小于 'ascent' 基准线高度" @@ -88,4 +88,18 @@ warning.config.block.state.lack_properties: "在文件 中发现 warning.config.block.state.lack_appearances: "在文件 中发现问题 - 方块 '' 的 'states' 配置缺少必要的 'appearances' 外观配置" warning.config.block.state.lack_variants: "在文件 中发现问题 - 方块 '' 的 'states' 配置缺少必要的 'variants' 变体配置" warning.config.block.state.variant.lack_appearance: "在文件 中发现问题 - 方块 '' 的 '' 变体配置缺少必要的 'appearance' 外观参数" -warning.config.block.state.variant.invalid_appearance: "在文件 中发现问题 - 方块 '' 的 '' 变体引用了不存在的外观配置 ''" \ No newline at end of file +warning.config.block.state.variant.invalid_appearance: "在文件 中发现问题 - 方块 '' 的 '' 变体引用了不存在的外观配置 ''" +warning.config.block.state.invalid_state: "在文件 中发现问题 - 方块 '' 使用了无效的原版方块状态 ''" +warning.config.block.state.unavailable_state: "在文件 中发现问题 - 方块 '' 使用了不可用的原版方块状态 ''" +warning.config.block.state.invalid_vanilla_state_id: "在文件 中发现问题 - 方块 '' 使用的原版方块状态 '' 超出可用槽位范围 '0~'" +warning.config.block.state.conflict: "在文件 中发现问题 - 方块 '' 使用的原版方块状态 '' 已被 '' 占用" +warning.config.block.state.bind_real_state: "在文件 中发现问题 - 方块 '' 未能绑定真实方块状态 '',该状态已被 '' 占用" +warning.config.block.state.invalid_property_structure: "在文件 中发现问题 - 方块 '' 的属性结构 '' 配置无效" +warning.config.block.state.invalid_property: "在文件 中发现问题 - 无法为方块 '' 创建属性 '':" +warning.config.block.state.no_model_set: "在文件 中发现问题 - 方块 '' 缺少必要的 'model' 或 'models' 模型参数" +warning.config.block.state.invalid_real_state_id: "在文件 中发现问题 - 方块 '' 使用的真实方块状态 '' 超出可用槽位范围 '0~'。若槽位已用尽,请考虑在 additional-real-blocks.yml 中添加更多真实状态" +warning.config.block.state.model.lack_path: "在文件 中发现问题 - 方块 '' 的 'model' 配置缺少必要的 'path' 路径参数" +warning.config.block.state.model.invalid_resource_location: "在文件 中发现问题 - 方块 '' 的 'path' 路径参数 [] 包含非法字符,请参考资源路径规范:https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" +warning.config.model.generation.conflict: "在文件 中发现问题 - 无法为 '' 生成模型,多个配置尝试用相同路径 '' 生成不同的JSON模型" +warning.config.model.generation.texture.invalid_resource_location: "在文件 中发现问题 - 配置项 '' 的 '' 纹理参数 [] 包含非法字符,请参考资源路径规范:https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" +warning.config.model.generation.parent.invalid_resource_location: "在文件 中发现问题 - 配置项 '' 的父模型参数 [] 包含非法字符,请参考资源路径规范:https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/translations/zh_tw.yml b/bukkit/loader/src/main/resources/translations/zh_tw.yml index b0d1da410..dfff5088e 100644 --- a/bukkit/loader/src/main/resources/translations/zh_tw.yml +++ b/bukkit/loader/src/main/resources/translations/zh_tw.yml @@ -53,4 +53,4 @@ command.search_recipe.not_found: "找不到此物品的配方" command.search_usage.not_found: "找不到此物品的用途" command.search_recipe.no_item: "執行此命令前請手持物品" command.search_usage.no_item: "執行此命令前請手持物品" -command.totem.not_totem: "'' 不是 totem_of_undying 類型" \ No newline at end of file +command.totem_animation.failure.not_totem: "'' 不是 totem_of_undying 類型" \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index c62766b00..a326b0678 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -21,6 +21,7 @@ import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; @@ -367,7 +368,7 @@ public class BukkitBlockManager extends AbstractBlockManager { return; } - Pair pair = parseAppearanceSection(path, id, stateSection); + Pair pair = parseAppearanceSection(pack, path, id, stateSection); if (pair == null) return; appearances = Map.of("default", pair.right()); @@ -407,7 +408,7 @@ public class BukkitBlockManager extends AbstractBlockManager { Map tempTypeMap = new HashMap<>(); for (Map.Entry appearanceEntry : appearancesSection.entrySet()) { if (appearanceEntry.getValue() instanceof Map appearanceSection) { - Pair pair = parseAppearanceSection(path, id, MiscUtils.castToMap(appearanceSection, false)); + Pair pair = parseAppearanceSection(pack, path, id, MiscUtils.castToMap(appearanceSection, false)); if (pair == null) return; appearances.put(appearanceEntry.getKey(), pair.right()); tempTypeMap.put(appearanceEntry.getKey(), pair.left()); @@ -463,7 +464,7 @@ public class BukkitBlockManager extends AbstractBlockManager { for (ImmutableBlockState state : block.variantProvider().states()) { ImmutableBlockState previous = stateId2ImmutableBlockStates[state.customBlockState().registryId() - BlockStateUtils.vanillaStateSize()]; if (previous != null && !previous.isEmpty()) { - TranslationManager.instance().log("warning.config.block.bind_real_state", path.toString(), id.toString(), state.toString(), previous.toString()); + TranslationManager.instance().log("warning.config.block.state.bind_real_state", path.toString(), id.toString(), state.toString(), previous.toString()); continue; } stateId2ImmutableBlockStates[state.customBlockState().registryId() - BlockStateUtils.vanillaStateSize()] = state; @@ -500,7 +501,7 @@ public class BukkitBlockManager extends AbstractBlockManager { } @Nullable - private Pair parseAppearanceSection(Path path, Key id, Map section) { + private Pair parseAppearanceSection(Pack pack, Path path, Key id, Map section) { // require state non null String vanillaStateString = (String) section.get("state"); if (vanillaStateString == null) { @@ -538,11 +539,11 @@ public class BukkitBlockManager extends AbstractBlockManager { List variants = new ArrayList<>(); if (models instanceof Map singleModelSection) { - loadVariantModel(variants, MiscUtils.castToMap(singleModelSection, false)); + loadVariantModel(pack, path, id, variants, MiscUtils.castToMap(singleModelSection, false)); } else if (models instanceof List modelList) { for (Object model : modelList) { if (model instanceof Map singleModelMap) { - loadVariantModel(variants, MiscUtils.castToMap(singleModelMap, false)); + loadVariantModel(pack, path, id, variants, MiscUtils.castToMap(singleModelMap, false)); } } } @@ -567,9 +568,17 @@ public class BukkitBlockManager extends AbstractBlockManager { return Pair.of(block, vanillaStateRegistryId); } - private void loadVariantModel(List variants, Map singleModelMap) { + private void loadVariantModel(Pack pack, Path path, Key id, List variants, Map singleModelMap) { JsonObject json = new JsonObject(); String modelPath = (String) singleModelMap.get("path"); + if (modelPath == null) { + TranslationManager.instance().log("warning.config.block.state.model.lack_path", path.toString(), id.toString()); + return; + } + if (!ResourceLocation.isValid(modelPath)) { + TranslationManager.instance().log("warning.config.block.state.model.invalid_resource_location", path.toString(), id.toString(), modelPath); + return; + } json.addProperty("model", modelPath); if (singleModelMap.containsKey("x")) json.addProperty("x", MiscUtils.getAsInt(singleModelMap.get("x"))); if (singleModelMap.containsKey("y")) json.addProperty("y", MiscUtils.getAsInt(singleModelMap.get("y"))); @@ -577,7 +586,7 @@ public class BukkitBlockManager extends AbstractBlockManager { if (singleModelMap.containsKey("weight")) json.addProperty("weight", MiscUtils.getAsInt(singleModelMap.get("weight"))); Map generationMap = MiscUtils.castToMap(singleModelMap.get("generation"), true); if (generationMap != null) { - prepareModelGeneration(new ModelGeneration(Key.of(modelPath), generationMap)); + prepareModelGeneration(path, id, new ModelGeneration(Key.of(modelPath), generationMap)); } variants.add(json); } 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 ee8bdb884..2e8905231 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 @@ -349,7 +349,7 @@ public class BukkitItemManager extends AbstractItemManager { // Parse models ItemModel model = ItemModels.fromMap(modelSection); for (ModelGeneration generation : model.modelsToGenerate()) { - prepareModelGeneration(generation); + prepareModelGeneration(path, id, generation); } if (Config.packMaxVersion() > 21.39f) { @@ -369,7 +369,7 @@ public class BukkitItemManager extends AbstractItemManager { // use components ItemModel model = ItemModels.fromMap(modelSection); for (ModelGeneration generation : model.modelsToGenerate()) { - prepareModelGeneration(generation); + prepareModelGeneration(path, id, generation); } if (Config.packMaxVersion() > 21.39f) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index a026bee0f..c047c60cd 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -297,6 +297,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { @Override public void unload() { + if (!Config.enableRecipeSystem()) return; super.unload(); try { if (VersionHelper.isVersionNewerThan1_21_2()) { @@ -310,6 +311,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { @Override public void delayedLoad() { + if (!Config.enableRecipeSystem()) return; this.injectDataPackRecipes(); } @@ -368,12 +370,23 @@ public class BukkitRecipeManager extends AbstractRecipeManager { for (Object pack : selected) { packResources.add(Reflections.method$Pack$open.invoke(pack)); } + + boolean hasDisabledAny = !Config.disabledVanillaRecipes().isEmpty(); try (AutoCloseable resourceManager = (AutoCloseable) Reflections.constructor$MultiPackResourceManager.newInstance(Reflections.instance$PackType$SERVER_DATA, packResources)) { Map scannedResources = (Map) Reflections.method$FileToIdConverter$listMatchingResources.invoke(fileToIdConverter, resourceManager); for (Map.Entry entry : scannedResources.entrySet()) { Key id = extractKeyFromResourceLocation(entry.getKey().toString()); - // Maybe it's unregistered by other plugins - if (Bukkit.getRecipe(new NamespacedKey(id.namespace(), id.value())) == null) { + // now CraftEngine takes over everything +// // Maybe it's unregistered by other plugins +// if (Bukkit.getRecipe(new NamespacedKey(id.namespace(), id.value())) == null) { +// continue; +// } + if (Config.disableAllVanillaRecipes()) { + this.delayedTasksOnMainThread.add(() -> unregisterPlatformRecipe(id)); + continue; + } + if (hasDisabledAny && Config.disabledVanillaRecipes().contains(id)) { + this.delayedTasksOnMainThread.add(() -> unregisterPlatformRecipe(id)); continue; } markAsDataPackRecipe(id); @@ -423,6 +436,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { @Override public void runDelayedSyncTasks() { + if (!Config.enableRecipeSystem()) return; try { // run delayed tasks for (Runnable r : this.delayedTasksOnMainThread) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index f83af185c..515ac12ec 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -46,7 +46,7 @@ public class BukkitCommandManager extends AbstractCommandManager new DebugSetBlockCommand(this, plugin), new DebugSpawnFurnitureCommand(this, plugin), new DebugTargetBlockCommand(this, plugin), - new TotemCommand(this, plugin) + new TotemAnimationCommand(this, plugin) )); final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager(); manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java similarity index 85% rename from bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java rename to bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java index 72e8a64db..1f21b667e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TotemAnimationCommand.java @@ -28,9 +28,9 @@ import org.incendo.cloud.suggestion.SuggestionProvider; import java.util.concurrent.CompletableFuture; -public class TotemCommand extends BukkitCommandFeature { +public class TotemAnimationCommand extends BukkitCommandFeature { - public TotemCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + public TotemAnimationCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { super(commandManager, plugin); } @@ -49,15 +49,10 @@ public class TotemCommand extends BukkitCommandFeature { NamespacedKey namespacedKey = context.get("id"); Key key = Key.of(namespacedKey.namespace(), namespacedKey.value()); CustomItem item = plugin().itemManager().getCustomItem(key).orElse(null); - if (item == null) { - handleFeedback(context, MessageConstants.COMMAND_ITEM_GET_FAILURE_NOT_EXIST, Component.text(key.toString())); - return; - } - if (MaterialUtils.getMaterial(item.material()) != Material.TOTEM_OF_UNDYING) { + if (item == null || MaterialUtils.getMaterial(item.material()) != Material.TOTEM_OF_UNDYING) { handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString())); return; } - ItemStack totem = item.buildItemStack(); MultiplePlayerSelector selector = context.get("players"); for (Player player : selector.values()) { @@ -68,6 +63,6 @@ public class TotemCommand extends BukkitCommandFeature { @Override public String getFeatureID() { - return "totem"; + return "totem_animation"; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index e362f2fc5..bb6dd519e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.plugin.user; import com.google.common.collect.Lists; import io.netty.channel.Channel; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -13,6 +14,7 @@ import net.momirealms.craftengine.core.block.PackedBlockState; import net.momirealms.craftengine.core.entity.player.InteractionHand; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.util.Direction; @@ -437,16 +439,26 @@ public class BukkitServerPlayer extends Player { return; } } - this.miningProgress = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos) + miningProgress; + + float progressToAdd = (float) Reflections.method$BlockStateBase$getDestroyProgress.invoke(this.destroyedState, serverPlayer, Reflections.method$Entity$level.invoke(serverPlayer), blockPos); + int id = BlockStateUtils.blockStateToId(this.destroyedState); + ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockState(id); + if (customState != null && !customState.isEmpty() + && !customState.settings().isCorrectTool(item == null ? ItemKeys.AIR : item.id())) { + progressToAdd *= customState.settings().incorrectToolSpeed(); + } + + this.miningProgress = progressToAdd + miningProgress; int packetStage = (int) (this.miningProgress * 10.0F); if (packetStage != this.lastSentState) { this.lastSentState = packetStage; broadcastDestroyProgress(player, hitPos, blockPos, packetStage); } + if (this.miningProgress >= 1f) { //Reflections.method$ServerLevel$levelEvent.invoke(Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()), null, 2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState)); Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); - Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState), false); + Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false); sendPacket(levelEventPacket, false); this.stopMiningBlock(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java index a75d84b1b..75711f4e9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSettings.java @@ -28,6 +28,7 @@ public class BlockSettings { @Nullable Key itemId; Set tags = Set.of(); + float incorrectToolSpeed = 0.3f; Set correctTools = Set.of(); String name; @@ -81,6 +82,7 @@ public class BlockSettings { newSettings.fluidState = settings.fluidState; newSettings.blockLight = settings.blockLight; newSettings.name = settings.name; + newSettings.incorrectToolSpeed = settings.incorrectToolSpeed; return newSettings; } @@ -124,6 +126,10 @@ public class BlockSettings { return canOcclude; } + public float incorrectToolSpeed() { + return incorrectToolSpeed; + } + public String name() { return name; } @@ -243,6 +249,11 @@ public class BlockSettings { return this; } + public BlockSettings incorrectToolSpeed(float incorrectToolSpeed) { + this.incorrectToolSpeed = incorrectToolSpeed; + return this; + } + public BlockSettings isRandomlyTicking(boolean isRandomlyTicking) { this.isRandomlyTicking = isRandomlyTicking; return this; @@ -381,6 +392,10 @@ public class BlockSettings { List tools = MiscUtils.getAsStringList(value); return settings -> settings.correctTools(tools.stream().map(Key::of).collect(Collectors.toSet())); })); + registerFactory("incorrect-tool-dig-speed", (value -> { + float floatValue = MiscUtils.getAsFloat(value); + return settings -> settings.incorrectToolSpeed(floatValue); + })); registerFactory("name", (value -> { String name = value.toString(); return settings -> settings.name(name); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java index d4c5dd264..90ce13fca 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java @@ -1,8 +1,11 @@ package net.momirealms.craftengine.core.pack.model.generation; +import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.Key; +import java.nio.file.Path; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -25,16 +28,23 @@ public abstract class AbstractModelGenerator implements ModelGenerator { this.modelsToGenerate.clear(); } - @Override - public void prepareModelGeneration(ModelGeneration model) { - ModelGeneration generation = this.modelsToGenerate.get(model.path()); - if (generation != null) { - if (generation.equals(model)) { + public void prepareModelGeneration(Path path, Key id, ModelGeneration model) { + ModelGeneration conflict = this.modelsToGenerate.get(model.path()); + if (conflict != null) { + if (conflict.equals(model)) { return; } - this.plugin.logger().severe("Two or more configurations attempt to generate different json models with the same path: " + model.path()); + TranslationManager.instance().log("warning.config.model.generation.conflict", path.toString(), id.toString(), model.path().toString()); return; } + if (!ResourceLocation.isValid(model.parentModelPath())) { + TranslationManager.instance().log("warning.config.model.generation.parent.invalid_resource_location", path.toString(), id.toString(), model.parentModelPath()); + } + for (Map.Entry texture : model.texturesOverride().entrySet()) { + if (!ResourceLocation.isValid(texture.getValue())) { + TranslationManager.instance().log("warning.config.model.generation.texture.invalid_resource_location", path.toString(), id.toString(), texture.getKey(), texture.getValue()); + } + } this.modelsToGenerate.put(model.path(), model); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGenerator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGenerator.java index fd6383595..2b57fd304 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGenerator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGenerator.java @@ -6,6 +6,4 @@ public interface ModelGenerator { Collection modelsToGenerate(); void clearModelsToGenerate(); - - void prepareModelGeneration(ModelGeneration model); } 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 e0bb910ba..41469ac5f 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 @@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.plugin.PluginProperties; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.plugin.logger.filter.DisconnectLogFilter; import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ReflectionUtils; @@ -30,6 +31,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.stream.Collectors; public class Config { private static Config instance; @@ -105,7 +107,10 @@ public class Config { protected boolean furniture$hide_base_entity; protected boolean block$sound_system$enable; + protected boolean recipe$enable; + protected boolean recipe$disable_vanilla_recipes$all; + protected Set recipe$disable_vanilla_recipes$list; protected boolean item$non_italic_tag; @@ -259,6 +264,8 @@ public class Config { // recipe recipe$enable = config.getBoolean("recipe.enable", true); + recipe$disable_vanilla_recipes$all = config.getBoolean("recipe.disable-vanilla-recipes.all", false); + recipe$disable_vanilla_recipes$list = config.getStringList("recipe.disable-vanilla-recipes.list").stream().map(Key::of).collect(Collectors.toSet()); // image image$illegal_characters_filter$anvil = config.getBoolean("image.illegal-characters-filter.anvil", true); @@ -350,6 +357,14 @@ public class Config { return instance.recipe$enable; } + public static boolean disableAllVanillaRecipes() { + return instance.recipe$disable_vanilla_recipes$all; + } + + public static Set disabledVanillaRecipes() { + return instance.recipe$disable_vanilla_recipes$list; + } + public static boolean nonItalic() { return instance.item$non_italic_tag; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java index bef7dd276..1151d1fe2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java @@ -20,5 +20,5 @@ public interface MessageConstants { TranslatableComponent.Builder COMMAND_SEARCH_RECIPE_NO_ITEM = Component.translatable().key("command.search_recipe.no_item"); TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NOT_FOUND = Component.translatable().key("command.search_usage.not_found"); TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NO_ITEM = Component.translatable().key("command.search_usage.no_item"); - TranslatableComponent.Builder COMMAND_TOTEM_NOT_TOTEM = Component.translatable().key("command.totem.not_totem"); + TranslatableComponent.Builder COMMAND_TOTEM_NOT_TOTEM = Component.translatable().key("command.totem_animation.failure.not_totem"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/PreConditions.java b/core/src/main/java/net/momirealms/craftengine/core/util/PreConditions.java deleted file mode 100644 index 6ed7f921d..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/util/PreConditions.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.momirealms.craftengine.core.util; - -import org.jetbrains.annotations.NotNull; - -public class PreConditions { - - private PreConditions() {} - - public static boolean runIfTrue(boolean value, @NotNull Runnable runnable) { - if (value) { - runnable.run(); - } - return value; - } - - public static boolean isNull(Object value, @NotNull Runnable runnable) { - if (value == null) { - runnable.run(); - } - return value == null; - } -} diff --git a/gradle.properties b/gradle.properties index 065750cb4..6a652c28d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G # Rule: [major update].[feature update].[bug fix] project_version=0.0.43 config_version=19 -lang_version=3 +lang_version=4 project_group=net.momirealms latest_minecraft_version=1.21.4