mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-04 03:39:37 +00:00 
			
		
		
		
	Heimdall: Implement Player Death and Player Advancement Tracking
This commit is contained in:
		@ -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()
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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()
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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") {
 | 
				
			||||||
 | 
				
			|||||||
@ -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") {
 | 
				
			||||||
 | 
				
			|||||||
@ -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")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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") {
 | 
				
			||||||
 | 
				
			|||||||
@ -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") {
 | 
				
			||||||
 | 
				
			|||||||
@ -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") {
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user