Heimdall: Block Place and Break Tracking

This commit is contained in:
Kenneth Endfinger 2021-12-24 01:32:40 -05:00
parent 847f46273b
commit 9952c4c427
No known key found for this signature in database
GPG Key ID: C4E68E5647420E10
8 changed files with 141 additions and 7 deletions

View File

@ -1,5 +1,7 @@
package cloud.kubelet.foundation.heimdall
import org.bukkit.Material
fun String.sqlSplitStatements(): List<String> {
val statements = mutableListOf<String>()
val buffer = StringBuilder()
@ -19,3 +21,6 @@ fun String.sqlSplitStatements(): List<String> {
flush()
return statements
}
val Material.storageBlockName: String
get() = "${key.namespace}:${key.key}"

View File

@ -4,22 +4,23 @@ import cloud.kubelet.foundation.core.FoundationCorePlugin
import cloud.kubelet.foundation.core.Util
import cloud.kubelet.foundation.heimdall.buffer.BufferFlushThread
import cloud.kubelet.foundation.heimdall.buffer.EventBuffer
import cloud.kubelet.foundation.heimdall.event.PlayerPositionEvent
import cloud.kubelet.foundation.heimdall.event.BlockBreak
import cloud.kubelet.foundation.heimdall.event.BlockPlace
import cloud.kubelet.foundation.heimdall.event.PlayerPosition
import cloud.kubelet.foundation.heimdall.model.HeimdallConfig
import cloud.kubelet.foundation.heimdall.table.PlayerPositionTable
import com.charleskorn.kaml.Yaml
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.BlockBreakEvent
import org.bukkit.event.block.BlockPlaceEvent
import org.bukkit.event.entity.EntityDeathEvent
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.plugin.java.JavaPlugin
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.transactions.transaction
import org.postgresql.Driver
import java.lang.Exception
import java.time.Instant
import kotlin.io.path.inputStream
class FoundationHeimdallPlugin : JavaPlugin(), Listener {
@ -82,7 +83,13 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
}
@EventHandler
fun onPlayerMove(event: PlayerMoveEvent) = buffer.push(PlayerPositionEvent(event))
fun onPlayerMove(event: PlayerMoveEvent) = buffer.push(PlayerPosition(event))
@EventHandler
fun onBlockBroken(event: BlockPlaceEvent) = buffer.push(BlockPlace(event))
@EventHandler
fun onBlockBroken(event: BlockBreakEvent) = buffer.push(BlockBreak(event))
override fun onDisable() {
bufferFlushThread.stop()

View File

@ -0,0 +1,35 @@
package cloud.kubelet.foundation.heimdall.event
import cloud.kubelet.foundation.heimdall.storageBlockName
import cloud.kubelet.foundation.heimdall.table.BlockBreakTable
import cloud.kubelet.foundation.heimdall.table.PlayerPositionTable
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.event.block.BlockBreakEvent
import org.bukkit.event.player.PlayerMoveEvent
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
) : HeimdallEvent() {
constructor(event: BlockBreakEvent) : this(event.player.uniqueId, event.block.location, event.block.type)
override fun store(transaction: Transaction) {
transaction.apply {
BlockBreakTable.insert {
it[time] = Instant.now()
it[player] = playerUniqueIdentity
it[world] = location.world.uid
it[block] = material.storageBlockName
it[x] = location.x
it[y] = location.y
it[z] = location.z
}
}
}
}

View File

@ -0,0 +1,33 @@
package cloud.kubelet.foundation.heimdall.event
import cloud.kubelet.foundation.heimdall.storageBlockName
import cloud.kubelet.foundation.heimdall.table.BlockPlaceTable
import org.bukkit.Location
import org.bukkit.Material
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
) : HeimdallEvent() {
constructor(event: BlockPlaceEvent) : this(event.player.uniqueId, event.block.location, event.block.type)
override fun store(transaction: Transaction) {
transaction.apply {
BlockPlaceTable.insert {
it[time] = Instant.now()
it[player] = playerUniqueIdentity
it[world] = location.world.uid
it[block] = material.storageBlockName
it[x] = location.x
it[y] = location.y
it[z] = location.z
}
}
}
}

View File

@ -8,7 +8,7 @@ import org.jetbrains.exposed.sql.insert
import java.time.Instant
import java.util.*
class PlayerPositionEvent(
class PlayerPosition(
val playerUniqueIdentity: UUID,
val location: Location
) : HeimdallEvent() {

View File

@ -0,0 +1,14 @@
package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.javatime.timestamp
object BlockBreakTable : Table("block_breaks") {
val time = timestamp("time")
val world = uuid("world")
val player = uuid("player")
val block = text("block")
val x = double("x")
val y = double("y")
val z = double("z")
}

View File

@ -0,0 +1,14 @@
package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.javatime.timestamp
object BlockPlaceTable : Table("block_places") {
val time = timestamp("time")
val world = uuid("world")
val player = uuid("player")
val block = text("block")
val x = double("x")
val y = double("y")
val z = double("z")
}

View File

@ -18,3 +18,29 @@ create table if not exists heimdall.player_positions (
);
--
select create_hypertable('heimdall.player_positions', 'time', 'player', 4, if_not_exists => TRUE);
--
create table if not exists heimdall.block_breaks (
time timestamp not null,
player uuid not null,
world uuid not null,
block text not null,
x double precision not null,
y double precision not null,
z double precision not null,
PRIMARY KEY (time, player, world)
);
--
select create_hypertable('heimdall.block_breaks', 'time', 'player', 4, if_not_exists => TRUE);
--
create table if not exists heimdall.block_places (
time timestamp not null,
player uuid not null,
world uuid not null,
block text not null,
x double precision not null,
y double precision not null,
z double precision not null,
PRIMARY KEY (time, player, world)
);
--
select create_hypertable('heimdall.block_places', 'time', 'player', 4, if_not_exists => TRUE);