diff --git a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/export/ExportedBlock.kt b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/export/ExportedBlock.kt index f668cb9..624808d 100644 --- a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/export/ExportedBlock.kt +++ b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/export/ExportedBlock.kt @@ -4,5 +4,6 @@ import kotlinx.serialization.Serializable @Serializable data class ExportedBlock( - val type: String + val type: String, + val data: String? = null ) diff --git a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockBreakTable.kt b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockBreakTable.kt index 415af20..f00266f 100644 --- a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockBreakTable.kt +++ b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockBreakTable.kt @@ -2,4 +2,5 @@ package gay.pizza.foundation.heimdall.table object BlockBreakTable : PlayerTimedLocalEventTable("block_breaks") { val block = text("block") + val blockData = text("block_data").nullable() } diff --git a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockPlaceTable.kt b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockPlaceTable.kt index 71712fd..539868f 100644 --- a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockPlaceTable.kt +++ b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/table/BlockPlaceTable.kt @@ -2,4 +2,5 @@ package gay.pizza.foundation.heimdall.table object BlockPlaceTable : PlayerTimedLocalEventTable("block_places") { val block = text("block") + val blockData = text("block_data").nullable() } diff --git a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/view/BlockChangeView.kt b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/view/BlockChangeView.kt index 02bcb35..bf95e85 100644 --- a/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/view/BlockChangeView.kt +++ b/common-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/view/BlockChangeView.kt @@ -5,4 +5,5 @@ 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() } diff --git a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockBreak.kt b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockBreak.kt index ca3057f..ede34b9 100644 --- a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockBreak.kt +++ b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockBreak.kt @@ -16,12 +16,14 @@ 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.type, + event.block.blockData.asString ) override fun store(transaction: Transaction) { @@ -29,6 +31,7 @@ class BlockBreak( BlockBreakTable.insert { putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity) it[block] = material.key.toString() + it[blockData] = this@BlockBreak.blockData } } } diff --git a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockPlace.kt b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockPlace.kt index c27c55c..a915b0f 100644 --- a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockPlace.kt +++ b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/event/BlockPlace.kt @@ -16,12 +16,14 @@ 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.type, + event.block.blockData.asString ) override fun store(transaction: Transaction) { @@ -29,6 +31,7 @@ class BlockPlace( BlockPlaceTable.insert { putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity) it[block] = material.key.toString() + it[blockData] = this@BlockPlace.blockData } } } diff --git a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/load/WorldReassembler.kt b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/load/WorldReassembler.kt index 65f3083..3caf325 100644 --- a/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/load/WorldReassembler.kt +++ b/foundation-heimdall/src/main/kotlin/gay/pizza/foundation/heimdall/plugin/load/WorldReassembler.kt @@ -1,5 +1,6 @@ package gay.pizza.foundation.heimdall.plugin.load +import gay.pizza.foundation.heimdall.export.ExportedBlock import gay.pizza.foundation.heimdall.load.WorldLoadFormat import gay.pizza.foundation.heimdall.load.WorldLoadWorld import org.bukkit.Location @@ -24,7 +25,7 @@ class WorldReassembler(val plugin: Plugin, val server: Server, val format: World continue } - val blocksToMake = mutableListOf>() + val blocksToMake = mutableListOf>() for ((x, zBlocks) in load.blocks) { for ((z, yBlocks) in zBlocks) { @@ -36,7 +37,7 @@ class WorldReassembler(val plugin: Plugin, val server: Server, val format: World continue } - blocksToMake.add(Location(world, x.toDouble(), y.toDouble(), z.toDouble()) to material) + blocksToMake.add(Location(world, x.toDouble(), y.toDouble(), z.toDouble()) to block) } } } @@ -50,9 +51,15 @@ class WorldReassembler(val plugin: Plugin, val server: Server, val format: World val copy = section.toList() val runnable = object : BukkitRunnable() { override fun run() { - for ((location, material) in copy) { + for ((location, blk) in copy) { val block = world.getBlockAt(location) - block.type = material + val blockData = if (blk.data != null) server.createBlockData(blk.data!!) else null + if (blockData != null) { + block.blockData = blockData + } else { + val material = Material.matchMaterial(blk.type)!! + block.type = material + } count.incrementAndGet() } feedback("Placed ${count.get()} blocks in ${world.name}") diff --git a/foundation-heimdall/src/main/resources/init.sql b/foundation-heimdall/src/main/resources/init.sql index aee8855..ac7888f 100644 --- a/foundation-heimdall/src/main/resources/init.sql +++ b/foundation-heimdall/src/main/resources/init.sql @@ -126,12 +126,6 @@ create table if not exists entity_kills ( -- select create_hypertable('entity_kills', 'time', 'player', 4, if_not_exists => TRUE); -- -create or replace view block_changes as - select true as break, * - from block_breaks - union all - select false as break, * from block_places; --- create or replace view player_names as with unique_player_ids as ( select distinct player @@ -145,3 +139,14 @@ create or replace view player_names as limit 1 ) 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; +-- diff --git a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/commands/GenerateWorldLoadFile.kt b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/commands/GenerateWorldLoadFile.kt index 6c67f6b..15ce2b2 100644 --- a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/commands/GenerateWorldLoadFile.kt +++ b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/commands/GenerateWorldLoadFile.kt @@ -33,7 +33,7 @@ class GenerateWorldLoadFile : CliktCommand(name = "generate-world-load", help = for ((id, changelog) in worldChangelogs) { val tracker = BlockLogTracker() tracker.replay(changelog) - val sparse = tracker.buildBlockMap { ExportedBlock(it.type) } + val sparse = tracker.buildBlockMap { ExportedBlock(it.type, it.data) } val blocks = sparse.blocks worlds[id.toString().lowercase()] = WorldLoadWorld( worldNames[id] ?: "unknown_$id", diff --git a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/export/ChunkExportLoader.kt b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/export/ChunkExportLoader.kt index 5c327ce..3d189ab 100644 --- a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/export/ChunkExportLoader.kt +++ b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/export/ChunkExportLoader.kt @@ -47,7 +47,7 @@ class ChunkExportLoader( } val coordinate = BlockCoordinate(x.toLong(), y.toLong(), z.toLong()) - val state = BlockState.cached(block.type) + val state = BlockState(block.type, block.data) map?.put(coordinate, state) if (allBlocks != null) { allBlocks[coordinate] = state diff --git a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockChangelog.kt b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockChangelog.kt index aa62050..828c06d 100644 --- a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockChangelog.kt +++ b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockChangelog.kt @@ -68,10 +68,11 @@ class BlockChangelog( val y = row[BlockChangeView.y] val z = row[BlockChangeView.z] val block = row[BlockChangeView.block] + val blockData = row[BlockChangeView.blockData] val location = BlockCoordinate(x.toLong(), y.toLong(), z.toLong()) val fromBlock = if (changeIsBreak) { - BlockState.cached(block) + BlockState(block, blockData) } else { BlockState.AirBlock } @@ -79,7 +80,7 @@ class BlockChangelog( val toBlock = if (changeIsBreak) { BlockState.AirBlock } else { - BlockState.cached(block) + BlockState(block, blockData) } BlockChange( diff --git a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockState.kt b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockState.kt index 2e70146..e2e7520 100644 --- a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockState.kt +++ b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockState.kt @@ -1,15 +1,13 @@ package gay.pizza.foundation.heimdall.tool.state -import java.util.concurrent.ConcurrentHashMap import kotlinx.serialization.Serializable -@Serializable(BlockStateSerializer::class) -data class BlockState(val type: String) { +@Serializable +data class BlockState( + val type: String, + val data: String? = null +) { companion object { - private val cache = ConcurrentHashMap() - - val AirBlock: BlockState = cached("minecraft:air") - - fun cached(type: String): BlockState = cache.computeIfAbsent(type) { BlockState(type) } + val AirBlock: BlockState = BlockState("minecraft:air") } } diff --git a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockStateSerializer.kt b/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockStateSerializer.kt deleted file mode 100644 index 255174e..0000000 --- a/tool-gjallarhorn/src/main/kotlin/gay/pizza/foundation/heimdall/tool/state/BlockStateSerializer.kt +++ /dev/null @@ -1,20 +0,0 @@ -package gay.pizza.foundation.heimdall.tool.state - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -class BlockStateSerializer : KSerializer { - override val descriptor: SerialDescriptor - get() = String.serializer().descriptor - - override fun deserialize(decoder: Decoder): BlockState { - return BlockState.cached(decoder.decodeString()) - } - - override fun serialize(encoder: Encoder, value: BlockState) { - encoder.encodeString(value.type) - } -}