mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-04 03:39:37 +00:00 
			
		
		
		
	Gjallarhorn: Timelapse Limiting and Coordinate Cropping
This commit is contained in:
		@ -25,6 +25,7 @@ class GjallarhornCommand : CliktCommand(invokeWithoutSubcommand = true) {
 | 
				
			|||||||
      jdbcUrl = jdbcConnectionUrl
 | 
					      jdbcUrl = jdbcConnectionUrl
 | 
				
			||||||
      username = jdbcConnectionUsername
 | 
					      username = jdbcConnectionUsername
 | 
				
			||||||
      password = jdbcConnectionPassword
 | 
					      password = jdbcConnectionPassword
 | 
				
			||||||
 | 
					      minimumIdle = dbPoolSize / 2
 | 
				
			||||||
      maximumPoolSize = dbPoolSize
 | 
					      maximumPoolSize = dbPoolSize
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    val db = Database.connect(pool)
 | 
					    val db = Database.connect(pool)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
package cloud.kubelet.foundation.gjallarhorn.commands
 | 
					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.render.*
 | 
				
			||||||
import cloud.kubelet.foundation.gjallarhorn.util.RandomColorKey
 | 
					import cloud.kubelet.foundation.gjallarhorn.util.RandomColorKey
 | 
				
			||||||
import cloud.kubelet.foundation.gjallarhorn.util.savePngFile
 | 
					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.option
 | 
				
			||||||
import com.github.ajalt.clikt.parameters.options.required
 | 
					import com.github.ajalt.clikt.parameters.options.required
 | 
				
			||||||
import com.github.ajalt.clikt.parameters.types.enum
 | 
					import com.github.ajalt.clikt.parameters.types.enum
 | 
				
			||||||
 | 
					import com.github.ajalt.clikt.parameters.types.int
 | 
				
			||||||
import jetbrains.exodus.kotlin.notNull
 | 
					import jetbrains.exodus.kotlin.notNull
 | 
				
			||||||
import org.jetbrains.exposed.sql.*
 | 
					import org.jetbrains.exposed.sql.*
 | 
				
			||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.lessEq
 | 
					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<Database>()
 | 
					  private val db by requireObject<Database>()
 | 
				
			||||||
  private val exactTimeAsString by option("--time", help = "Replay Time")
 | 
					  private val exactTimeAsString by option("--time", help = "Replay Time")
 | 
				
			||||||
  private val timelapseMode by option("--timelapse", help = "Timelapse Mode").enum<TimelapseMode> { it.id }
 | 
					  private val timelapseMode by option("--timelapse", help = "Timelapse Mode").enum<TimelapseMode> { 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<RenderType> { it.id }.required()
 | 
					  private val render by option("--render", help = "Render Top Down Image").enum<RenderType> { it.id }.required()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private val considerAirBlocks by option("--consider-air-blocks", help = "Enable Air Block Consideration").flag()
 | 
					  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)
 | 
					  private val logger = LoggerFactory.getLogger(BlockLogReplay::class.java)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun run() {
 | 
					  override fun run() {
 | 
				
			||||||
@ -43,13 +48,17 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo
 | 
				
			|||||||
        row[minTimeColumn]!! to row[maxTimeColumn]!!
 | 
					        row[minTimeColumn]!! to row[maxTimeColumn]!!
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      val intervals = mutableListOf<Instant>()
 | 
					      var intervals = mutableListOf<Instant>()
 | 
				
			||||||
      var current = start
 | 
					      var current = start
 | 
				
			||||||
      while (!current.isAfter(end)) {
 | 
					      while (!current.isAfter(end)) {
 | 
				
			||||||
        intervals.add(current)
 | 
					        intervals.add(current)
 | 
				
			||||||
        current = current.plus(timelapseMode!!.interval)
 | 
					        current = current.plus(timelapseMode!!.interval)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (timelapseIntervalLimit != null) {
 | 
				
			||||||
 | 
					        intervals = intervals.takeLast(timelapseIntervalLimit!!).toMutableList()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      val trackerPool = ScheduledThreadPoolExecutor(8)
 | 
					      val trackerPool = ScheduledThreadPoolExecutor(8)
 | 
				
			||||||
      val trackers = ConcurrentHashMap<Int, BlockStateTracker>()
 | 
					      val trackers = ConcurrentHashMap<Int, BlockStateTracker>()
 | 
				
			||||||
      for (time in intervals) {
 | 
					      for (time in intervals) {
 | 
				
			||||||
@ -69,14 +78,14 @@ class BlockLogReplay : CliktCommand("Replay Block Logs", name = "replay-block-lo
 | 
				
			|||||||
      logger.info("State Tracking Completed")
 | 
					      logger.info("State Tracking Completed")
 | 
				
			||||||
      val allBlockOffsets = trackers.map { it.value.calculateZeroBlockOffset() }
 | 
					      val allBlockOffsets = trackers.map { it.value.calculateZeroBlockOffset() }
 | 
				
			||||||
      val globalBlockOffset = BlockPosition.maxOf(allBlockOffsets.asSequence())
 | 
					      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 globalBlockMax = BlockPosition.maxOf(allBlockMaxes.asSequence())
 | 
				
			||||||
      val globalBlockExpanse = BlockExpanse.offsetAndMax(globalBlockOffset, globalBlockMax)
 | 
					      val globalBlockExpanse = BlockExpanse.offsetAndMax(globalBlockOffset, globalBlockMax)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      logger.info("Calculations Completed")
 | 
					      logger.info("Calculations Completed")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      val renderState = render.createState()
 | 
					      val renderState = render.createState()
 | 
				
			||||||
      val renderPool = ScheduledThreadPoolExecutor(8)
 | 
					      val renderPool = ScheduledThreadPoolExecutor(16)
 | 
				
			||||||
      for ((i, tracker) in trackers.entries) {
 | 
					      for ((i, tracker) in trackers.entries) {
 | 
				
			||||||
        renderPool.submit {
 | 
					        renderPool.submit {
 | 
				
			||||||
          val count = trackers.size.toString().length
 | 
					          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
 | 
					    val uniqueBlockPositions = tracker.blocks.size
 | 
				
			||||||
    logger.info("Job $job Unique Block Positions... $uniqueBlockPositions")
 | 
					    logger.info("Job $job Unique Block Positions... $uniqueBlockPositions")
 | 
				
			||||||
 | 
					    maybeTrimState(tracker)
 | 
				
			||||||
    return 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")
 | 
					  @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",
 | 
					    TopDown("top-down",
 | 
				
			||||||
      { TopDownState(RandomColorKey()) },
 | 
					      { TopDownState(RandomColorKey()) },
 | 
				
			||||||
      { state, image, expanse -> image.buildTopDownImage(expanse, (state as TopDownState).randomColorKey) }),
 | 
					      { state, image, expanse -> image.buildTopDownImage(expanse, (state as TopDownState).randomColorKey) }),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
package cloud.kubelet.foundation.gjallarhorn.commands
 | 
					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 cloud.kubelet.foundation.heimdall.table.PlayerPositionTable
 | 
				
			||||||
import com.github.ajalt.clikt.core.CliktCommand
 | 
					import com.github.ajalt.clikt.core.CliktCommand
 | 
				
			||||||
import com.github.ajalt.clikt.core.requireObject
 | 
					import com.github.ajalt.clikt.core.requireObject
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
package cloud.kubelet.foundation.gjallarhorn.commands
 | 
					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 cloud.kubelet.foundation.heimdall.table.PlayerSessionTable
 | 
				
			||||||
import com.github.ajalt.clikt.core.CliktCommand
 | 
					import com.github.ajalt.clikt.core.CliktCommand
 | 
				
			||||||
import com.github.ajalt.clikt.core.requireObject
 | 
					import com.github.ajalt.clikt.core.requireObject
 | 
				
			||||||
 | 
				
			|||||||
@ -72,7 +72,8 @@ class BlockStateImage {
 | 
				
			|||||||
  private fun buildPixelQuadImage(expanse: BlockExpanse, callback: BufferedImage.(Long, Long) -> Unit): BufferedImage {
 | 
					  private fun buildPixelQuadImage(expanse: BlockExpanse, callback: BufferedImage.(Long, Long) -> Unit): BufferedImage {
 | 
				
			||||||
    val width = expanse.size.x
 | 
					    val width = expanse.size.x
 | 
				
			||||||
    val height = expanse.size.z
 | 
					    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 (x in 0 until width) {
 | 
				
			||||||
      for (z in 0 until height) {
 | 
					      for (z in 0 until height) {
 | 
				
			||||||
 | 
				
			|||||||
@ -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 {
 | 
					  fun calculateZeroBlockOffset(): BlockPosition {
 | 
				
			||||||
    val x = blocks.keys.minOf { it.x }
 | 
					    val x = blocks.keys.minOf { it.x }
 | 
				
			||||||
    val y = blocks.keys.minOf { it.y }
 | 
					    val y = blocks.keys.minOf { it.y }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
package cloud.kubelet.foundation.gjallarhorn
 | 
					package cloud.kubelet.foundation.gjallarhorn.util
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.jetbrains.exposed.sql.Op
 | 
					import org.jetbrains.exposed.sql.Op
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user