diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 37c7bea86..ef65e98c7 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -38,11 +38,11 @@ argument.parse.failure.aggregate.missing: "Missing component ''Invalid component '': " argument.parse.failure.either: "Could not resolve or from ''" argument.parse.failure.namedtextcolor: "'' is not a named text color" -command.reload.config.success: "Configs reloaded in ms." +command.reload.config.success: "Configs reloaded in ms. (Async: ms | Sync: ms)" command.reload.config.failure: "Config reload failed. Check console logs." command.reload.pack.success: "Resource pack reloaded in ms." command.reload.pack.failure: "Resource pack reload failed. Check console logs." -command.reload.all.success: "Reload completed in ms." +command.reload.all.success: "Reload completed in ms. (Async: ms | Sync: ms | Pack: ms)" command.reload.all.failure: "Reload failed. Check console logs." command.item.get.success: "Got " command.item.get.failure.not_exist: "'>" @@ -54,6 +54,7 @@ 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" +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'." warning.config.image.no_file: "Issue found in file - The image '' is missing the required 'file' argument." @@ -78,4 +79,13 @@ warning.config.item.lack_material: "Issue found in file - The it 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." warning.config.item.custom_model_data_conflict: "Issue found in file - The item '' is using a custom model data [] that has been occupied by item ''" -warning.config.item.lack_model_id: "Issue found in file - The item '' is missing the required 'custom-model-data' or 'item-model' argument." \ No newline at end of file +warning.config.item.lack_model_id: "Issue found in file - The item '' is missing the required 'custom-model-data' or 'item-model' argument." +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.lack_real_id: "Issue found in file - The block '' is missing the required 'id' argument for 'state'." +warning.config.block.state.lack_state: "Issue found in file - The block '' is missing the required 'state' argument for 'state'." +warning.config.block.state.lack_properties: "Issue found in file - The block '' is missing the required 'properties' section for 'states'." +warning.config.block.state.lack_appearances: "Issue found in file - The block '' is missing the required 'appearances' section for 'states'." +warning.config.block.state.lack_variants: "Issue found in file - The block '' is missing the required 'variants' section for 'states'." +warning.config.block.state.variant.lack_appearance: "Issue found in file - The block '' is missing the required 'appearance' argument for variant ''." +warning.config.block.state.variant.invalid_appearance: "Issue found in file - The block '' has an error that the variant '' is using a non-existing appearance ''." \ 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 23de3a017..f04f051a0 100644 --- a/bukkit/loader/src/main/resources/translations/es.yml +++ b/bukkit/loader/src/main/resources/translations/es.yml @@ -38,11 +38,11 @@ argument.parse.failure.aggregate.missing: "Componente Faltante ''Componente Invalido '': " argument.parse.failure.either: "No se ha podido resolver o de ''" argument.parse.failure.namedtextcolor: "'' no es un color de texto con nombre" -command.reload.config.success: "Recargado. Tomó ms." +command.reload.config.success: "Recargado. Tomó ms. (Async: ms | Sync: ms)" command.reload.config.failure: "Error al recargar la configuración. Por favor, revisa el registro de la consola." command.reload.pack.success: "Paquete de recursos recargado. Tomó ms." command.reload.pack.failure: "Error al recargar el paquete de recursos. Por favor, revisa el registro de la consola." -command.reload.all.success: "Todo recargado. Tomó ms." +command.reload.all.success: "Todo recargado. Tomó ms. (Async: ms | Sync: ms | Pack: ms)" command.reload.all.failure: "Error al recargar. Por favor, revisa el registro de la consola." command.item.get.success: "Obtener " command.item.get.failure.not_exist: "'>" diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index 29cb7a370..498ebfe90 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -38,11 +38,11 @@ argument.parse.failure.aggregate.missing: "缺少组件 ''" argument.parse.failure.aggregate.failure: "无效的组件 '': " argument.parse.failure.either: "无法从 '' 解析 " argument.parse.failure.namedtextcolor: "'' 不是颜色代码" -command.reload.config.success: "重新加载配置完成. 耗时 毫秒" +command.reload.config.success: "重新加载配置完成. 耗时 毫秒 (异步: ms | 同步: ms)" command.reload.config.failure: "重新加载配置失败,请检查控制台日志。" command.reload.pack.success: "资源包重新加载完成. 耗时 毫秒" command.reload.pack.failure: "重新加载资源包失败,请检查控制台日志。" -command.reload.all.success: "全部重新加载完成. 耗时 毫秒" +command.reload.all.success: "全部重新加载完成. 耗时 毫秒 (异步: ms | 同步: ms | 资源包: ms)" command.reload.all.failure: "重新加载失败,请检查控制台日志。" command.item.get.success: "获得" command.item.get.failure.not_exist: "'>" diff --git a/bukkit/loader/src/main/resources/translations/zh_tw.yml b/bukkit/loader/src/main/resources/translations/zh_tw.yml index 37aae210f..b0d1da410 100644 --- a/bukkit/loader/src/main/resources/translations/zh_tw.yml +++ b/bukkit/loader/src/main/resources/translations/zh_tw.yml @@ -38,11 +38,11 @@ argument.parse.failure.aggregate.missing: "缺少元件 ''" argument.parse.failure.aggregate.failure: "無效的元件 '': " argument.parse.failure.either: "無法從 '' 解析 " argument.parse.failure.namedtextcolor: "'' 不是顏色代碼" -command.reload.config.success: "重新加載配置完成. 耗時 毫秒" +command.reload.config.success: "重新加載配置完成. 耗時 毫秒 (非同步: ms | 同步: ms)" command.reload.config.failure: "重新加載配置失敗,請檢查控制台日誌。" command.reload.pack.success: "資源包重新加載完成. 耗時 毫秒" command.reload.pack.failure: "重新加載資源包失敗,請檢查控制台日誌。" -command.reload.all.success: "全部重新加載完成. 耗時 毫秒" +command.reload.all.success: "全部重新加載完成. 耗時 毫秒 (非同步: ms | 同步: ms | 資源包: ms)" command.reload.all.failure: "重新加載失敗,請檢查控制台日誌。" command.item.get.success: "獲得" command.item.get.failure.not_exist: "'>" 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 0757e0cf4..071cade69 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 @@ -19,10 +19,13 @@ import net.momirealms.craftengine.core.block.*; import net.momirealms.craftengine.core.block.properties.Properties; 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.model.generation.ModelGeneration; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.ConfigManager; +import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.WritableRegistry; @@ -45,6 +48,7 @@ import java.util.*; public class BukkitBlockManager extends AbstractBlockManager { private static BukkitBlockManager instance; private final BukkitCraftEngine plugin; + private final BlockParser blockParser; // A temporary map used to detect whether the same block state corresponds to multiple models. private final Map tempRegistryIdConflictMap = new HashMap<>(); @@ -57,7 +61,7 @@ public class BukkitBlockManager extends AbstractBlockManager { private int customBlockCount; // CraftEngine objects - private final Map id2CraftEngineBlocks = new HashMap<>(); + private final Map byId = new HashMap<>(); private final ImmutableBlockState[] stateId2ImmutableBlockStates; // Minecraft objects @@ -96,6 +100,7 @@ public class BukkitBlockManager extends AbstractBlockManager { public BukkitBlockManager(BukkitCraftEngine plugin) { super(plugin); this.plugin = plugin; + this.blockParser = new BlockParser(); this.initVanillaRegistry(); this.loadMappingsAndAdditionalBlocks(); if (plugin.hasMod() && plugin.requiresRestart()) { @@ -150,7 +155,7 @@ public class BukkitBlockManager extends AbstractBlockManager { super.clearModelsToGenerate(); this.clearCache(); this.appearanceToRealState.clear(); - this.id2CraftEngineBlocks.clear(); + this.byId.clear(); this.cachedSuggestions.clear(); this.blockStateOverrides.clear(); this.modBlockStates.clear(); @@ -221,6 +226,11 @@ public class BukkitBlockManager extends AbstractBlockManager { return Collections.unmodifiableMap(this.modBlockStates); } + @Override + public ConfigSectionParser parser() { + return this.blockParser; + } + @Override public Map> blockOverrides() { return Collections.unmodifiableMap(this.blockStateOverrides); @@ -228,12 +238,12 @@ public class BukkitBlockManager extends AbstractBlockManager { @Override public Map blocks() { - return Collections.unmodifiableMap(this.id2CraftEngineBlocks); + return Collections.unmodifiableMap(this.byId); } @Override public Optional getBlock(Key key) { - return Optional.ofNullable(this.id2CraftEngineBlocks.get(key)); + return Optional.ofNullable(this.byId.get(key)); } @Override @@ -246,7 +256,7 @@ public class BukkitBlockManager extends AbstractBlockManager { this.cachedSuggestions.clear(); this.namespacesInUse.clear(); Set states = new HashSet<>(); - for (CustomBlock block : this.id2CraftEngineBlocks.values()) { + for (CustomBlock block : this.byId.values()) { states.add(block.id().toString()); this.namespacesInUse.add(block.id().namespace()); for (ImmutableBlockState state : block.variantProvider().states()) { @@ -368,100 +378,134 @@ public class BukkitBlockManager extends AbstractBlockManager { } } - @Override - public void parseSection(Pack pack, Path path, Key id, Map section) { - // read block settings - BlockSettings settings = BlockSettings.fromMap(MiscUtils.castToMap(section.getOrDefault("settings", Map.of()), false)); - // read loot table - LootTable lootTable = LootTable.fromMap(MiscUtils.castToMap(section.getOrDefault("loot", Map.of()), false)); - // read states - Map> properties; - Map appearances; - Map variants; - Map stateSection = MiscUtils.castToMap(section.get("state"), true); - if (stateSection != null) { - properties = Map.of(); - int internalId = MiscUtils.getAsInt(stateSection.getOrDefault("id", -1)); - if (PreConditions.runIfTrue(internalId < 0, () -> plugin.logger().warn(path, "No state id configured for block " + id))) return; - Pair pair = parseAppearanceSection(path, stateSection, id); - if (pair == null) return; - appearances = Map.of("default", pair.right()); - Key internalBlockId = Key.of(CraftEngine.NAMESPACE, pair.left().value() + "_" + internalId); - int internalBlockRegistryId = MiscUtils.getAsInt(this.internalId2StateId.getOrDefault(internalBlockId, -1)); - if (internalBlockRegistryId == -1) { - plugin.logger().warn(path, "Failed to register " + id + " because id " + internalId + " is not a value between 0~" + (MiscUtils.getAsInt(this.registeredRealBlockSlots.get(pair.left()))-1) + - ". Consider editing additional-real-blocks.yml if the number of real block IDs is insufficient while there are still available appearances"); - return; - } - variants = Map.of("", new VariantState("default", settings, internalBlockRegistryId)); - } else { - Map statesSection = MiscUtils.castToMap(section.get("states"), true); - if (statesSection == null) { - plugin.logger().warn(path, "No states configured for block " + id); - return; - } - Map propertySection = MiscUtils.castToMap(statesSection.get("properties"), true); - if (PreConditions.isNull(propertySection, () -> plugin.logger().warn(path, "No properties configured for block " + id))) return; - properties = parseProperties(path, propertySection); - Map appearancesSection = MiscUtils.castToMap(statesSection.get("appearances"), true); - if (PreConditions.isNull(appearancesSection, () -> plugin.logger().warn(path, "No appearances configured for block " + id))) return; - appearances = new HashMap<>(); - Map tempTypeMap = new HashMap<>(); - for (Map.Entry appearanceEntry : appearancesSection.entrySet()) { - if (appearanceEntry.getValue() instanceof Map appearanceSection) { - Pair pair = parseAppearanceSection(path, MiscUtils.castToMap(appearanceSection, false), id); - if (pair == null) return; - appearances.put(appearanceEntry.getKey(), pair.right()); - tempTypeMap.put(appearanceEntry.getKey(), pair.left()); - } - } - Map variantsSection = MiscUtils.castToMap(statesSection.get("variants"), true); - if (PreConditions.isNull(variantsSection, () -> plugin.logger().warn(path, "No variants configured for block " + id))) return; - variants = new HashMap<>(); - for (Map.Entry variantEntry : variantsSection.entrySet()) { - if (variantEntry.getValue() instanceof Map variantSection0) { - Map variantSection = MiscUtils.castToMap(variantSection0, false); - String variantName = variantEntry.getKey(); - String appearance = (String) variantSection.get("appearance"); - if (appearance == null) { - plugin.logger().warn(path, "No appearance configured for variant " + variantName); - return; - } - if (!appearances.containsKey(appearance)) { - plugin.logger().warn(path, appearance + " is not a valid appearance for block " + id); - return; - } - int internalId = MiscUtils.getAsInt(variantSection.getOrDefault("id", -1)); - Key baseBlock = tempTypeMap.get(appearance); - Key internalBlockId = Key.of(CraftEngine.NAMESPACE, baseBlock.value() + "_" + internalId); - int internalBlockRegistryId = MiscUtils.getAsInt(this.internalId2StateId.getOrDefault(internalBlockId, -1)); - if (internalBlockRegistryId == -1) { - plugin.logger().warn(path, "Failed to register " + id + " because id " + internalId + " is not a value between 0~" + (MiscUtils.getAsInt(this.registeredRealBlockSlots.getOrDefault(baseBlock, 1))-1) + - ". Consider editing additional-real-blocks.yml if the number of real block IDs is insufficient while there are still available appearances"); - return; - } - Map anotherSetting = MiscUtils.castToMap(variantSection.get("settings"), true); - variants.put(variantName, new VariantState(appearance, anotherSetting == null ? settings : BlockSettings.ofFullCopy(settings, anotherSetting), internalBlockRegistryId)); - } - } + public class BlockParser implements ConfigSectionParser { + public static final String[] CONFIG_SECTION_NAME = new String[] {"blocks", "block"}; + + @Override + public String[] sectionId() { + return CONFIG_SECTION_NAME; } - // create or get block holder - Holder.Reference holder = BuiltInRegistries.BLOCK.get(id).orElseGet(() -> - ((WritableRegistry) BuiltInRegistries.BLOCK).registerForHolder(new ResourceKey<>(BuiltInRegistries.BLOCK.key().location(), id))); - // create block - Map behaviorSection = MiscUtils.castToMap(section.getOrDefault("behavior", Map.of()), false); - BukkitCustomBlock block = new BukkitCustomBlock(id, holder, properties, appearances, variants, settings, behaviorSection, lootTable); + @Override + public int loadingSequence() { + return LoadingSequence.BLOCK; + } - // bind appearance - bindAppearance(block); - this.id2CraftEngineBlocks.put(id, block); + @Override + public void parseSection(Pack pack, Path path, Key id, Map section) { + if (byId.containsKey(id)) { + TranslationManager.instance().log("warning.config.block.duplicated", path.toString(), id.toString()); + return; + } - // generate mod assets - if (ConfigManager.generateModAssets()) { - for (ImmutableBlockState state : block.variantProvider().states()) { - Key realBlockId = BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState()); - this.modBlockStates.put(realBlockId, this.tempVanillaBlockStateModels.get(state.vanillaBlockState().registryId())); + // read block settings + BlockSettings settings = BlockSettings.fromMap(MiscUtils.castToMap(section.getOrDefault("settings", Map.of()), false)); + // read loot table + LootTable lootTable = LootTable.fromMap(MiscUtils.castToMap(section.getOrDefault("loot", Map.of()), false)); + // read states + Map> properties; + Map appearances; + Map variants; + Map stateSection = MiscUtils.castToMap(section.get("state"), true); + if (stateSection != null) { + properties = Map.of(); + int internalId = MiscUtils.getAsInt(stateSection.getOrDefault("id", -1)); + if (internalId < 0) { + TranslationManager.instance().log("warning.config.block.lack_real_id", path.toString(), id.toString()); + return; + } + Pair pair = parseAppearanceSection(path, id, stateSection); + if (pair == null) return; + appearances = Map.of("default", pair.right()); + Key internalBlockId = Key.of(CraftEngine.NAMESPACE, pair.left().value() + "_" + internalId); + int internalBlockRegistryId = MiscUtils.getAsInt(internalId2StateId.getOrDefault(internalBlockId, -1)); + if (internalBlockRegistryId == -1) { + plugin.logger().warn(path, "Failed to register " + id + " because id " + internalId + " is not a value between 0~" + (MiscUtils.getAsInt(registeredRealBlockSlots.get(pair.left()))-1) + + ". Consider editing additional-real-blocks.yml if the number of real block IDs is insufficient while there are still available appearances"); + return; + } + variants = Map.of("", new VariantState("default", settings, internalBlockRegistryId)); + } else { + Map statesSection = MiscUtils.castToMap(section.get("states"), true); + if (statesSection == null) { + TranslationManager.instance().log("warning.config.block.lack_state", path.toString(), id.toString()); + return; + } + Map propertySection = MiscUtils.castToMap(statesSection.get("properties"), true); + if (propertySection == null) { + TranslationManager.instance().log("warning.config.block.state.lack_properties", path.toString(), id.toString()); + return; + } + properties = parseProperties(path, propertySection); + Map appearancesSection = MiscUtils.castToMap(statesSection.get("appearances"), true); + if (appearancesSection == null) { + TranslationManager.instance().log("warning.config.block.state.lack_appearances", path.toString(), id.toString()); + return; + } + + appearances = new HashMap<>(); + 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)); + if (pair == null) return; + appearances.put(appearanceEntry.getKey(), pair.right()); + tempTypeMap.put(appearanceEntry.getKey(), pair.left()); + } + } + + Map variantsSection = MiscUtils.castToMap(statesSection.get("variants"), true); + if (variantsSection == null) { + TranslationManager.instance().log("warning.config.block.state.lack_variants", path.toString(), id.toString()); + return; + } + + variants = new HashMap<>(); + for (Map.Entry variantEntry : variantsSection.entrySet()) { + if (variantEntry.getValue() instanceof Map variantSection0) { + Map variantSection = MiscUtils.castToMap(variantSection0, false); + String variantName = variantEntry.getKey(); + String appearance = (String) variantSection.get("appearance"); + if (appearance == null) { + TranslationManager.instance().log("warning.config.block.state.variant.lack_appearance", path.toString(), id.toString(), variantName); + return; + } + if (!appearances.containsKey(appearance)) { + TranslationManager.instance().log("warning.config.block.state.variant.invalid_appearance", path.toString(), id.toString(), variantName, appearance); + return; + } + int internalId = MiscUtils.getAsInt(variantSection.getOrDefault("id", -1)); + Key baseBlock = tempTypeMap.get(appearance); + Key internalBlockId = Key.of(CraftEngine.NAMESPACE, baseBlock.value() + "_" + internalId); + int internalBlockRegistryId = MiscUtils.getAsInt(internalId2StateId.getOrDefault(internalBlockId, -1)); + if (internalBlockRegistryId == -1) { + plugin.logger().warn(path, "Failed to register " + id + " because id " + internalId + " is not a value between 0~" + (MiscUtils.getAsInt(registeredRealBlockSlots.getOrDefault(baseBlock, 1))-1) + + ". Consider editing additional-real-blocks.yml if the number of real block IDs is insufficient while there are still available appearances"); + return; + } + Map anotherSetting = MiscUtils.castToMap(variantSection.get("settings"), true); + variants.put(variantName, new VariantState(appearance, anotherSetting == null ? settings : BlockSettings.ofFullCopy(settings, anotherSetting), internalBlockRegistryId)); + } + } + } + // create or get block holder + Holder.Reference holder = BuiltInRegistries.BLOCK.get(id).orElseGet(() -> + ((WritableRegistry) BuiltInRegistries.BLOCK).registerForHolder(new ResourceKey<>(BuiltInRegistries.BLOCK.key().location(), id))); + // create block + Map behaviorSection = MiscUtils.castToMap(section.getOrDefault("behavior", Map.of()), false); + + BukkitCustomBlock block = new BukkitCustomBlock(id, holder, properties, appearances, variants, settings, behaviorSection, lootTable); + + // bind appearance + bindAppearance(block); + byId.put(id, block); + + // generate mod assets + if (ConfigManager.generateModAssets()) { + for (ImmutableBlockState state : block.variantProvider().states()) { + Key realBlockId = BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState()); + modBlockStates.put(realBlockId, tempVanillaBlockStateModels.get(state.vanillaBlockState().registryId())); + } } } } @@ -493,10 +537,13 @@ public class BukkitBlockManager extends AbstractBlockManager { } @Nullable - private Pair parseAppearanceSection(Path path, Map section, Key id) { + private Pair parseAppearanceSection(Path path, Key id, Map section) { String vanillaStateString = (String) section.get("state"); - if (PreConditions.isNull(vanillaStateString, - () -> this.plugin.logger().warn(path, "No block state found for: " + id))) return null; + if (vanillaStateString == null) { + TranslationManager.instance().log("warning.config.block.state.lack_state", path.toString(), id.toString()); + return null; + } + int vanillaStateRegistryId; try { vanillaStateRegistryId = parseVanillaStateRegistryId(vanillaStateString); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java index 511a3845b..40b96fe9d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java @@ -176,7 +176,7 @@ public class BlockItemBehavior extends ItemBehavior { throw new IllegalArgumentException("Missing required parameter 'block' for block_item behavior"); } if (id instanceof Map map) { - BukkitBlockManager.instance().parseSection(pack, path, key, MiscUtils.castToMap(map, false)); + BukkitBlockManager.instance().parser().parseSection(pack, path, key, MiscUtils.castToMap(map, false)); return new BlockItemBehavior(key); } else { return new BlockItemBehavior(Key.of(id.toString())); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/LiquidCollisionBlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/LiquidCollisionBlockItemBehavior.java index 1163a1ab8..09a8575b3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/LiquidCollisionBlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/LiquidCollisionBlockItemBehavior.java @@ -67,7 +67,7 @@ public class LiquidCollisionBlockItemBehavior extends BlockItemBehavior { } int offset = MiscUtils.getAsInt(arguments.getOrDefault("y-offset", 1)); if (id instanceof Map map) { - BukkitBlockManager.instance().parseSection(pack, path, key, MiscUtils.castToMap(map, false)); + BukkitBlockManager.instance().parser().parseSection(pack, path, key, MiscUtils.castToMap(map, false)); return new LiquidCollisionBlockItemBehavior(key, offset); } else { return new LiquidCollisionBlockItemBehavior(Key.of(id.toString()), offset); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ReloadCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ReloadCommand.java index e6fff1b0b..bac46d3a0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ReloadCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ReloadCommand.java @@ -37,10 +37,7 @@ public class ReloadCommand extends BukkitCommandFeature { plugin().scheduler().executeAsync(() -> { try { RELOAD_PACK_FLAG = true; - long time1 = System.currentTimeMillis(); - plugin().reload(); - long time2 = System.currentTimeMillis(); - handleFeedback(context, MessageConstants.COMMAND_RELOAD_CONFIG_SUCCESS, Component.text(time2 - time1)); + plugin().reload((a, b) -> handleFeedback(context, MessageConstants.COMMAND_RELOAD_CONFIG_SUCCESS, Component.text(a + b), Component.text(a), Component.text(b))); } catch (Exception e) { handleFeedback(context, MessageConstants.COMMAND_RELOAD_CONFIG_FAILURE); plugin().logger().warn("Failed to reload config", e); @@ -60,16 +57,17 @@ public class ReloadCommand extends BukkitCommandFeature { }); } else if (argument == ReloadArgument.ALL) { plugin().scheduler().executeAsync(() -> { - long time1 = System.currentTimeMillis(); - plugin().reload(); - try { - plugin().packManager().generateResourcePack(); - long time2 = System.currentTimeMillis(); - handleFeedback(context, MessageConstants.COMMAND_RELOAD_ALL_SUCCESS, Component.text(time2 - time1)); - } catch (Exception e) { - handleFeedback(context, MessageConstants.COMMAND_RELOAD_ALL_FAILURE); - plugin().logger().warn("Failed to generate resource pack", e); - } + plugin().reload((a, b) -> { + try { + long time1 = System.currentTimeMillis(); + plugin().packManager().generateResourcePack(); + long time2 = System.currentTimeMillis(); + handleFeedback(context, MessageConstants.COMMAND_RELOAD_ALL_SUCCESS, Component.text(a + b + time2 - time1), Component.text(a), Component.text(b), Component.text(time2 - time1)); + } catch (Exception e) { + handleFeedback(context, MessageConstants.COMMAND_RELOAD_ALL_FAILURE); + plugin().logger().warn("Failed to generate resource pack", e); + } + }); }); } }); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java index 4b20d0e78..7b5d27868 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java @@ -13,16 +13,9 @@ import java.util.Collection; import java.util.Map; import java.util.Optional; -public interface BlockManager extends Reloadable, ModelGenerator, ConfigSectionParser { - String[] CONFIG_SECTION_NAME = new String[] {"blocks", "block"}; +public interface BlockManager extends Reloadable, ModelGenerator { - default String[] sectionId() { - return CONFIG_SECTION_NAME; - } - - default int loadingSequence() { - return LoadingSequence.BLOCK; - } + ConfigSectionParser parser(); Collection modelsToGenerate(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index 2f51310ce..988dc9228 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -136,6 +136,11 @@ public abstract class AbstractFontManager implements FontManager { @Override public void parseSection(Pack pack, Path path, Key id, Map section) { + if (images.containsKey(id)) { + TranslationManager.instance().log("warning.config.image.duplicated", path.toString(), id.toString()); + return; + } + Object heightObj = section.get("height"); if (heightObj == null) { TranslationManager.instance().log("warning.config.image.lack_height", path.toString(), id.toString()); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 88e5967fd..e6c8b01f5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -34,6 +34,8 @@ import org.apache.logging.log4j.LogManager; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; @@ -98,7 +100,12 @@ public abstract class CraftEngine implements Plugin { @Override public void reload() { + reload((a, b) -> {}); + } + + public void reload(BiConsumer time) { if (this.isReloading) return; + long time1 = System.currentTimeMillis(); this.isReloading = true; this.configManager.reload(); // reset debugger @@ -130,9 +137,12 @@ public abstract class CraftEngine implements Plugin { this.soundManager.delayedLoad(); this.fontManager.delayedLoad(); this.recipeManager.delayedLoad(); + long time2 = System.currentTimeMillis(); scheduler().sync().run(() -> { try { this.recipeManager.runSyncTasks(); + long time3 = System.currentTimeMillis(); + time.accept(time2 - time1, time3 - time2); } finally { this.isReloading = false; } @@ -194,7 +204,7 @@ public abstract class CraftEngine implements Plugin { // register furniture parser this.packManager.registerConfigSectionParser(this.furnitureManager.parser()); // register block parser - this.packManager.registerConfigSectionParser(this.blockManager); + this.packManager.registerConfigSectionParser(this.blockManager.parser()); // register recipe parser this.packManager.registerConfigSectionParser(this.recipeManager.parser()); // register category parser