diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/GjallarhornCommand.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/GjallarhornCommand.kt index 7afd8ce..0784e89 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/GjallarhornCommand.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/GjallarhornCommand.kt @@ -25,6 +25,7 @@ class GjallarhornCommand : CliktCommand(invokeWithoutSubcommand = true) { jdbcUrl = jdbcConnectionUrl username = jdbcConnectionUsername password = jdbcConnectionPassword + minimumIdle = dbPoolSize / 2 maximumPoolSize = dbPoolSize }) val db = Database.connect(pool) diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/BlockLogReplay.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/BlockLogReplay.kt index 6a9cda6..7666ff7 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/BlockLogReplay.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/BlockLogReplay.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.gjallarhorn.commands -import cloud.kubelet.foundation.gjallarhorn.compose +import cloud.kubelet.foundation.gjallarhorn.util.compose import cloud.kubelet.foundation.gjallarhorn.render.* import cloud.kubelet.foundation.gjallarhorn.util.RandomColorKey import cloud.kubelet.foundation.gjallarhorn.util.savePngFile @@ -11,6 +11,7 @@ import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.required import com.github.ajalt.clikt.parameters.types.enum +import com.github.ajalt.clikt.parameters.types.int import jetbrains.exodus.kotlin.notNull import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.lessEq @@ -28,10 +29,14 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo private val db by requireObject() private val exactTimeAsString by option("--time", help = "Replay Time") private val timelapseMode by option("--timelapse", help = "Timelapse Mode").enum { it.id } + private val timelapseIntervalLimit by option("--timelapse-limit", help = "Timelapse Limit Intervals").int() private val render by option("--render", help = "Render Top Down Image").enum { it.id }.required() private val considerAirBlocks by option("--consider-air-blocks", help = "Enable Air Block Consideration").flag() + private val fromCoordinate by option("--trim-from", help = "Trim From Coordinate") + private val toCoordinate by option("--trim-to", help = "Trim To Coordinate") + private val logger = LoggerFactory.getLogger(BlockLogReplay::class.java) override fun run() { @@ -43,13 +48,17 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo row[minTimeColumn]!! to row[maxTimeColumn]!! } - val intervals = mutableListOf() + var intervals = mutableListOf() var current = start while (!current.isAfter(end)) { intervals.add(current) current = current.plus(timelapseMode!!.interval) } + if (timelapseIntervalLimit != null) { + intervals = intervals.takeLast(timelapseIntervalLimit!!).toMutableList() + } + val trackerPool = ScheduledThreadPoolExecutor(8) val trackers = ConcurrentHashMap() for (time in intervals) { @@ -69,14 +78,14 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo logger.info("State Tracking Completed") val allBlockOffsets = trackers.map { it.value.calculateZeroBlockOffset() } val globalBlockOffset = BlockPosition.maxOf(allBlockOffsets.asSequence()) - val allBlockMaxes = trackers.map { it.value.calculateZeroBlockOffset() } + val allBlockMaxes = trackers.map { it.value.calculateMaxBlock() } val globalBlockMax = BlockPosition.maxOf(allBlockMaxes.asSequence()) val globalBlockExpanse = BlockExpanse.offsetAndMax(globalBlockOffset, globalBlockMax) logger.info("Calculations Completed") val renderState = render.createState() - val renderPool = ScheduledThreadPoolExecutor(8) + val renderPool = ScheduledThreadPoolExecutor(16) for ((i, tracker) in trackers.entries) { renderPool.submit { val count = trackers.size.toString().length @@ -139,11 +148,30 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo val uniqueBlockPositions = tracker.blocks.size logger.info("Job $job Unique Block Positions... $uniqueBlockPositions") + maybeTrimState(tracker) return tracker } + fun maybeTrimState(tracker: BlockStateTracker) { + if (fromCoordinate == null || toCoordinate == null) { + return + } + + val from = fromCoordinate!!.split(",").map { it.toLong() } + val to = toCoordinate!!.split(",").map { it.toLong() } + + val fromBlock = BlockPosition(from[0], 0, from[1]) + val toBlock = BlockPosition(to[0], 0, to[1]) + + tracker.trimOutsideXAndZRange(fromBlock, toBlock) + } + @Suppress("unused") - enum class RenderType(val id: String, val createState: () -> Any, val renderBufferedImage: (Any, BlockStateImage, BlockExpanse) -> BufferedImage) { + enum class RenderType( + val id: String, + val createState: () -> Any, + val renderBufferedImage: (Any, BlockStateImage, BlockExpanse) -> BufferedImage + ) { TopDown("top-down", { TopDownState(RandomColorKey()) }, { state, image, expanse -> image.buildTopDownImage(expanse, (state as TopDownState).randomColorKey) }), diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerPositionExport.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerPositionExport.kt index b3ac3f9..5ff4df0 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerPositionExport.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerPositionExport.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.gjallarhorn.commands -import cloud.kubelet.foundation.gjallarhorn.compose +import cloud.kubelet.foundation.gjallarhorn.util.compose import cloud.kubelet.foundation.heimdall.table.PlayerPositionTable import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.requireObject diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerSessionExport.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerSessionExport.kt index f8acba6..aaa87dc 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerSessionExport.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/commands/PlayerSessionExport.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.gjallarhorn.commands -import cloud.kubelet.foundation.gjallarhorn.compose +import cloud.kubelet.foundation.gjallarhorn.util.compose import cloud.kubelet.foundation.heimdall.table.PlayerSessionTable import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.requireObject diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateImage.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateImage.kt index c20ec20..dc94dcd 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateImage.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateImage.kt @@ -72,7 +72,8 @@ class BlockStateImage { private fun buildPixelQuadImage(expanse: BlockExpanse, callback: BufferedImage.(Long, Long) -> Unit): BufferedImage { val width = expanse.size.x val height = expanse.size.z - val bufferedImage = BufferedImage(width.toInt() * quadImageSize, height.toInt() * quadImageSize, BufferedImage.TYPE_4BYTE_ABGR) + val bufferedImage = + BufferedImage(width.toInt() * quadImageSize, height.toInt() * quadImageSize, BufferedImage.TYPE_4BYTE_ABGR) for (x in 0 until width) { for (z in 0 until height) { diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateTracker.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateTracker.kt index 28b9b92..127b6a0 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateTracker.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/render/BlockStateTracker.kt @@ -17,6 +17,17 @@ class BlockStateTracker(private val mode: BlockTrackMode = BlockTrackMode.Remove } } + fun trimOutsideXAndZRange(min: BlockPosition, max: BlockPosition) { + val blockPositionsToRemove = blocks.keys.filter { + it.x < min.x || + it.z < min.z || + it.x > max.x || + it.z > max.z + }.toList() + + blockPositionsToRemove.forEach { blocks.remove(it) } + } + fun calculateZeroBlockOffset(): BlockPosition { val x = blocks.keys.minOf { it.x } val y = blocks.keys.minOf { it.y } diff --git a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/util/compose.kt b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/util/compose.kt index 0f1a87e..2e1e0e3 100644 --- a/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/util/compose.kt +++ b/tool-gjallarhorn/src/main/kotlin/cloud/kubelet/foundation/gjallarhorn/util/compose.kt @@ -1,4 +1,4 @@ -package cloud.kubelet.foundation.gjallarhorn +package cloud.kubelet.foundation.gjallarhorn.util import org.jetbrains.exposed.sql.Op