mirror of
https://github.com/GayPizzaSpecifications/foundation.git
synced 2025-08-02 21:20:55 +00:00
heimdall: implement precise block change collector
This commit is contained in:
parent
eaa3888821
commit
ef822f9217
@ -4,4 +4,5 @@ object BlockChangeTable : PlayerTimedLocalEventTable("block_changes") {
|
||||
val block = text("block")
|
||||
val data = text("data")
|
||||
val cause = text("cause")
|
||||
val inc = integer("inc")
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
|
||||
private val buffer = EventBuffer()
|
||||
private val bufferFlushThread = BufferFlushThread(this, buffer)
|
||||
|
||||
private val collectors = mutableListOf<EventCollector<*>>()
|
||||
val collectors = mutableListOf<EventCollector<*>>()
|
||||
|
||||
override fun onEnable() {
|
||||
val exportChunksCommand = getCommand("export_all_chunks") ?:
|
||||
@ -48,10 +48,10 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
|
||||
)
|
||||
config = Yaml.default.decodeFromStream(HeimdallConfig.serializer(), configPath.inputStream())
|
||||
if (!config.enabled) {
|
||||
slF4JLogger.info("Heimdall is not enabled.")
|
||||
slF4JLogger.info("Heimdall tracking is not enabled.")
|
||||
return
|
||||
}
|
||||
slF4JLogger.info("Heimdall is enabled.")
|
||||
slF4JLogger.info("Heimdall tracking is enabled.")
|
||||
if (!Driver.isRegistered()) {
|
||||
Driver.register()
|
||||
}
|
||||
@ -91,7 +91,7 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
|
||||
bufferFlushThread.start()
|
||||
|
||||
for (collectorProvider in EventCollectorProviders.all) {
|
||||
val collector = collectorProvider.collector(buffer)
|
||||
val collector = collectorProvider.collector(config, buffer)
|
||||
server.pluginManager.registerEvents(collector, this)
|
||||
collectors.add(collector)
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ class BufferFlushThread(val plugin: FoundationHeimdallPlugin, val buffer: EventB
|
||||
fun start() {
|
||||
running.set(true)
|
||||
val thread = Thread {
|
||||
plugin.slF4JLogger.info("Buffer Flusher Started")
|
||||
plugin.slF4JLogger.info("Buffer flusher started.")
|
||||
while (running.get()) {
|
||||
flush()
|
||||
Thread.sleep(5000)
|
||||
}
|
||||
plugin.slF4JLogger.info("Buffer Flusher Stopped")
|
||||
plugin.slF4JLogger.info("Buffer flusher stopped.")
|
||||
}
|
||||
thread.name = "Heimdall Buffer Flush"
|
||||
thread.isDaemon = false
|
||||
@ -31,6 +31,10 @@ class BufferFlushThread(val plugin: FoundationHeimdallPlugin, val buffer: EventB
|
||||
|
||||
fun flush() {
|
||||
try {
|
||||
for (collector in plugin.collectors) {
|
||||
collector.beforeBufferFlush()
|
||||
}
|
||||
|
||||
val db = plugin.db
|
||||
if (db == null) {
|
||||
buffer.clear()
|
||||
@ -39,7 +43,7 @@ class BufferFlushThread(val plugin: FoundationHeimdallPlugin, val buffer: EventB
|
||||
transaction(plugin.db) {
|
||||
val count = buffer.flush(this)
|
||||
if (count > 0) {
|
||||
plugin.slF4JLogger.debug("Flushed $count Events")
|
||||
plugin.slF4JLogger.debug("Flushed $count events.")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -12,7 +12,7 @@ class EventBuffer : IEventBuffer {
|
||||
var count = 0L
|
||||
while (referenceOfEvents.isNotEmpty()) {
|
||||
val event = referenceOfEvents.removeAt(0)
|
||||
event.store(transaction)
|
||||
event.store(transaction, count.toInt())
|
||||
count++
|
||||
}
|
||||
return count
|
||||
@ -22,6 +22,10 @@ class EventBuffer : IEventBuffer {
|
||||
events.add(event)
|
||||
}
|
||||
|
||||
override fun pushAll(events: List<HeimdallEvent>) {
|
||||
this.events.addAll(events)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
events = mutableListOf()
|
||||
}
|
||||
|
@ -4,4 +4,5 @@ import gay.pizza.foundation.heimdall.plugin.event.HeimdallEvent
|
||||
|
||||
interface IEventBuffer {
|
||||
fun push(event: HeimdallEvent)
|
||||
fun pushAll(events: List<HeimdallEvent>)
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.IEventBuffer
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.block.*
|
||||
|
||||
class AccurateBlockChangeCollector(val buffer: IEventBuffer) : EventCollector<BlockChange> {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockPlaced(event: BlockPlaceEvent) =
|
||||
buffer.push(BlockChangeConversions.blockPlace(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockBreak(event: BlockBreakEvent) =
|
||||
buffer.push(BlockChangeConversions.blockBreak(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockExplode(event: BlockExplodeEvent) =
|
||||
buffer.pushAll(BlockChangeConversions.blockExplode(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockBurn(event: BlockBurnEvent) =
|
||||
buffer.push(BlockChangeConversions.blockBurn(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockDamage(event: BlockDamageEvent) =
|
||||
buffer.push(BlockChangeConversions.blockDamage(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockForm(event: BlockFormEvent) =
|
||||
buffer.push(BlockChangeConversions.blockForm(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockGrow(event: BlockGrowEvent) =
|
||||
buffer.push(BlockChangeConversions.blockGrow(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockFade(event: BlockFadeEvent) =
|
||||
buffer.push(BlockChangeConversions.blockFade(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockIgnite(event: BlockIgniteEvent) =
|
||||
buffer.push(BlockChangeConversions.blockIgnite(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockSpread(event: BlockSpreadEvent) =
|
||||
buffer.push(BlockChangeConversions.blockSpread(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onFluidLevelChange(event: FluidLevelChangeEvent) =
|
||||
buffer.push(BlockChangeConversions.fluidLevelChange(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onSpongeAbsorb(event: SpongeAbsorbEvent) =
|
||||
buffer.pushAll(BlockChangeConversions.spongeAbsorb(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onSignChange(event: SignChangeEvent) =
|
||||
buffer.push(BlockChangeConversions.signChange(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onMoistureChange(event: MoistureChangeEvent) =
|
||||
buffer.push(BlockChangeConversions.moistureChange(event))
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockCook(event: BlockCookEvent) =
|
||||
buffer.push(BlockChangeConversions.blockCook(event))
|
||||
}
|
@ -1,26 +1,14 @@
|
||||
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.plugin.model.HeimdallConfig
|
||||
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.block.BlockState
|
||||
import org.bukkit.block.data.BlockData
|
||||
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
|
||||
@ -39,19 +27,25 @@ class BlockChange(
|
||||
isBreak: Boolean = false,
|
||||
cause: String,
|
||||
event: BlockEvent,
|
||||
block: Block = event.block
|
||||
block: Block = event.block,
|
||||
state: BlockState = block.state,
|
||||
data: BlockData = state.blockData
|
||||
) : 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
|
||||
location = block.location.clone(),
|
||||
material = if (isBreak) Material.AIR else data.material,
|
||||
blockData =
|
||||
if (isBreak)
|
||||
Material.AIR.createBlockData().asString
|
||||
else
|
||||
data.asString
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
BlockChangeTable.insert {
|
||||
it[inc] = index
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
it[block] = material.key.toString()
|
||||
it[data] = this@BlockChange.blockData
|
||||
@ -60,123 +54,12 @@ class BlockChange(
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<BlockChange> =
|
||||
if (config.blockChangePrecise) {
|
||||
PreciseBlockChangeCollector(config, buffer)
|
||||
} else {
|
||||
AccurateBlockChangeCollector(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,143 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import org.bukkit.event.block.*
|
||||
|
||||
object BlockChangeConversions {
|
||||
fun blockPlace(event: BlockPlaceEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player.uniqueId,
|
||||
isBreak = false,
|
||||
cause = "place",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun blockBreak(event: BlockBreakEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player.uniqueId,
|
||||
isBreak = true,
|
||||
cause = "break",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun blockExplode(event: BlockExplodeEvent): List<BlockChange> =
|
||||
mutableListOf<BlockChange>().apply {
|
||||
addAll(event.blockList().map { block ->
|
||||
BlockChange(
|
||||
cause = "explode",
|
||||
event = event,
|
||||
block = block,
|
||||
isBreak = true
|
||||
)
|
||||
})
|
||||
|
||||
add(BlockChange(
|
||||
cause = "exploded",
|
||||
event = event,
|
||||
block = event.block,
|
||||
isBreak = true
|
||||
))
|
||||
}
|
||||
|
||||
fun blockBurn(event: BlockBurnEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
isBreak = true,
|
||||
cause = "burn",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun blockDamage(event: BlockDamageEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "damage",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun blockForm(event: BlockFormEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "form",
|
||||
event = event,
|
||||
state = event.newState
|
||||
)
|
||||
|
||||
fun blockGrow(event: BlockGrowEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "grow",
|
||||
event = event,
|
||||
state = event.newState
|
||||
)
|
||||
|
||||
fun blockFade(event: BlockFadeEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "fade",
|
||||
event = event,
|
||||
state = event.newState
|
||||
)
|
||||
|
||||
fun blockIgnite(event: BlockIgniteEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player?.uniqueId,
|
||||
cause = "ignite",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun blockSpread(event: BlockSpreadEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "spread",
|
||||
event = event,
|
||||
state = event.newState
|
||||
)
|
||||
|
||||
fun fluidLevelChange(event: FluidLevelChangeEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
cause = "fluid-level-change",
|
||||
event = event,
|
||||
data = event.newData
|
||||
)
|
||||
|
||||
fun signChange(event: SignChangeEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = event.player.uniqueId,
|
||||
cause = "sign-change",
|
||||
event = event
|
||||
)
|
||||
|
||||
fun spongeAbsorb(event: SpongeAbsorbEvent): List<BlockChange> =
|
||||
event.blocks.map { block ->
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "sponge-absorb",
|
||||
block = block.block,
|
||||
state = block
|
||||
)
|
||||
}
|
||||
|
||||
fun moistureChange(event: MoistureChangeEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "moisture-change",
|
||||
state = event.newState
|
||||
)
|
||||
|
||||
fun blockCook(event: BlockCookEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
cause = "cook"
|
||||
)
|
||||
|
||||
fun physics(event: BlockPhysicsEvent): BlockChange =
|
||||
BlockChange(
|
||||
playerUniqueIdentity = null,
|
||||
event = event,
|
||||
data = event.changedBlockData,
|
||||
cause = "physics"
|
||||
)
|
||||
}
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.EntityKillTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.event.EventHandler
|
||||
@ -18,7 +19,7 @@ class EntityKill(
|
||||
val entityTypeName: String,
|
||||
val timestamp: Instant = Instant.now()
|
||||
) : HeimdallEvent() {
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
EntityKillTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
@ -35,7 +36,7 @@ class EntityKill(
|
||||
buffer.push(
|
||||
EntityKill(
|
||||
killer.uniqueId,
|
||||
killer.location,
|
||||
killer.location.clone(),
|
||||
event.entity.uniqueId,
|
||||
event.entityType.key.toString()
|
||||
)
|
||||
@ -44,6 +45,6 @@ class EntityKill(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<EntityKill> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<EntityKill> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<EntityKill> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,6 @@ import org.bukkit.Server
|
||||
import org.bukkit.event.Listener
|
||||
|
||||
interface EventCollector<T : HeimdallEvent> : Listener {
|
||||
fun beforeBufferFlush() {}
|
||||
fun onPluginDisable(server: Server) {}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
|
||||
import gay.pizza.foundation.heimdall.plugin.model.HeimdallConfig
|
||||
|
||||
interface EventCollectorProvider<T : HeimdallEvent> {
|
||||
fun collector(buffer: EventBuffer): EventCollector<T>
|
||||
fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<T>
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ package gay.pizza.foundation.heimdall.plugin.event
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
|
||||
abstract class HeimdallEvent {
|
||||
abstract fun store(transaction: Transaction)
|
||||
abstract fun store(transaction: Transaction, index: Int)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.PlayerAdvancementTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.advancement.Advancement
|
||||
@ -20,11 +21,11 @@ class PlayerAdvancement(
|
||||
) : HeimdallEvent() {
|
||||
constructor(event: PlayerAdvancementDoneEvent) : this(
|
||||
event.player.uniqueId,
|
||||
event.player.location,
|
||||
event.player.location.clone(),
|
||||
event.advancement
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
PlayerAdvancementTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
@ -39,6 +40,6 @@ class PlayerAdvancement(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<PlayerAdvancement> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<PlayerAdvancement> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<PlayerAdvancement> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.PlayerDeathTable
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
|
||||
import org.bukkit.Location
|
||||
@ -21,12 +22,12 @@ class PlayerDeath(
|
||||
) : HeimdallEvent() {
|
||||
constructor(event: PlayerDeathEvent, deathMessage: String? = null) : this(
|
||||
event.player.uniqueId,
|
||||
event.player.location,
|
||||
event.player.location.clone(),
|
||||
event.player.exp,
|
||||
deathMessage
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
PlayerDeathTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
@ -52,6 +53,6 @@ class PlayerDeath(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<PlayerDeath> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<PlayerDeath> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<PlayerDeath> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.PlayerPositionTable
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.event.EventHandler
|
||||
@ -18,10 +19,10 @@ class PlayerPosition(
|
||||
) : HeimdallEvent() {
|
||||
constructor(event: PlayerMoveEvent) : this(
|
||||
event.player.uniqueId,
|
||||
event.to
|
||||
event.to.clone()
|
||||
)
|
||||
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
PlayerPositionTable.insert {
|
||||
putPlayerTimedLocalEvent(it, timestamp, location, playerUniqueIdentity)
|
||||
@ -35,6 +36,6 @@ class PlayerPosition(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<PlayerPosition> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<PlayerPosition> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<PlayerPosition> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.PlayerSessionTable
|
||||
import org.bukkit.Server
|
||||
import org.bukkit.event.EventHandler
|
||||
@ -19,7 +20,7 @@ class PlayerSession(
|
||||
val startTimeInstant: Instant,
|
||||
val endTimeInstant: Instant
|
||||
) : HeimdallEvent() {
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
PlayerSessionTable.insert {
|
||||
it[id] = UUID.randomUUID()
|
||||
@ -61,6 +62,6 @@ class PlayerSession(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<PlayerSession> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<PlayerSession> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<PlayerSession> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package gay.pizza.foundation.heimdall.plugin.event
|
||||
|
||||
import gay.pizza.foundation.heimdall.plugin.buffer.IEventBuffer
|
||||
import gay.pizza.foundation.heimdall.plugin.model.HeimdallConfig
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.block.BlockPhysicsEvent
|
||||
|
||||
class PreciseBlockChangeCollector(val config: HeimdallConfig, val buffer: IEventBuffer) : EventCollector<BlockChange> {
|
||||
private var changes = mutableMapOf<String, BlockChange>()
|
||||
|
||||
override fun beforeBufferFlush() {
|
||||
if (config.blockChangePreciseImmediate) {
|
||||
return
|
||||
}
|
||||
val changesToInsert = changes
|
||||
changes = mutableMapOf()
|
||||
buffer.pushAll(changesToInsert.values.toList())
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onBlockPhysics(event: BlockPhysicsEvent) {
|
||||
val change = BlockChangeConversions.physics(event)
|
||||
if (config.blockChangePreciseImmediate) {
|
||||
buffer.push(change)
|
||||
return
|
||||
}
|
||||
changes[(event.sourceBlock.location.world.name to listOf(
|
||||
event.sourceBlock.location.x.toLong(),
|
||||
event.sourceBlock.location.y.toLong(),
|
||||
event.sourceBlock.location.z.toLong()
|
||||
)).toString()] = change
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ 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.plugin.model.HeimdallConfig
|
||||
import gay.pizza.foundation.heimdall.table.WorldChangeTable
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent
|
||||
@ -18,7 +19,7 @@ class WorldChange(
|
||||
val toWorldActualName: String,
|
||||
val timestamp: Instant = Instant.now()
|
||||
) : HeimdallEvent() {
|
||||
override fun store(transaction: Transaction) {
|
||||
override fun store(transaction: Transaction, index: Int) {
|
||||
transaction.apply {
|
||||
WorldChangeTable.insert {
|
||||
putTimedEvent(it, timestamp)
|
||||
@ -45,6 +46,6 @@ class WorldChange(
|
||||
}
|
||||
|
||||
companion object : EventCollectorProvider<WorldChange> {
|
||||
override fun collector(buffer: EventBuffer): EventCollector<WorldChange> = Collector(buffer)
|
||||
override fun collector(config: HeimdallConfig, buffer: EventBuffer): EventCollector<WorldChange> = Collector(buffer)
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ import kotlinx.serialization.Serializable
|
||||
@Serializable
|
||||
data class HeimdallConfig(
|
||||
val enabled: Boolean = false,
|
||||
val db: DbConfig
|
||||
val db: DbConfig,
|
||||
val blockChangePrecise: Boolean = false,
|
||||
val blockChangePreciseImmediate: Boolean = false
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
@ -1,6 +1,16 @@
|
||||
# Whether Heimdall should be enabled for tracking events.
|
||||
enabled: false
|
||||
|
||||
# Whether the block change events should be precise.
|
||||
# Detail of the cause will be lost but all block updates
|
||||
# will be captured utilizing physics recording.
|
||||
blockChangePrecise: false
|
||||
|
||||
# Whether the precise block change collector should
|
||||
# immediately insert changes to the buffer. This is not
|
||||
# recommended as this may cause large insert operations.
|
||||
blockChangePreciseImmediate: false
|
||||
|
||||
# Database connection information.
|
||||
db:
|
||||
# JDBC URL
|
||||
|
@ -28,6 +28,7 @@ select add_compression_policy('player_positions', interval '3 days', if_not_exis
|
||||
--
|
||||
create table if not exists block_changes (
|
||||
time timestamp not null,
|
||||
inc int not null,
|
||||
player uuid null,
|
||||
world uuid not null,
|
||||
x double precision not null,
|
||||
@ -38,10 +39,10 @@ create table if not exists block_changes (
|
||||
block text not null,
|
||||
data text not null,
|
||||
cause text not null,
|
||||
PRIMARY KEY (time, world, x, y, z)
|
||||
PRIMARY KEY (time, inc)
|
||||
);
|
||||
--
|
||||
select create_hypertable('block_changes', 'time', 'x', 4, if_not_exists => TRUE);
|
||||
select create_hypertable('block_changes', 'time', 'inc', 4, if_not_exists => TRUE);
|
||||
--
|
||||
create table if not exists player_sessions (
|
||||
id uuid not null,
|
||||
|
Loading…
Reference in New Issue
Block a user