From 4d6eb03edb658301d0f96202ed38b45eb3116116 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sun, 27 Apr 2025 19:30:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E9=AA=8C=E6=80=A7=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 2 + .../advancement/BukkitAdvancementManager.java | 4 +- .../furniture/BukkitFurnitureManager.java | 30 ++++++----- .../entity/furniture/FurnitureSettings.java | 3 +- .../core/pack/AbstractPackManager.java | 6 ++- .../plugin/config/ConfigSectionParser.java | 3 +- .../plugin/locale/LocalizedException.java | 51 ++++++++++++++++++- .../craftengine/core/util/ArrayUtils.java | 20 ++++++++ gradle.properties | 2 +- 9 files changed, 98 insertions(+), 23 deletions(-) diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 38a99eb8e..f0e1f0abc 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -63,6 +63,7 @@ command.upload.failure.not_supported: "Current hosting method '' doe command.upload.on_progress: "Started uploading progress. Check the console for more information." command.send_resource_pack.success.single: "Sent resource pack to ." command.send_resource_pack.success.multiple: "Send resource packs to players." +warning.config.not_a_section: "Issue found in file - '.' is expected to be a config section while it's actually a(n) ''." 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'." @@ -83,6 +84,7 @@ warning.config.jukebox_song.duplicated: "Issue found in file - D warning.config.furniture.duplicated: "Issue found in file - Duplicated furniture ''." warning.config.furniture.lack_placement: "Issue found in file - The furniture '' is missing the required 'placement' argument." warning.config.furniture.element.lack_item: "Issue found in file - The furniture '' is missing the required 'item' argument for one of its elements." +warning.config.furniture.settings.unknown: "Issue found in file - The furniture '' is using an unknown setting type ''." warning.config.item.duplicated: "Issue found in file - Duplicated item ''." 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 ''." diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java index c1ed78270..29035442a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java @@ -7,6 +7,7 @@ import net.momirealms.craftengine.core.advancement.AbstractAdvancementManager; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; @@ -51,8 +52,7 @@ public class BukkitAdvancementManager extends AbstractAdvancementManager { @Override public void parseSection(Pack pack, Path path, Key id, Map section) { if (advancements.containsKey(id)) { - TranslationManager.instance().log("warning.config.advancement.duplicated", path.toString(), id.toString()); - return; + throw new LocalizedException("warning.config.advancement.duplicated", path.toString(), id.toString()); } JsonElement jsonTree = GsonHelper.get().toJsonTree(section); FastNMS.INSTANCE.registerAdvancement(id.decompose(), jsonTree); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 29ee90605..bcfd7fb99 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -12,6 +12,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.sound.SoundData; import net.momirealms.craftengine.core.util.Key; @@ -106,19 +107,18 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { @Override public void parseSection(Pack pack, Path path, Key id, Map section) { if (byId.containsKey(id)) { - TranslationManager.instance().log("warning.config.furniture.duplicated", path.toString(), id.toString()); - return; + throw new LocalizedException("warning.config.furniture.duplicated", path.toString(), id.toString()); } Map lootMap = MiscUtils.castToMap(section.get("loot"), true); Map settingsMap = MiscUtils.castToMap(section.get("settings"), true); Map placementMap = MiscUtils.castToMap(section.get("placement"), true); - EnumMap placements = new EnumMap<>(AnchorType.class); if (placementMap == null) { - TranslationManager.instance().log("warning.config.furniture.lack_placement", path.toString(), id.toString()); - return; + throw new LocalizedException("warning.config.furniture.lack_placement", path.toString(), id.toString()); } + EnumMap placements = new EnumMap<>(AnchorType.class); + for (Map.Entry entry : placementMap.entrySet()) { // anchor type AnchorType anchorType = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)); @@ -130,8 +130,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { for (Map element : elementConfigs) { String key = (String) element.get("item"); if (key == null) { - TranslationManager.instance().log("warning.config.furniture.element.lack_item", path.toString(), id.toString()); - return; + throw new LocalizedException("warning.config.furniture.element.lack_item", path.toString(), id.toString()); } ItemDisplayContext transform = ItemDisplayContext.valueOf(element.getOrDefault("transform", "NONE").toString().toUpperCase(Locale.ENGLISH)); Billboard billboard = Billboard.valueOf(element.getOrDefault("billboard", "FIXED").toString().toUpperCase(Locale.ENGLISH)); @@ -192,13 +191,16 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { } } - CustomFurniture furniture = new CustomFurniture( - id, - FurnitureSettings.fromMap(settingsMap), - placements, - lootMap == null ? null : LootTable.fromMap(lootMap) - ); - + // get furniture settings + FurnitureSettings settings; + try { + settings = FurnitureSettings.fromMap(settingsMap); + } catch (LocalizedException e) { + e.setArgument(0, path.toString()); + e.setArgument(1, id.toString()); + throw e; + } + CustomFurniture furniture = new CustomFurniture(id, settings, placements, lootMap == null ? null : LootTable.fromMap(lootMap)); byId.put(id, furniture); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureSettings.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureSettings.java index d997323f3..9a9ed04e9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureSettings.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.entity.furniture; +import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.jetbrains.annotations.Nullable; @@ -38,7 +39,7 @@ public class FurnitureSettings { if (factory != null) { factory.createModifier(entry.getValue()).apply(settings); } else { - throw new IllegalArgumentException("Unknown item settings key: " + entry.getKey()); + throw new LocalizedException("warning.config.furniture.settings.unknown", new RuntimeException("Unknown furniture settings: " + entry.getKey()), "null", "null", entry.getKey()); } } return settings; diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 79cfe4596..de3c80cba 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -454,11 +454,13 @@ public abstract class AbstractPackManager implements PackManager { parser.parseSection(cached.pack(), cached.filePath(), id, plugin.templateManager().applyTemplates(configSection1)); } } else { - this.plugin.logger().warn(cached.filePath(), "Configuration section is required for " + parser.sectionId()[0] + "." + configEntry.getKey() + " - "); + TranslationManager.instance().log("warning.config.not_a_section", cached.filePath().toString(), parser.sectionId()[0], configEntry.getKey(), configEntry.getValue().getClass().getSimpleName()); } } + } catch (LocalizedException e) { + TranslationManager.instance().log(e.node(), e.arguments()); } catch (Exception e) { - this.plugin.logger().warn(cached.filePath(), "Error loading " + parser.sectionId()[0] + "." + key, e); + this.plugin.logger().warn("Unexpected error loading file " + cached.filePath() + " - '" + parser.sectionId()[0] + "." + key + "'. Please find the cause according to the stacktrace or seek developer help.", e); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java index 3b5f9ef92..0c7f94f94 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.plugin.config; import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.NotNull; @@ -11,7 +12,7 @@ public interface ConfigSectionParser extends Comparable { String[] sectionId(); - void parseSection(Pack pack, Path path, Key id, Map section); + void parseSection(Pack pack, Path path, Key id, Map section) throws LocalizedException; int loadingSequence(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/LocalizedException.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/LocalizedException.java index 87c4dc8a3..dc8b20522 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/LocalizedException.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/LocalizedException.java @@ -1,13 +1,32 @@ package net.momirealms.craftengine.core.plugin.locale; +import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.craftengine.core.util.ArrayUtils; +import org.jetbrains.annotations.Nullable; + public class LocalizedException extends RuntimeException { private final String node; - private final String[] arguments; + private final Exception originalException; + private String[] arguments; - public LocalizedException(String node, String... arguments) { + public LocalizedException(String node, Exception originalException, String... arguments) { super(node); this.node = node; this.arguments = arguments; + this.originalException = originalException; + } + + public LocalizedException(String node, String... arguments) { + this(node, (Exception) null, arguments); + } + + public LocalizedException(String node, String[] arguments1, String... arguments2) { + this(node, (Exception) null, ArrayUtils.merge(arguments1, arguments2)); + } + + @Nullable + public Exception originalException() { + return originalException; } public String[] arguments() { @@ -17,4 +36,32 @@ public class LocalizedException extends RuntimeException { public String node() { return node; } + + public void setArgument(int index, String argument) { + this.arguments[index] = argument; + } + + public void appendHeadArgument(String argument) { + this.arguments = ArrayUtils.appendElementToArrayHead(this.arguments, argument); + } + + public void appendTailArgument(String argument) { + this.arguments = ArrayUtils.appendElementToArrayTail(this.arguments, argument); + } + + // we should not call this method directly, as it's inaccurate + @Override + public String getMessage() { + if (originalException != null) { + return originalException.getMessage(); + } + String text = AdventureHelper.miniMessage().stripTags(TranslationManager.instance().miniMessageTranslation(this.node)); + for (int i = 0; i < arguments.length; i++) { + text = text.replace("", arguments[i]); + } + return text; +// return "\n" + "Node: '" + this.node + "'" + +// "\n" + "Translation: '" + AdventureHelper.miniMessage().stripTags(TranslationManager.instance().miniMessageTranslation(this.node)) + "'" + +// "\n" + "Arguments: " + Arrays.toString(this.arguments); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ArrayUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ArrayUtils.java index 85e8beddd..da87a2c53 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ArrayUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ArrayUtils.java @@ -25,6 +25,26 @@ public class ArrayUtils { return subArray; } + @SuppressWarnings("unchecked") + public static T[] merge(T[] array1, T[] array2) { + if (array1 == null && array2 == null) { + return null; + } + if (array1 == null) { + return Arrays.copyOf(array2, array2.length); + } + if (array2 == null) { + return Arrays.copyOf(array1, array1.length); + } + T[] mergedArray = (T[]) Array.newInstance( + array1.getClass().getComponentType(), + array1.length + array2.length + ); + System.arraycopy(array1, 0, mergedArray, 0, array1.length); + System.arraycopy(array2, 0, mergedArray, array1.length, array2.length); + return mergedArray; + } + public static List splitArray(T[] array, int chunkSize) { List result = new ArrayList<>(); for (int i = 0; i < array.length; i += chunkSize) { diff --git a/gradle.properties b/gradle.properties index a38fd2bdd..6bef76c12 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.51 config_version=30 -lang_version=7 +lang_version=8 project_group=net.momirealms latest_supported_version=1.21.5