Skip to content

Instantly share code, notes, and snippets.

@Edouard127
Created February 1, 2025 00:04
Show Gist options
  • Save Edouard127/640631bf701e239c75c707b2cd7ed0a0 to your computer and use it in GitHub Desktop.
Save Edouard127/640631bf701e239c75c707b2cd7ed0a0 to your computer and use it in GitHub Desktop.
private fun StructureTemplate.readSpongeV1OrException(
lookup: RegistryEntryLookup<Block>,
nbt: NbtCompound,
): Throwable? {
val version = nbt.getInt("DataVersion")
val width = (nbt.getShort("Width") and 0xFFFF.toShort()).toInt()
val height = (nbt.getShort("Height") and 0xFFFF.toShort()).toInt()
val length = (nbt.getShort("Length") and 0xFFFF.toShort()).toInt()
val metadata = nbt.getCompound("Metadata")
// If the offset is too far, we simply ignore it
// I think at some point schematica calculated
// the offset based on the distance between the player position
// and the schematic lower corner, so it would fuck up everything
// when you tried to import and build it using Baritone
// val minimumPosition = nbt.getIntArray("Offset")
// .takeIf { it.isNotEmpty() }
// ?.let { fastVectorOf(it[0], it[1], it[2]) }
// ?.takeIf { 274945015809L times 16 < it } ?: 0L
val palette = nbt.getCompound("Palette")
val paletteMax = nbt.getInt("PaletteMax")
val newPalette = NbtList()
if (palette.size != paletteMax) return IllegalStateException("Block palette size does not match the provided size (corrupted?)")
palette.keys
.sortedBy { palette.getInt(it) }
.forEach { key ->
val resource = key.substringBefore('[')
val blockState = NbtCompound()
// Why ?
// I know it's supposed to be SNBT, but it cannot be parsed back
key.substringAfter('[')
.substringBefore(']')
.takeIf { it != resource }
?.split(',')
?.associate { it.substringBefore('=') to it.substringAfter('=') }
?.forEach { (key, value) -> blockState.putString(key, value) }
// Populate the list using the correct indices
newPalette.add(NbtCompound().apply {
putString("Name", resource)
put("Properties", blockState)
})
}
val newBlocks = NbtList()
var blockIndex = 0
VarIntIterator(nbt.getByteArray("BlockData"))
.forEach { blockId ->
val blockpos = positionFromIndex(width, length, blockIndex++)
newBlocks.add(NbtCompound().apply {
putIntList("pos", blockpos.x, blockpos.y, blockpos.z)
putInt("state", blockId)
})
}
// Construct a structure compatible nbt compound
nbt.putIntList("size", width, height, length)
nbt.put("palette", newPalette)
nbt.put("blocks", newBlocks)
nbt.putString("author", metadata.getString("Author"))
// Fix the data for future versions
DataFixTypes.STRUCTURE.update(mc.dataFixer, nbt, version)
// Use the StructureTemplate NBT read utils in order to construct the template
return readNbtOrException(lookup, nbt)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment