@@ -2,59 +2,131 @@ package tech.aliorpse.mcutils.model.server
22
33import kotlinx.serialization.KSerializer
44import kotlinx.serialization.builtins.ListSerializer
5- import kotlinx.serialization.builtins.SetSerializer
65import kotlinx.serialization.descriptors.SerialDescriptor
76import kotlinx.serialization.descriptors.buildClassSerialDescriptor
8- import kotlinx.serialization.descriptors.element
97import kotlinx.serialization.encoding.Decoder
108import kotlinx.serialization.encoding.Encoder
9+ import kotlinx.serialization.json.JsonArray
1110import kotlinx.serialization.json.JsonDecoder
1211import kotlinx.serialization.json.JsonEncoder
12+ import kotlinx.serialization.json.JsonObject
13+ import kotlinx.serialization.json.JsonPrimitive
14+ import kotlinx.serialization.json.booleanOrNull
1315import kotlinx.serialization.json.buildJsonObject
14- import kotlinx.serialization.json.jsonObject
15- import kotlinx.serialization.json.jsonPrimitive
1616import kotlinx.serialization.json.put
17- import kotlin.collections.emptyList
18- import kotlin.let
17+ import tech.aliorpse.mcutils.utils.toTextComponent
18+ import java.util.EnumSet
1919
2020internal object TextComponentSerializer : KSerializer<TextComponent> {
21- private val extraSerializer by lazy { ListSerializer (TextComponentSerializer ) }
22-
23- override val descriptor: SerialDescriptor =
24- buildClassSerialDescriptor(" TextComponent" ) {
25- element<String >(" text" )
26- element<String >(" color" )
27- element<Set <TextStyle >>(" styles" )
28- element<List <TextComponent >>(" extra" , isOptional = true )
29- }
21+ override val descriptor: SerialDescriptor = buildClassSerialDescriptor(" TextComponent" )
3022
3123 override fun serialize (encoder : Encoder , value : TextComponent ) {
3224 require(encoder is JsonEncoder )
25+
3326 val obj = buildJsonObject {
3427 put(" text" , value.text)
35- put(" color" , value.color)
36- put(" styles" , encoder.json.encodeToJsonElement(SetSerializer (TextStyle .serializer()), value.styles))
28+ if (value.color.isNotEmpty()) put(" color" , value.color)
29+
30+ styleMap.forEach { (name, style) ->
31+ if (value.styles.contains(style)) put(name, true )
32+ }
33+
3734 if (value.extra.isNotEmpty()) {
38- put(" extra" , encoder.json.encodeToJsonElement(extraSerializer, value.extra))
35+ put(
36+ " extra" ,
37+ encoder.json.encodeToJsonElement(ListSerializer (TextComponentSerializer ), value.extra)
38+ )
3939 }
4040 }
41+
4142 encoder.encodeJsonElement(obj)
4243 }
4344
4445 override fun deserialize (decoder : Decoder ): TextComponent {
4546 require(decoder is JsonDecoder )
46- val json = decoder.decodeJsonElement().jsonObject
47-
48- val text = json[" text" ]?.jsonPrimitive?.content ? : " "
49- val color = json[" color" ]?.jsonPrimitive?.content ? : " "
50- val styles = json[" styles" ]?.let {
51- decoder.json.decodeFromJsonElement(SetSerializer (TextStyle .serializer()), it)
52- } ? : emptySet()
53- val extra = json[" extra" ]?.let {
54- // 在这里使用 lazy 初始化的 extraSerializer
55- decoder.json.decodeFromJsonElement(extraSerializer, it)
56- } ? : emptyList()
57-
58- return TextComponent (text, color, styles, extra)
47+ return when (val element = decoder.decodeJsonElement()) {
48+ is JsonPrimitive -> { element.content.toTextComponent() }
49+
50+ is JsonObject -> {
51+ var text = " "
52+ var color = " "
53+ val styles: EnumSet <TextStyle > = EnumSet .noneOf(TextStyle ::class .java)
54+ var extra: List <TextComponent > = emptyList()
55+
56+ element.forEach { (name, value) ->
57+ when (name) {
58+ " text" -> {
59+ val rawText = when (value) {
60+ is JsonPrimitive -> value.content
61+ is JsonObject -> decoder.json.decodeFromJsonElement(TextComponentSerializer , value).text
62+ else -> value.toString()
63+ }
64+
65+ val parsed = rawText.toTextComponent()
66+ if (" §" !in rawText) {
67+ text = rawText
68+ } else {
69+ text = parsed.text
70+ color = parsed.color
71+ styles + = parsed.styles
72+ if (parsed.extra.isNotEmpty()) extra = parsed.extra
73+ }
74+ }
75+
76+ " color" -> {
77+ val colorName = if (value is JsonPrimitive ) value.content else value.toString()
78+ color = colors[colorName] ? : colorName
79+ }
80+
81+ " extra" -> {
82+ if (value is JsonArray ) {
83+ extra = decoder.json.decodeFromJsonElement(
84+ ListSerializer (TextComponentSerializer ), value
85+ )
86+ }
87+ }
88+
89+ in styleMap.keys -> {
90+ if (value is JsonPrimitive && value.booleanOrNull == true ) {
91+ styles + = styleMap.getValue(name)
92+ }
93+ }
94+
95+ else -> {}
96+ }
97+ }
98+ TextComponent (text, color, styles, extra)
99+ }
100+ else -> {
101+ TextComponent (" " , " #FFFFFF" )
102+ }
103+ }
59104 }
105+
106+ private val styleMap = mapOf (
107+ " bold" to TextStyle .BOLD ,
108+ " italic" to TextStyle .ITALIC ,
109+ " underlined" to TextStyle .UNDERLINED ,
110+ " strikethrough" to TextStyle .STRIKETHROUGH ,
111+ " obfuscated" to TextStyle .OBFUSCATED ,
112+ )
113+
114+ private val colors = mapOf (
115+ " black" to " #000000" ,
116+ " dark_blue" to " #0000AA" ,
117+ " dark_green" to " #00AA00" ,
118+ " dark_aqua" to " #00AAAA" ,
119+ " dark_red" to " #AA0000" ,
120+ " dark_purple" to " #AA00AA" ,
121+ " gold" to " #FFAA00" ,
122+ " gray" to " #AAAAAA" ,
123+ " dark_gray" to " #555555" ,
124+ " blue" to " #5555FF" ,
125+ " green" to " #55FF55" ,
126+ " aqua" to " #55FFFF" ,
127+ " red" to " #FF5555" ,
128+ " light_purple" to " #FF55FF" ,
129+ " yellow" to " #FFFF55" ,
130+ " white" to " #FFFFFF"
131+ )
60132}
0 commit comments