From cbf1e64db9d5b6fb1244d683b64cf20967839f6d Mon Sep 17 00:00:00 2001 From: Kalle Struik Date: Sun, 7 Nov 2021 16:31:24 +0100 Subject: [PATCH] Bunch of config stuff + logging basics --- .../kotlin/nl/kallestruik/darena/DArena.kt | 16 ----- .../nl/kallestruik/darena/arenas/Arena.kt | 14 ++-- .../kallestruik/darena/arenas/ArenaConfig.kt | 53 +++++++++++---- .../kallestruik/darena/arenas/ArenaSession.kt | 9 +-- .../darena/managers/ArenaManager.kt | 6 +- .../darena/types/ConfigListLoadable.kt | 4 ++ .../darena/types/ConfigListSaveable.kt | 7 ++ .../darena/types/ConfigLoadable.kt | 6 ++ .../darena/types/ConfigSaveable.kt | 7 ++ .../darena/types/arena/ArenaCheckpoint.kt | 26 ++++---- .../darena/types/arena/ArenaEnchantment.kt | 29 ++++---- .../darena/types/arena/ArenaItem.kt | 22 +++---- .../darena/types/arena/ArenaLoadout.kt | 23 +++---- .../darena/types/arena/ArenaLocation.kt | 13 +++- .../darena/types/arena/ArenaPoints.kt | 11 ++++ .../darena/types/arena/ArenaPotionEffect.kt | 28 ++++++++ .../darena/types/arena/ArenaSpawn.kt | 28 ++++---- .../darena/types/arena/ArenaSpawnRule.kt | 27 ++++++++ .../nl/kallestruik/darena/util/ArenaUtil.kt | 4 +- .../kallestruik/darena/util/ConfigHelper.kt | 66 ++++++++++++++++++- .../nl/kallestruik/darena/util/Logger.kt | 53 +++++++++++++++ src/main/resources/template/arena.yml | 30 ++++++--- 22 files changed, 372 insertions(+), 110 deletions(-) create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/ConfigListLoadable.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/ConfigListSaveable.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/ConfigLoadable.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/ConfigSaveable.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPotionEffect.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawnRule.kt create mode 100644 src/main/kotlin/nl/kallestruik/darena/util/Logger.kt diff --git a/src/main/kotlin/nl/kallestruik/darena/DArena.kt b/src/main/kotlin/nl/kallestruik/darena/DArena.kt index 533a843..2112a1e 100644 --- a/src/main/kotlin/nl/kallestruik/darena/DArena.kt +++ b/src/main/kotlin/nl/kallestruik/darena/DArena.kt @@ -11,22 +11,6 @@ class DArena : JavaPlugin() { private lateinit var pointsManager: PointsManager private lateinit var teamManager: TeamManager - // TODO: - // Thinking: - // - Datastructures for arenas - // - Datastructures for teams (Everyone is always in a team even when solo) - // - How will points work for teams/individuals - // - Teams are always the same during one event - // - Teams on the leaderboard - // - Rotate teams each new game as an option - // Programing: - // - Loading arenas from config files - // - Commands to interact with the plugin - // - Custom world creation for arenas - // - Basic arena mechanics - // - Points system - // - Advanced arena mechanics (Special items like fireballs) - override fun onEnable() { configManager = ConfigManager(File(dataFolder, "config.yml")) configManager.load() diff --git a/src/main/kotlin/nl/kallestruik/darena/arenas/Arena.kt b/src/main/kotlin/nl/kallestruik/darena/arenas/Arena.kt index 235c634..eebff5e 100644 --- a/src/main/kotlin/nl/kallestruik/darena/arenas/Arena.kt +++ b/src/main/kotlin/nl/kallestruik/darena/arenas/Arena.kt @@ -11,7 +11,7 @@ class Arena( private val arenaUtil: ArenaUtil, private val plugin: JavaPlugin, private val world: ArenaWorld = ArenaWorld(config.name, plugin), - ) { +) { private lateinit var session: ArenaSession // Simple stuff done: 0.001474s // createArena start: 0.0001026s @@ -33,19 +33,25 @@ class Arena( session.spectators.addAll(arenaUtil.getPossibleSpectators()); // Reset the world world.reset() + + + // Place all spectators in the arena session.spectators.forEach { // config.spectatorSpawn.spawn(world, it) } // Randomize spawns - session.spawns.addAll(config.spawns) - session.spawns.shuffle() + session.initialSpawns.addAll(config.spawns.filter { + //TODO: make this filter only spawns that meet the intitial spawn condidtions. Or just replace this whole method. + return@filter true + }.keys) + session.initialSpawns.shuffle() // Spawn all the players session.participants.forEachIndexed { index, player -> // TODO: Freeze players in place (for in arena countdown) (if countdown is 0 dont freeze them) - session.spawns[index % session.spawns.size].spawn(world, player) + config.spawns[session.initialSpawns[index % session.initialSpawns.size]]!!.spawn(world, player) } // TODO: } diff --git a/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaConfig.kt b/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaConfig.kt index e5377cf..1b52db9 100644 --- a/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaConfig.kt +++ b/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaConfig.kt @@ -1,44 +1,73 @@ package nl.kallestruik.darena.arenas import nl.kallestruik.darena.types.arena.ArenaLoadout -import nl.kallestruik.darena.types.arena.ArenaSpawn import nl.kallestruik.darena.types.arena.ArenaCheckpoint import nl.kallestruik.darena.types.arena.ArenaPoints +import nl.kallestruik.darena.types.arena.ArenaSpawn +import nl.kallestruik.darena.types.arena.ArenaSpawnRule import nl.kallestruik.darena.util.ConfigHelper import java.io.File +import org.bukkit.configuration.InvalidConfigurationException +import org.bukkit.configuration.file.YamlConfiguration +import kotlin.collections.mutableMapOf data class ArenaConfig( - var name: String = "[Missing name]", - var spawns: List = emptyList(), - var loadouts: List = emptyList(), - var checkpoints: List = emptyList(), + var name: String, + var file: File, + var spawns: MutableMap = mutableMapOf(), + var loadouts: MutableMap = mutableMapOf(), + var checkpoints: MutableMap = mutableMapOf(), var points: ArenaPoints = ArenaPoints(), + var spawnRules: MutableMap = mutableMapOf() ) { + fun save(toString: Boolean = false): String? { + val config = YamlConfiguration() + config.set("name", name) + + ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(config, "spawns"), spawns) + ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(config, "loadouts"), loadouts) + ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(config, "checkpoints"), checkpoints) + points.save(ConfigHelper.getOrCreateSection(config, "points")) + ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(config, "spawnRules"), spawnRules) + + if (toString) { + return config.saveToString() + } + + config.save(file) + return null + } + companion object { + @Throws(InvalidConfigurationException::class) fun load(file: File): ArenaConfig { val config = ConfigHelper.getOrCreateConfig(file, "template/arena.yml") - val arenaConfig = ArenaConfig() - - if (config.contains("name")) { - arenaConfig.name = config.getString("name")!! + if (!config.contains("name")) { + throw InvalidConfigurationException("The arena configuration file '${file.name}' does not contain the required attribute 'name'") } + val arenaConfig = ArenaConfig(config.getString("name")!!, file) + if (config.contains("spawns")) { - arenaConfig.spawns = ArenaSpawn.loadList(config.getConfigurationSection("spawns")!!) + arenaConfig.spawns = ConfigHelper.loadMap(config.getConfigurationSection("spawns")!!, ArenaSpawn) } if (config.contains("loadouts")) { - arenaConfig.loadouts = ArenaLoadout.loadList(config.getConfigurationSection("loadouts")!!) + arenaConfig.loadouts = ConfigHelper.loadMap(config.getConfigurationSection("loadouts")!!, ArenaLoadout) } if (config.contains("checkpoints")) { - arenaConfig.checkpoints = ArenaCheckpoint.loadList(config.getConfigurationSection("checkpoints")!!) + arenaConfig.checkpoints = ConfigHelper.loadMap(config.getConfigurationSection("checkpoints")!!, ArenaCheckpoint) } if (config.contains("points")) { arenaConfig.points = ArenaPoints.load(config.getConfigurationSection("points")!!) } + if (config.contains("spawnRules")) { + arenaConfig.spawnRules = ConfigHelper.loadMap(config.getConfigurationSection("spawnRules")!!, ArenaSpawnRule) + } + return arenaConfig } } diff --git a/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaSession.kt b/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaSession.kt index e5bbd94..63fe4f8 100644 --- a/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaSession.kt +++ b/src/main/kotlin/nl/kallestruik/darena/arenas/ArenaSession.kt @@ -2,11 +2,12 @@ package nl.kallestruik.darena.arenas import nl.kallestruik.darena.types.arena.ArenaSpawn import org.bukkit.entity.Player +import java.util.UUID data class ArenaSession( val participants: MutableList = ArrayList(), val spectators: MutableList = ArrayList(), - val completedObjective: MutableList = ArrayList(), - val deaths: MutableList = ArrayList(), - val spawns: MutableList = ArrayList(), -) \ No newline at end of file + val completedObjective: MutableList = ArrayList(), + val deaths: MutableList = ArrayList(), + val initialSpawns: MutableList = ArrayList(), +) diff --git a/src/main/kotlin/nl/kallestruik/darena/managers/ArenaManager.kt b/src/main/kotlin/nl/kallestruik/darena/managers/ArenaManager.kt index 266efad..df3d8a4 100644 --- a/src/main/kotlin/nl/kallestruik/darena/managers/ArenaManager.kt +++ b/src/main/kotlin/nl/kallestruik/darena/managers/ArenaManager.kt @@ -19,9 +19,9 @@ class ArenaManager( arenas.add(Arena( ArenaConfig.load(path.toFile()), arenaUtil, - plugin - )) + plugin) + ) } } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/ConfigListLoadable.kt b/src/main/kotlin/nl/kallestruik/darena/types/ConfigListLoadable.kt new file mode 100644 index 0000000..6a8e656 --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/ConfigListLoadable.kt @@ -0,0 +1,4 @@ +package nl.kallestruik.darena.types + +interface ConfigListLoadable { + fun loadFromList(key: String, value: Any): T diff --git a/src/main/kotlin/nl/kallestruik/darena/types/ConfigListSaveable.kt b/src/main/kotlin/nl/kallestruik/darena/types/ConfigListSaveable.kt new file mode 100644 index 0000000..4ec9edc --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/ConfigListSaveable.kt @@ -0,0 +1,7 @@ +package nl.kallestruik.darena.types + +interface ConfigListSaveable { + fun getKey(): String + + fun getValue(): Any +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/ConfigLoadable.kt b/src/main/kotlin/nl/kallestruik/darena/types/ConfigLoadable.kt new file mode 100644 index 0000000..73a4fc8 --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/ConfigLoadable.kt @@ -0,0 +1,6 @@ +package nl.kallestruik.darena.types + +import org.bukkit.configuration.ConfigurationSection + +interface ConfigLoadable { + fun load(section: ConfigurationSection): T diff --git a/src/main/kotlin/nl/kallestruik/darena/types/ConfigSaveable.kt b/src/main/kotlin/nl/kallestruik/darena/types/ConfigSaveable.kt new file mode 100644 index 0000000..0b37d32 --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/ConfigSaveable.kt @@ -0,0 +1,7 @@ +package nl.kallestruik.darena.types + +import org.bukkit.configuration.ConfigurationSection + +interface ConfigSaveable { + fun save(section: ConfigurationSection) +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaCheckpoint.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaCheckpoint.kt index 1ba206d..b9e733c 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaCheckpoint.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaCheckpoint.kt @@ -2,24 +2,28 @@ package nl.kallestruik.darena.types.arena import org.bukkit.configuration.ConfigurationSection import javax.naming.ConfigurationException +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable +import nl.kallestruik.darena.util.ConfigHelper +import nl.kallestruik.darena.util.Logger data class ArenaCheckpoint( val label: String, val lower: ArenaLocation, val upper: ArenaLocation, val spawn: String, -) { - companion object { - fun loadList(section: ConfigurationSection): List { - val list = mutableListOf() - for (key in section.getKeys(false)) { - list.add(load(section.getConfigurationSection(key)!!)) - } +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + Logger.trace(ArenaCheckpoint::class, "save(section: ${section.currentPath})") + section.set("label", label) + lower.save(ConfigHelper.getOrCreateSection(section, "lower")) + upper.save(ConfigHelper.getOrCreateSection(section, "upper")) + section.set("spawn", spawn) + } - return list - } - - fun load(section: ConfigurationSection): ArenaCheckpoint { + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaCheckpoint { + Logger.trace(ArenaCheckpoint::class, "load(section: ${section.currentPath})") return ArenaCheckpoint( section.name, ArenaLocation.load(section.getConfigurationSection("lower")!!), diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaEnchantment.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaEnchantment.kt index b1c693b..cb36343 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaEnchantment.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaEnchantment.kt @@ -2,25 +2,30 @@ package nl.kallestruik.darena.types.arena import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.InvalidConfigurationException +import nl.kallestruik.darena.types.ConfigListSaveable +import nl.kallestruik.darena.types.ConfigListLoadable +import nl.kallestruik.darena.util.Logger data class ArenaEnchantment( val name: String, val level: Int, -) { - companion object { - fun loadList(section: ConfigurationSection): List { - val list = mutableListOf() - for (key in section.getKeys(false)) { - list.add(load(section.getConfigurationSection(key)!!)) - } +): ConfigListSaveable { + override fun getKey(): String { + Logger.trace(ArenaEnchantment::class, "getKey()") + return name + } - return list - } + override fun getValue(): Int { + Logger.trace(ArenaEnchantment::class, "getValue()") + return level + } - fun load(section: ConfigurationSection): ArenaEnchantment { + companion object: ConfigListLoadable { + override fun loadFromList(key: String, value: Any): ArenaEnchantment { + Logger.trace(ArenaEnchantment::class, "loadFromList(key: $key, value: $value)") return ArenaEnchantment( - section.getString("name") ?: throw InvalidConfigurationException("Could not find required field name in section '${section.currentPath}'"), - section.getInt("level", 1) + key, + value as Int ) } } diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaItem.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaItem.kt index c95d574..dd8889a 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaItem.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaItem.kt @@ -1,6 +1,8 @@ package nl.kallestruik.darena.types.arena import nl.kallestruik.darena.util.ConfigHelper +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection @@ -9,18 +11,16 @@ data class ArenaItem( val amount: Int = 1, val enchantments: List = listOf(), val unbreakable: Boolean = false, -) { - companion object { - fun loadList(section: ConfigurationSection): List { - val list = mutableListOf() - for (key in section.getKeys(false)) { - list.add(load(section.getConfigurationSection(key)!!)) - } +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + section.set("material", material.toString()) + section.set("amount", amount) + ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "enchantments"), enchantments, ArenaEnchantment) + section.set("unbreakable", unbreakable) + } - return list - } - - fun load(section: ConfigurationSection): ArenaItem { + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaItem { val enchantments = section.getConfigurationSection("enchantments")?.let { ArenaEnchantment.loadList(it) } ?: listOf() diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLoadout.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLoadout.kt index 0a9367a..2c577dd 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLoadout.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLoadout.kt @@ -1,24 +1,25 @@ package nl.kallestruik.darena.types.arena import org.bukkit.configuration.ConfigurationSection +import nl.kallestruik.darena.util.ConfigHelper +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable data class ArenaLoadout( val name: String, val hotbar: List, val armor: List, val offhand: ArenaItem, -) { - companion object { - fun loadList(section: ConfigurationSection): List { - val list = mutableListOf() - for (key in section.getKeys(false)) { - list.add(load(section.getConfigurationSection(key)!!)) - } +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "hotbar"), hotbar) + ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "armor"), armor) + offhand.save(ConfigHelper.getOrCreateSection(section, "offhand")) + } - return list - } + companion object : ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaLoadout { - fun load(section: ConfigurationSection): ArenaLoadout { val hotbar = section.getConfigurationSection("hotbar")?.let { ArenaItem.loadList(it) }?: listOf() @@ -39,4 +40,4 @@ data class ArenaLoadout( ) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLocation.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLocation.kt index 5d202f8..bc77685 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLocation.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaLocation.kt @@ -1,15 +1,22 @@ package nl.kallestruik.darena.types.arena import org.bukkit.configuration.ConfigurationSection +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable data class ArenaLocation( val x: Int, val y: Int, val z: Int -) { - companion object { +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + section.set("x", x) + section.set("y", y) + section.set("z", z) + } - fun load(section: ConfigurationSection): ArenaLocation { + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaLocation { return ArenaLocation( section.getInt("x", 0), section.getInt("y", 0), diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPoints.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPoints.kt index c8419a4..e72d5b8 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPoints.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPoints.kt @@ -8,6 +8,17 @@ data class ArenaPoints( val lastManStanding: List = listOf(0), val checkpoints: Map> = mapOf() ) { + fun save(section: ConfigurationSection) { + section.set("kill", ConfigHelper.intListToString(kill)) + section.set("lastManStanding", ConfigHelper.intListToString(lastManStanding)) + + val checkpointSection = ConfigHelper.getOrCreateSection(section, "checkpoints") + for (entry in checkpoints) { + checkpointSection.set(entry.key, ConfigHelper.intListToString(entry.value)) + } + + } + companion object { fun load(section: ConfigurationSection): ArenaPoints { return ArenaPoints( diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPotionEffect.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPotionEffect.kt new file mode 100644 index 0000000..ce222a5 --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaPotionEffect.kt @@ -0,0 +1,28 @@ +package nl.kallestruik.darena.types.arena + +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable +import org.bukkit.configuration.ConfigurationSection + +class ArenaPotionEffect( + val name: String, + val strength: Int, + val duration: Int, + val hidden: Boolean +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + section.set("strength", strength) + section.set("duration", duration) + section.set("hidden", hidden) + } + + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaPotionEffect { + return ArenaPotionEffect( + section.name, + section.getInt("strength"), + section.getInt("duration"), + section.getBoolean("hidden")) + } + } +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawn.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawn.kt index 1a8a139..a4f2605 100644 --- a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawn.kt +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawn.kt @@ -1,6 +1,9 @@ package nl.kallestruik.darena.types.arena import nl.kallestruik.darena.arenas.world.ArenaWorld +import nl.kallestruik.darena.util.ConfigHelper +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable import org.bukkit.Location import org.bukkit.configuration.ConfigurationSection import org.bukkit.entity.Player @@ -13,23 +16,22 @@ data class ArenaSpawn( val yaw: Float, val pitch: Float, val loadout: String -) { +): ConfigSaveable { fun spawn(world: ArenaWorld, player: Player) { player.teleport(Location(world.world, x, y, z, yaw, pitch)) } - companion object { - fun loadList(section: ConfigurationSection): List { - val list = mutableListOf() + override fun save(section: ConfigurationSection) { + section.set("x", x) + section.set("y", y) + section.set("z", z) + section.set("yaw", yaw.toDouble()) + section.set("pitch", pitch.toDouble()) + section.set("loadout", loadout) + } - for (key in section.getKeys(false)) { - list.add(load(section.getConfigurationSection(key)!!)) - } - - return list - } - - fun load(section: ConfigurationSection): ArenaSpawn { + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaSpawn { return ArenaSpawn( section.name, section.getDouble("x"), @@ -41,4 +43,4 @@ data class ArenaSpawn( ) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawnRule.kt b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawnRule.kt new file mode 100644 index 0000000..52bc12f --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/types/arena/ArenaSpawnRule.kt @@ -0,0 +1,27 @@ +package nl.kallestruik.darena.types.arena + +import nl.kallestruik.darena.types.ConfigLoadable +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.util.ConfigHelper +import org.bukkit.configuration.ConfigurationSection + +class ArenaSpawnRule( + val reuseSpawns: Boolean, + val effects: Map, + val spawns: List +): ConfigSaveable { + override fun save(section: ConfigurationSection) { + section.set("reuseSpawns", reuseSpawns) + ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(section, "effects"), effects) + section.set("spawns", spawns) + } + + companion object: ConfigLoadable { + override fun load(section: ConfigurationSection): ArenaSpawnRule { + return ArenaSpawnRule( + section.getBoolean("reuseSpawn", true), + ConfigHelper.loadMap(section.getConfigurationSection("effects")!!, ArenaPotionEffect), + section.getStringList("spawns")) + } + } +} diff --git a/src/main/kotlin/nl/kallestruik/darena/util/ArenaUtil.kt b/src/main/kotlin/nl/kallestruik/darena/util/ArenaUtil.kt index 1ffa4ac..c8ce0cd 100644 --- a/src/main/kotlin/nl/kallestruik/darena/util/ArenaUtil.kt +++ b/src/main/kotlin/nl/kallestruik/darena/util/ArenaUtil.kt @@ -7,10 +7,12 @@ import org.bukkit.entity.Player class ArenaUtil { fun getPossibleParticipants(): List { + Logger.trace(ArenaUtil::class, "getPossibleParticipants()") return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SURVIVAL } } fun getPossibleSpectators(): List { + Logger.trace(ArenaUtil::class, "getPossibleSpectators()") return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SPECTATOR } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/nl/kallestruik/darena/util/ConfigHelper.kt b/src/main/kotlin/nl/kallestruik/darena/util/ConfigHelper.kt index 3218583..e377c59 100644 --- a/src/main/kotlin/nl/kallestruik/darena/util/ConfigHelper.kt +++ b/src/main/kotlin/nl/kallestruik/darena/util/ConfigHelper.kt @@ -1,6 +1,10 @@ package nl.kallestruik.darena.util import nl.kallestruik.darena.exceptions.MaterialNotFoundException +import nl.kallestruik.darena.types.ConfigSaveable +import nl.kallestruik.darena.types.ConfigLoadable +import nl.kallestruik.darena.types.ConfigListSaveable +import nl.kallestruik.darena.types.ConfigListLoadable import org.bukkit.Material import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.configuration.ConfigurationSection @@ -9,6 +13,7 @@ import java.io.* object ConfigHelper { fun getOrCreateConfig(file: File, template: String): YamlConfiguration { + Logger.trace(ConfigHelper::class, "getOrCreateConfig(file: ${file.toString()}, template: $template)") if (!file.parentFile.exists()) file.parentFile.mkdirs() if (!file.exists()) @@ -20,10 +25,12 @@ object ConfigHelper { } private fun createConfig(file: File, template: String) { + Logger.trace(ConfigHelper::class, "createConfig(file: ${file.toString()}, template: $template)") try { ConfigHelper.javaClass.getResourceAsStream("/$template").use { stream -> FileOutputStream(file).use { resStreamOut -> if (stream == null) { + Logger.error(ConfigHelper::class, "Cannot get resource \"$template\" from jar file.") throw IOException("Cannot get resource \"$template\" from Jar file.") } var readBytes: Int @@ -38,20 +45,77 @@ object ConfigHelper { } } + fun getOrCreateSection(section: ConfigurationSection, key: String): ConfigurationSection { + Logger.trace(ConfigHelper::class, "getOrCreateSection(section: ${section.currentPath}, key: $key)") + if (section.contains(key) && section.isConfigurationSection(key)) { + return section.getConfigurationSection(key)!! + } + + return section.createSection(key) + } + + fun saveMap(section: ConfigurationSection, map: Map) { + Logger.trace(ConfigHelper::class, "saveMap(section: ${section.currentPath}, map: ${map.toString()})") + for (entry in map.entries) { + entry.value.save(ConfigHelper.getOrCreateSection(section, entry.key)) + } + } + + fun saveList(section: ConfigurationSection, list: List) { + Logger.trace(ConfigHelper::class, "saveList(section: ${section.currentPath}, list: ${list.toString()})") + for (item in list) { + section.set(item.getKey(), item.getValue()) + } + } + + fun > loadMap(section: ConfigurationSection, loader: T): MutableMap { + Logger.trace(ConfigHelper::class, "loadMap(section: ${section.currentPath}, loader: ${loader::class.qualifiedName})") + val map = mutableMapOf() + for (key in section.getKeys(false)) { + map.put(key, loader.load(section.getConfigurationSection(key)!!)) + } + + return map + } + + fun > loadList(section: ConfigurationSection, loader: T): MutableList { + Logger.trace(ConfigHelper::class, "loadList(section: ${section.currentPath}, loader: ${loader::class.qualifiedName})") + val list = mutableListOf() + for (key in section.getKeys(false)) { + loader.loadFromList(key, section.get(key)!!) + } + + return list + } + @Throws(MaterialNotFoundException::class) fun matchMaterial(material: String): Material { - return Material.matchMaterial(material) ?: throw MaterialNotFoundException("There is not material with the name '$material'") + Logger.trace(ConfigHelper::class, "matchMaterial(material: $material)") + return Material.matchMaterial(material) ?: throw MaterialNotFoundException("There is no material with the name '$material'") } fun parseIntList(string: String): List { + Logger.trace(ConfigHelper::class, "parseIntList(string: $string)") val list = mutableListOf() for (key in string.split(" ")) { list.add(key.toInt()) } + return list } + fun intListToString(list: List): String { + Logger.trace(ConfigHelper::class, "list: ${list.toString()}") + val sb = StringBuilder() + for (i in list) { + sb.append(i) + } + + return sb.toString().trim() + } + fun parseStringIntListMap(section: ConfigurationSection): Map> { + Logger.trace(ConfigHelper::class, "parseStringIntListMap(section: ${section.currentPath})") val map = mutableMapOf>() for (key in section.getKeys(true)) { map[key] = parseIntList(section.getString(key)!!) diff --git a/src/main/kotlin/nl/kallestruik/darena/util/Logger.kt b/src/main/kotlin/nl/kallestruik/darena/util/Logger.kt new file mode 100644 index 0000000..0c9a38d --- /dev/null +++ b/src/main/kotlin/nl/kallestruik/darena/util/Logger.kt @@ -0,0 +1,53 @@ +package nl.kallestruik.darena.util + +import kotlin.reflect.KClass + +object Logger { + var level: LogLevel = LogLevel.INFO + + + fun trace(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.TRACE)) + println("[TRACE] [${source.qualifiedName}] $message") + } + + fun debug(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.DEBUG)) + println("[DEBUG] [${source.qualifiedName}] $message") + } + + fun info(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.INFO)) + println("[INFO] [${source.qualifiedName}] $message") + } + + fun warn(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.WARN)) + println("[WARN] [${source.qualifiedName}] $message") + } + + fun error(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.ERROR)) + println("[ERROR] [${source.qualifiedName}] $message") + } + + fun critical(source: KClass<*>, message: String) { + if (level.shouldLog(LogLevel.CRITICAL)) + println("[CRITICAL] [${source.qualifiedName}] $message") + } + + enum LogLevel( + val weight: Int + ) { + TRACE(100), + DEBUG(80), + INFO(60), + WARN(40), + ERROR(20), + CRITICAL(0) + + fun shouldLog(level: LogLevel): Boolean { + return level.weight <= weight + } + } +} diff --git a/src/main/resources/template/arena.yml b/src/main/resources/template/arena.yml index cf0cd7a..70fa6a9 100644 --- a/src/main/resources/template/arena.yml +++ b/src/main/resources/template/arena.yml @@ -8,35 +8,30 @@ # z: 0 # yaw: 0 # pitch: 0 -# loadout: "default" # label2: # x: 10 # y: 100 # z: 0 # yaw: 0 # pitch: 0 -# loadout: "default" # label3: # x: 10 # y: 100 # z: 10 # yaw: 0 # pitch: 0 -# loadout: "default" # label4: # x: 0 # y: 100 # z: 10 # yaw: 0 # pitch: 0 -# loadout: "default" # specatorSpawn: # x: 0 # y: 150 # z: 0 # yaw: 0 # pitch: 0 -# loadout: "none" #loadouts: # default: # hotbar: @@ -76,7 +71,7 @@ # x: 10 # y: 10 # z: 10 -# spawn: "label1" +# spawnRule: "label1" # checkpoint2: # lower: # x: 20 @@ -86,7 +81,7 @@ # x: 30 # y: 10 # z: 30 -# spawn: "label2" +# spawnRule: "label2" # finish: # lower: # x: 40 @@ -96,7 +91,7 @@ # x: 50 # y: 10 # z: 50 -# spawn: "spectatorSpawn" +# spawnRule: "spectator" #points: # kill: 10 5 # last-man-standing: 10 5 3 0 @@ -104,3 +99,22 @@ # checkpoint1: 10 # checkpoint2: 5 # finish: 20 10 5 +#spawnRules: +# initial: +# reuse-spawns: true +# effects: +# swiftness: +# strength: 1 +# duration: 10 +# hidden: false +# invisability: +# strength: 1 +# duration: 100000000 +# hidden: true +# spawns: +# - "label1" +# loadout: "default" +# spectator: +# reuse-spawns: true +# spawns: +# - "spectatorSpawn"