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.HikariConfig
import com.zaxxer.hikari.HikariDataSource import com.zaxxer.hikari.HikariDataSource
import gay.pizza.foundation.common.FoundationCoreLoader 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.BufferFlushThread
import gay.pizza.foundation.heimdall.plugin.buffer.EventBuffer 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.export.ExportAllChunksCommand
import gay.pizza.foundation.heimdall.plugin.load.ImportWorldLoadCommand import gay.pizza.foundation.heimdall.plugin.load.ImportWorldLoadCommand
import gay.pizza.foundation.heimdall.plugin.model.HeimdallConfig import gay.pizza.foundation.heimdall.plugin.model.HeimdallConfig
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer import gay.pizza.foundation.shared.PluginMainClass
import org.bukkit.event.EventHandler import gay.pizza.foundation.shared.copyDefaultConfig
import org.bukkit.event.Listener 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.bukkit.plugin.java.JavaPlugin
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database
import org.postgresql.Driver import org.postgresql.Driver
import java.time.Duration import java.time.Duration
import java.time.Instant
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.io.path.inputStream import kotlin.io.path.inputStream
@PluginMainClass @PluginMainClass
@ -38,15 +29,15 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
private val buffer = EventBuffer() private val buffer = EventBuffer()
private val bufferFlushThread = BufferFlushThread(this, buffer) private val bufferFlushThread = BufferFlushThread(this, buffer)
private val playerJoinTimes = ConcurrentHashMap<UUID, Instant>() private val collectors = mutableListOf<EventCollector<*>>()
private val legacyComponentSerializer = LegacyComponentSerializer.builder().build()
override fun onEnable() { 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)) 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)) importWorldLoadCommand.setExecutor(ImportWorldLoadCommand(this))
val foundation = FoundationCoreLoader.get(server) val foundation = FoundationCoreLoader.get(server)
@ -98,79 +89,20 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
db = Database.connect(pool) db = Database.connect(pool)
server.pluginManager.registerEvents(this, this) server.pluginManager.registerEvents(this, this)
bufferFlushThread.start() bufferFlushThread.start()
}
@EventHandler for (collectorProvider in EventCollectorProviders.all) {
fun onPlayerMove(event: PlayerMoveEvent) = buffer.push(PlayerPosition(event)) val collector = collectorProvider.collector(buffer)
server.pluginManager.registerEvents(collector, this)
@EventHandler collectors.add(collector)
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
} }
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() { override fun onDisable() {
bufferFlushThread.stop() bufferFlushThread.stop()
val endTime = Instant.now() for (collector in collectors) {
for (playerId in playerJoinTimes.keys().toList()) { collector.onPluginDisable(server)
val startTime = playerJoinTimes.remove(playerId) ?: continue
buffer.push(PlayerSession(
playerId,
server.getPlayer(playerId)?.name ?: "__unknown__",
startTime,
endTime
))
} }
collectors.clear()
bufferFlushThread.flush() bufferFlushThread.flush()
} }
} }

View File

@ -3,7 +3,7 @@ package gay.pizza.foundation.heimdall.plugin.buffer
import gay.pizza.foundation.heimdall.plugin.event.HeimdallEvent import gay.pizza.foundation.heimdall.plugin.event.HeimdallEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
class EventBuffer { class EventBuffer : IEventBuffer {
private var events = mutableListOf<HeimdallEvent>() private var events = mutableListOf<HeimdallEvent>()
fun flush(transaction: Transaction): Long { fun flush(transaction: Transaction): Long {
@ -18,7 +18,7 @@ class EventBuffer {
return count return count
} }
fun push(event: HeimdallEvent) { override fun push(event: HeimdallEvent) {
events.add(event) 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 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 gay.pizza.foundation.heimdall.table.BlockBreakTable
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockBreakEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert 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 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 gay.pizza.foundation.heimdall.table.BlockPlaceTable
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.block.BlockPlaceEvent import org.bukkit.event.block.BlockPlaceEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert 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 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 gay.pizza.foundation.heimdall.table.EntityKillTable
import org.bukkit.Location 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.Transaction
import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.insert
import java.time.Instant 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, location: Location,
player: UUID player: UUID
) { ) {
statement[this.time] = time putTimedLocalEvent(statement, time, location)
statement[this.world] = location.world.uid
statement[this.x] = location.x
statement[this.y] = location.y
statement[this.z] = location.z
statement[this.player] = player statement[this.player] = player
statement[this.pitch] = location.pitch.toDouble() statement[this.pitch] = location.pitch.toDouble()
statement[this.yaw] = location.yaw.toDouble() statement[this.yaw] = location.yaw.toDouble()

View File

@ -1,8 +1,11 @@
package gay.pizza.foundation.heimdall.plugin.event 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 gay.pizza.foundation.heimdall.table.PlayerAdvancementTable
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.advancement.Advancement import org.bukkit.advancement.Advancement
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerAdvancementDoneEvent import org.bukkit.event.player.PlayerAdvancementDoneEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert 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 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 gay.pizza.foundation.heimdall.table.PlayerDeathTable
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.entity.PlayerDeathEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert 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 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 gay.pizza.foundation.heimdall.table.PlayerPositionTable
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerMoveEvent import org.bukkit.event.player.PlayerMoveEvent
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert 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 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 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.Transaction
import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.insert
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap
class PlayerSession( class PlayerSession(
val playerUniqueIdentity: UUID, 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 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 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.Transaction
import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.insert
import java.time.Instant 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)
}
} }