@@ -52,13 +52,15 @@ import trplugins.menu.module.display.dialog.model.DialogWidgetSpec
5252import trplugins.menu.module.display.icon.Icon
5353import trplugins.menu.module.display.icon.IconProperty
5454import trplugins.menu.module.display.icon.Position
55+ import trplugins.menu.module.display.item.DisplayEnchant
5556import trplugins.menu.module.display.item.Item
5657import trplugins.menu.module.display.item.Lore
5758import trplugins.menu.module.display.item.Meta
5859import trplugins.menu.module.display.layout.Layout
5960import trplugins.menu.module.display.layout.MenuLayout
6061import trplugins.menu.module.display.texture.Texture
6162import trplugins.menu.module.internal.script.js.ScriptFunction
63+ import trplugins.menu.util.Regexs
6264import trplugins.menu.util.bukkit.ItemMatcher
6365import trplugins.menu.util.collections.CycleList
6466import trplugins.menu.util.collections.IndivList
@@ -395,7 +397,12 @@ object MenuSerializer : ISerializer {
395397
396398 // Meta
397399 val amount = if (inherit.contains(Property .ICON_DISPLAY_AMOUNT )) def!! .display.meta.amount else Property .ICON_DISPLAY_AMOUNT .ofString(display, " 1" )
398- val shiny = if (inherit.contains(Property .ICON_DISPLAY_SHINY )) def!! .display.meta.shiny else Property .ICON_DISPLAY_SHINY .ofString(display, " false" )
400+ val shiny = if (inherit.contains(Property .ICON_DISPLAY_SHINY )) def!! .display.meta.shiny else parseDisplayShiny(display)
401+ val enchants = if (inherit.contains(Property .ICON_DISPLAY_ENCHANT )) {
402+ def!! .display.meta.enchants
403+ } else {
404+ parseDisplayEnchants(display)
405+ }
399406 val flags = if (inherit.contains(Property .ICON_DISPLAY_FLAGS )) {
400407 def!! .display.meta.flags
401408 } else Property .ICON_DISPLAY_FLAGS .ofStringList(display).mapNotNull { flag ->
@@ -458,7 +465,7 @@ object MenuSerializer : ISerializer {
458465 if (def != null && inherit.contains(Property .ICON_DISPLAY_LORE ) && lore.isEmpty()) def.display.lore
459466 else CycleList (lore.map { Lore (line(it)) }),
460467 // 图标附加属性
461- Meta (amount, shiny, flags, nbt, tooltipStyle, itemModel, hideTooltip, unbreakable, data)
468+ Meta (amount, shiny, flags, enchants, nbt, tooltipStyle, itemModel, hideTooltip, unbreakable, data)
462469 )
463470
464471 // i18n
@@ -686,6 +693,117 @@ object MenuSerializer : ISerializer {
686693 return major * 10000 + minor * 100 + patch
687694 }
688695
696+ private fun parseDisplayShiny (display : Configuration ? ): String {
697+ if (display == null ) {
698+ return " false"
699+ }
700+ display.getKeys(false ).firstOrNull { it.equals(" shiny" , true ) || it.equals(" glow" , true ) }?.let { key ->
701+ return display[key].toString()
702+ }
703+ display.getKeys(false ).firstOrNull { it.matches(Property .ICON_DISPLAY_ENCHANT .regex) }?.let { key ->
704+ val value = display[key]
705+ if (value is Boolean ) {
706+ return value.toString()
707+ }
708+ val content = value?.toString()?.trim().orEmpty()
709+ if (content.matches(Regexs .BOOLEAN )) {
710+ return content
711+ }
712+ }
713+ return " false"
714+ }
715+
716+ private fun parseDisplayEnchants (display : Configuration ? ): List <DisplayEnchant > {
717+ if (display == null ) {
718+ return emptyList()
719+ }
720+ val key = display.getKeys(false ).firstOrNull { it.matches(Property .ICON_DISPLAY_ENCHANT .regex) } ? : return emptyList()
721+ return parseDisplayEnchantValue(display[key])
722+ }
723+
724+ private fun parseDisplayEnchantValue (raw : Any? ): List <DisplayEnchant > {
725+ return when (raw) {
726+ null -> emptyList()
727+ is List <* > -> raw.flatMap { parseDisplayEnchantElement(it) }
728+ is ConfigurationSection -> parseDisplayEnchantMap(raw.getValues(false ))
729+ is Map <* , * > -> parseDisplayEnchantMap(raw)
730+ else -> listOfNotNull(parseDisplayEnchantString(raw.toString()))
731+ }
732+ }
733+
734+ private fun parseDisplayEnchantElement (raw : Any? ): List <DisplayEnchant > {
735+ return when (raw) {
736+ null -> emptyList()
737+ is List <* > -> raw.flatMap { parseDisplayEnchantElement(it) }
738+ is ConfigurationSection -> parseDisplayEnchantMap(raw.getValues(false ))
739+ is Map <* , * > -> parseDisplayEnchantMap(raw)
740+ else -> listOfNotNull(parseDisplayEnchantString(raw.toString()))
741+ }
742+ }
743+
744+ private fun parseDisplayEnchantMap (raw : Map <* , * >): List <DisplayEnchant > {
745+ if (raw.isEmpty()) {
746+ return emptyList()
747+ }
748+ if (isDisplayEnchantDescriptor(raw)) {
749+ return listOfNotNull(parseDisplayEnchantDescriptor(raw))
750+ }
751+ return raw.entries.mapNotNull { (key, value) ->
752+ val enchantKey = key?.toString()?.trim().orEmpty()
753+ val enchantLevel = value?.toString()?.trim().orEmpty()
754+ if (enchantKey.isEmpty() || enchantLevel.isEmpty()) {
755+ null
756+ } else {
757+ DisplayEnchant (enchantKey, enchantLevel)
758+ }
759+ }
760+ }
761+
762+ private fun isDisplayEnchantDescriptor (raw : Map <* , * >): Boolean {
763+ return raw.keys.any { key ->
764+ val content = key?.toString().orEmpty()
765+ content.equals(" id" , true ) ||
766+ content.equals(" key" , true ) ||
767+ content.equals(" type" , true ) ||
768+ content.equals(" enchant" , true ) ||
769+ content.equals(" enchantment" , true )
770+ }
771+ }
772+
773+ private fun parseDisplayEnchantDescriptor (raw : Map <* , * >): DisplayEnchant ? {
774+ val enchantKey = readDisplayEnchantField(raw, " id" , " key" , " type" , " enchant" , " enchantment" ) ? : return null
775+ val enchantLevel = readDisplayEnchantField(raw, " level" , " lvl" , " value" , " amount" ) ? : " 1"
776+ return DisplayEnchant (enchantKey, enchantLevel)
777+ }
778+
779+ private fun readDisplayEnchantField (raw : Map <* , * >, vararg names : String ): String? {
780+ return raw.entries.firstOrNull { entry -> names.any { entry.key?.toString().equals(it, true ) } }
781+ ?.value
782+ ?.toString()
783+ ?.trim()
784+ ?.takeIf { it.isNotEmpty() }
785+ }
786+
787+ private fun parseDisplayEnchantString (raw : String ): DisplayEnchant ? {
788+ val content = raw.trim()
789+ if (content.isEmpty()) {
790+ return null
791+ }
792+ val split = content.split(Regex (" [,\\ s]+" ), limit = 2 ).map { it.trim() }.filter { it.isNotEmpty() }
793+ if (split.size == 2 ) {
794+ return DisplayEnchant (split[0 ], split[1 ])
795+ }
796+ val lastColon = content.lastIndexOf(' :' )
797+ if (lastColon in 1 until content.lastIndex) {
798+ val enchantKey = content.substring(0 , lastColon).trim()
799+ val enchantLevel = content.substring(lastColon + 1 ).trim()
800+ if (enchantKey.isNotEmpty() && enchantLevel.toIntOrNull() != null ) {
801+ return DisplayEnchant (enchantKey, enchantLevel)
802+ }
803+ }
804+ return DisplayEnchant (content, " 1" )
805+ }
806+
689807 val line: (List <String >) -> List <String > =
690808 { origin -> mutableListOf<String >().also { list -> origin.forEach { list.addAll(it.split(" \n " )) } } }
691809
0 commit comments