Skip to content

Commit 466f3f3

Browse files
committed
Cleanup
1 parent 437f9e9 commit 466f3f3

File tree

3 files changed

+76
-80
lines changed

3 files changed

+76
-80
lines changed

common/src/main/kotlin/com/lambda/interaction/construction/StructureRegistry.kt

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import kotlin.io.path.*
2929
*/
3030
@OptIn(ExperimentalPathApi::class)
3131
@Suppress("JavaIoSerializableObjectMustHaveReadResolve")
32-
object StructureRegistry
33-
: ConcurrentHashMap<String, StructureTemplate?>(), Loadable {
32+
object StructureRegistry : ConcurrentHashMap<String, StructureTemplate?>(), Loadable {
3433
private val levelSession = mc.levelStorage.createSession(FolderRegister.structure.path)
3534
private val structurePath = levelSession.getDirectory(WorldSavePath.ROOT).normalize()
3635
private val pathWatcher = FileSystems.getDefault().newWatchService()
@@ -39,12 +38,12 @@ object StructureRegistry
3938
/**
4039
* Map of file suffix to their respective read function
4140
*/
42-
val serializers = mapOf(
41+
private val serializers = mapOf(
4342
"nbt" to StructureTemplate::readNbtOrException,
4443
"schem" to StructureTemplate::readSpongeOrException,
4544
"litematica" to StructureTemplate::readLitematicaOrException,
4645

47-
// Not supported, who could guess that converting a format from 14 years ago would be hard ? :clueless:
46+
// Not supported, who could guess that converting a format from 14 years ago would be hard? :clueless:
4847
"schematic" to StructureTemplate::readSchematicOrException,
4948
)
5049

@@ -54,7 +53,7 @@ object StructureRegistry
5453
* @param name The name of the structure file without the extension.
5554
* @return The corresponding [File] if found, or null otherwise.
5655
*/
57-
fun findStructureByName(name: String): File? =
56+
private fun findStructureByName(name: String): File? =
5857
serializers
5958
.keys
6059
.firstNotNullOfOrNull { extension ->
@@ -81,93 +80,94 @@ object StructureRegistry
8180
"Invalid structure template: $name",
8281
"The structure folder is not a folder"
8382
)
83+
return null
8484
}
8585

8686
// Poll directory file events to load many structures at once
8787
// They might not show up in the command suggestion, but they are
8888
// present in the map
89-
pathWatcher.poll()
90-
?.let { key ->
91-
key.pollEvents()?.forEach { event ->
92-
@Suppress("UNCHECKED_CAST")
93-
event as WatchEvent<Path>
94-
95-
val kind = event.kind()
89+
pathWatcher.poll()?.let { key ->
90+
key.pollEvents()
91+
?.filterIsInstance<WatchEvent<Path>>()
92+
?.forEach { event ->
9693
val path = event.context()
9794
val nameNoExt = path.nameWithoutExtension
9895

99-
when (kind) {
96+
when (event.kind()) {
10097
ENTRY_DELETE -> remove(nameNoExt)
101-
ENTRY_CREATE -> if (!contains(nameNoExt) && nameNoExt != name) loadStructureByName(path.nameWithoutExtension, convert = true)
98+
ENTRY_CREATE -> {
99+
if (!contains(nameNoExt) && nameNoExt != name) {
100+
loadStructureByName(path.nameWithoutExtension, convert = true)
101+
}
102+
}
102103
}
103104

104105
// Reset the key -- this step is critical if you want to
105106
// receive further watch events. If the key is no longer valid,
106107
// the directory is inaccessible so exit the loop.
107108
if (!key.reset()) return@forEach
108109
}
109-
}
110+
}
110111

111-
return computeIfAbsent(name.lowercase()) {
112-
findStructureByName(name)
113-
?.let { it to it.extension }
114-
?.let { (file, extension) ->
115-
file.inputStream().use { templateStream ->
116-
val compound = NbtIo.readCompressed(templateStream, NbtSizeTracker.ofUnlimitedBytes())
117-
val template = createStructure(compound, extension)
118-
119-
// Only delete structure files that aren't NBT
120-
if (convert && extension != "nbt") {
121-
template
122-
?.let { saveStructure(name, it) }
123-
?.let { structurePath.resolve("$name.$extension").deleteIfExists() }
124-
}
112+
return computeIfAbsent(name.lowercase()) { loadFileAndCreate(name, convert) }
113+
}
125114

126-
// Verify the structure integrity after it had been
127-
// converted to a regular structure template
128-
if (compound.isValidStructureTemplate()) template
129-
else {
130-
logError(
131-
"Invalid structure template: $it",
132-
"File does not match template format, it might have been corrupted",
133-
)
134-
null
135-
}
115+
/**
116+
* Loads the structure file and creates a [StructureTemplate].
117+
*
118+
* @param name The name of the structure file (without extension).
119+
* @param convert Whether to replace the file after converting it.
120+
* @return The created [StructureTemplate], or null if the structure is not found or invalid.
121+
*/
122+
private fun loadFileAndCreate(name: String, convert: Boolean) =
123+
findStructureByName(name)
124+
?.let { it to it.extension }
125+
?.let { (file, extension) ->
126+
file.inputStream().use { templateStream ->
127+
val compound = NbtIo.readCompressed(templateStream, NbtSizeTracker.ofUnlimitedBytes())
128+
val template = createStructure(compound, extension)
129+
130+
if (convert && extension != "nbt") {
131+
template?.let { saveStructure(name, it) }
132+
}
133+
134+
// Verify the structure integrity after it had been
135+
// converted to a regular structure template
136+
if (compound.isValidStructureTemplate()) {
137+
template
138+
} else {
139+
logError(
140+
"Invalid structure template: $name",
141+
"File does not match template format, it might have been corrupted",
142+
)
143+
null
136144
}
137145
}
138-
}
139-
}
146+
}
140147

141148
/**
142149
* Creates a [StructureTemplate] from the provided NBT data.
143150
*
144151
* @param nbt The [NbtCompound] containing the structure's data.
145152
* @return The created [StructureTemplate], or null if there was an error.
146153
*/
147-
private fun createStructure(nbt: NbtCompound, suffix: String): StructureTemplate? {
148-
val template = StructureTemplate()
149-
150-
serializers[suffix]
151-
?.invoke(
152-
template,
153-
Registries.BLOCK.readOnlyWrapper,
154-
nbt,
155-
)
156-
?.let { error ->
157-
logError("Could not create structure from file", error.message ?: "")
158-
return null
159-
}
160-
161-
return template
162-
}
154+
private fun createStructure(nbt: NbtCompound, suffix: String): StructureTemplate? =
155+
StructureTemplate().apply {
156+
serializers[suffix]
157+
?.invoke(this, Registries.BLOCK.readOnlyWrapper, nbt)
158+
?.let { error ->
159+
logError("Could not create structure from file", error.message ?: "")
160+
return null
161+
}
162+
}
163163

164164
/**
165165
* Saves the provided [structure] to disk under the specified [name].
166166
*
167167
* @param name The name of the structure file (without the extension).
168168
* @param structure The [StructureTemplate] to save.
169169
*/
170-
fun saveStructure(name: String, structure: StructureTemplate) {
170+
private fun saveStructure(name: String, structure: StructureTemplate) {
171171
val path = structurePath.resolve("$name.nbt")
172172
val compound = structure.writeNbt(NbtCompound())
173173

@@ -180,17 +180,16 @@ object StructureRegistry
180180
/**
181181
* Verifies that the provided NBT data represents a valid Minecraft structure template.
182182
*
183-
* @param this@isValidStructureTemplate The [NbtCompound] to validate.
183+
* @receiver The [NbtCompound] to validate.
184184
* @return True if the NBT contains valid structure template data, false otherwise.
185185
*/
186186
private fun NbtCompound.isValidStructureTemplate() =
187187
contains("DataVersion") && contains("blocks") && contains("palette") && contains("size")
188188

189189
override fun load(): String {
190-
structurePath.walk().forEach { path ->
191-
if (path.extension in serializers.keys)
192-
loadStructureByName(path.nameWithoutExtension)
193-
}
190+
structurePath.walk()
191+
.filter { it.extension in serializers.keys }
192+
.forEach { path -> loadStructureByName(path.nameWithoutExtension) }
194193

195194
return "Loaded $size structure templates"
196195
}

common/src/main/kotlin/com/lambda/util/extension/Nbt.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ import net.minecraft.nbt.NbtList
88
* Puts a list of integer into the component, this is not the same as an int array
99
*/
1010
fun NbtCompound.putIntList(key: String, vararg values: Int) {
11-
this.put(key, values
12-
.fold(NbtList()) { list, value -> list.add(NbtInt.of(value)); list })
11+
put(key, values.fold(NbtList()) { list, value -> list.add(NbtInt.of(value)); list })
1312
}

common/src/main/kotlin/com/lambda/util/extension/World.kt

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,43 +97,41 @@ private fun StructureTemplate.readSpongeV1OrException(
9797
val paletteMax = nbt.getInt("PaletteMax")
9898
val palette = nbt.getCompound("Palette")
9999

100-
if (palette.size != paletteMax)
101-
return IllegalStateException("Block palette size does not match the provided size (corrupted?)")
100+
check(palette.size == paletteMax) {
101+
"Block palette size does not match the provided size (corrupted?)"
102+
}
102103

103104
val newPalette = NbtList()
104-
val newBlocks = NbtList()
105105

106106
palette.keys.forEach { key ->
107107
val resource = key.substringBefore('[')
108-
val paletteEntry = NbtCompound()
109108
val blockState = NbtCompound()
110109

111110
// Why ?
112111
// I know it's supposed to be SNBT, but it cannot be parsed back
113-
key
114-
.substringAfter('[')
112+
key.substringAfter('[')
115113
.substringBefore(']')
116114
.takeIf { it != resource }
117115
?.split(',')
118116
?.associate { it.substringBefore('=') to it.substringAfter('=') }
119117
?.forEach { (key, value) -> blockState.putString(key, value) }
120118

121-
paletteEntry.putString("Name", resource)
122-
paletteEntry.put("Properties", blockState)
123-
124-
newPalette.add(paletteEntry)
119+
newPalette.add(NbtCompound().apply {
120+
putString("Name", resource)
121+
put("Properties", blockState)
122+
})
125123
}
126124

125+
val newBlocks = NbtList()
127126
var blockIndex = 0
128127
VarIntIterator(nbt.getByteArray("BlockData"))
129128
.forEach { blockId ->
130-
val compound = NbtCompound()
131129
val blockpos = positionFromIndex(width, length, blockIndex++)
132130

133-
compound.putIntList("pos", blockpos.x, blockpos.y, blockpos.z)
134-
compound.putInt("state", blockId.toInt())
135-
136-
newBlocks.add(compound)
131+
newBlocks.add(NbtCompound().apply {
132+
putIntList("pos", blockpos.x, blockpos.y, blockpos.z)
133+
putInt("state", blockId)
134+
})
137135
}
138136

139137
// Construct a structure compatible nbt compound

0 commit comments

Comments
 (0)