Heimdall: Implement Player Death and Player Advancement Tracking

This commit is contained in:
Kenneth Endfinger 2021-12-24 04:10:29 -05:00
parent c1f621aa7b
commit 767faba8d8
No known key found for this signature in database
GPG Key ID: C4E68E5647420E10
12 changed files with 174 additions and 22 deletions

View File

@ -9,14 +9,13 @@ import cloud.kubelet.foundation.heimdall.model.HeimdallConfig
import com.charleskorn.kaml.Yaml 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 net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockBreakEvent
import org.bukkit.event.block.BlockPlaceEvent import org.bukkit.event.block.BlockPlaceEvent
import org.bukkit.event.player.PlayerChangedWorldEvent import org.bukkit.event.entity.PlayerDeathEvent
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.*
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.event.player.PlayerQuitEvent
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
@ -35,6 +34,8 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
private val playerJoinTimes = ConcurrentHashMap<UUID, Instant>() private val playerJoinTimes = ConcurrentHashMap<UUID, Instant>()
private val legacyComponentSerializer = LegacyComponentSerializer.builder().build()
override fun onEnable() { override fun onEnable() {
val foundation = server.pluginManager.getPlugin("Foundation") as FoundationCorePlugin val foundation = server.pluginManager.getPlugin("Foundation") as FoundationCorePlugin
@ -108,18 +109,30 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener {
} }
@EventHandler @EventHandler
fun onWorldLoad(event: PlayerChangedWorldEvent) { fun onPlayerDeath(event: PlayerDeathEvent) {
buffer.push( val deathMessage = event.deathMessage()
WorldChange( val deathMessageString = if (deathMessage != null) {
event.player.uniqueId, legacyComponentSerializer.serialize(deathMessage)
event.from.uid, } else {
event.from.name, null
event.player.world.uid, }
event.player.world.name 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
)
)
override fun onDisable() { override fun onDisable() {
bufferFlushThread.stop() bufferFlushThread.stop()
val endTime = Instant.now() val endTime = Instant.now()

View File

@ -2,11 +2,9 @@ package cloud.kubelet.foundation.heimdall.event
import cloud.kubelet.foundation.heimdall.storageBlockName import cloud.kubelet.foundation.heimdall.storageBlockName
import cloud.kubelet.foundation.heimdall.table.BlockBreakTable import cloud.kubelet.foundation.heimdall.table.BlockBreakTable
import cloud.kubelet.foundation.heimdall.table.PlayerPositionTable
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockBreakEvent
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
import java.time.Instant import java.time.Instant

View File

@ -0,0 +1,35 @@
package cloud.kubelet.foundation.heimdall.event
import cloud.kubelet.foundation.heimdall.table.PlayerAdvancementTable
import org.bukkit.Location
import org.bukkit.advancement.Advancement
import org.bukkit.event.player.PlayerAdvancementDoneEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
import java.time.Instant
import java.util.*
class PlayerAdvancement(
val playerUniqueIdentity: UUID,
val location: Location,
val advancement: Advancement,
val timestamp: Instant = Instant.now()
) : HeimdallEvent() {
constructor(event: PlayerAdvancementDoneEvent) : this(event.player.uniqueId, event.player.location, event.advancement)
override fun store(transaction: Transaction) {
transaction.apply {
PlayerAdvancementTable.insert {
it[time] = timestamp
it[player] = playerUniqueIdentity
it[world] = location.world.uid
it[x] = location.x
it[y] = location.y
it[z] = location.z
it[pitch] = location.pitch.toDouble()
it[yaw] = location.yaw.toDouble()
it[advancement] = this@PlayerAdvancement.advancement.key.toString()
}
}
}
}

View File

@ -0,0 +1,41 @@
package cloud.kubelet.foundation.heimdall.event
import cloud.kubelet.foundation.heimdall.table.PlayerDeathTable
import org.bukkit.Location
import org.bukkit.event.entity.PlayerDeathEvent
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.insert
import java.time.Instant
import java.util.*
class PlayerDeath(
val playerUniqueIdentity: UUID,
val location: Location,
val experienceLevel: Float,
val deathMessage: String?,
val timestamp: Instant = Instant.now()
) : HeimdallEvent() {
constructor(event: PlayerDeathEvent, deathMessage: String? = null) : this(
event.player.uniqueId,
event.player.location,
event.player.exp,
deathMessage
)
override fun store(transaction: Transaction) {
transaction.apply {
PlayerDeathTable.insert {
it[time] = timestamp
it[player] = playerUniqueIdentity
it[world] = location.world.uid
it[x] = location.x
it[y] = location.y
it[z] = location.z
it[pitch] = location.pitch.toDouble()
it[yaw] = location.yaw.toDouble()
it[experience] = experienceLevel.toDouble()
it[message] = deathMessage
}
}
}
}

View File

@ -1,6 +1,6 @@
package cloud.kubelet.foundation.heimdall.table package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
object BlockBreakTable : Table("block_breaks") { object BlockBreakTable : Table("block_breaks") {

View File

@ -1,6 +1,6 @@
package cloud.kubelet.foundation.heimdall.table package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
object BlockPlaceTable : Table("block_places") { object BlockPlaceTable : Table("block_places") {

View File

@ -0,0 +1,16 @@
package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp
object PlayerAdvancementTable : Table("player_advancements") {
val time = timestamp("time")
val world = uuid("world")
val player = uuid("player")
val x = double("x")
val y = double("y")
val z = double("z")
val pitch = double("pitch")
val yaw = double("yaw")
val advancement = text("advancement")
}

View File

@ -0,0 +1,17 @@
package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp
object PlayerDeathTable : Table("player_deaths") {
val time = timestamp("time")
val world = uuid("world")
val player = uuid("player")
val x = double("x")
val y = double("y")
val z = double("z")
val pitch = double("pitch")
val yaw = double("yaw")
val experience = double("experience")
val message = text("message").nullable()
}

View File

@ -1,6 +1,6 @@
package cloud.kubelet.foundation.heimdall.table package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
object PlayerPositionTable : Table("player_positions") { object PlayerPositionTable : Table("player_positions") {

View File

@ -1,6 +1,6 @@
package cloud.kubelet.foundation.heimdall.table package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
object PlayerSessionTable : Table("player_sessions") { object PlayerSessionTable : Table("player_sessions") {

View File

@ -1,6 +1,6 @@
package cloud.kubelet.foundation.heimdall.table package cloud.kubelet.foundation.heimdall.table
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
object WorldChangeTable : Table("world_changes") { object WorldChangeTable : Table("world_changes") {

View File

@ -62,7 +62,39 @@ create table if not exists heimdall.world_changes (
from_world uuid not null, from_world uuid not null,
from_world_name text not null, from_world_name text not null,
to_world uuid not null, to_world uuid not null,
to_world_name text not null to_world_name text not null,
primary key (time, player)
); );
-- --
select create_hypertable('heimdall.world_changes', 'time', 'player', 4, if_not_exists => TRUE); select create_hypertable('heimdall.world_changes', 'time', 'player', 4, if_not_exists => TRUE);
--
create table if not exists heimdall.player_deaths (
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,
experience double precision not null,
message text null,
primary key (time, player)
);
--
select create_hypertable('heimdall.player_deaths', 'time', 'player', 4, if_not_exists => TRUE);
--
create table if not exists heimdall.player_advancements (
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,
advancement text null,
primary key (time, player, advancement)
);
--
select create_hypertable('heimdall.player_advancements', 'time', 'player', 4, if_not_exists => TRUE);