mirror of
https://github.com/GayPizzaSpecifications/foundation.git
synced 2025-08-02 21:20:55 +00:00
Rewrite Heimdall block handling to support more event types and non-player block changes.
This commit is contained in:
parent
688106a6e6
commit
e0823f7b15
@ -1,6 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.table
|
||||
|
||||
object BlockBreakTable : PlayerTimedLocalEventTable("block_breaks") {
|
||||
val block = text("block")
|
||||
val blockData = text("block_data").nullable()
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package gay.pizza.foundation.heimdall.table
|
||||
|
||||
object BlockChangeTable : PlayerTimedLocalEventTable("block_changes") {
|
||||
val block = text("block")
|
||||
val data = text("data")
|
||||
val cause = text("cause")
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.table
|
||||
|
||||
object BlockPlaceTable : PlayerTimedLocalEventTable("block_places") {
|
||||
val block = text("block")
|
||||
val blockData = text("block_data").nullable()
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package gay.pizza.foundation.heimdall.table
|
||||
|
||||
abstract class PlayerTimedLocalEventTable(name: String) : TimedLocalEventTable(name) {
|
||||
val player = uuid("player")
|
||||
val player = uuid("player").nullable()
|
||||
val pitch = double("pitch")
|
||||
val yaw = double("yaw")
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.view
|
||||
|
||||
import gay.pizza.foundation.heimdall.table.PlayerTimedLocalEventTable
|
||||
|
||||
object BlockChangeView : PlayerTimedLocalEventTable("block_changes") {
|
||||
val isBreak = bool("break")
|
||||
val block = text("block")
|
||||
val blockData = text("block_data").nullable()
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.IEventBuffer
|
||||
import gay.pizza.foundation.heimdall.table.BlockBreakTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
class BlockBreak(
|
||||
val playerUniqueIdentity: UUID,
|
||||
val location: Location,
|
||||
val material: Material,
|
||||
val blockData: String? = null,
|
||||
val timestamp: Instant = Instant.now()
|
||||
) : HeimdallEvent() {
|
||||
constructor(event: BlockBreakEvent) : this(
|
||||
event.player.uniqueId,
|
||||
event.block.location,
|
||||
event.block.type,
|
||||
event.block.blockData.asString
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
transaction.apply {
|
||||
BlockBreakTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
it[block] = material.key.toString()
|
||||
it[blockData] = this@BlockBreak.blockData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Collector(val buffer: IEventBuffer) : EventCollector<BlockBreak> {
|
||||
@EventHandler
|
||||
fun onBlockBroken(event: BlockBreakEvent) = buffer.push(BlockBreak(event))
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<BlockBreak> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<BlockBreak> = Collector(buffer)
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.IEventBuffer
|
||||
import gay.pizza.foundation.heimdall.table.BlockChangeTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.event.block.BlockBurnEvent
|
||||
import org.bukkit.event.block.BlockDamageEvent
|
||||
import org.bukkit.event.block.BlockDispenseEvent
|
||||
import org.bukkit.event.block.BlockEvent
|
||||
import org.bukkit.event.block.BlockExplodeEvent
|
||||
import org.bukkit.event.block.BlockFadeEvent
|
||||
import org.bukkit.event.block.BlockFormEvent
|
||||
import org.bukkit.event.block.BlockGrowEvent
|
||||
import org.bukkit.event.block.BlockIgniteEvent
|
||||
import org.bukkit.event.block.BlockPlaceEvent
|
||||
import org.bukkit.event.block.BlockSpreadEvent
|
||||
import org.bukkit.event.block.FluidLevelChangeEvent
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
class BlockChange(
|
||||
val playerUniqueIdentity: UUID? = null,
|
||||
val cause: String = "place",
|
||||
val location: Location,
|
||||
val material: Material,
|
||||
val blockData: String,
|
||||
val timestamp: Instant = Instant.now()
|
||||
) : HeimdallEvent() {
|
||||
constructor(
|
||||
playerUniqueIdentity: UUID? = null,
|
||||
isBreak: Boolean = false,
|
||||
cause: String,
|
||||
event: BlockEvent,
|
||||
block: Block = event.block
|
||||
) : this(
|
||||
playerUniqueIdentity = playerUniqueIdentity,
|
||||
cause = cause,
|
||||
location = block.location,
|
||||
material = if (isBreak) Material.AIR else block.type,
|
||||
blockData = if (isBreak) Material.AIR.createBlockData().asString
|
||||
else block.blockData.asString
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
transaction.apply {
|
||||
BlockChangeTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
it[block] = material.key.toString()
|
||||
it[data] = this@BlockChange.blockData
|
||||
it[cause] = this@BlockChange.cause
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Collector(val buffer: IEventBuffer) : EventCollector<BlockChange> {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockPlaced(event: BlockPlaceEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player.uniqueId,
|
||||
event = event,
|
||||
cause = "place",
|
||||
isBreak = false
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockBreak(event: BlockBreakEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player.uniqueId,
|
||||
event = event,
|
||||
cause = "break",
|
||||
isBreak = true
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockExplode(event: BlockExplodeEvent) = event.blockList().forEach { block ->
|
||||
buffer.push(
|
||||
BlockChange(
|
||||
event = event,
|
||||
cause = "explode",
|
||||
isBreak = true,
|
||||
block = block
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockBurn(event: BlockBurnEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "burn",
|
||||
isBreak = true
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockDamage(event: BlockDamageEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "damage"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockForm(event: BlockFormEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "form"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockGrow(event: BlockGrowEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "grow"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockFade(event: BlockFadeEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "fade"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockIgnite(event: BlockIgniteEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "ignite"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockDispense(event: BlockDispenseEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "dispense"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockSpread(event: BlockSpreadEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "spread"
|
||||
)
|
||||
)
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onFluidLevelChange(event: FluidLevelChangeEvent) = buffer.push(
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "fluid-level-change"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<BlockChange> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<BlockChange> = Collector(buffer)
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.IEventBuffer
|
||||
import gay.pizza.foundation.heimdall.table.BlockPlaceTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.block.BlockPlaceEvent
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
class BlockPlace(
|
||||
val playerUniqueIdentity: UUID,
|
||||
val location: Location,
|
||||
val material: Material,
|
||||
val blockData: String? = null,
|
||||
val timestamp: Instant = Instant.now()
|
||||
) : HeimdallEvent() {
|
||||
constructor(event: BlockPlaceEvent) : this(
|
||||
event.player.uniqueId,
|
||||
event.block.location,
|
||||
event.block.type,
|
||||
event.block.blockData.asString
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
transaction.apply {
|
||||
BlockPlaceTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
it[block] = material.key.toString()
|
||||
it[blockData] = this@BlockPlace.blockData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Collector(val buffer: IEventBuffer) : EventCollector<BlockPlace> {
|
||||
@EventHandler
|
||||
fun onBlockPlaced(event: BlockPlaceEvent) = buffer.push(BlockPlace(event))
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<BlockPlace> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<BlockPlace> = Collector(buffer)
|
||||
}
|
||||
}
|
@ -2,8 +2,7 @@ package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
object EventCollectorProviders {
|
||||
val all = listOf<EventCollectorProvider<*>>(
|
||||
BlockBreak,
|
||||
BlockPlace,
|
||||
BlockChange,
|
||||
EntityKill,
|
||||
PlayerAdvancement,
|
||||
PlayerDeath,
|
||||
|
@ -28,7 +28,7 @@ fun <T : PlayerTimedLocalEventTable, K : Any> T.putPlayerTimedLocalEvent(
|
||||
statement: InsertStatement<K>,
|
||||
time: Instant,
|
||||
location: Location,
|
||||
player: UUID
|
||||
player: UUID?
|
||||
) {
|
||||
putTimedLocalEvent(statement, time, location)
|
||||
statement[this.player] = player
|
||||
|
@ -26,9 +26,9 @@ alter table player_positions set (
|
||||
--
|
||||
select add_compression_policy('player_positions', interval '3 days', if_not_exists => true);
|
||||
--
|
||||
create table if not exists block_breaks (
|
||||
create table if not exists block_changes (
|
||||
time timestamp not null,
|
||||
player uuid not null,
|
||||
player uuid null,
|
||||
world uuid not null,
|
||||
x double precision not null,
|
||||
y double precision not null,
|
||||
@ -36,25 +36,12 @@ create table if not exists block_breaks (
|
||||
pitch double precision not null,
|
||||
yaw double precision not null,
|
||||
block text not null,
|
||||
PRIMARY KEY (time, player, world)
|
||||
data text not null,
|
||||
cause text not null,
|
||||
PRIMARY KEY (time, world, x, y, z)
|
||||
);
|
||||
--
|
||||
select create_hypertable('block_breaks', 'time', 'player', 4, if_not_exists => TRUE);
|
||||
--
|
||||
create table if not exists block_places (
|
||||
time timestamp not null,
|
||||
player uuid not null,
|
||||
world uuid not null,
|
||||
x double precision not null,
|
||||
y double precision not null,
|
||||
z double precision not null,
|
||||
pitch double precision not null,
|
||||
yaw double precision not null,
|
||||
block text not null,
|
||||
PRIMARY KEY (time, player, world)
|
||||
);
|
||||
--
|
||||
select create_hypertable('block_places', 'time', 'player', 4, if_not_exists => TRUE);
|
||||
select create_hypertable('block_changes', 'time', 'x', 4, if_not_exists => TRUE);
|
||||
--
|
||||
create table if not exists player_sessions (
|
||||
id uuid not null,
|
||||
@ -140,13 +127,3 @@ create or replace view player_names as
|
||||
) as name
|
||||
from unique_player_ids;
|
||||
--
|
||||
alter table block_places add column if not exists block_data text null;
|
||||
--
|
||||
alter table block_breaks add column if not exists block_data text null;
|
||||
--
|
||||
create or replace view block_changes as
|
||||
select true as break, *
|
||||
from block_breaks
|
||||
union all
|
||||
select false as break, * from block_places;
|
||||
--
|
||||
|
@ -8,11 +8,11 @@ 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 gay.pizza.foundation.heimdall.table.BlockChangeTable
|
||||
import gay.pizza.foundation.heimdall.table.WorldChangeTable
|
||||
import gay.pizza.foundation.heimdall.tool.render.*
|
||||
import gay.pizza.foundation.heimdall.tool.state.*
|
||||
import gay.pizza.foundation.heimdall.tool.util.compose
|
||||
import gay.pizza.foundation.heimdall.view.BlockChangeView
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.greaterEq
|
||||
@ -49,8 +49,6 @@ class BlockChangeTimelapseCommand : CliktCommand("Block Change Timelapse", name
|
||||
.enum<ImageFormatType> { it.id }
|
||||
.default(ImageFormatType.Png)
|
||||
|
||||
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")
|
||||
|
||||
@ -100,11 +98,11 @@ class BlockChangeTimelapseCommand : CliktCommand("Block Change Timelapse", name
|
||||
|
||||
val filter = compose(
|
||||
combine = { a, b -> a and b },
|
||||
{ trim?.first?.x != null } to { BlockChangeView.x greaterEq trim!!.first.x.toDouble() },
|
||||
{ trim?.first?.z != null } to { BlockChangeView.z greaterEq trim!!.first.z.toDouble() },
|
||||
{ trim?.second?.x != null } to { BlockChangeView.x lessEq trim!!.second.x.toDouble() },
|
||||
{ trim?.second?.z != null } to { BlockChangeView.z lessEq trim!!.second.z.toDouble() },
|
||||
{ true } to { BlockChangeView.world eq world }
|
||||
{ trim?.first?.x != null } to { BlockChangeTable.x greaterEq trim!!.first.x.toDouble() },
|
||||
{ trim?.first?.z != null } to { BlockChangeTable.z greaterEq trim!!.first.z.toDouble() },
|
||||
{ trim?.second?.x != null } to { BlockChangeTable.x lessEq trim!!.second.x.toDouble() },
|
||||
{ trim?.second?.z != null } to { BlockChangeTable.z lessEq trim!!.second.z.toDouble() },
|
||||
{ true } to { BlockChangeTable.world eq world }
|
||||
)
|
||||
|
||||
val changelog = BlockChangelog.query(db, filter)
|
||||
@ -131,7 +129,6 @@ class BlockChangeTimelapseCommand : CliktCommand("Block Change Timelapse", name
|
||||
|
||||
val pool = BlockMapRenderPool(
|
||||
changelog = changelog,
|
||||
blockTrackMode = if (considerAirBlocks) BlockTrackMode.AirOnDelete else BlockTrackMode.RemoveOnDelete,
|
||||
delegate = timelapse,
|
||||
createRendererFunction = { expanse -> render.createNewRenderer(expanse, db) },
|
||||
threadPoolExecutor = threadPoolExecutor
|
||||
|
@ -36,9 +36,9 @@ class PlayerLocationShareRenderer(
|
||||
val player = it[PlayerPositionTable.player]
|
||||
playerSparseMap.createOrModify(
|
||||
coordinate,
|
||||
create = { mutableListOf(player) },
|
||||
modify = { players -> players.add(player) })
|
||||
allPlayerIds.add(player)
|
||||
create = { mutableListOf(player!!) },
|
||||
modify = { players -> players.add(player!!) })
|
||||
allPlayerIds.add(player!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
package gay.pizza.foundation.heimdall.tool.state
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
enum class BlockChangeType {
|
||||
Place,
|
||||
Break
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package gay.pizza.foundation.heimdall.tool.state
|
||||
|
||||
import gay.pizza.foundation.heimdall.view.BlockChangeView
|
||||
import gay.pizza.foundation.heimdall.table.BlockChangeTable
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.Op
|
||||
import org.jetbrains.exposed.sql.select
|
||||
@ -10,7 +10,7 @@ import java.time.Instant
|
||||
import java.util.stream.Stream
|
||||
|
||||
class BlockChangelog(
|
||||
val changes: List<BlockChange>
|
||||
val changes: List<RecordedBlockChange>
|
||||
) {
|
||||
fun slice(slice: ChangelogSlice): BlockChangelog = BlockChangelog(changes.filter {
|
||||
slice.isTimeWithinFullRange(it.time)
|
||||
@ -60,43 +60,30 @@ class BlockChangelog(
|
||||
|
||||
companion object {
|
||||
fun query(db: Database, filter: Op<Boolean> = Op.TRUE): BlockChangelog = transaction(db) {
|
||||
BlockChangelog(BlockChangeView.select(filter).orderBy(BlockChangeView.time).map { row ->
|
||||
val time = row[BlockChangeView.time]
|
||||
val changeIsBreak = row[BlockChangeView.isBreak]
|
||||
val world = row[BlockChangeView.world]
|
||||
val x = row[BlockChangeView.x]
|
||||
val y = row[BlockChangeView.y]
|
||||
val z = row[BlockChangeView.z]
|
||||
val block = row[BlockChangeView.block]
|
||||
val blockData = row[BlockChangeView.blockData]
|
||||
BlockChangelog(BlockChangeTable.select(filter).orderBy(BlockChangeTable.time).map { row ->
|
||||
val time = row[BlockChangeTable.time]
|
||||
val world = row[BlockChangeTable.world]
|
||||
val x = row[BlockChangeTable.x]
|
||||
val y = row[BlockChangeTable.y]
|
||||
val z = row[BlockChangeTable.z]
|
||||
val blockMaterial = row[BlockChangeTable.block]
|
||||
val blockData = row[BlockChangeTable.data]
|
||||
val location = BlockCoordinate(x.toLong(), y.toLong(), z.toLong())
|
||||
|
||||
val fromBlock = if (changeIsBreak) {
|
||||
BlockState(block, blockData)
|
||||
} else {
|
||||
BlockState.AirBlock
|
||||
}
|
||||
val block = BlockState(blockMaterial, blockData)
|
||||
|
||||
val toBlock = if (changeIsBreak) {
|
||||
BlockState.AirBlock
|
||||
} else {
|
||||
BlockState(block, blockData)
|
||||
}
|
||||
|
||||
BlockChange(
|
||||
RecordedBlockChange(
|
||||
time,
|
||||
world,
|
||||
if (changeIsBreak) BlockChangeType.Break else BlockChangeType.Place,
|
||||
location,
|
||||
fromBlock,
|
||||
toBlock
|
||||
block
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> splitBy(key: (BlockChange) -> T): Map<T, BlockChangelog> {
|
||||
val logs = mutableMapOf<T, MutableList<BlockChange>>()
|
||||
fun <T> splitBy(key: (RecordedBlockChange) -> T): Map<T, BlockChangelog> {
|
||||
val logs = mutableMapOf<T, MutableList<RecordedBlockChange>>()
|
||||
for (change in changes) {
|
||||
val k = key(change)
|
||||
var log = logs[k]
|
||||
|
@ -5,7 +5,7 @@ import gay.pizza.foundation.heimdall.tool.util.minOfAll
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
class BlockLogTracker(private val mode: BlockTrackMode = BlockTrackMode.RemoveOnDelete, isConcurrent: Boolean = false) {
|
||||
class BlockLogTracker(isConcurrent: Boolean = false) {
|
||||
internal val blocks: MutableMap<BlockCoordinate, BlockState> = if (isConcurrent) ConcurrentHashMap() else mutableMapOf()
|
||||
|
||||
fun place(position: BlockCoordinate, state: BlockState) {
|
||||
@ -16,14 +16,6 @@ class BlockLogTracker(private val mode: BlockTrackMode = BlockTrackMode.RemoveOn
|
||||
blocks.putAll(map)
|
||||
}
|
||||
|
||||
fun delete(position: BlockCoordinate) {
|
||||
if (mode == BlockTrackMode.AirOnDelete) {
|
||||
blocks[position] = BlockState.AirBlock
|
||||
} else {
|
||||
blocks.remove(position)
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateZeroBlockOffset(): BlockCoordinate {
|
||||
val (x, y, z) = blocks.keys.minOfAll(3) { listOf(it.x, it.y, it.z) }
|
||||
val xOffset = if (x < 0) x.absoluteValue else 0
|
||||
@ -60,11 +52,7 @@ class BlockLogTracker(private val mode: BlockTrackMode = BlockTrackMode.RemoveOn
|
||||
}
|
||||
|
||||
fun replay(changelog: BlockChangelog) = changelog.changes.forEach { change ->
|
||||
if (change.type == BlockChangeType.Break) {
|
||||
delete(change.location)
|
||||
} else {
|
||||
place(change.location, change.to)
|
||||
}
|
||||
place(change.location, change.state)
|
||||
}
|
||||
|
||||
fun get(position: BlockCoordinate): BlockState? = blocks[position]
|
||||
|
@ -8,7 +8,6 @@ import java.util.concurrent.ThreadPoolExecutor
|
||||
|
||||
class BlockMapRenderPool<T>(
|
||||
val changelog: BlockChangelog,
|
||||
val blockTrackMode: BlockTrackMode,
|
||||
val createRendererFunction: (BlockExpanse) -> BlockMapRenderer<T>,
|
||||
val delegate: BlockMapRenderPoolDelegate<T>,
|
||||
val threadPoolExecutor: ThreadPoolExecutor,
|
||||
@ -64,7 +63,7 @@ class BlockMapRenderPool<T>(
|
||||
private fun runPlaybackSlice(id: String, slice: ChangelogSlice) {
|
||||
val start = System.currentTimeMillis()
|
||||
val sliced = changelog.slice(slice)
|
||||
val tracker = BlockLogTracker(blockTrackMode)
|
||||
val tracker = BlockLogTracker()
|
||||
tracker.replay(sliced)
|
||||
if (tracker.isNotEmpty()) {
|
||||
trackers[slice] = tracker
|
||||
|
@ -21,7 +21,7 @@ class PlayerPositionChangelog(
|
||||
val pitch = row[PlayerPositionTable.z]
|
||||
val yaw = row[PlayerPositionTable.z]
|
||||
|
||||
PlayerPositionChange(time, player, world, x, y, z, pitch, yaw)
|
||||
PlayerPositionChange(time, player!!, world, x, y, z, pitch, yaw)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,9 @@ package gay.pizza.foundation.heimdall.tool.state
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
|
||||
data class BlockChange(
|
||||
data class RecordedBlockChange(
|
||||
val time: Instant,
|
||||
val world: UUID,
|
||||
val type: BlockChangeType,
|
||||
val location: BlockCoordinate,
|
||||
val from: BlockState,
|
||||
val to: BlockState
|
||||
val state: BlockState
|
||||
)
|
Loading…
Reference in New Issue
Block a user