mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-04 11:39:39 +00:00 
			
		
		
		
	Rewrite Heimdall block handling to support more event types and non-player block changes.
This commit is contained in:
		@ -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;
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user