Rewrite Heimdall block handling to support more event types and non-player block changes.

This commit is contained in:
2023-02-07 23:41:22 -05:00
parent 688106a6e6
commit e0823f7b15
19 changed files with 228 additions and 218 deletions

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -2,8 +2,7 @@ package gay.pizza.foundation.heimdall.plugin.event
object EventCollectorProviders {
val all = listOf<EventCollectorProvider<*>>(
BlockBreak,
BlockPlace,
BlockChange,
EntityKill,
PlayerAdvancement,
PlayerDeath,

View File

@ -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

View File

@ -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;
--