blob: 0e630eb6785b045c3aaed8970f9fc55bc8577e7a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
package moe.nea.firmament.util.mc
import net.minecraft.nbt.CollectionTag
import net.minecraft.nbt.ByteTag
import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag
import net.minecraft.nbt.Tag
import net.minecraft.nbt.EndTag
import net.minecraft.nbt.FloatTag
import net.minecraft.nbt.IntTag
import net.minecraft.nbt.IntArrayTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.LongTag
import net.minecraft.nbt.LongArrayTag
import net.minecraft.nbt.ShortTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.TagVisitor
class SNbtFormatter private constructor() : TagVisitor {
private val result = StringBuilder()
private var indent = 0
private fun writeIndent() {
result.append("\t".repeat(indent))
}
private fun pushIndent() {
indent++
}
private fun popIndent() {
indent--
}
fun apply(element: Tag): StringBuilder {
element.accept(this)
return result
}
override fun visitString(element: StringTag) {
result.append(StringTag.quoteAndEscape(element.value))
}
override fun visitByte(element: ByteTag) {
result.append(element.box()).append("b")
}
override fun visitShort(element: ShortTag) {
result.append(element.shortValue()).append("s")
}
override fun visitInt(element: IntTag) {
result.append(element.intValue())
}
override fun visitLong(element: LongTag) {
result.append(element.longValue()).append("L")
}
override fun visitFloat(element: FloatTag) {
result.append(element.floatValue()).append("f")
}
override fun visitDouble(element: DoubleTag) {
result.append(element.doubleValue()).append("d")
}
private fun visitArrayContents(array: CollectionTag) {
array.forEachIndexed { index, element ->
writeIndent()
element.accept(this)
if (array.size() != index + 1) {
result.append(",")
}
result.append("\n")
}
}
private fun writeArray(arrayTypeTag: String, array: CollectionTag) {
result.append("[").append(arrayTypeTag).append("\n")
pushIndent()
visitArrayContents(array)
popIndent()
writeIndent()
result.append("]")
}
override fun visitByteArray(element: ByteArrayTag) {
writeArray("B;", element)
}
override fun visitIntArray(element: IntArrayTag) {
writeArray("I;", element)
}
override fun visitLongArray(element: LongArrayTag) {
writeArray("L;", element)
}
override fun visitList(element: ListTag) {
writeArray("", element)
}
override fun visitCompound(compound: CompoundTag) {
result.append("{\n")
pushIndent()
val keys = compound.keySet().sorted()
keys.forEachIndexed { index, key ->
writeIndent()
val element = compound[key] ?: error("Key '$key' found but not present in compound: $compound")
val escapedName = escapeName(key)
result.append(escapedName).append(": ")
element.accept(this)
if (keys.size != index + 1) {
result.append(",")
}
result.append("\n")
}
popIndent()
writeIndent()
result.append("}")
}
override fun visitEnd(element: EndTag) {
result.append("END")
}
companion object {
fun prettify(nbt: Tag): String {
return SNbtFormatter().apply(nbt).toString()
}
fun Tag.toPrettyString() = prettify(this)
fun escapeName(key: String): String =
if (key.matches(SIMPLE_NAME)) key else StringTag.quoteAndEscape(key)
val SIMPLE_NAME = "[A-Za-z0-9._+-]+".toRegex()
}
}
|