Skip to content

Commit

Permalink
Experimental | Update ItemResolver&Improve Argument
Browse files Browse the repository at this point in the history
  • Loading branch information
TheFloodDragon committed May 18, 2024
1 parent 6e20255 commit fe878bc
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const val DEFAULT_ALGORITHM = "SHA-256"

fun randomUUID() = UUID.randomUUID().toString().replace("-", "").lowercase()


const val ESCAPE_CHAR = "\\"

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ interface ArgumentFactory : ArgumentSupplier {
* @throws ArgumentNotFoundException 当无法找到指定类型的参数时抛出
*/
@Throws(ArgumentNotFoundException::class)
fun <T : Any> pop(type: Class<T>): Argument<T>
fun <T : Any> pop(type: Class<T>): Argument<T> = popOrNull(type) ?: throw ArgumentNotFoundException(type)

fun <T : Any> popOrNull(type: Class<T>): Argument<T>?

/**
* 弹出所有指定类型的参数
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,7 @@ import cn.fd.ratziel.function.argument.exception.ArgumentException
import cn.fd.ratziel.function.util.uncheck
import java.util.function.Function

fun <T : Any> ArgumentFactory.popOrNull(type: Class<T>): Argument<T>? =
try {
pop(type)
} catch (ex: ArgumentException) {
null
}

fun <T : Any> ArgumentFactory.popOr(type: Class<T>, default: T): Argument<T> =
try {
pop(type)
} catch (ex: ArgumentException) {
SingleArgument(default)
}
fun <T : Any> ArgumentFactory.popOr(type: Class<T>, default: T): Argument<T> = popOrNull(type) ?: SingleArgument(default)

fun <T : Any> ArgumentSupplier.supplyOrNull(type: Class<T>): Argument<T>? =
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cn.fd.ratziel.function.argument

import cn.fd.ratziel.function.argument.exception.ArgumentNotFoundException
import cn.fd.ratziel.function.util.uncheck
import java.util.concurrent.CopyOnWriteArrayList

Expand All @@ -18,10 +17,8 @@ open class DefaultArgumentFactory(protected open val list: CopyOnWriteArrayList<

constructor() : this(CopyOnWriteArrayList())

override fun <T : Any> pop(type: Class<T>): Argument<T> =
list.find { type.isAssignableFrom(it.type) }
?.let { handledCast(it, type) }
?: throw ArgumentNotFoundException(type)
override fun <T : Any> popOrNull(type: Class<T>): Argument<T>? =
list.find { type.isAssignableFrom(it.type) }?.let { handledCast(it, type) }

override fun <T : Any> popAll(type: Class<T>): List<Argument<T>> =
list.mapNotNull { arg ->
Expand Down
1 change: 1 addition & 0 deletions project/module-item/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies {
compileTaboo("module-nms-util-stable")
compileTaboo("module-bukkit-xseries")
compileTaboo("module-bukkit-util")
compileTaboo("module-bukkit-hook")
compileModule("runtime-bukkit")
compileOnly(fileTree("libs"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cn.fd.ratziel.module.item.api.common

import cn.fd.ratziel.function.argument.ArgumentFactory
import cn.fd.ratziel.function.argument.DefaultArgumentFactory
import cn.fd.ratziel.module.item.api.Resolver

/**
* StringResolver
*
* @author TheFloodDragon
* @since 2024/5/18 15:15
*/
interface StringResolver : Resolver<Array<String>, String?> {

/**
* 解析器名称
*/
val name: String

/**
* 解析器别名
*/
val alias: Array<String>

/**
* 解析元素 (带参数)
*/
fun resolve(element: Array<String>, arguments: ArgumentFactory): String?

/**
* 解析元素 (带空参数)
*/
override fun resolve(element: Array<String>): String? = resolve(element, DefaultArgumentFactory())

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class DefaultItemGenerator(override val origin: Element) : ItemGenerator {

override val serializers: MutableSet<Priority<ItemSerializer<*>>> = CopyOnWriteArraySet(listOf(DefaultItemSerializer(json).priority()))

override val resolvers: MutableSet<Priority<ItemResolver>> = CopyOnWriteArraySet(listOf(DefaultItemResolver().priority()))
override val resolvers: MutableSet<Priority<ItemResolver>> = CopyOnWriteArraySet(listOf(DefaultItemResolver.priority()))

/**
* 解析
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,115 @@
package cn.fd.ratziel.module.item.impl.builder

import cn.fd.ratziel.core.serialization.asMutable
import cn.fd.ratziel.core.serialization.handle
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.common.StringResolver
import cn.fd.ratziel.module.item.impl.builder.resolver.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

/**
* DefaultItemResolver
*
* @author TheFloodDragon
* @since 2024/4/20 10:03
*/
class DefaultItemResolver : ItemResolver {
object DefaultItemResolver : ItemResolver {

override fun resolve(element: JsonElement, arguments: ArgumentFactory) = access(element) { origin ->
// 过滤拿到处理对象并处理
val handle = origin.filter { DefaultItemSerializer.occupiedNodes.contains(it.key) }.asMutable()
// 写回修改过的部分
putAll(handle)
/**
* 参数分割符
*/
const val ARGUMENT_SEPRATION_SIGN = ":"

/**
* 变量读取器
*/
val reader = VariableReader("{", "}")

/**
* 字符串解析器 (解析器名称-解析器)
*/
val resolvers = mutableListOf<StringResolver>(
RandomResolver
)

/**
* 解析:
* 过滤 -> 字符串处理
*/
override fun resolve(element: JsonElement, arguments: ArgumentFactory): JsonElement {
// 过滤该处理的
val filtered = filter(element)
// 处理所有字符串
val resolved = handleStrings(filtered, arguments)
// 返回结果
return resolved
}

fun access(target: JsonElement, action: MutableMap<String, JsonElement>.(JsonObject) -> Unit) =
if (target is JsonObject) target.handle(action) else target
/**
* 处理所有字符串
*/
fun handleStrings(json: JsonElement, arguments: ArgumentFactory) = json.handlePrimitives { p ->
p.takeIf { it.isString }?.content?.let { source ->
var handle = source
// 获取玩家
val player = arguments.popOrNull<OfflinePlayer>()?.value
// 处理PAPI变量
if (player != null) handle = handle.replacePlaceholder(player)
// 处理变量
val result = reader.readToFlatten(handle).map {
// 如果是变量, 则通过字符串解析器解析
if (it.isVariable) {
distribute(it.text, arguments)
} else it // 不然就是他本身
}
JsonPrimitive(result.joinToString("")) // 拼接结果成字符串并返回
} ?: p
}

/**
* 分配 [StringResolver]
*/
fun distribute(source: String, arguments: ArgumentFactory): String {
// 分割
val split = source.splitNonEscaped(ARGUMENT_SEPRATION_SIGN)
val name = split.firstOrNull()
// 获取解析器
val resolver = resolvers.find { it.name == name || it.alias.contains(name) }
// 解析并返回
return resolver?.resolve(split.drop(1).toTypedArray(), arguments) ?: source
}

/**
* 判断此节点是否应该被解析
*/
fun isResolvable(node: String) = DefaultItemSerializer.occupiedNodes.contains(node)

/**
* 初步过滤掉无用内容
*/
fun filter(element: JsonElement) = access(element) { origin ->
for (entry in origin) {
// 过滤, 放入应该被处理的
if (isResolvable(entry.key)) {
put(entry.key, entry.value)
}
}
}

fun access(target: JsonElement, action: MutableJsonObject.(JsonObject) -> Unit): JsonElement {
if (target is JsonObject) {
val map = LinkedHashMap<String, JsonElement>()
action(map, target)
return JsonObject(map)
} else return target
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cn.fd.ratziel.module.item.impl.builder.resolver

import cn.fd.ratziel.function.argument.ArgumentFactory
import cn.fd.ratziel.module.item.api.common.StringResolver
import taboolib.common.util.random

/**
* RandomResolver
*
* @author TheFloodDragon
* @since 2024/5/18 16:22
*/
object RandomResolver : StringResolver {

override val name = "random"

override val alias = arrayOf("ran", "rd")

override fun resolve(element: Array<String>, arguments: ArgumentFactory): String? {
if (element.isEmpty()) return null
// TODO 写完这个
return random().nextInt().toString()
}

}

0 comments on commit fe878bc

Please sign in to comment.