From be220bdcbd4e2512e23ea7a64cfb2f89fca0ed56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MC=7E=E8=9B=9F=E9=BE=99?= <1610105206@qq.com> Date: Tue, 25 Jun 2024 20:37:53 +0800 Subject: [PATCH] Experimental | Update ItemResolver --- .../fd/ratziel/core/serialization/JsonUtil.kt | 7 +- .../cn/fd/ratziel/module/item/ItemRegistry.kt | 5 +- .../item/api/builder/ItemSectionResolver.kt | 40 ------- .../item/impl/builder/BasicItemResolver.kt | 112 ------------------ .../builder/resolver/BasicItemResolver.kt | 96 +++++++++++++++ .../item/impl/builder/resolver/CleanUpUtil.kt | 36 ++++++ .../builder/resolver/SectionStringResolver.kt | 11 ++ .../builder/resolver/SectionTagResolver.kt | 23 ++++ .../resolver/sectionResolvers/PapiResolver.kt | 24 ++++ .../sectionResolvers}/RandomResolver.kt | 6 +- 10 files changed, 196 insertions(+), 164 deletions(-) delete mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemSectionResolver.kt delete mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/BasicItemResolver.kt create mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt create mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/CleanUpUtil.kt create mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionStringResolver.kt create mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionTagResolver.kt create mode 100644 project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt rename project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/{tagResolvers => resolver/sectionResolvers}/RandomResolver.kt (68%) diff --git a/project/module-core/src/main/kotlin/cn/fd/ratziel/core/serialization/JsonUtil.kt b/project/module-core/src/main/kotlin/cn/fd/ratziel/core/serialization/JsonUtil.kt index c199b0fe..a5f28fb5 100644 --- a/project/module-core/src/main/kotlin/cn/fd/ratziel/core/serialization/JsonUtil.kt +++ b/project/module-core/src/main/kotlin/cn/fd/ratziel/core/serialization/JsonUtil.kt @@ -38,12 +38,7 @@ operator fun JsonObject.get(names: Iterable): JsonElement? { /** * 可变化 */ -fun Map.asMutable(): MutableJsonObject = - when (this) { - is MutableJsonObject -> this - is MutableMap<*, *> -> MutableJsonObject(this as MutableMap) - else -> MutableJsonObject(this.toMutableMap()) - } +fun Map.asMutable(): MutableJsonObject = if (this is MutableJsonObject) this else MutableJsonObject(this.toMutableMap()) /** * 处理 [JsonObject] diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/ItemRegistry.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/ItemRegistry.kt index 962f76a6..d2a7d24f 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/ItemRegistry.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/ItemRegistry.kt @@ -9,8 +9,8 @@ import cn.fd.ratziel.module.item.api.builder.ItemSerializer import cn.fd.ratziel.module.item.api.registry.ComponentRegistry import cn.fd.ratziel.module.item.api.registry.ResolverRegistry import cn.fd.ratziel.module.item.api.registry.SerializerRegistry -import cn.fd.ratziel.module.item.impl.builder.BasicItemResolver import cn.fd.ratziel.module.item.impl.builder.DefaultItemSerializer +import cn.fd.ratziel.module.item.impl.builder.resolver.BasicItemResolver import cn.fd.ratziel.module.item.impl.component.ItemDisplay import cn.fd.ratziel.module.item.impl.component.ItemDurability import cn.fd.ratziel.module.item.impl.component.ItemMetadata @@ -38,8 +38,7 @@ object ItemRegistry { Component.register(ItemSundry::class.java, ItemSundry) Component.register(ItemMetadata::class.java, ItemMetadata) // 注册默认物品解析器 - Resolver.register(BasicItemResolver, 0) - Resolver.register(BasicItemResolver.CleanUp, Byte.MAX_VALUE)// 最后清除 + Resolver.register(BasicItemResolver) } object Component : ComponentRegistry { diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemSectionResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemSectionResolver.kt deleted file mode 100644 index 849912ed..00000000 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/api/builder/ItemSectionResolver.kt +++ /dev/null @@ -1,40 +0,0 @@ -package cn.fd.ratziel.module.item.api.builder - -import cn.fd.ratziel.core.serialization.MutableJsonObject -import cn.fd.ratziel.core.serialization.asMutable -import cn.fd.ratziel.function.argument.ArgumentFactory -import cn.fd.ratziel.module.item.api.ArgumentResolver -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject - -/** - * ItemSectionResolver - * - * @author TheFloodDragon - * @since 2024/5/24 20:53 - */ -interface ItemSectionResolver : ItemResolver { - - fun resolveWith(builder: MutableJsonObject, arguments: ArgumentFactory): JsonElement - - fun resolveWith(element: JsonElement, arguments: ArgumentFactory): JsonElement - - override fun resolve(element: JsonElement, arguments: ArgumentFactory): JsonElement = - if (element is JsonObject) resolveWith(element.asMutable(), arguments) - else resolveWith(element, arguments) - - interface TagResolver : ArgumentResolver, String?> { - - /** - * 解析器名称 - */ - val name: String - - /** - * 解析器别名 - */ - val alias: Array - - } - -} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/BasicItemResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/BasicItemResolver.kt deleted file mode 100644 index 8e852176..00000000 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/BasicItemResolver.kt +++ /dev/null @@ -1,112 +0,0 @@ -package cn.fd.ratziel.module.item.impl.builder - -import cn.fd.ratziel.core.serialization.MutableJsonObject -import cn.fd.ratziel.core.serialization.handlePrimitives -import cn.fd.ratziel.core.util.splitNonEscaped -import cn.fd.ratziel.function.argument.ArgumentFactory -import cn.fd.ratziel.function.argument.popOrNull -import cn.fd.ratziel.module.item.api.builder.ItemResolver -import cn.fd.ratziel.module.item.api.builder.ItemSectionResolver -import cn.fd.ratziel.module.item.impl.builder.tagResolvers.RandomResolver -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import org.bukkit.OfflinePlayer -import taboolib.common.util.VariableReader -import taboolib.platform.compat.replacePlaceholder -import java.util.function.Function - -/** - * BasicItemResolver - 基础解析器 - * - * 解析 [ItemSectionResolver.TagResolver] 和玩家变量 - * - * @author TheFloodDragon - * @since 2024/5/24 21:32 - */ -object BasicItemResolver : ItemSectionResolver { - - object CleanUp : ItemResolver { - - /** - * 允许通过(有用的)的节点 - */ - @JvmStatic - val accessedNodes: MutableSet = DefaultItemSerializer.occupiedNodes.toMutableSet() - - /** - * 过滤掉无用的节点 (节点不在[accessedNodes]内的) - */ - @JvmStatic - @JvmOverloads - fun cleanUp(element: JsonElement, action: Function = Function { it }): JsonElement { - if (element is JsonObject) { - val newJson = MutableJsonObject() - for (entry in element) { - if (entry.key in accessedNodes) newJson[entry.key] = action.apply(entry.value) - } - return newJson.asImmutable() - } else return element - } - - override fun resolve(element: JsonElement, arguments: ArgumentFactory) = cleanUp(element) - - } - - /** - * 标签解析器 - */ - val tagResolvers: MutableList = mutableListOf( - RandomResolver - ) - - override fun resolveWith(builder: MutableJsonObject, arguments: ArgumentFactory): JsonElement { - for (entry in builder) { - if (entry.key in CleanUp.accessedNodes) { - builder[entry.key] = resolveWith(entry.value, arguments) - } - } - return builder.asImmutable() - } - - override fun resolveWith(element: JsonElement, arguments: ArgumentFactory) = element.handlePrimitives { json -> - var handle = json.content - // 获取玩家 - val player = arguments.popOrNull()?.value - // 处理Papi变量 - if (player != null) handle = handle.replacePlaceholder(player) - // 处理标签 - val result = reader.readToFlatten(handle).map { - // 如果是标签, 则通过标签解析器解析 - if (it.isVariable) { - handle(it.text, arguments) - } else it.text // 不然就是它本身 - } - JsonPrimitive(result.joinToString("")) // 拼接结果成字符串并返回 - } - - /** - * 寻找 [ItemSectionResolver.TagResolver] 并处理 - */ - fun handle(source: String, arguments: ArgumentFactory): String { - // 分割 - val split = source.splitNonEscaped(ARGUMENT_SEPRATION_SIGN) - // 获取名称 - val name = split.firstOrNull() ?: return source - // 获取解析器 - val resolver = tagResolvers.find { it.name == name || it.alias.contains(name) } - // 解析并返回 - return resolver?.resolve(split.drop(1), arguments) ?: source - } - - /** - * 参数分割符 - */ - const val ARGUMENT_SEPRATION_SIGN = ":" - - /** - * 变量读取器 - */ - val reader = VariableReader("{", "}") - -} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt new file mode 100644 index 00000000..443218da --- /dev/null +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/BasicItemResolver.kt @@ -0,0 +1,96 @@ +package cn.fd.ratziel.module.item.impl.builder.resolver + +import cn.fd.ratziel.core.Priority +import cn.fd.ratziel.core.serialization.handlePrimitives +import cn.fd.ratziel.core.util.priority +import cn.fd.ratziel.core.util.sortPriority +import cn.fd.ratziel.core.util.splitNonEscaped +import cn.fd.ratziel.function.argument.ArgumentFactory +import cn.fd.ratziel.module.item.api.builder.ItemResolver +import cn.fd.ratziel.module.item.impl.builder.DefaultItemSerializer +import cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers.PapiResolver +import cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers.RandomResolver +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import taboolib.common.util.VariableReader + +/** + * BasicItemResolver - 基础解析器 + * + * 解析 [SectionTagResolver] 和玩家变量 + * + * @author TheFloodDragon + * @since 2024/5/24 21:32 + */ +object BasicItemResolver : ItemResolver { + + val accessibleNodes: MutableSet = DefaultItemSerializer.occupiedNodes.toMutableSet() + + /** + * 字符串解析器 + */ + val resolvers: MutableList> = mutableListOf( + PapiResolver priority -1, + BasicTagResolver priority 99, + ) + + override fun resolve(element: JsonElement, arguments: ArgumentFactory): JsonElement = + // 过滤节点 + CleanUpUtil.handleOnFilter(element, accessibleNodes) { filtered -> + // 处理 JsonPrimitive + filtered.value.handlePrimitives { resolvePrimitive(it, arguments) } + } + + fun resolvePrimitive(element: JsonPrimitive, arguments: ArgumentFactory): JsonElement { + var handle = element.content + // 遍历字符串解析器处理 + for (resolver in resolvers.sortPriority()) { + handle = resolver.resolve(handle, arguments) + } + return JsonPrimitive(handle) + } + + object BasicTagResolver : SectionStringResolver { + + /** + * 标签解析器 + */ + val resolvers: MutableList = mutableListOf( + RandomResolver + ) + + /** + * 参数分割符 + */ + const val ARGUMENT_SEPRATION_SIGN = ":" + + /** + * 变量读取器 + */ + val reader = VariableReader("{", "}") + + override fun resolve(element: String, arguments: ArgumentFactory): String = + reader.readToFlatten(element).joinToString("") { + // 如果是标签, 则通过标签解析器解析 + if (it.isVariable) { + handle(it.text, arguments) + } else it.text // 不然就是它本身 + } // 拼接结果成字符串并返回 + + /** + * 寻找 [SectionTagResolver] 并处理 + */ + fun handle(source: String, arguments: ArgumentFactory): String { + // 分割 + val split = source.splitNonEscaped(ARGUMENT_SEPRATION_SIGN) + // 获取名称 + val name = split.firstOrNull() ?: return source + // 获取解析器 + val resolver = resolvers.find { it.name == name || it.alias.contains(name) } + // 解析并返回 + return resolver?.resolve(split.drop(1), arguments) ?: source + } + + } + +} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/CleanUpUtil.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/CleanUpUtil.kt new file mode 100644 index 00000000..ca2315d4 --- /dev/null +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/CleanUpUtil.kt @@ -0,0 +1,36 @@ +package cn.fd.ratziel.module.item.impl.builder.resolver + +import cn.fd.ratziel.core.serialization.asMutable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import java.util.function.Function + +/** + * CleanUpUtil + * + * @author TheFloodDragon + * @since 2024/6/25 20:03 + */ +object CleanUpUtil { + + @JvmStatic + fun handleOnFilter( + element: JsonObject, + accessibleNodes: Iterable, + action: Function, JsonElement> + ): JsonObject { + val builder = element.asMutable() + for (entry in builder) { + // 在允许的节点范围内 + if (entry.key in accessibleNodes) { + builder[entry.key] = action.apply(entry) // 通过操作替换节点 + } + } + return builder.asImmutable() + } + + @JvmStatic + fun handleOnFilter(element: JsonElement, accessibleNodes: Iterable, action: Function, JsonElement>): JsonElement = + if (element is JsonObject) handleOnFilter(element, accessibleNodes, action) else element + +} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionStringResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionStringResolver.kt new file mode 100644 index 00000000..4a042a9c --- /dev/null +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionStringResolver.kt @@ -0,0 +1,11 @@ +package cn.fd.ratziel.module.item.impl.builder.resolver + +import cn.fd.ratziel.module.item.api.ArgumentResolver + +/** + * SectionStringResolver + * + * @author TheFloodDragon + * @since 2024/6/25 20:16 + */ +interface SectionStringResolver : ArgumentResolver \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionTagResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionTagResolver.kt new file mode 100644 index 00000000..1597f6c0 --- /dev/null +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/SectionTagResolver.kt @@ -0,0 +1,23 @@ +package cn.fd.ratziel.module.item.impl.builder.resolver + +import cn.fd.ratziel.module.item.api.ArgumentResolver + +/** + * SectionTagResolver + * + * @author TheFloodDragon + * @since 2024/6/25 20:04 + */ +interface SectionTagResolver : ArgumentResolver, String?> { + + /** + * 解析器名称 + */ + val name: String + + /** + * 解析器别名 + */ + val alias: Array + +} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt new file mode 100644 index 00000000..cacfeb72 --- /dev/null +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/PapiResolver.kt @@ -0,0 +1,24 @@ +package cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers + +import cn.fd.ratziel.function.argument.ArgumentFactory +import cn.fd.ratziel.function.argument.popOrNull +import cn.fd.ratziel.module.item.impl.builder.resolver.SectionStringResolver +import org.bukkit.OfflinePlayer +import taboolib.platform.compat.replacePlaceholder + +/** + * PapiResolver + * + * @author TheFloodDragon + * @since 2024/6/25 20:18 + */ +object PapiResolver : SectionStringResolver { + + override fun resolve(element: String, arguments: ArgumentFactory): String { + // 获取玩家 + val player = arguments.popOrNull()?.value ?: return element // 没玩家处理啥? + // 处理Papi变量 + return element.replacePlaceholder(player) + } + +} \ No newline at end of file diff --git a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/tagResolvers/RandomResolver.kt b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt similarity index 68% rename from project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/tagResolvers/RandomResolver.kt rename to project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt index 619b0684..95c60318 100644 --- a/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/tagResolvers/RandomResolver.kt +++ b/project/module-item/src/main/kotlin/cn/fd/ratziel/module/item/impl/builder/resolver/sectionResolvers/RandomResolver.kt @@ -1,7 +1,7 @@ -package cn.fd.ratziel.module.item.impl.builder.tagResolvers +package cn.fd.ratziel.module.item.impl.builder.resolver.sectionResolvers import cn.fd.ratziel.function.argument.ArgumentFactory -import cn.fd.ratziel.module.item.api.builder.ItemSectionResolver +import cn.fd.ratziel.module.item.impl.builder.resolver.SectionTagResolver import taboolib.common.util.random /** @@ -10,7 +10,7 @@ import taboolib.common.util.random * @author TheFloodDragon * @since 2024/5/18 16:22 */ -object RandomResolver : ItemSectionResolver.TagResolver { +object RandomResolver : SectionTagResolver { override val name = "random"