mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 00:49:20 +00:00
Merge branch 'Xiao-MoMi:dev' into dev
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
items:
|
items:
|
||||||
# client-bound-data requires CraftEngine mod to apply
|
|
||||||
minecraft:string:
|
minecraft:string:
|
||||||
client-bound-data:
|
client-bound-data:
|
||||||
components:
|
components:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public interface TemplateManager extends Manageable {
|
|||||||
String TEMPLATE = "template";
|
String TEMPLATE = "template";
|
||||||
String OVERRIDES = "overrides";
|
String OVERRIDES = "overrides";
|
||||||
String ARGUMENTS = "arguments";
|
String ARGUMENTS = "arguments";
|
||||||
|
String MERGES = "merges";
|
||||||
|
|
||||||
ConfigParser parser();
|
ConfigParser parser();
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
public class TemplateManagerImpl implements TemplateManager {
|
public class TemplateManagerImpl implements TemplateManager {
|
||||||
private final Map<Key, Object> templates = new HashMap<>();
|
private final Map<Key, Object> templates = new HashMap<>();
|
||||||
private final static Set<String> NON_TEMPLATE_KEY = new HashSet<>(Set.of(TEMPLATE, ARGUMENTS, OVERRIDES));
|
private final static Set<String> NON_TEMPLATE_KEY = new HashSet<>(Set.of(TEMPLATE, ARGUMENTS, OVERRIDES, MERGES));
|
||||||
private final TemplateParser templateParser;
|
private final TemplateParser templateParser;
|
||||||
|
|
||||||
public TemplateManagerImpl() {
|
public TemplateManagerImpl() {
|
||||||
@@ -65,17 +66,19 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
public Map<String, Object> applyTemplates(Key id, Map<String, Object> input) {
|
public Map<String, Object> applyTemplates(Key id, Map<String, Object> input) {
|
||||||
Objects.requireNonNull(input, "Input must not be null");
|
Objects.requireNonNull(input, "Input must not be null");
|
||||||
Map<String, Object> result = new LinkedHashMap<>();
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
processMap(input, Map.of("{__ID__}", PlainStringTemplateArgument.plain(id.value()),
|
processMap(input,
|
||||||
"{__NAMESPACE__}", PlainStringTemplateArgument.plain(id.namespace())), (obj) -> {
|
Map.of("{__ID__}", PlainStringTemplateArgument.plain(id.value()),
|
||||||
// 当前位于根节点下,如果下一级就是模板,则应把模板结果与当前map合并
|
"{__NAMESPACE__}", PlainStringTemplateArgument.plain(id.namespace())),
|
||||||
// 如果模板结果不是map,则为非法值,因为不可能出现类似于下方的配置
|
(obj) -> {
|
||||||
// items:
|
// 当前位于根节点下,如果下一级就是模板,则应把模板结果与当前map合并
|
||||||
// test:invalid: 111
|
// 如果模板结果不是map,则为非法值,因为不可能出现类似于下方的配置
|
||||||
if (obj instanceof Map<?,?> mapResult) {
|
// items:
|
||||||
result.putAll(MiscUtils.castToMap(mapResult, false));
|
// test:invalid: 111
|
||||||
} else {
|
if (obj instanceof Map<?,?> mapResult) {
|
||||||
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
result.putAll(MiscUtils.castToMap(mapResult, false));
|
||||||
}
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -99,16 +102,20 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Object firstTemplate = processedTemplates.get(0);
|
Object firstTemplate = processedTemplates.get(0);
|
||||||
// 对于map和list,应当对多模板合并
|
// 如果是map,应当深度合并
|
||||||
if (firstTemplate instanceof Map<?,?>) {
|
if (firstTemplate instanceof Map<?,?>) {
|
||||||
Map<String, Object> results = new LinkedHashMap<>();
|
Map<String, Object> results = new LinkedHashMap<>();
|
||||||
// 仅仅合并list
|
|
||||||
for (Object processedTemplate : processedTemplates) {
|
for (Object processedTemplate : processedTemplates) {
|
||||||
if (processedTemplate instanceof Map<?, ?> anotherMap) {
|
if (processedTemplate instanceof Map<?, ?> anotherMap) {
|
||||||
results.putAll(MiscUtils.castToMap(anotherMap, false));
|
deepMergeMaps(results, MiscUtils.castToMap(anotherMap, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results.putAll(processingResult.overrides());
|
if (processingResult.overrides() instanceof Map<?, ?> overrides) {
|
||||||
|
results.putAll(MiscUtils.castToMap(overrides, false));
|
||||||
|
}
|
||||||
|
if (processingResult.merges() instanceof Map<?, ?> merges) {
|
||||||
|
deepMergeMaps(results, MiscUtils.castToMap(merges, false));
|
||||||
|
}
|
||||||
processCallBack.accept(results);
|
processCallBack.accept(results);
|
||||||
} else if (firstTemplate instanceof List<?>) {
|
} else if (firstTemplate instanceof List<?>) {
|
||||||
List<Object> results = new ArrayList<>();
|
List<Object> results = new ArrayList<>();
|
||||||
@@ -118,10 +125,22 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
results.addAll(anotherList);
|
results.addAll(anotherList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (processingResult.overrides() instanceof List<?> overrides) {
|
||||||
|
results.clear();
|
||||||
|
results.addAll(overrides);
|
||||||
|
}
|
||||||
|
if (processingResult.merges() instanceof List<?> merges) {
|
||||||
|
results.addAll(merges);
|
||||||
|
}
|
||||||
processCallBack.accept(results);
|
processCallBack.accept(results);
|
||||||
} else {
|
} else {
|
||||||
// 其他情况下应当忽略其他的template
|
Object overrides = processingResult.overrides();
|
||||||
processCallBack.accept(firstTemplate);
|
if (overrides != null) {
|
||||||
|
processCallBack.accept(overrides);
|
||||||
|
} else {
|
||||||
|
// 其他情况下应当忽略其他的template
|
||||||
|
processCallBack.accept(firstTemplate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果不是模板,则返回值一定是map
|
// 如果不是模板,则返回值一定是map
|
||||||
@@ -169,7 +188,7 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
List<Object> templateList = new ArrayList<>();
|
List<Object> templateList = new ArrayList<>();
|
||||||
for (String templateId : templateIds) {
|
for (String templateId : templateIds) {
|
||||||
// 如果模板id被用了参数,则应先应用参数后再查询模板
|
// 如果模板id被用了参数,则应先应用参数后再查询模板
|
||||||
Object actualTemplate = templateId.contains(LEFT_BRACKET) && templateId.contains(RIGHT_BRACKET) ? applyArgument(templateId, parentArguments) : templateId;
|
Object actualTemplate = applyArgument(templateId, parentArguments);
|
||||||
if (actualTemplate == null) continue; // 忽略被null掉的模板
|
if (actualTemplate == null) continue; // 忽略被null掉的模板
|
||||||
Object template = Optional.ofNullable(templates.get(Key.of(actualTemplate.toString())))
|
Object template = Optional.ofNullable(templates.get(Key.of(actualTemplate.toString())))
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Template not found: " + actualTemplate));
|
.orElseThrow(() -> new IllegalArgumentException("Template not found: " + actualTemplate));
|
||||||
@@ -180,29 +199,133 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
MiscUtils.castToMap(input.getOrDefault(ARGUMENTS, Collections.emptyMap()), false),
|
MiscUtils.castToMap(input.getOrDefault(ARGUMENTS, Collections.emptyMap()), false),
|
||||||
parentArguments
|
parentArguments
|
||||||
);
|
);
|
||||||
// 对overrides参数应用 本节点 + 父节点 参数
|
|
||||||
Map<String, Object> overrides = new LinkedHashMap<>();
|
Object override = input.get(OVERRIDES);
|
||||||
processMap(MiscUtils.castToMap(input.getOrDefault(OVERRIDES, Map.of()), false), arguments, (obj) -> {
|
if (override instanceof Map<?, ?> rawOverrides) {
|
||||||
// 如果overrides的下一级就是一个模板,则模板必须为map类型
|
// 对overrides参数应用 本节点 + 父节点 参数
|
||||||
if (obj instanceof Map<?,?> mapResult) {
|
Map<String, Object> overrides = new LinkedHashMap<>();
|
||||||
overrides.putAll(MiscUtils.castToMap(mapResult, false));
|
processMap(MiscUtils.castToMap(rawOverrides, false), arguments, (obj) -> {
|
||||||
|
// 如果overrides的下一级就是一个模板,则模板必须为map类型
|
||||||
|
if (obj instanceof Map<?,?> mapResult) {
|
||||||
|
overrides.putAll(MiscUtils.castToMap(mapResult, false));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (input.get(MERGES) instanceof Map<?, ?> rawMerges) {
|
||||||
|
Map<String, Object> merges = new LinkedHashMap<>();
|
||||||
|
processMap(MiscUtils.castToMap(rawMerges, false), arguments, (obj) -> {
|
||||||
|
// 如果merges的下一级就是一个模板,则模板必须为map类型
|
||||||
|
if (obj instanceof Map<?,?> mapResult) {
|
||||||
|
merges.putAll(MiscUtils.castToMap(mapResult, false));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 返回处理结果
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
overrides,
|
||||||
|
merges,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
overrides,
|
||||||
|
null,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (override instanceof List<?> overrides) {
|
||||||
|
// overrides不为空,且不是map
|
||||||
|
List<Object> processedOverrides = new ArrayList<>(overrides.size());
|
||||||
|
for (Object item : overrides) {
|
||||||
|
processUnknownTypeMember(item, arguments, processedOverrides::add);
|
||||||
|
}
|
||||||
|
if (input.get(MERGES) instanceof List<?> rawMerges) {
|
||||||
|
List<Object> merges = new ArrayList<>(rawMerges.size());
|
||||||
|
for (Object item : rawMerges) {
|
||||||
|
processUnknownTypeMember(item, arguments, merges::add);
|
||||||
|
}
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
processedOverrides,
|
||||||
|
merges,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// overrides不为空,且不是map
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
processedOverrides,
|
||||||
|
null,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (override != null) {
|
||||||
|
// overrides不为空,且不是map。此情况不用再考虑merge了
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
override,
|
||||||
|
null,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 获取merges
|
||||||
|
Object merge = input.get(MERGES);
|
||||||
|
if (merge instanceof Map<?, ?> rawMerges) {
|
||||||
|
Map<String, Object> merges = new LinkedHashMap<>();
|
||||||
|
processMap(MiscUtils.castToMap(rawMerges, false), arguments, (obj) -> {
|
||||||
|
// 如果merges的下一级就是一个模板,则模板必须为map类型
|
||||||
|
if (obj instanceof Map<?,?> mapResult) {
|
||||||
|
merges.putAll(MiscUtils.castToMap(mapResult, false));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid template used. Input: " + GsonHelper.get().toJson(input) + ". Template: " + GsonHelper.get().toJson(obj));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Map<String, Object> overrides = new LinkedHashMap<>();
|
||||||
|
// 会不会有一种可能,有笨比用户不会使用overrides,把模板和普通配置混合在了一起?再次遍历input后处理
|
||||||
|
for (Map.Entry<String, Object> inputEntry : input.entrySet()) {
|
||||||
|
String inputKey = inputEntry.getKey();
|
||||||
|
if (NON_TEMPLATE_KEY.contains(inputKey)) continue;
|
||||||
|
// 处理那些overrides
|
||||||
|
processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> overrides.put(inputKey, processed));
|
||||||
|
}
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
overrides.isEmpty() ? null : overrides,
|
||||||
|
merges,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
} else if (merge instanceof List<?> rawMerges) {
|
||||||
|
List<Object> merges = new ArrayList<>(rawMerges.size());
|
||||||
|
for (Object item : rawMerges) {
|
||||||
|
processUnknownTypeMember(item, arguments, merges::add);
|
||||||
|
}
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
null,
|
||||||
|
merges,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Map<String, Object> overrides = new LinkedHashMap<>();
|
||||||
|
// 会不会有一种可能,有笨比用户不会使用overrides,把模板和普通配置混合在了一起?再次遍历input后处理
|
||||||
|
for (Map.Entry<String, Object> inputEntry : input.entrySet()) {
|
||||||
|
String inputKey = inputEntry.getKey();
|
||||||
|
if (NON_TEMPLATE_KEY.contains(inputKey)) continue;
|
||||||
|
// 处理那些overrides
|
||||||
|
processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> overrides.put(inputKey, processed));
|
||||||
|
}
|
||||||
|
return new TemplateProcessingResult(
|
||||||
|
templateList,
|
||||||
|
overrides.isEmpty() ? null : overrides,
|
||||||
|
merge,
|
||||||
|
arguments
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
// 会不会有一种可能,有笨比用户不会使用overrides,把模板和普通配置混合在了一起?再次遍历input后处理
|
|
||||||
for (Map.Entry<String, Object> inputEntry : input.entrySet()) {
|
|
||||||
String inputKey = inputEntry.getKey();
|
|
||||||
if (NON_TEMPLATE_KEY.contains(inputKey)) continue;
|
|
||||||
// 处理那些overrides
|
|
||||||
processUnknownTypeMember(inputEntry.getValue(), arguments, (processed) -> overrides.put(inputKey, processed));
|
|
||||||
}
|
}
|
||||||
// 返回处理结果
|
|
||||||
return new TemplateProcessingResult(
|
|
||||||
templateList,
|
|
||||||
overrides,
|
|
||||||
arguments
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并参数
|
// 合并参数
|
||||||
@@ -214,7 +337,7 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
// argument_1: "{parent_argument}"
|
// argument_1: "{parent_argument}"
|
||||||
for (Map.Entry<String, Object> argumentEntry : rawChildArguments.entrySet()) {
|
for (Map.Entry<String, Object> argumentEntry : rawChildArguments.entrySet()) {
|
||||||
// 获取最终的string形式参数
|
// 获取最终的string形式参数
|
||||||
String placeholder = LEFT_BRACKET + argumentEntry.getKey() + RIGHT_BRACKET;
|
String placeholder = argumentEntry.getKey();
|
||||||
// 父亲参数最大
|
// 父亲参数最大
|
||||||
if (result.containsKey(placeholder)) continue;
|
if (result.containsKey(placeholder)) continue;
|
||||||
Object rawArgument = argumentEntry.getValue();
|
Object rawArgument = argumentEntry.getValue();
|
||||||
@@ -255,34 +378,136 @@ public class TemplateManagerImpl implements TemplateManager {
|
|||||||
|
|
||||||
// 将某个输入变成最终的结果,可以是string->string,也可以是string->map/list
|
// 将某个输入变成最终的结果,可以是string->string,也可以是string->map/list
|
||||||
private Object applyArgument(String input, Map<String, TemplateArgument> arguments) {
|
private Object applyArgument(String input, Map<String, TemplateArgument> arguments) {
|
||||||
StringBuilder result = new StringBuilder();
|
if (input.charAt(0) == '{' && input.charAt(input.length() - 1) == '}') {
|
||||||
Matcher matcher = ARGUMENT_PATTERN.matcher(input);
|
String key = input.substring(1, input.length() - 2);
|
||||||
boolean first = true;
|
if (arguments.containsKey(key)) {
|
||||||
while (matcher.find()) {
|
return arguments.get(key).get();
|
||||||
String placeholder = matcher.group();
|
|
||||||
Supplier<Object> replacer = arguments.get(placeholder);
|
|
||||||
if (replacer == null) {
|
|
||||||
matcher.appendReplacement(result, placeholder);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
if (input.length() == placeholder.length()) {
|
|
||||||
return replacer.get();
|
|
||||||
} else {
|
|
||||||
matcher.appendReplacement(result, replacer.get().toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
matcher.appendReplacement(result, replacer.get().toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matcher.appendTail(result);
|
return replacePlaceholders(input, arguments);
|
||||||
return result.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private record TemplateProcessingResult(
|
private record TemplateProcessingResult(
|
||||||
List<Object> templates,
|
List<Object> templates,
|
||||||
Map<String, Object> overrides,
|
Object overrides,
|
||||||
|
Object merges,
|
||||||
Map<String, TemplateArgument> arguments
|
Map<String, TemplateArgument> arguments
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void deepMergeMaps(Map<String, Object> baseMap, Map<String, Object> mapToMerge) {
|
||||||
|
for (Map.Entry<String, Object> entry : mapToMerge.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (baseMap.containsKey(key)) {
|
||||||
|
Object existingValue = baseMap.get(key);
|
||||||
|
if (existingValue instanceof Map && value instanceof Map) {
|
||||||
|
Map<String, Object> existingMap = (Map<String, Object>) existingValue;
|
||||||
|
Map<String, Object> newMap = (Map<String, Object>) value;
|
||||||
|
deepMergeMaps(existingMap, newMap);
|
||||||
|
} else if (existingValue instanceof List && value instanceof List) {
|
||||||
|
List<Object> existingList = (List<Object>) existingValue;
|
||||||
|
List<Object> newList = (List<Object>) value;
|
||||||
|
existingList.addAll(newList);
|
||||||
|
} else {
|
||||||
|
baseMap.put(key, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static String replacePlaceholders(String input, Map<String, TemplateArgument> replacements) {
|
||||||
|
if (input == null || input.isEmpty()) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder finalResult = new StringBuilder();
|
||||||
|
int n = input.length();
|
||||||
|
int lastAppendPosition = 0; // 追踪上一次追加操作结束的位置
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < n) {
|
||||||
|
// 检查当前字符是否为未转义的 '{'
|
||||||
|
int backslashes = 0;
|
||||||
|
int temp_i = i - 1;
|
||||||
|
while (temp_i >= 0 && input.charAt(temp_i) == '\\') {
|
||||||
|
backslashes++;
|
||||||
|
temp_i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.charAt(i) == '{' && backslashes % 2 == 0) {
|
||||||
|
// 发现占位符起点
|
||||||
|
int placeholderStartIndex = i;
|
||||||
|
|
||||||
|
// 追加从上一个位置到当前占位符之前的文本
|
||||||
|
finalResult.append(input, lastAppendPosition, placeholderStartIndex);
|
||||||
|
|
||||||
|
// --- 开始解析占位符内部 ---
|
||||||
|
StringBuilder keyBuilder = new StringBuilder();
|
||||||
|
int depth = 1;
|
||||||
|
int j = i + 1;
|
||||||
|
boolean foundMatch = false;
|
||||||
|
|
||||||
|
while (j < n) {
|
||||||
|
char c = input.charAt(j);
|
||||||
|
if (c == '\\') { // 处理转义
|
||||||
|
if (j + 1 < n) {
|
||||||
|
keyBuilder.append(input.charAt(j + 1));
|
||||||
|
j += 2;
|
||||||
|
} else {
|
||||||
|
keyBuilder.append(c);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
} else if (c == '{') {
|
||||||
|
depth++;
|
||||||
|
keyBuilder.append(c);
|
||||||
|
j++;
|
||||||
|
} else if (c == '}') {
|
||||||
|
depth--;
|
||||||
|
if (depth == 0) { // 找到匹配的结束括号
|
||||||
|
String key = keyBuilder.toString();
|
||||||
|
TemplateArgument value = replacements.get(key);
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
// 如果在 Map 中找到值,则进行替换
|
||||||
|
finalResult.append(value.get());
|
||||||
|
} else {
|
||||||
|
// 否则,保留原始占位符(包括 '{}')
|
||||||
|
finalResult.append(input, placeholderStartIndex, j + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新位置指针
|
||||||
|
i = j + 1;
|
||||||
|
lastAppendPosition = i;
|
||||||
|
foundMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
keyBuilder.append(c); // 嵌套的 '}'
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
keyBuilder.append(c);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- 占位符解析结束 ---
|
||||||
|
|
||||||
|
if (!foundMatch) {
|
||||||
|
// 如果内层循环结束仍未找到匹配的 '}',则不进行任何特殊处理
|
||||||
|
// 外层循环的 i 会自然递增
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 追加最后一个占位符之后的所有剩余文本
|
||||||
|
if (lastAppendPosition < n) {
|
||||||
|
finalResult.append(input, lastAppendPosition, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalResult.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Project settings
|
# Project settings
|
||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=0.0.56
|
project_version=0.0.56.1
|
||||||
config_version=34
|
config_version=34
|
||||||
lang_version=14
|
lang_version=14
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
|
|||||||
Reference in New Issue
Block a user