From 755be24182f94367f0015e7e4ad15cf8f733ff72 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 5 Jun 2025 21:19:43 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=94=B9=E5=96=84=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/font/AbstractFontManager.java | 22 ++-- .../craftengine/core/font/BitmapImage.java | 4 +- .../craftengine/core/font/OffsetFont.java | 19 +-- .../config/template/TemplateManagerImpl.java | 124 +++++++++++++----- 4 files changed, 120 insertions(+), 49 deletions(-) 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 92ae329cb..6fd850ca0 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 @@ -269,21 +269,25 @@ public abstract class AbstractFontManager implements FontManager { } private void buildImageTagTrie() { - this.tagMapper = new HashMap<>(); + this.tagMapper = new HashMap<>(1024); for (BitmapImage image : this.images.values()) { String id = image.id().toString(); - this.tagMapper.put(imageTag(id), AdventureHelper.miniMessage().deserialize(image.miniMessage(0, 0))); - this.tagMapper.put("\\" + imageTag(id), Component.text(imageTag(id))); + String simpleImageTag = imageTag(id); + this.tagMapper.put(simpleImageTag, image.componentAt(0, 0)); + this.tagMapper.put("\\" + simpleImageTag, Component.text(simpleImageTag)); for (int i = 0; i < image.rows(); i++) { for (int j = 0; j < image.columns(); j++) { - this.tagMapper.put(imageTag(id + ":" + i + ":" + j), AdventureHelper.miniMessage().deserialize(image.miniMessage(i, j))); - this.tagMapper.put(imageTag("\\" + id + ":" + i + ":" + j), Component.text(imageTag(id + ":" + i + ":" + j))); + String imageArgs = id + ":" + i + ":" + j; + String imageTag = imageTag(imageArgs); + this.tagMapper.put(imageTag, image.componentAt(i, j)); + this.tagMapper.put("\\" + imageTag, Component.text(imageTag)); } } } for (int i = -256; i <= 256; i++) { - this.tagMapper.put("", AdventureHelper.miniMessage().deserialize(this.offsetFont.createOffset(i, FormatUtils::miniMessageFont))); - this.tagMapper.put("\\", Component.text("")); + String shiftTag = ""; + this.tagMapper.put(shiftTag, AdventureHelper.miniMessage().deserialize(this.offsetFont.createOffset(i, FormatUtils::miniMessageFont))); + this.tagMapper.put("\\" + shiftTag, Component.text(shiftTag)); } this.imageTagTrie = Trie.builder() .ignoreOverlaps() @@ -377,7 +381,7 @@ public abstract class AbstractFontManager implements FontManager { Key imageId = new Key(split[0], split[1]); Optional bitmapImage = bitmapImageByImageId(imageId); if (bitmapImage.isPresent()) { - image = bitmapImage.get().miniMessage(0, 0); + image = bitmapImage.get().miniMessageAt(0, 0); } else { throw new LocalizedResourceConfigException("warning.config.emoji.invalid_image", path, id, rawImage); } @@ -386,7 +390,7 @@ public abstract class AbstractFontManager implements FontManager { Optional bitmapImage = bitmapImageByImageId(imageId); if (bitmapImage.isPresent()) { try { - image = bitmapImage.get().miniMessage(Integer.parseInt(split[2]), Integer.parseInt(split[3])); + image = bitmapImage.get().miniMessageAt(Integer.parseInt(split[2]), Integer.parseInt(split[3])); } catch (ArrayIndexOutOfBoundsException e) { throw new LocalizedResourceConfigException("warning.config.emoji.invalid_image", path, id, rawImage); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/BitmapImage.java b/core/src/main/java/net/momirealms/craftengine/core/font/BitmapImage.java index 8272d7419..671a4df05 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/BitmapImage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/BitmapImage.java @@ -26,9 +26,9 @@ public class BitmapImage implements Supplier { this.codepointGrid = codepointGrid; } - public String miniMessage(int row, int col) { + public String miniMessageAt(int row, int col) { int codepoint = codepointGrid[row][col]; - return FormatUtils.miniMessageFont(new String(Character.toChars(codepoint)), font.toString()); + return FormatUtils.miniMessageFont(new String(Character.toChars(codepoint)), this.font.toString()); } public int height() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/OffsetFont.java b/core/src/main/java/net/momirealms/craftengine/core/font/OffsetFont.java index eaa5e9444..c1ae43aa3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/OffsetFont.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/OffsetFont.java @@ -3,13 +3,17 @@ package net.momirealms.craftengine.core.font; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import dev.dejvokep.boostedyaml.block.implementation.Section; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.util.CharacterUtils; +import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; public class OffsetFont { private final String font; + private final Key fontKey; private final String NEG_16; private final String NEG_24; @@ -37,6 +41,7 @@ public class OffsetFont { public OffsetFont(Section section) { font = section.getString("font", "minecraft:default"); + fontKey = Key.key(font); NEG_16 = convertIfUnicode(section.getString("-16", "")); NEG_24 = convertIfUnicode(section.getString("-24", "")); @@ -59,16 +64,14 @@ public class OffsetFont { } } + public Component createOffset(int offset) { + if (offset == 0) return Component.empty(); + return Component.text(Objects.requireNonNull(this.fastLookup.get(offset, k -> k > 0 ? createPos(k) : createNeg(-k)))).font(this.fontKey); + } + public String createOffset(int offset, BiFunction tagDecorator) { if (offset == 0) return ""; - String raw = fastLookup.get(offset, k -> { - if (k > 0) { - return createPos(k); - } else { - return createNeg(-k); - } - }); - return tagDecorator.apply(raw, font); + return tagDecorator.apply(this.fastLookup.get(offset, k -> k > 0 ? createPos(k) : createNeg(-k)), this.font); } @SuppressWarnings("DuplicatedCode") diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index 356d9719a..cad38db9f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -188,18 +188,23 @@ public class TemplateManagerImpl implements TemplateManager { Map parentArguments) { // 先获取template节点下所有的模板 List templateIds = MiscUtils.getAsStringList(input.get(TEMPLATE)); - List templateList = new ArrayList<>(); + List templateList = new ArrayList<>(templateIds.size()); + for (String templateId : templateIds) { // 如果模板id被用了参数,则应先应用参数后再查询模板 Object actualTemplate = applyArgument(templateId, parentArguments); if (actualTemplate == null) continue; // 忽略被null掉的模板 - Object template = Optional.ofNullable(templates.get(Key.of(actualTemplate.toString()))) + Object template = Optional.ofNullable(this.templates.get(Key.of(actualTemplate.toString()))) .orElseThrow(() -> new IllegalArgumentException("Template not found: " + actualTemplate)); templateList.add(template); } + + Object argument = input.get(ARGUMENTS); + boolean hasArgument = argument != null; + // 将本节点下的参数与父参数合并 - Map arguments = mergeArguments( - MiscUtils.castToMap(input.getOrDefault(ARGUMENTS, Collections.emptyMap()), false), + Map arguments = !hasArgument ? parentArguments : mergeArguments( + MiscUtils.castToMap(argument, false), parentArguments ); @@ -215,6 +220,7 @@ public class TemplateManagerImpl implements TemplateManager { throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj)); } }); + // overrides是map了,merges也只能是map if (input.get(MERGES) instanceof Map rawMerges) { Map merges = new LinkedHashMap<>(); processMap(MiscUtils.castToMap(rawMerges, false), arguments, (obj) -> { @@ -225,6 +231,15 @@ public class TemplateManagerImpl implements TemplateManager { throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj)); } }); + // 已有template,merges,overrides 和可选的arguments + if (input.size() > (hasArgument ? 4 : 3)) { + // 会不会有一种可能,有笨比用户把模板和普通配置混合在了一起?再次遍历input后处理 + for (Map.Entry inputEntry : input.entrySet()) { + String inputKey = inputEntry.getKey(); + if (NON_TEMPLATE_KEY.contains(inputKey)) continue; + processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> merges.put(inputKey, processed)); + } + } // 返回处理结果 return new TemplateProcessingResult( templateList, @@ -233,12 +248,29 @@ public class TemplateManagerImpl implements TemplateManager { arguments ); } else { - return new TemplateProcessingResult( - templateList, - overrides, - null, - arguments - ); + // 已有template,overrides 和可选的arguments + if (input.size() > (hasArgument ? 3 : 2)) { + Map merges = new LinkedHashMap<>(); + // 会不会有一种可能,有笨比用户把模板和普通配置混合在了一起?再次遍历input后处理 + for (Map.Entry inputEntry : input.entrySet()) { + String inputKey = inputEntry.getKey(); + if (NON_TEMPLATE_KEY.contains(inputKey)) continue; + processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> merges.put(inputKey, processed)); + } + return new TemplateProcessingResult( + templateList, + overrides, + merges, + arguments + ); + } else { + return new TemplateProcessingResult( + templateList, + overrides, + null, + arguments + ); + } } } else if (override instanceof List overrides) { // overrides不为空,且不是map @@ -258,7 +290,6 @@ public class TemplateManagerImpl implements TemplateManager { arguments ); } else { - // overrides不为空,且不是map return new TemplateProcessingResult( templateList, processedOverrides, @@ -266,8 +297,15 @@ public class TemplateManagerImpl implements TemplateManager { arguments ); } + } else if (override instanceof String rawOverride) { + return new TemplateProcessingResult( + templateList, + applyArgument(rawOverride, arguments), + null, + arguments + ); } else if (override != null) { - // overrides不为空,且不是map。此情况不用再考虑merge了 + // overrides不为空,且不是map,list。此情况不用再考虑merge了 return new TemplateProcessingResult( templateList, override, @@ -287,17 +325,18 @@ public class TemplateManagerImpl implements TemplateManager { throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj)); } }); - Map overrides = new LinkedHashMap<>(); - // 会不会有一种可能,有笨比用户不会使用overrides,把模板和普通配置混合在了一起?再次遍历input后处理 - for (Map.Entry inputEntry : input.entrySet()) { - String inputKey = inputEntry.getKey(); - if (NON_TEMPLATE_KEY.contains(inputKey)) continue; - // 处理那些overrides - processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> overrides.put(inputKey, processed)); + // 已有template和merges 和可选的arguments + if (input.size() > (hasArgument ? 3 : 2)) { + // 会不会有一种可能,有笨比用户把模板和普通配置混合在了一起?再次遍历input后处理 + for (Map.Entry inputEntry : input.entrySet()) { + String inputKey = inputEntry.getKey(); + if (NON_TEMPLATE_KEY.contains(inputKey)) continue; + processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> merges.put(inputKey, processed)); + } } return new TemplateProcessingResult( templateList, - overrides.isEmpty() ? null : overrides, + null, merges, arguments ); @@ -312,21 +351,46 @@ public class TemplateManagerImpl implements TemplateManager { merges, arguments ); - } else { - Map overrides = new LinkedHashMap<>(); - // 会不会有一种可能,有笨比用户不会使用overrides,把模板和普通配置混合在了一起?再次遍历input后处理 - for (Map.Entry inputEntry : input.entrySet()) { - String inputKey = inputEntry.getKey(); - if (NON_TEMPLATE_KEY.contains(inputKey)) continue; - // 处理那些overrides - processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> overrides.put(inputKey, processed)); - } + } else if (merge instanceof String rawMerge) { + // merge是个string return new TemplateProcessingResult( templateList, - overrides.isEmpty() ? null : overrides, + null, + applyArgument(rawMerge, arguments), + arguments + ); + } else if (merge != null) { + // merge是个普通的类型 + return new TemplateProcessingResult( + templateList, + null, merge, arguments ); + } else { + // 无overrides和merges + // 会不会有一种可能,有笨比用户不会使用merges,把模板和普通配置混合在了一起?再次遍历input后处理 + if (input.size() > (hasArgument ? 2 : 1)) { + Map merges = new LinkedHashMap<>(); + for (Map.Entry inputEntry : input.entrySet()) { + String inputKey = inputEntry.getKey(); + if (NON_TEMPLATE_KEY.contains(inputKey)) continue; + processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> merges.put(inputKey, processed)); + } + return new TemplateProcessingResult( + templateList, + null, + merges, + arguments + ); + } else { + return new TemplateProcessingResult( + templateList, + null, + null, + arguments + ); + } } } } From fb49db654745e98411c0f3b2bcf7b2460a832ac7 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 5 Jun 2025 21:48:31 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=89=8D=E6=9C=80?= =?UTF-8?q?=E7=BB=88=E7=9A=84=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/config/template/TemplateManagerImpl.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index cad38db9f..3ae0e421e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -150,7 +150,8 @@ public class TemplateManagerImpl implements TemplateManager { // 依次处理map下的每个参数 Map result = new LinkedHashMap<>(); for (Map.Entry inputEntry : input.entrySet()) { - processUnknownTypeMember(inputEntry.getValue(), parentArguments, (processed) -> result.put(inputEntry.getKey(), processed)); + String key = applyArgument(inputEntry.getKey(), parentArguments).toString(); + processUnknownTypeMember(inputEntry.getValue(), parentArguments, (processed) -> result.put(key, processed)); } processCallBack.accept(result); } @@ -404,7 +405,7 @@ public class TemplateManagerImpl implements TemplateManager { // argument_1: "{parent_argument}" for (Map.Entry argumentEntry : rawChildArguments.entrySet()) { // 获取最终的string形式参数 - String placeholder = argumentEntry.getKey(); + String placeholder = applyArgument(argumentEntry.getKey(), parentArguments).toString(); // 父亲参数最大 if (result.containsKey(placeholder)) continue; Object rawArgument = argumentEntry.getValue(); @@ -449,9 +450,9 @@ public class TemplateManagerImpl implements TemplateManager { if (input.length() < 3) return input; if (input.charAt(0) == '{' && input.charAt(input.length() - 1) == '}') { String key = input.substring(1, input.length() - 1); - if (arguments.containsKey(key)) { - return arguments.get(key).get(); - } + return Optional.ofNullable(arguments.get(key)) + .map(TemplateArgument::get) + .orElse(replacePlaceholders(input, arguments)); } return replacePlaceholders(input, arguments); } From cb7548a1938ecd4209641e23cd6ab7acc009e74e Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 5 Jun 2025 22:16:15 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E9=9A=BE=E7=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/SelfIncreaseIntTemplateArgument.java | 13 ++++++++----- .../plugin/config/template/TemplateManagerImpl.java | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java index d99690814..6d2c94ca2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java @@ -20,8 +20,11 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument { @Override public String get() { - String value = String.valueOf(current); - if (current < max) current += 1; + String value = String.valueOf(this.current); + if (this.current < this.max) this.current += 1; + else { + throw new IllegalStateException("SelfIncreaseInt " + this.current + " is already >= " + this.max); + } return value; } @@ -31,15 +34,15 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument { } public int current() { - return current; + return this.current; } public int min() { - return min; + return this.min; } public int max() { - return max; + return this.max; } public static class Factory implements TemplateArgumentFactory { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index 3ae0e421e..a87eeae02 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -452,7 +452,7 @@ public class TemplateManagerImpl implements TemplateManager { String key = input.substring(1, input.length() - 1); return Optional.ofNullable(arguments.get(key)) .map(TemplateArgument::get) - .orElse(replacePlaceholders(input, arguments)); + .orElseGet(() -> replacePlaceholders(input, arguments)); } return replacePlaceholders(input, arguments); } From 04b1f7873d367dd5fe2320d4f688f2cb6a642fef Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 5 Jun 2025 22:28:34 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9A=BE=E7=BB=B7?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/template/SelfIncreaseIntTemplateArgument.java | 3 --- .../core/plugin/config/template/TemplateManagerImpl.java | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java index 6d2c94ca2..92772099d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/SelfIncreaseIntTemplateArgument.java @@ -22,9 +22,6 @@ public class SelfIncreaseIntTemplateArgument implements TemplateArgument { public String get() { String value = String.valueOf(this.current); if (this.current < this.max) this.current += 1; - else { - throw new IllegalStateException("SelfIncreaseInt " + this.current + " is already >= " + this.max); - } return value; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index a87eeae02..c020036ab 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -450,9 +450,10 @@ public class TemplateManagerImpl implements TemplateManager { if (input.length() < 3) return input; if (input.charAt(0) == '{' && input.charAt(input.length() - 1) == '}') { String key = input.substring(1, input.length() - 1); - return Optional.ofNullable(arguments.get(key)) - .map(TemplateArgument::get) - .orElseGet(() -> replacePlaceholders(input, arguments)); + TemplateArgument argument = arguments.get(key); + if (argument != null) { + return argument.get(); + } } return replacePlaceholders(input, arguments); }