diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/ChunkExportLoaderCommand.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/ChunkExportLoaderCommand.kt index 62479b7..0a0527f 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/ChunkExportLoaderCommand.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/ChunkExportLoaderCommand.kt @@ -2,8 +2,8 @@ package cloud.kubelet.foundation.gjallarhorn.commands import cloud.kubelet.foundation.gjallarhorn.export.ChunkExportLoader import cloud.kubelet.foundation.gjallarhorn.state.BlockExpanse +import cloud.kubelet.foundation.gjallarhorn.state.BlockLogTracker import cloud.kubelet.foundation.gjallarhorn.state.ChangelogSlice -import cloud.kubelet.foundation.gjallarhorn.state.SparseBlockStateMap import cloud.kubelet.foundation.gjallarhorn.util.savePngFile import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.requireObject @@ -22,12 +22,12 @@ class ChunkExportLoaderCommand : CliktCommand("Chunk Export Loader", name = "chu private val render by option("--render", help = "Render Top Down Image").enum { it.id } override fun run() { - val map = SparseBlockStateMap() - val loader = ChunkExportLoader(map) + val tracker = BlockLogTracker(isConcurrent = true) + val loader = ChunkExportLoader(tracker = tracker) loader.loadAllChunksForWorld(exportDirectoryPath, world, fast = true) if (render != null) { - val expanse = BlockExpanse.offsetAndMax(map.calculateZeroBlockOffset(), map.calculateMaxBlock()) - map.applyCoordinateOffset(expanse.offset) + val expanse = BlockExpanse.zeroOffsetAndMax(tracker.calculateZeroBlockOffset(), tracker.calculateMaxBlock()) + val map = tracker.buildBlockMap(expanse.offset) val renderer = render!!.create(expanse, db) val image = renderer.render(ChangelogSlice.none, map) image.savePngFile("full.png") diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/export/ChunkExportLoader.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/export/ChunkExportLoader.kt index 4fc2659..2b60460 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/export/ChunkExportLoader.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/export/ChunkExportLoader.kt @@ -1,6 +1,7 @@ package cloud.kubelet.foundation.gjallarhorn.export import cloud.kubelet.foundation.gjallarhorn.state.BlockCoordinate +import cloud.kubelet.foundation.gjallarhorn.state.BlockLogTracker import cloud.kubelet.foundation.gjallarhorn.state.BlockState import cloud.kubelet.foundation.gjallarhorn.state.SparseBlockStateMap import cloud.kubelet.foundation.heimdall.export.ExportedChunk @@ -12,7 +13,7 @@ import java.util.zip.GZIPInputStream import kotlin.io.path.inputStream import kotlin.io.path.listDirectoryEntries -class ChunkExportLoader(val map: SparseBlockStateMap) { +class ChunkExportLoader(val map: SparseBlockStateMap? = null, val tracker: BlockLogTracker? = null) { fun loadAllChunksForWorld(path: Path, world: String, fast: Boolean = false) { val chunkFiles = path.listDirectoryEntries("${world}_chunk_*.json.gz") if (fast) { @@ -30,6 +31,7 @@ class ChunkExportLoader(val map: SparseBlockStateMap) { val chunk = Json.decodeFromStream(ExportedChunk.serializer(), gzipInputStream) var blockCount = 0L + val allBlocks = if (tracker != null) mutableMapOf() else null for (section in chunk.sections) { val x = (chunk.x * 16) + section.x val z = (chunk.z * 16) + section.z @@ -40,10 +42,18 @@ class ChunkExportLoader(val map: SparseBlockStateMap) { val coordinate = BlockCoordinate(x.toLong(), y.toLong(), z.toLong()) val state = BlockState.cached(block.type) - map.put(coordinate, state) + map?.put(coordinate, state) + if (allBlocks != null) { + allBlocks[coordinate] = state + } blockCount++ } } + + if (allBlocks != null) { + tracker?.placeAll(allBlocks) + } + logger.info("($id) Chunk X=${chunk.x} Z=${chunk.z} had $blockCount blocks") } diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockCoordinateSparseMap.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockCoordinateSparseMap.kt index 5a48337..c4b353b 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockCoordinateSparseMap.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockCoordinateSparseMap.kt @@ -57,8 +57,8 @@ open class BlockCoordinateSparseMap : BlockCoordinateStore { val zSectionMap = TreeMap>() (xSection.key + offset.x) to xSection.value.map { zSection -> val ySectionMap = TreeMap() - (zSection.key + offset.z) to zSection.value.map { ySection -> - (ySection.key + offset.y) to ySection.value + (zSection.key + offset.z) to zSection.value.mapKeys { + (it.key + offset.y) }.toMap(ySectionMap) }.toMap(zSectionMap) }.toMap(root) diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockExpanse.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockExpanse.kt index b2fa0a4..c1b0a17 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockExpanse.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockExpanse.kt @@ -5,7 +5,7 @@ class BlockExpanse( val size: BlockCoordinate ) { companion object { - fun offsetAndMax(offset: BlockCoordinate, max: BlockCoordinate) = BlockExpanse( + fun zeroOffsetAndMax(offset: BlockCoordinate, max: BlockCoordinate) = BlockExpanse( offset, offset.applyAsOffset(max) ) diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockLogTracker.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockLogTracker.kt index d5f3b4f..c1a8437 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockLogTracker.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockLogTracker.kt @@ -10,6 +10,10 @@ class BlockLogTracker(private val mode: BlockTrackMode = BlockTrackMode.RemoveOn blocks[position] = state } + fun placeAll(map: Map) { + blocks.putAll(map) + } + fun delete(position: BlockCoordinate) { if (mode == BlockTrackMode.AirOnDelete) { blocks[position] = BlockState.AirBlock diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockMapTimelapse.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockMapTimelapse.kt index 262f9c0..a39cbb8 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockMapTimelapse.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/state/BlockMapTimelapse.kt @@ -17,7 +17,7 @@ class BlockMapTimelapse : val globalBlockOffset = BlockCoordinate.maxOf(allBlockOffsets) val allBlockMaxes = trackers.map { it.value.calculateMaxBlock() } val globalBlockMax = BlockCoordinate.maxOf(allBlockMaxes) - val globalBlockExpanse = BlockExpanse.offsetAndMax(globalBlockOffset, globalBlockMax) + val globalBlockExpanse = BlockExpanse.zeroOffsetAndMax(globalBlockOffset, globalBlockMax) val renderer = pool.createRendererFunction(globalBlockExpanse) for ((slice, tracker) in trackers) {