From 767faba8d873b82f0f5844d6cbfae123cdbf1544 Mon Sep 17 00:00:00 2001 From: Kenneth Endfinger Date: Fri, 24 Dec 2021 04:10:29 -0500 Subject: [PATCH] Heimdall: Implement Player Death and Player Advancement Tracking --- .../heimdall/FoundationHeimdallPlugin.kt | 41 ++++++++++++------- .../foundation/heimdall/event/BlockBreak.kt | 2 - .../heimdall/event/PlayerAdvancement.kt | 35 ++++++++++++++++ .../foundation/heimdall/event/PlayerDeath.kt | 41 +++++++++++++++++++ .../heimdall/table/BlockBreakTable.kt | 2 +- .../heimdall/table/BlockPlaceTable.kt | 2 +- .../heimdall/table/PlayerAdvancementTable.kt | 16 ++++++++ .../heimdall/table/PlayerDeathTable.kt | 17 ++++++++ .../heimdall/table/PlayerPositionTable.kt | 2 +- .../heimdall/table/PlayerSessionTable.kt | 2 +- .../heimdall/table/WorldChangeTable.kt | 2 +- .../src/main/resources/init.sql | 34 ++++++++++++++- 12 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerAdvancement.kt create mode 100644 foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerDeath.kt create mode 100644 foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerAdvancementTable.kt create mode 100644 foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerDeathTable.kt diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/FoundationHeimdallPlugin.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/FoundationHeimdallPlugin.kt index 443b25c..eb4f7b3 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/FoundationHeimdallPlugin.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/FoundationHeimdallPlugin.kt @@ -9,14 +9,13 @@ import cloud.kubelet.foundation.heimdall.model.HeimdallConfig import com.charleskorn.kaml.Yaml import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.block.BlockPlaceEvent -import org.bukkit.event.player.PlayerChangedWorldEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerMoveEvent -import org.bukkit.event.player.PlayerQuitEvent +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 @@ -35,6 +34,8 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener { private val playerJoinTimes = ConcurrentHashMap() + private val legacyComponentSerializer = LegacyComponentSerializer.builder().build() + override fun onEnable() { val foundation = server.pluginManager.getPlugin("Foundation") as FoundationCorePlugin @@ -108,18 +109,30 @@ class FoundationHeimdallPlugin : JavaPlugin(), Listener { } @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 - ) - ) + 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 + ) + ) + override fun onDisable() { bufferFlushThread.stop() val endTime = Instant.now() diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/BlockBreak.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/BlockBreak.kt index 1533d31..e7ec6cb 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/BlockBreak.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/BlockBreak.kt @@ -2,11 +2,9 @@ package cloud.kubelet.foundation.heimdall.event import cloud.kubelet.foundation.heimdall.storageBlockName import cloud.kubelet.foundation.heimdall.table.BlockBreakTable -import cloud.kubelet.foundation.heimdall.table.PlayerPositionTable import org.bukkit.Location import org.bukkit.Material import org.bukkit.event.block.BlockBreakEvent -import org.bukkit.event.player.PlayerMoveEvent import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.insert import java.time.Instant diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerAdvancement.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerAdvancement.kt new file mode 100644 index 0000000..06f2dff --- /dev/null +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerAdvancement.kt @@ -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() + } + } + } +} diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerDeath.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerDeath.kt new file mode 100644 index 0000000..b8b58c3 --- /dev/null +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/event/PlayerDeath.kt @@ -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 + } + } + } +} diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockBreakTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockBreakTable.kt index 8abe6c1..af6d022 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockBreakTable.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockBreakTable.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.heimdall.table -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.javatime.timestamp object BlockBreakTable : Table("block_breaks") { diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockPlaceTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockPlaceTable.kt index fb5f1be..f7bfd8e 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockPlaceTable.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/BlockPlaceTable.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.heimdall.table -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.javatime.timestamp object BlockPlaceTable : Table("block_places") { diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerAdvancementTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerAdvancementTable.kt new file mode 100644 index 0000000..86a7b3d --- /dev/null +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerAdvancementTable.kt @@ -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") +} diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerDeathTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerDeathTable.kt new file mode 100644 index 0000000..bfcf717 --- /dev/null +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerDeathTable.kt @@ -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() +} diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerPositionTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerPositionTable.kt index cd662af..cbe268f 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerPositionTable.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerPositionTable.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.heimdall.table -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.javatime.timestamp object PlayerPositionTable : Table("player_positions") { diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerSessionTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerSessionTable.kt index 8bce120..4de1b54 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerSessionTable.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/PlayerSessionTable.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.heimdall.table -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.javatime.timestamp object PlayerSessionTable : Table("player_sessions") { diff --git a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/WorldChangeTable.kt b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/WorldChangeTable.kt index 12fcc34..76dfbd2 100644 --- a/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/WorldChangeTable.kt +++ b/foundation-heimdall/src/main/kotlin/cloud/kubelet/foundation/heimdall/table/WorldChangeTable.kt @@ -1,6 +1,6 @@ package cloud.kubelet.foundation.heimdall.table -import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.javatime.timestamp object WorldChangeTable : Table("world_changes") { diff --git a/foundation-heimdall/src/main/resources/init.sql b/foundation-heimdall/src/main/resources/init.sql index c3ba763..8663986 100644 --- a/foundation-heimdall/src/main/resources/init.sql +++ b/foundation-heimdall/src/main/resources/init.sql @@ -62,7 +62,39 @@ create table if not exists heimdall.world_changes ( from_world uuid not null, from_world_name text 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); +-- +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);