Browse Source

Player time

merge-requests/3/head
Augusto Dwenger 2 years ago
parent
commit
3c56f8b51a
  1. 4
      .gitignore
  2. 4
      build.gradle.kts
  3. 31
      src/main/kotlin/Main.kt
  4. 139
      src/main/kotlin/PlayerService.kt
  5. 40
      src/main/kotlin/commands/PlayTime.kt
  6. 22
      src/main/kotlin/commands/TestCommand.kt
  7. 39
      src/main/kotlin/commands/UpTime.kt
  8. 62
      src/main/kotlin/db/FileDB.kt
  9. 42
      src/main/kotlin/db/PlayerTimeDB.kt
  10. 21
      src/main/kotlin/listener/JoinListener.kt
  11. 21
      src/main/kotlin/listener/QuitListener.kt
  12. 7
      src/main/kotlin/models/Player.kt
  13. 14
      src/main/resources/plugin.yml
  14. 197
      src/test/kotlin/PlayerServiceTest.kt
  15. 55
      src/test/kotlin/commands/PlayTimeTest.kt
  16. 26
      src/test/kotlin/commands/UpTimeTest.kt
  17. 77
      src/test/kotlin/db/FileDBTest.kt
  18. 11
      start_minecraft.sh

4
.gitignore

@ -27,4 +27,6 @@ hs_err_pid*
# Gradle
.gradle
build/
build/
minecraftTestServer/

4
build.gradle.kts

@ -1,6 +1,7 @@
plugins {
kotlin("jvm") version "1.3.61"
id("org.jlleitschuh.gradle.ktlint") version "9.0.0"
id("com.github.johnrengelman.shadow") version "5.2.0"
}
group = "de.augustodwenger"
@ -23,9 +24,10 @@ dependencies {
implementation("io.github.microutils:kotlin-logging:1.7.8")
implementation("ch.qos.logback:logback-classic:1.2.3")
implementation("ch.qos.logback:logback-core:1.2.3")
compileOnly("org.spigotmc:spigot-api:1.15.1-R0.1-SNAPSHOT")
compile("org.spigotmc:spigot-api:1.15.1-R0.1-SNAPSHOT")
testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit5"))
testImplementation("io.mockk:mockk:1.9.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.5.2")
}

31
src/main/kotlin/Main.kt

@ -0,0 +1,31 @@
import commands.PlayTime
import commands.TestCommand
import commands.UpTime
import db.FileDB
import java.io.File
import listener.JoinListener
import listener.QuitListener
import mu.KotlinLogging
import org.bukkit.plugin.java.JavaPlugin
class Main : JavaPlugin() {
private val log = KotlinLogging.logger { }
private val storageDir = File("./plugins/PlayTime/")
override fun onEnable() {
super.onEnable()
storageDir.mkdirs()
println("dir?... : " + storageDir.isDirectory)
println("path... : " + storageDir.absolutePath)
val playerService = object : PlayerService(FileDB(storageDir)) {}
println("The plugin is now enabled!")
log.info { "logging works for the plugin too!" }
this.getCommand("test")?.setExecutor(TestCommand())
this.getCommand("playtime")?.setExecutor(PlayTime(playerService))
this.getCommand("uptime")?.setExecutor(UpTime())
server.pluginManager.registerEvents(JoinListener(playerService), this)
server.pluginManager.registerEvents(QuitListener(playerService), this)
}
}

139
src/main/kotlin/PlayerService.kt

@ -0,0 +1,139 @@
import db.PlayerTimeDB
import java.time.Duration
import java.time.LocalDateTime
import java.util.UUID
import models.Player
/**
* A service to hold the all player that are currently playing
* It should only be used as Singleton @see Kotlin objects
*
* @param db the DB implementation which should be used to persist the state
*/
open class PlayerService(private val db: PlayerTimeDB) {
/**
* Holds all online players
*/
private val playerMap = mutableMapOf<UUID, Player>()
/**
* Adds the player to the playerMap.
* It creates an new player if it's no persisted and adds/refreshes the join time
*
* @param uuid the actual uuid of a player
* @param playerName for debugging because with the new api playerNames are not longer unique
*
* @exception UnsupportedOperationException if the player is already in the map. To prevent this check before adding if it's already present
*/
fun addPlayer(uuid: UUID, playerName: String) {
if (playerMap.contains(uuid)) throw UnsupportedOperationException("""Trying to add $playerName to the instance that already exists""")
val player: Player = if (db.findUUID(uuid)) {
val player = db.readPlayer(uuid)
player.joinTime = LocalDateTime.now()
player
} else {
val player = Player(uuid, playerName)
db.createPlayer(player)
player
}
playerMap[uuid] = player
}
/**
* Removes a player from the map and persists its status
*
*@param uuid players uuid
*
* @exception IndexOutOfBoundsException if the map is empty
* @exception NoSuchElementException if the map does not contain the key
*/
fun removePlayer(uuid: UUID) {
validateLookUp(uuid)
persistPlayer(uuid)
playerMap.remove(uuid)
}
/**
* Wrapper for the map to prevent directly exposition
*
* @return status of the inner map
*/
fun containsPlayer(uuid: UUID): Boolean {
return playerMap.containsKey(uuid)
}
/**
* Wrapper for the map to prevent directly exposition
*
* @return status of the inner map
*/
fun isEmpty(): Boolean {
return playerMap.isEmpty()
}
/**
* Updates and writes the current status to the db
*
* @param uuid player uuid
*
* @exception IndexOutOfBoundsException if the map is empty
* @exception NoSuchElementException if the map does not contain the key
*/
fun persistPlayer(uuid: UUID) {
val duration = timePlayed(uuid)
val player = getPlayer(uuid)
player.playTime = Duration.from(duration)
db.writePlayer(player)
}
/**
* Persists all player
*/
fun persistAllPlayer() {
for ((uuid, _) in playerMap) {
persistPlayer(uuid)
}
}
/**
* Returns the player with that uuid
*
* @param uuid player uuid
*
* @exception IndexOutOfBoundsException if the map is empty
* @exception NoSuchElementException if the map does not contain the key
*/
fun getPlayer(uuid: UUID): Player {
validateLookUp(uuid)
return playerMap[uuid]!!
}
/**
* Returns the player time including the old time
*
* @param uuid player uuid
*
* @exception IndexOutOfBoundsException if the map is empty
* @exception NoSuchElementException if the map does not contain the key
*/
fun timePlayed(uuid: UUID): Duration {
validateLookUp(uuid)
val player = getPlayer(uuid)
val duration = Duration.between(player.joinTime, LocalDateTime.now())
return Duration.from(player.playTime).plus(duration)
}
/**
* It validates if the lookup is possible
*
* @param uuid the player uuid
*
* @exception IndexOutOfBoundsException if the map is empty
* @exception NoSuchElementException if the map does not contain the key
*/
private fun validateLookUp(uuid: UUID) {
if (playerMap.isEmpty()) throw IndexOutOfBoundsException("The map is empty")
if (!playerMap.containsKey(uuid)) throw NoSuchElementException("There is no entry for the key $uuid inside of the playerMap")
}
}

40
src/main/kotlin/commands/PlayTime.kt

@ -0,0 +1,40 @@
package commands
import PlayerService
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
/**
* The command executor for the playtime
*
* @param playerService the service which holds the current status
*/
class PlayTime(private val playerService: PlayerService) : CommandExecutor {
/**
* It sends the playtime of and to the CommandSender
*
* @param sender to send a message
*
* @return true when the sender is a actual player
*/
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if (sender is Player) {
val duration = playerService.timePlayed(sender.uniqueId)
val days: String =
if (duration.toDaysPart() < 10) """0${duration.toDaysPart()}""" else """${duration.toDaysPart()}"""
val hours: String =
if (duration.toHoursPart() < 10) """0${duration.toHoursPart()}""" else """${duration.toHoursPart()}"""
val minutes: String =
if (duration.toMinutesPart() < 10) """0${duration.toMinutesPart()}""" else """${duration.toMinutesPart()}"""
sender.sendMessage("""Your play time: $days:$hours:$minutes""")
return true
}
sender.sendMessage("This command can only be executed as a player")
return false
}
}

22
src/main/kotlin/commands/TestCommand.kt

@ -0,0 +1,22 @@
package commands
import mu.KotlinLogging
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
class TestCommand : CommandExecutor {
private val log = KotlinLogging.logger { }
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
return if (sender is Player) {
sender.sendMessage("u are a Player")
true
} else {
sender.sendMessage("not Player")
true
}
}
}

39
src/main/kotlin/commands/UpTime.kt

@ -0,0 +1,39 @@
package commands
import java.time.LocalDateTime
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
class UpTime(val startTime: LocalDateTime = LocalDateTime.now()) : CommandExecutor {
/**
* It sends the uptime of the server to the CommandSender
*
* @param sender to send a message
*
* @return always true
*/
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
val timeList = timePassed(LocalDateTime.now())
val days: String = if (timeList[0] < 10) """0${timeList[0]}""" else """${timeList[0]}"""
val hours: String = if (timeList[1] < 10) """0${timeList[1]}""" else """${timeList[1]}"""
val minutes: String = if (timeList[2] < 10) """0${timeList[2]}""" else """${timeList[2]}"""
sender.sendMessage("""$days:$hours:$minutes""")
return true
}
/**
* Calculates the past time
* If the uptime is longer than one year these 365 days will be ignored
* @param now the time that will be used to calculate the time diff
* @return a list with the time format DD,HH,MM
*/
fun timePassed(now: LocalDateTime): List<Long> {
val duration = java.time.Duration.between(startTime, now)
return listOf(duration.toDaysPart(), duration.toHoursPart().toLong(), duration.toMinutesPart().toLong())
}
}

62
src/main/kotlin/db/FileDB.kt

@ -0,0 +1,62 @@
package db
import com.google.gson.Gson
import java.io.File
import java.util.UUID
import models.Player
/**
* FileDB manages the file based PlayerTime DB and provides basic functionality to interact with it
*/
class FileDB(private val path: File) : PlayerTimeDB {
private val gson = Gson()
/**
* It looks if a certain file already exits
*
* @param uuid the uuid as id for the file tha should be found
*
* @return if the file is present
*/
override fun findUUID(uuid: UUID): Boolean {
return File(path, uuid.toString()).exists()
}
/**
* Creates a playerTime file
*
* @param player the player for which the file should be created
*
* @exception FileAlreadyExistsException is thrown if the playerTime file already exists. To prevent it check it with the findUUID method
*/
override fun createPlayer(player: Player) {
val file = File(path, player.uuid.toString())
if (file.exists()) throw FileAlreadyExistsException(file)
file.createNewFile()
writePlayer(player)
}
/**
* reads the player out of the file
*
* @param uuid the uuid of the player that should be read
*
* @return Player
*/
override fun readPlayer(uuid: UUID): Player {
val file = File(path, uuid.toString())
return gson.fromJson(file.readText(), Player::class.java)
}
/**
* Writs a player into an existing file
* To create a new player file @see createPlayer
*
* @param player that should be written
*/
override fun writePlayer(player: Player) {
val file = File(path, player.uuid.toString())
file.writeText(gson.toJson(player))
}
}

42
src/main/kotlin/db/PlayerTimeDB.kt

@ -0,0 +1,42 @@
package db
import java.util.UUID
import models.Player
interface PlayerTimeDB {
/**
* It looks if a certain file already exits
*
* @param uuid the uuid as id for the file tha should be found
*
* @return if the file is present
*/
fun findUUID(uuid: UUID): Boolean
/**
* Creates a playerTime file
*
* @param player the player for which the file should be created
*
* @exception FileAlreadyExistsException is thrown if the playerTime file already exists. To prevent it check it with the findUUID method
*/
fun createPlayer(player: Player)
/**
* reads the player out of the file
*
* @param uuid the uuid of the player that should be read
*
* @return Player
*/
fun readPlayer(uuid: UUID): Player
/**
* Writs a player into an existing file
* To create a new player file @see createPlayer
*
* @param player that should be written
*/
fun writePlayer(player: Player)
}

21
src/main/kotlin/listener/JoinListener.kt

@ -0,0 +1,21 @@
package listener
import PlayerService
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
class JoinListener(private val playerService: PlayerService) : Listener {
/**
* Registers as handler for the PlayerJoinEvent
* Adds the player to the service
*
* @param event to get the player that emitted it
*/
@EventHandler
fun onPlayerJoin(event: PlayerJoinEvent) {
val player = event.player
playerService.addPlayer(player.uniqueId, player.name)
}
}

21
src/main/kotlin/listener/QuitListener.kt

@ -0,0 +1,21 @@
package listener
import PlayerService
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerQuitEvent
class QuitListener(private val playerService: PlayerService) : Listener {
/**
* Registers as handler for the PlayerQuitEvent
* Removes the user from the service
*
* @param event to get the player that emitted it
*/
@EventHandler
fun onPlayerQuit(event: PlayerQuitEvent) {
val player = event.player
playerService.removePlayer(player.uniqueId)
}
}

7
src/main/kotlin/models/Player.kt

@ -0,0 +1,7 @@
package models
import java.time.Duration
import java.time.LocalDateTime
import java.util.UUID
data class Player(val uuid: UUID, val playerName: String, var playTime: Duration = Duration.ZERO, var joinTime: LocalDateTime = LocalDateTime.now(), var lastSave: LocalDateTime? = null)

14
src/main/resources/plugin.yml

@ -1,15 +1,17 @@
name: "PlayTime"
author: "hamburghammer"
version: "1.0"
version: "0.0.1"
description: "allows player to see how much they have played for."
main: java.Main
main: Main
commands:
test:
usage: /<command>
description: "Test command for foo"
playtime:
usage: /<command>
aliases: [timeplayed, pt]
# aliases: [timeplayed, pt]
description: "Shows the playtime of a player!"
serveruptime:
uptime:
usage: /<command>
aliases: [uptime, sp]
description: "Shows how long the server has been up for!"
description: "Shows the up time of the server"

197
src/test/kotlin/PlayerServiceTest.kt

@ -0,0 +1,197 @@
import db.PlayerTimeDB
import io.mockk.Runs
import io.mockk.confirmVerified
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.verify
import java.time.Duration
import java.time.LocalDateTime
import java.util.UUID
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import models.Player
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
class PlayerServiceTest {
@Test
fun `should add new player`() {
val uuid = UUID.randomUUID()
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns false
every { mockDB.createPlayer(any()) } just Runs
val playerService = PlayerService(mockDB)
assertTrue(playerService.isEmpty())
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
assertTrue(playerService.containsPlayer(uuid))
verify(exactly = 1) { mockDB.findUUID(uuid) }
verify(exactly = 1) { mockDB.createPlayer(any()) }
confirmVerified(mockDB)
}
@Test
fun `should add existing player`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
player.joinTime = LocalDateTime.now().minusDays(1)
val originalPlayer = player.copy()
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
val playerService = PlayerService(mockDB)
assertTrue(playerService.isEmpty())
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
assertTrue(playerService.containsPlayer(uuid))
val extract = playerService.getPlayer(uuid)
assertNotEquals(originalPlayer.joinTime, extract.joinTime)
verify(exactly = 1) { mockDB.findUUID(uuid) }
verify(exactly = 1) { mockDB.readPlayer(uuid) }
confirmVerified(mockDB)
}
@Test
fun `throws exception if the uuid is already in the map`() {
val uuid = UUID.randomUUID()
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns false
every { mockDB.createPlayer(any()) } just Runs
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
val exception: Exception = assertThrows(UnsupportedOperationException::class.java) {
playerService.addPlayer(uuid, "playerName")
}
assertEquals("Trying to add playerName to the instance that already exists", exception.message)
}
@Test
fun `remove a player from the map`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
every { mockDB.writePlayer(player) } just Runs
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
playerService.removePlayer(uuid)
assertTrue(playerService.isEmpty())
verify(exactly = 1) { mockDB.writePlayer(player) }
}
@Test
fun `persist a player from the map`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
every { mockDB.writePlayer(player) } just Runs
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
playerService.persistPlayer(uuid)
verify(exactly = 1) { mockDB.writePlayer(player) }
}
@Test
fun `persist all player from the map`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
every { mockDB.writePlayer(player) } just Runs
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
playerService.persistAllPlayer()
verify(exactly = 1) { mockDB.writePlayer(player) }
}
@Test
fun `get player`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
every { mockDB.writePlayer(player) } just Runs
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
val extractedPlayer = playerService.getPlayer(uuid)
assertEquals(player.uuid, extractedPlayer.uuid)
assertEquals(player.playerName, extractedPlayer.playerName)
assertEquals(player.playTime, extractedPlayer.playTime)
}
@Test
fun `get played time and update the field`() {
val uuid = UUID.randomUUID()
val player = Player(uuid, "playerName")
val mockDB = mockk<PlayerTimeDB>()
every { mockDB.findUUID(uuid) } returns true
every { mockDB.readPlayer(uuid) } returns player
val playerService = PlayerService(mockDB)
playerService.addPlayer(uuid, "playerName")
assertFalse(playerService.isEmpty())
assertNotEquals(0, playerService.timePlayed(uuid).toNanos())
assertEquals(Duration.ZERO, playerService.getPlayer(uuid).playTime)
}
@Test
fun `duration`() {
val duration = Duration.ZERO.plusSeconds(100)
assertEquals(200, duration.plus(Duration.ZERO.plusSeconds(100)).toSeconds())
}
}

55
src/test/kotlin/commands/PlayTimeTest.kt

@ -0,0 +1,55 @@
package commands
import PlayerService
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import java.time.Duration
import java.util.UUID
import kotlin.test.assertTrue
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Test
internal class PlayTimeTest {
@Test
fun `get the current play time`() {
val list = mutableListOf<String>()
val mockedPlayerService = mockk<PlayerService>()
every { mockedPlayerService.timePlayed(any()) } returns Duration.ofMinutes(10)
val playTime = PlayTime(mockedPlayerService)
val mockCommandSender = mockk<Player>()
every { mockCommandSender.uniqueId } returns UUID.randomUUID()
every { mockCommandSender.sendMessage(capture(list)) } just Runs
assertTrue(playTime.onCommand(mockCommandSender, mockk(), "", arrayOf()))
assertFalse(list.isEmpty())
assertEquals("Your play time: 00:00:10", list[0])
}
@Test
fun `error if not send by player`() {
val list = mutableListOf<String>()
val mockedPlayerService = mockk<PlayerService>()
every { mockedPlayerService.timePlayed(any()) } returns Duration.ofMinutes(10)
val playTime = PlayTime(mockedPlayerService)
val mockCommandSender = mockk<CommandSender>()
every { mockCommandSender.sendMessage(capture(list)) } just Runs
assertFalse(playTime.onCommand(mockCommandSender, mockk(), "", arrayOf()))
assertFalse(list.isEmpty())
assertEquals("This command can only be executed as a player", list[0])
}
}

26
src/test/kotlin/commands/UpTimeTest.kt

@ -0,0 +1,26 @@
package commands
import java.time.LocalDateTime
import kotlin.test.Test
import org.junit.jupiter.api.Assertions.assertEquals
internal class UpTimeTest {
@Test
fun `should set current time`() {
val now = LocalDateTime.now()
val upTime = UpTime(now)
assertEquals(now, upTime.startTime)
}
@Test
fun `should calculate time passed`() {
val startTime = LocalDateTime.of(2019, 12, 27, 15, 33)
val upTime = UpTime(startTime)
assertEquals(listOf(0, 0, 35L), upTime.timePassed(startTime.plusMinutes(35)))
assertEquals(listOf(0, 1L, 5L), upTime.timePassed(startTime.plusMinutes(65)))
assertEquals(listOf(0, 2L, 0), upTime.timePassed(startTime.plusHours(2)))
assertEquals(listOf(1L, 1L, 0), upTime.timePassed(startTime.plusHours(25)))
}
}

77
src/test/kotlin/db/FileDBTest.kt

@ -0,0 +1,77 @@
package db
import com.google.gson.Gson
import java.io.File
import java.util.UUID
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import models.Player
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
internal class FileDBTest {
private var dbDir = createTempDir()
@BeforeTest
fun setUp() {
dbDir = createTempDir()
}
@AfterTest
fun cleanUp() {
dbDir.delete()
}
@Test
fun `find user over uuid file name`() {
val uuid = UUID.randomUUID()
val fileDB = FileDB(dbDir)
assertFalse(fileDB.findUUID(uuid))
File(dbDir, uuid.toString()).createNewFile()
assertTrue(fileDB.findUUID(uuid))
}
@Test
fun `create new player file`() {
val uuid = UUID.randomUUID()
val fileDB = FileDB(dbDir)
val player = Player(uuid, "username")
assertFalse(fileDB.findUUID(uuid))
fileDB.createPlayer(player)
assertTrue(fileDB.findUUID(uuid))
val writtenFile = File(dbDir, uuid.toString())
assertEquals(player, Gson().fromJson(writtenFile.readText(), Player::class.java))
}
@Test
fun `read player from file`() {
val uuid = UUID.randomUUID()
val fileDB = FileDB(dbDir)
val player = Player(uuid, "username")
File(dbDir, uuid.toString()).writeText(Gson().toJson(player))
assertEquals(player, fileDB.readPlayer(uuid))
}
@Test
fun `write player to file`() {
val uuid = UUID.randomUUID()
val fileDB = FileDB(dbDir)
val player = Player(uuid, "username")
val file = File(dbDir, uuid.toString())
assertTrue(file.createNewFile())
fileDB.writePlayer(player)
assertEquals(player, Gson().fromJson(file.readText(), Player::class.java))
}
}

11
start_minecraft.sh

@ -0,0 +1,11 @@
#!/usr/bin/env bash
VERSION=0.0.1
cp build/libs/PlayTime-${VERSION}-SNAPSHOT-all.jar minecraftTestServer/plugins/
rm minecraftTestServer/plugins/PlayTime/*
cd minecraftTestServer/
java -Xmx2G -jar spigot-1.15.1.jar
Loading…
Cancel
Save