aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/util/LegacyTagWriter.kt
blob: 9889b2cb721efc4cdf19fd9634578faabcaab4d0 (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
package moe.nea.firmament.util

import kotlinx.serialization.json.JsonPrimitive
import net.minecraft.nbt.AbstractNbtList
import net.minecraft.nbt.NbtByte
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtDouble
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtEnd
import net.minecraft.nbt.NbtFloat
import net.minecraft.nbt.NbtInt
import net.minecraft.nbt.NbtLong
import net.minecraft.nbt.NbtShort
import net.minecraft.nbt.NbtString
import moe.nea.firmament.util.mc.SNbtFormatter.Companion.SIMPLE_NAME

class LegacyTagWriter(val compact: Boolean) {
	companion object {
		fun stringify(nbt: NbtElement, compact: Boolean): String {
			return LegacyTagWriter(compact).also { it.writeElement(nbt) }
				.stringWriter.toString()
		}

		fun NbtElement.toLegacyString(pretty: Boolean = false): String {
			return stringify(this, !pretty)
		}
	}

	val stringWriter = StringBuilder()
	var indent = 0
	fun newLine() {
		if (compact) return
		stringWriter.append('\n')
		repeat(indent) {
			stringWriter.append("  ")
		}
	}

	fun writeElement(nbt: NbtElement) {
		when (nbt) {
			is NbtInt -> stringWriter.append(nbt.value.toString())
			is NbtString -> stringWriter.append(escapeString(nbt.value))
			is NbtFloat -> stringWriter.append(nbt.value).append('F')
			is NbtDouble -> stringWriter.append(nbt.value).append('D')
			is NbtByte -> stringWriter.append(nbt.value).append('B')
			is NbtLong -> stringWriter.append(nbt.value).append('L')
			is NbtShort -> stringWriter.append(nbt.value).append('S')
			is NbtCompound -> writeCompound(nbt)
			is NbtEnd -> {}
			is AbstractNbtList -> writeArray(nbt)
		}
	}

	fun writeArray(nbt: AbstractNbtList) {
		stringWriter.append('[')
		indent++
		newLine()
		nbt.forEachIndexed { index, element ->
			writeName(index.toString())
			writeElement(element)
			if (index != nbt.size() - 1) {
				stringWriter.append(',')
				newLine()
			}
		}
		indent--
		if (nbt.size() != 0)
			newLine()
		stringWriter.append(']')
	}

	fun writeCompound(nbt: NbtCompound) {
		stringWriter.append('{')
		indent++
		newLine()
		val entries = nbt.entrySet().sortedBy { it.key }
		entries.forEachIndexed { index, it ->
			writeName(it.key)
			writeElement(it.value)
			if (index != entries.lastIndex) {
				stringWriter.append(',')
				newLine()
			}
		}
		indent--
		if (nbt.size != 0)
			newLine()
		stringWriter.append('}')
	}

	fun escapeString(string: String): String {
		return JsonPrimitive(string).toString()
	}

	fun escapeName(key: String): String =
		if (key.matches(SIMPLE_NAME)) key else escapeString(key)

	fun writeName(key: String) {
		stringWriter.append(escapeName(key))
		stringWriter.append(':')
		if (!compact) stringWriter.append(' ')
	}
}