Reform Heimdall to move event collectors to the event class themselves.

This commit is contained in:
2023-02-07 19:51:25 -05:00
parent 0fe76a73f9
commit 760b77364a
15 changed files with 210 additions and 91 deletions

View File

@ -4,29 +4,20 @@ import com.charleskorn.kaml.Yaml
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import gay.pizza.foundation.common.FoundationCoreLoader
import gay.pizza.foundation.shared.PluginMainClass
import gay.pizza.foundation.shared.copyDefaultConfig
import gay.pizza.foundation.heimdall.plugin.buffer.BufferFlushThread
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
import gay.pizza.foundation.heimdall.plugin.event.*
import gay.pizza.foundation.heimdall.plugin.event.EventCollector
import gay.pizza.foundation.heimdall.plugin.event.EventCollectorProviders
import gay.pizza.foundation.heimdall.plugin.export.ExportAllChunksCommand
import gay.pizza.foundation.heimdall.plugin.load.ImportWorldLoadCommand
import gay.pizza.foundation.heimdall.plugin.model.HeimdallConfig
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.event.EventHandler
import gay.pizza.foundation.shared.PluginMainClass
import gay.pizza.foundation.shared.copyDefaultConfig
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.entity.PlayerDeathEvent
import org.bukkit.event.player.*
import org.bukkit.plugin.java.JavaPlugin
import org.jetbrains.exposed.sql.Database
import org.postgresql.Driver
import java.time.Duration
import java.time.Instant
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.io.path.inputStream
@PluginMainClass
@ -38,15 +29,15 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
private val buffer = EventBuffer()
private val bufferFlushThread = BufferFlushThread(this, buffer)
private val playerJoinTimes = ConcurrentHashMap<UUID, Instant>()
private val legacyComponentSerializer = LegacyComponentSerializer.builder().build()
private val collectors = mutableListOf<EventCollector<*>>()
override fun onEnable() {
val exportChunksCommand = getCommand("export_all_chunks") ?: throw Exception("Failed to get export_all_chunks command")
val exportChunksCommand = getCommand("export_all_chunks") ?:
throw Exception("Failed to get export_all_chunks command")
exportChunksCommand.setExecutor(ExportAllChunksCommand(this))
val importWorldLoadCommand = getCommand("import_world_load") ?: throw Exception("Failed to get import_world_load command")
val importWorldLoadCommand = getCommand("import_world_load") ?:
throw Exception("Failed to get import_world_load command")
importWorldLoadCommand.setExecutor(ImportWorldLoadCommand(this))
val foundation = FoundationCoreLoader.get(server)
@ -98,79 +89,20 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
db = Database.connect(pool)
server.pluginManager.registerEvents(this, this)
bufferFlushThread.start()
}
@EventHandler
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))
@EventHandler
fun onPlayerJoin(event: PlayerJoinEvent) {
playerJoinTimes[event.player.uniqueId] = Instant.now()
}
@EventHandler
fun onPlayerQuit(event: PlayerQuitEvent) {
val startTime = playerJoinTimes.remove(event.player.uniqueId) ?: return
val endTime = Instant.now()
buffer.push(PlayerSession(event.player.uniqueId, event.player.name, startTime, endTime))
}
@EventHandler
fun onPlayerDeath(event: PlayerDeathEvent) {
val deathMessage = event.deathMessage()
val deathMessageString = if (deathMessage != null) {
legacyComponentSerializer.serialize(deathMessage)
} else {
null
for (collectorProvider in EventCollectorProviders.all) {
val collector = collectorProvider.collector(buffer)
server.pluginManager.registerEvents(collector, this)
collectors.add(collector)
}
buffer.push(PlayerDeath(event, deathMessageString))
}
@EventHandler
fun onPlayerAdvancementDone(event: PlayerAdvancementDoneEvent) = buffer.push(PlayerAdvancement(event))
@EventHandler
fun onWorldLoad(event: PlayerChangedWorldEvent) = buffer.push(
WorldChange(
event.player.uniqueId,
event.from.uid,
event.from.name,
event.player.world.uid,
event.player.world.name
)
)
@EventHandler
fun onEntityDeath(event: EntityDeathEvent) {
val killer = event.entity.killer ?: return
buffer.push(
EntityKill(
killer.uniqueId,
killer.location,
event.entity.uniqueId,
event.entityType.key.toString()
)
)
}
override fun onDisable() {
bufferFlushThread.stop()
val endTime = Instant.now()
for (playerId in playerJoinTimes.keys().toList()) {
val startTime = playerJoinTimes.remove(playerId) ?: continue
buffer.push(PlayerSession(
playerId,
server.getPlayer(playerId)?.name ?: "__unknown__",
startTime,
endTime
))
for (collector in collectors) {
collector.onPluginDisable(server)
}
collectors.clear()
bufferFlushThread.flush()
}
}

View File

@ -3,7 +3,7 @@ package gay.pizza.foundation.heimdall.plugin.buffer
import gay.pizza.foundation.heimdall.plugin.event.HeimdallEvent
import org.jetbrains.exposed.sql.Transaction
class EventBuffer {
class EventBuffer : IEventBuffer {
private var events = mutableListOf<HeimdallEvent>()
fun flush(transaction: Transaction): Long {
@ -18,7 +18,7 @@ class EventBuffer {
return count
}
fun push(event: HeimdallEvent) {
override fun push(event: HeimdallEvent) {
events.add(event)
}

View File

@ -0,0 +1,7 @@
package gay.pizza.foundation.heimdall.plugin.buffer
import gay.pizza.foundation.heimdall.plugin.event.HeimdallEvent
interface IEventBuffer {
fun push(event: HeimdallEvent)
}

View File

@ -1,8 +1,11 @@
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
@ -29,4 +32,13 @@ class BlockBreak(
}
}
}
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

@ -1,8 +1,11 @@
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
@ -29,4 +32,13 @@ class BlockPlace(
}
}
}
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

@ -1,7 +1,11 @@
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.EntityKillTable
import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.entity.EntityDeathEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
import java.time.Instant
@ -23,4 +27,23 @@ class EntityKill(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<EntityKill> {
@EventHandler
fun onEntityDeath(event: EntityDeathEvent) {
val killer = event.entity.killer ?: return
buffer.push(
EntityKill(
killer.uniqueId,
killer.location,
event.entity.uniqueId,
event.entityType.key.toString()
)
)
}
}
companion object : EventCollectorProvider<EntityKill> {
override fun collector(buffer: EventBuffer): EventCollector<EntityKill> = Collector(buffer)
}
}

View File

@ -0,0 +1,8 @@
package gay.pizza.foundation.heimdall.plugin.event
import org.bukkit.Server
import org.bukkit.event.Listener
interface EventCollector<T : HeimdallEvent> : Listener {
fun onPluginDisable(server: Server) {}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.foundation.heimdall.plugin.event
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer
interface EventCollectorProvider<T : HeimdallEvent> {
fun collector(buffer: EventBuffer): EventCollector<T>
}

View File

@ -0,0 +1,14 @@
package gay.pizza.foundation.heimdall.plugin.event
object EventCollectorProviders {
val all = listOf<EventCollectorProvider<*>>(
BlockBreak,
BlockPlace,
EntityKill,
PlayerAdvancement,
PlayerDeath,
PlayerPosition,
PlayerSession,
WorldChange
)
}

View File

@ -30,11 +30,7 @@ fun <T : PlayerTimedLocalEventTable, K : Any> T.putPlayerTimedLocalEvent(
location: Location,
player: UUID
) {
statement[this.time] = time
statement[this.world] = location.world.uid
statement[this.x] = location.x
statement[this.y] = location.y
statement[this.z] = location.z
putTimedLocalEvent(statement, time, location)
statement[this.player] = player
statement[this.pitch] = location.pitch.toDouble()
statement[this.yaw] = location.yaw.toDouble()

View File

@ -1,8 +1,11 @@
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.PlayerAdvancementTable
import org.bukkit.Location
import org.bukkit.advancement.Advancement
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerAdvancementDoneEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
@ -29,4 +32,13 @@ class PlayerAdvancement(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<PlayerAdvancement> {
@EventHandler
fun onPlayerAdvancementDone(event: PlayerAdvancementDoneEvent) = buffer.push(PlayerAdvancement(event))
}
companion object : EventCollectorProvider<PlayerAdvancement> {
override fun collector(buffer: EventBuffer): EventCollector<PlayerAdvancement> = Collector(buffer)
}
}

View File

@ -1,7 +1,11 @@
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.PlayerDeathTable
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.entity.PlayerDeathEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
@ -31,4 +35,23 @@ class PlayerDeath(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<PlayerDeath> {
private val legacyComponentSerializer = LegacyComponentSerializer.builder().build()
@EventHandler
fun onPlayerDeath(event: PlayerDeathEvent) {
val deathMessage = event.deathMessage()
val deathMessageString = if (deathMessage != null) {
legacyComponentSerializer.serialize(deathMessage)
} else {
null
}
buffer.push(PlayerDeath(event, deathMessageString))
}
}
companion object : EventCollectorProvider<PlayerDeath> {
override fun collector(buffer: EventBuffer): EventCollector<PlayerDeath> = Collector(buffer)
}
}

View File

@ -1,7 +1,10 @@
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.PlayerPositionTable
import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerMoveEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
@ -25,4 +28,13 @@ class PlayerPosition(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<PlayerPosition> {
@EventHandler
fun onPlayerMove(event: PlayerMoveEvent) = buffer.push(PlayerPosition(event))
}
companion object : EventCollectorProvider<PlayerPosition> {
override fun collector(buffer: EventBuffer): EventCollector<PlayerPosition> = Collector(buffer)
}
}

View File

@ -1,10 +1,17 @@
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.PlayerSessionTable
import org.bukkit.Server
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
import java.time.Instant
import java.util.*
import java.util.concurrent.ConcurrentHashMap
class PlayerSession(
val playerUniqueIdentity: UUID,
@ -23,4 +30,37 @@ class PlayerSession(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<PlayerSession> {
private val playerJoinTimes = ConcurrentHashMap<UUID, Instant>()
@EventHandler
fun onPlayerJoin(event: PlayerJoinEvent) {
playerJoinTimes[event.player.uniqueId] = Instant.now()
}
@EventHandler
fun onPlayerQuit(event: PlayerQuitEvent) {
val startTime = playerJoinTimes.remove(event.player.uniqueId) ?: return
val endTime = Instant.now()
buffer.push(PlayerSession(event.player.uniqueId, event.player.name, startTime, endTime))
}
override fun onPluginDisable(server: Server) {
val endTime = Instant.now()
for (playerId in playerJoinTimes.keys().toList()) {
val startTime = playerJoinTimes.remove(playerId) ?: continue
buffer.push(PlayerSession(
playerId,
server.getPlayer(playerId)?.name ?: "__unknown__",
startTime,
endTime
))
}
}
}
companion object : EventCollectorProvider<PlayerSession> {
override fun collector(buffer: EventBuffer): EventCollector<PlayerSession> = Collector(buffer)
}
}

View File

@ -1,6 +1,10 @@
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.WorldChangeTable
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerChangedWorldEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
import java.time.Instant
@ -26,4 +30,21 @@ class WorldChange(
}
}
}
class Collector(val buffer: IEventBuffer) : EventCollector<WorldChange> {
@EventHandler
fun onWorldLoad(event: PlayerChangedWorldEvent) = buffer.push(
WorldChange(
event.player.uniqueId,
event.from.uid,
event.from.name,
event.player.world.uid,
event.player.world.name
)
)
}
companion object : EventCollectorProvider<WorldChange> {
override fun collector(buffer: EventBuffer): EventCollector<WorldChange> = Collector(buffer)
}
}