From 11ab46bc8e9a8d1925b0cc969029d0f2ea937a5b Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sun, 18 May 2025 18:00:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=A8=A1=E5=9E=8B=E8=AF=BB?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 4 + .../src/main/resources/translations/zh_cn.yml | 1 + .../bukkit/item/BukkitItemManager.java | 3 +- .../core/item/AbstractItemManager.java | 88 ++++++++++++++----- .../core/pack/model/LegacyItemModel.java | 43 +++++++++ 5 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/model/LegacyItemModel.java diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 2a6d99bac..c33a67965 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -145,14 +145,18 @@ warning.config.item.duplicate: "Issue found in file - Duplicated warning.config.item.settings.unknown: "Issue found in file - The item '' is using an unknown setting type ''." warning.config.item.missing_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.invalid_custom_model_data: "Issue found in file - The item '' is using a negative custom model data '' which is invalid." warning.config.item.bad_custom_model_data: "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.missing_model_id: "Issue found in file - The item '' is missing the required 'custom-model-data' or 'item-model' argument." +warning.config.item.missing_model: "Issue found in file - The item '' is missing the required 'model' section for 1.21.4+ resource pack support." warning.config.item.behavior.missing_type: "Issue found in file - The item '' is missing the required 'type' argument for its item behavior." warning.config.item.behavior.invalid_type: "Issue found in file - The item '' is using an invalid item behavior type ''." warning.config.item.behavior.block.missing_block: "Issue found in file - The item '' is missing the required 'block' argument for 'block_item' behavior." warning.config.item.behavior.furniture.missing_furniture: "Issue found in file - The item '' is missing the required 'furniture' argument for 'furniture_item' behavior." warning.config.item.behavior.liquid_collision.missing_block: "Issue found in file - The item '' is missing the required 'block' argument for 'liquid_collision_block_item' behavior." +warning.config.item.legacy_model.missing_path: "Issue found in file - The item '' is missing the require 'path' argument for legacy-model." +warning.config.item.legacy_model.cannot_convert: "Issue found in file - Cannot convert 1.21.4+ items to legacy format for item ''. Please manually create 'legacy-model' section for this item." warning.config.item.model.invalid_type: "Issue found in file - The item '' is using an invalid model type ''." warning.config.item.model.tint.missing_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 ''." diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index f0f71519f..ea6b6e9b8 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -143,6 +143,7 @@ warning.config.item.duplicate: "在文件 发现问题 - 重复 warning.config.item.settings.unknown: "在文件 发现问题 - 物品 '' 使用了未知的设置类型 ''" warning.config.item.missing_material: "在文件 发现问题 - 物品 '' 缺少必需的 'material' 参数" warning.config.item.invalid_material: "在文件 发现问题 - 物品 '' 使用了无效的材料类型 ''" +warning.config.item.invalid_custom_model_data: "在文件 发现问题 - 物品 '' 使用了无效的负数模型值 ''." warning.config.item.bad_custom_model_data: "在文件 发现问题 - 物品 '' 使用的自定义模型数据 '' 数值过大 建议使用小于 16,777,216 的值" warning.config.item.custom_model_data_conflict: "在文件 发现问题 - 物品 '' 使用的自定义模型数据 '' 已被物品 '' 占用" warning.config.item.missing_model_id: "在文件 发现问题 - 物品 '' 缺少必需的 'custom-model-data' 或 'item-model' 参数" 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 d7fb27b85..175a35013 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 @@ -56,7 +56,6 @@ public class BukkitItemManager extends AbstractItemManager { private final DebugStickListener debugStickListener; private final ArmorEventListener armorEventListener; - public BukkitItemManager(BukkitCraftEngine plugin) { super(plugin); instance = this; @@ -131,7 +130,7 @@ public class BukkitItemManager extends AbstractItemManager { @Override public Optional> getVanillaItem(Key key) { - Material material = Registry.MATERIAL.get(Objects.requireNonNull(NamespacedKey.fromString(key.toString()))); + Material material = Registry.MATERIAL.get(KeyUtils.toNamespacedKey(key)); if (material == null) { return Optional.empty(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 8719601b8..d0dd2f51c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -17,6 +17,7 @@ import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.event.EventFunctions; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +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; @@ -270,7 +271,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl @Override public void parseSection(Pack pack, Path path, Key id, Map section) { - if (customItems.containsKey(id)) { + if (AbstractItemManager.this.customItems.containsKey(id)) { throw new LocalizedResourceConfigException("warning.config.item.duplicate"); } @@ -282,7 +283,12 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl boolean isVanillaItem = isVanillaItem(id); Key material = Key.from(isVanillaItem ? id.value() : ResourceConfigUtils.requireNonEmptyStringOrThrow(section.get("material"), "warning.config.item.missing_material")); int customModelData = ResourceConfigUtils.getAsInt(section.getOrDefault("custom-model-data", 0), "custom-model-data"); - // TODO give warnings if negative + if (customModelData < 0) { + throw new LocalizedResourceConfigException("warning.config.item.invalid_custom_model_data", String.valueOf(customModelData)); + } + if (customModelData > 16_777_216) { + throw new LocalizedResourceConfigException("warning.config.item.bad_custom_model_data", String.valueOf(customModelData)); + } Key itemModelKey = null; @@ -306,7 +312,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl } } - if (hasItemModelSection) { + if (hasItemModelSection && VersionHelper.isOrAbove1_21_2()) { itemModelKey = Key.from(section.get("item-model").toString()); itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey)); } @@ -338,28 +344,67 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl // model part, can be null // but if it exists, either custom model data or item model should be configured Map modelSection = MiscUtils.castToMap(section.get("model"), true); - if (modelSection == null) { + Map legacyModelSection = MiscUtils.castToMap(section.get("legacy-model"), true); + if (modelSection == null && legacyModelSection == null) { return; } - if (customModelData <= 0 && itemModelKey == null) { + // 如果设置了model,但是没有模型值? + if (customModelData == 0 && itemModelKey == null) { throw new LocalizedResourceConfigException("warning.config.item.missing_model_id"); } - - ItemModel model = ItemModels.fromMap(modelSection); - for (ModelGeneration generation : model.modelsToGenerate()) { - prepareModelGeneration(generation); + // 1.21.4+必须要配置model区域 + if (Config.packMaxVersion() >= 21.4f && modelSection == null) { + throw new LocalizedResourceConfigException("warning.config.item.missing_model"); } + // 新版格式 + ItemModel modernModel = null; + // 旧版格式 TreeSet legacyOverridesModels = null; - if (Config.packMinVersion() < 21.4f) { - legacyOverridesModels = new TreeSet<>(); - if (section.containsKey("legacy-model")) { + if (Config.packMaxVersion() >= 21.4f) { + modernModel = ItemModels.fromMap(modelSection); + for (ModelGeneration generation : modernModel.modelsToGenerate()) { + prepareModelGeneration(generation); + } + // 如果最低支持版本低于1.21.4,则需要准备旧版overrides模型 + if (Config.packMinVersion() < 21.4f) { + // 如果有旧版格式,就用旧版 + if (legacyModelSection != null) { + LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection); + for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) { + prepareModelGeneration(generation); + } + legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides()); + } else { + // 否则把新版格式并转换为旧版 + legacyOverridesModels = new TreeSet<>(); + processModelRecursively(modernModel, new LinkedHashMap<>(), legacyOverridesModels, material, customModelData); + if (legacyOverridesModels.isEmpty()) { + TranslationManager.instance().log("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString()); + } + } + } + } + // 最高支持版本不超过1.21.4,所以新版model格式为非必需 + else { + // 如果有旧版格式,就用旧版 + if (legacyModelSection != null) { + LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection); + for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) { + prepareModelGeneration(generation); + } + legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides()); } else { + // 否则读新版格式并转换为旧版 + ItemModel model = ItemModels.fromMap(modelSection); + for (ModelGeneration generation : model.modelsToGenerate()) { + prepareModelGeneration(generation); + } + legacyOverridesModels = new TreeSet<>(); processModelRecursively(model, new LinkedHashMap<>(), legacyOverridesModels, material, customModelData); if (legacyOverridesModels.isEmpty()) { - // TODO give warnings - plugin.debug(() -> "Can't convert " + id + "'s model to legacy format."); + TranslationManager.instance().log("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString()); } } } @@ -372,16 +417,13 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl if (conflict.containsKey(customModelData)) { throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString()); } - if (customModelData > 16_777_216) { - throw new LocalizedResourceConfigException("warning.config.item.bad_custom_model_data", String.valueOf(customModelData)); - } conflict.put(customModelData, id); // Parse models - if (Config.packMaxVersion() >= 21.4f) { + if (Config.packMaxVersion() >= 21.4f && modernModel != null) { TreeMap map = modernOverrides.computeIfAbsent(material, k -> new TreeMap<>()); - map.put(customModelData, model); + map.put(customModelData, modernModel); } - if (Config.packMinVersion() < 21.4f) { + if (Config.packMinVersion() < 21.4f && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { TreeSet lom = legacyOverrides.computeIfAbsent(material, k -> new TreeSet<>()); lom.addAll(legacyOverridesModels); } @@ -389,10 +431,10 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl // use item model if (itemModelKey != null) { - if (Config.packMaxVersion() >= 21.4f) { - modernItemModels1_21_4.put(itemModelKey, model); + if (Config.packMaxVersion() >= 21.4f && modernModel != null) { + modernItemModels1_21_4.put(itemModelKey, modernModel); } - if (Config.packMaxVersion() >= 21.2f && Config.packMinVersion() < 21.4f) { + if (Config.packMaxVersion() >= 21.2f && Config.packMinVersion() < 21.4f && legacyOverridesModels != null && !legacyOverridesModels.isEmpty()) { modernItemModels1_21_2.put(itemModelKey, legacyOverridesModels); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/LegacyItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/LegacyItemModel.java new file mode 100644 index 000000000..81db56d2e --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/LegacyItemModel.java @@ -0,0 +1,43 @@ +package net.momirealms.craftengine.core.pack.model; + +import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; + +import java.util.List; +import java.util.Map; + +public class LegacyItemModel { + private final List modelsToGenerate; + private final String path; + private final List overrides; + + public LegacyItemModel(String path, List overrides, List modelsToGenerate) { + this.modelsToGenerate = modelsToGenerate; + this.path = path; + this.overrides = overrides; + } + + public List modelsToGenerate() { + return modelsToGenerate; + } + + public List overrides() { + return overrides; + } + + public String path() { + return path; + } + + public static LegacyItemModel fromMap(Map legacyModel) { + String legacyModelPath = ResourceConfigUtils.requireNonEmptyStringOrThrow(legacyModel.get("path"), "warning.config.item.legacy_model.missing_path"); + Map generation = MiscUtils.castToMap(legacyModel.get("generation"), true); + ModelGeneration modelGeneration = null; + if (generation != null) { + modelGeneration = ModelGeneration.of(Key.of(legacyModelPath), generation); + } + LegacyOverridesModel legacyOverridesModel = new LegacyOverridesModel(); + } +}