Bunch of config stuff + logging basics

master
kalle 2021-11-07 16:31:24 +01:00
parent f05208f1a0
commit cbf1e64db9
22 changed files with 372 additions and 110 deletions

View File

@ -11,22 +11,6 @@ class DArena : JavaPlugin() {
private lateinit var pointsManager: PointsManager private lateinit var pointsManager: PointsManager
private lateinit var teamManager: TeamManager 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() { override fun onEnable() {
configManager = ConfigManager(File(dataFolder, "config.yml")) configManager = ConfigManager(File(dataFolder, "config.yml"))
configManager.load() configManager.load()

View File

@ -11,7 +11,7 @@ class Arena(
private val arenaUtil: ArenaUtil, private val arenaUtil: ArenaUtil,
private val plugin: JavaPlugin, private val plugin: JavaPlugin,
private val world: ArenaWorld = ArenaWorld(config.name, plugin), private val world: ArenaWorld = ArenaWorld(config.name, plugin),
) { ) {
private lateinit var session: ArenaSession private lateinit var session: ArenaSession
// Simple stuff done: 0.001474s // Simple stuff done: 0.001474s
// createArena start: 0.0001026s // createArena start: 0.0001026s
@ -33,19 +33,25 @@ class Arena(
session.spectators.addAll(arenaUtil.getPossibleSpectators()); session.spectators.addAll(arenaUtil.getPossibleSpectators());
// Reset the world // Reset the world
world.reset() world.reset()
// Place all spectators in the arena // Place all spectators in the arena
session.spectators.forEach { session.spectators.forEach {
// config.spectatorSpawn.spawn(world, it) // config.spectatorSpawn.spawn(world, it)
} }
// Randomize spawns // Randomize spawns
session.spawns.addAll(config.spawns) session.initialSpawns.addAll(config.spawns.filter {
session.spawns.shuffle() //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 // Spawn all the players
session.participants.forEachIndexed { index, player -> session.participants.forEachIndexed { index, player ->
// TODO: Freeze players in place (for in arena countdown) (if countdown is 0 dont freeze them) // 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: // TODO:
} }

View File

@ -1,44 +1,73 @@
package nl.kallestruik.darena.arenas package nl.kallestruik.darena.arenas
import nl.kallestruik.darena.types.arena.ArenaLoadout 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.ArenaCheckpoint
import nl.kallestruik.darena.types.arena.ArenaPoints 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 nl.kallestruik.darena.util.ConfigHelper
import java.io.File import java.io.File
import org.bukkit.configuration.InvalidConfigurationException
import org.bukkit.configuration.file.YamlConfiguration
import kotlin.collections.mutableMapOf
data class ArenaConfig( data class ArenaConfig(
var name: String = "[Missing name]", var name: String,
var spawns: List<ArenaSpawn> = emptyList(), var file: File,
var loadouts: List<ArenaLoadout> = emptyList(), var spawns: MutableMap<String, ArenaSpawn> = mutableMapOf(),
var checkpoints: List<ArenaCheckpoint> = emptyList(), var loadouts: MutableMap<String, ArenaLoadout> = mutableMapOf(),
var checkpoints: MutableMap<String, ArenaCheckpoint> = mutableMapOf(),
var points: ArenaPoints = ArenaPoints(), var points: ArenaPoints = ArenaPoints(),
var spawnRules: MutableMap<String, ArenaSpawnRule> = 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 { companion object {
@Throws(InvalidConfigurationException::class)
fun load(file: File): ArenaConfig { fun load(file: File): ArenaConfig {
val config = ConfigHelper.getOrCreateConfig(file, "template/arena.yml") val config = ConfigHelper.getOrCreateConfig(file, "template/arena.yml")
val arenaConfig = ArenaConfig() if (!config.contains("name")) {
throw InvalidConfigurationException("The arena configuration file '${file.name}' does not contain the required attribute 'name'")
if (config.contains("name")) {
arenaConfig.name = config.getString("name")!!
} }
val arenaConfig = ArenaConfig(config.getString("name")!!, file)
if (config.contains("spawns")) { if (config.contains("spawns")) {
arenaConfig.spawns = ArenaSpawn.loadList(config.getConfigurationSection("spawns")!!) arenaConfig.spawns = ConfigHelper.loadMap(config.getConfigurationSection("spawns")!!, ArenaSpawn)
} }
if (config.contains("loadouts")) { if (config.contains("loadouts")) {
arenaConfig.loadouts = ArenaLoadout.loadList(config.getConfigurationSection("loadouts")!!) arenaConfig.loadouts = ConfigHelper.loadMap(config.getConfigurationSection("loadouts")!!, ArenaLoadout)
} }
if (config.contains("checkpoints")) { if (config.contains("checkpoints")) {
arenaConfig.checkpoints = ArenaCheckpoint.loadList(config.getConfigurationSection("checkpoints")!!) arenaConfig.checkpoints = ConfigHelper.loadMap(config.getConfigurationSection("checkpoints")!!, ArenaCheckpoint)
} }
if (config.contains("points")) { if (config.contains("points")) {
arenaConfig.points = ArenaPoints.load(config.getConfigurationSection("points")!!) arenaConfig.points = ArenaPoints.load(config.getConfigurationSection("points")!!)
} }
if (config.contains("spawnRules")) {
arenaConfig.spawnRules = ConfigHelper.loadMap(config.getConfigurationSection("spawnRules")!!, ArenaSpawnRule)
}
return arenaConfig return arenaConfig
} }
} }

View File

@ -2,11 +2,12 @@ package nl.kallestruik.darena.arenas
import nl.kallestruik.darena.types.arena.ArenaSpawn import nl.kallestruik.darena.types.arena.ArenaSpawn
import org.bukkit.entity.Player import org.bukkit.entity.Player
import java.util.UUID
data class ArenaSession( data class ArenaSession(
val participants: MutableList<Player> = ArrayList(), val participants: MutableList<Player> = ArrayList(),
val spectators: MutableList<Player> = ArrayList(), val spectators: MutableList<Player> = ArrayList(),
val completedObjective: MutableList<Player> = ArrayList(), val completedObjective: MutableList<UUID> = ArrayList(),
val deaths: MutableList<Player> = ArrayList(), val deaths: MutableList<UUID> = ArrayList(),
val spawns: MutableList<ArenaSpawn> = ArrayList(), val initialSpawns: MutableList<String> = ArrayList(),
) )

View File

@ -19,9 +19,9 @@ class ArenaManager(
arenas.add(Arena( arenas.add(Arena(
ArenaConfig.load(path.toFile()), ArenaConfig.load(path.toFile()),
arenaUtil, arenaUtil,
plugin plugin)
)) )
} }
} }
} }
} }

View File

@ -0,0 +1,4 @@
package nl.kallestruik.darena.types
interface ConfigListLoadable<T> {
fun loadFromList(key: String, value: Any): T

View File

@ -0,0 +1,7 @@
package nl.kallestruik.darena.types
interface ConfigListSaveable {
fun getKey(): String
fun getValue(): Any
}

View File

@ -0,0 +1,6 @@
package nl.kallestruik.darena.types
import org.bukkit.configuration.ConfigurationSection
interface ConfigLoadable<T> {
fun load(section: ConfigurationSection): T

View File

@ -0,0 +1,7 @@
package nl.kallestruik.darena.types
import org.bukkit.configuration.ConfigurationSection
interface ConfigSaveable {
fun save(section: ConfigurationSection)
}

View File

@ -2,24 +2,28 @@ package nl.kallestruik.darena.types.arena
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import javax.naming.ConfigurationException 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( data class ArenaCheckpoint(
val label: String, val label: String,
val lower: ArenaLocation, val lower: ArenaLocation,
val upper: ArenaLocation, val upper: ArenaLocation,
val spawn: String, val spawn: String,
) { ): ConfigSaveable {
companion object { override fun save(section: ConfigurationSection) {
fun loadList(section: ConfigurationSection): List<ArenaCheckpoint> { Logger.trace(ArenaCheckpoint::class, "save(section: ${section.currentPath})")
val list = mutableListOf<ArenaCheckpoint>() section.set("label", label)
for (key in section.getKeys(false)) { lower.save(ConfigHelper.getOrCreateSection(section, "lower"))
list.add(load(section.getConfigurationSection(key)!!)) upper.save(ConfigHelper.getOrCreateSection(section, "upper"))
} section.set("spawn", spawn)
}
return list companion object: ConfigLoadable<ArenaCheckpoint> {
} override fun load(section: ConfigurationSection): ArenaCheckpoint {
Logger.trace(ArenaCheckpoint::class, "load(section: ${section.currentPath})")
fun load(section: ConfigurationSection): ArenaCheckpoint {
return ArenaCheckpoint( return ArenaCheckpoint(
section.name, section.name,
ArenaLocation.load(section.getConfigurationSection("lower")!!), ArenaLocation.load(section.getConfigurationSection("lower")!!),

View File

@ -2,25 +2,30 @@ package nl.kallestruik.darena.types.arena
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.InvalidConfigurationException 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( data class ArenaEnchantment(
val name: String, val name: String,
val level: Int, val level: Int,
) { ): ConfigListSaveable {
companion object { override fun getKey(): String {
fun loadList(section: ConfigurationSection): List<ArenaEnchantment> { Logger.trace(ArenaEnchantment::class, "getKey()")
val list = mutableListOf<ArenaEnchantment>() return name
for (key in section.getKeys(false)) { }
list.add(load(section.getConfigurationSection(key)!!))
}
return list override fun getValue(): Int {
} Logger.trace(ArenaEnchantment::class, "getValue()")
return level
}
fun load(section: ConfigurationSection): ArenaEnchantment { companion object: ConfigListLoadable<ArenaEnchantment> {
override fun loadFromList(key: String, value: Any): ArenaEnchantment {
Logger.trace(ArenaEnchantment::class, "loadFromList(key: $key, value: $value)")
return ArenaEnchantment( return ArenaEnchantment(
section.getString("name") ?: throw InvalidConfigurationException("Could not find required field name in section '${section.currentPath}'"), key,
section.getInt("level", 1) value as Int
) )
} }
} }

View File

@ -1,6 +1,8 @@
package nl.kallestruik.darena.types.arena package nl.kallestruik.darena.types.arena
import nl.kallestruik.darena.util.ConfigHelper 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.Material
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
@ -9,18 +11,16 @@ data class ArenaItem(
val amount: Int = 1, val amount: Int = 1,
val enchantments: List<ArenaEnchantment> = listOf(), val enchantments: List<ArenaEnchantment> = listOf(),
val unbreakable: Boolean = false, val unbreakable: Boolean = false,
) { ): ConfigSaveable {
companion object { override fun save(section: ConfigurationSection) {
fun loadList(section: ConfigurationSection): List<ArenaItem> { section.set("material", material.toString())
val list = mutableListOf<ArenaItem>() section.set("amount", amount)
for (key in section.getKeys(false)) { ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "enchantments"), enchantments, ArenaEnchantment)
list.add(load(section.getConfigurationSection(key)!!)) section.set("unbreakable", unbreakable)
} }
return list companion object: ConfigLoadable<ArenaItem> {
} override fun load(section: ConfigurationSection): ArenaItem {
fun load(section: ConfigurationSection): ArenaItem {
val enchantments = section.getConfigurationSection("enchantments")?.let { val enchantments = section.getConfigurationSection("enchantments")?.let {
ArenaEnchantment.loadList(it) ArenaEnchantment.loadList(it)
} ?: listOf() } ?: listOf()

View File

@ -1,24 +1,25 @@
package nl.kallestruik.darena.types.arena package nl.kallestruik.darena.types.arena
import org.bukkit.configuration.ConfigurationSection 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( data class ArenaLoadout(
val name: String, val name: String,
val hotbar: List<ArenaItem>, val hotbar: List<ArenaItem>,
val armor: List<ArenaItem>, val armor: List<ArenaItem>,
val offhand: ArenaItem, val offhand: ArenaItem,
) { ): ConfigSaveable {
companion object { override fun save(section: ConfigurationSection) {
fun loadList(section: ConfigurationSection): List<ArenaLoadout> { ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "hotbar"), hotbar)
val list = mutableListOf<ArenaLoadout>() ConfigHelper.saveList(ConfigHelper.getOrCreateSection(section, "armor"), armor)
for (key in section.getKeys(false)) { offhand.save(ConfigHelper.getOrCreateSection(section, "offhand"))
list.add(load(section.getConfigurationSection(key)!!)) }
}
return list companion object : ConfigLoadable<ArenaLoadout> {
} override fun load(section: ConfigurationSection): ArenaLoadout {
fun load(section: ConfigurationSection): ArenaLoadout {
val hotbar = section.getConfigurationSection("hotbar")?.let { val hotbar = section.getConfigurationSection("hotbar")?.let {
ArenaItem.loadList(it) ArenaItem.loadList(it)
}?: listOf() }?: listOf()
@ -39,4 +40,4 @@ data class ArenaLoadout(
) )
} }
} }
} }

View File

@ -1,15 +1,22 @@
package nl.kallestruik.darena.types.arena package nl.kallestruik.darena.types.arena
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import nl.kallestruik.darena.types.ConfigSaveable
import nl.kallestruik.darena.types.ConfigLoadable
data class ArenaLocation( data class ArenaLocation(
val x: Int, val x: Int,
val y: Int, val y: Int,
val z: Int val z: Int
) { ): ConfigSaveable {
companion object { 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<ArenaLocation> {
override fun load(section: ConfigurationSection): ArenaLocation {
return ArenaLocation( return ArenaLocation(
section.getInt("x", 0), section.getInt("x", 0),
section.getInt("y", 0), section.getInt("y", 0),

View File

@ -8,6 +8,17 @@ data class ArenaPoints(
val lastManStanding: List<Int> = listOf(0), val lastManStanding: List<Int> = listOf(0),
val checkpoints: Map<String, List<Int>> = mapOf() val checkpoints: Map<String, List<Int>> = 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 { companion object {
fun load(section: ConfigurationSection): ArenaPoints { fun load(section: ConfigurationSection): ArenaPoints {
return ArenaPoints( return ArenaPoints(

View File

@ -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<ArenaPotionEffect> {
override fun load(section: ConfigurationSection): ArenaPotionEffect {
return ArenaPotionEffect(
section.name,
section.getInt("strength"),
section.getInt("duration"),
section.getBoolean("hidden"))
}
}
}

View File

@ -1,6 +1,9 @@
package nl.kallestruik.darena.types.arena package nl.kallestruik.darena.types.arena
import nl.kallestruik.darena.arenas.world.ArenaWorld 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.Location
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.entity.Player import org.bukkit.entity.Player
@ -13,23 +16,22 @@ data class ArenaSpawn(
val yaw: Float, val yaw: Float,
val pitch: Float, val pitch: Float,
val loadout: String val loadout: String
) { ): ConfigSaveable {
fun spawn(world: ArenaWorld, player: Player) { fun spawn(world: ArenaWorld, player: Player) {
player.teleport(Location(world.world, x, y, z, yaw, pitch)) player.teleport(Location(world.world, x, y, z, yaw, pitch))
} }
companion object { override fun save(section: ConfigurationSection) {
fun loadList(section: ConfigurationSection): List<ArenaSpawn> { section.set("x", x)
val list = mutableListOf<ArenaSpawn>() 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)) { companion object: ConfigLoadable<ArenaSpawn> {
list.add(load(section.getConfigurationSection(key)!!)) override fun load(section: ConfigurationSection): ArenaSpawn {
}
return list
}
fun load(section: ConfigurationSection): ArenaSpawn {
return ArenaSpawn( return ArenaSpawn(
section.name, section.name,
section.getDouble("x"), section.getDouble("x"),
@ -41,4 +43,4 @@ data class ArenaSpawn(
) )
} }
} }
} }

View File

@ -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<String, ArenaPotionEffect>,
val spawns: List<String>
): ConfigSaveable {
override fun save(section: ConfigurationSection) {
section.set("reuseSpawns", reuseSpawns)
ConfigHelper.saveMap(ConfigHelper.getOrCreateSection(section, "effects"), effects)
section.set("spawns", spawns)
}
companion object: ConfigLoadable<ArenaSpawnRule> {
override fun load(section: ConfigurationSection): ArenaSpawnRule {
return ArenaSpawnRule(
section.getBoolean("reuseSpawn", true),
ConfigHelper.loadMap(section.getConfigurationSection("effects")!!, ArenaPotionEffect),
section.getStringList("spawns"))
}
}
}

View File

@ -7,10 +7,12 @@ import org.bukkit.entity.Player
class ArenaUtil { class ArenaUtil {
fun getPossibleParticipants(): List<Player> { fun getPossibleParticipants(): List<Player> {
Logger.trace(ArenaUtil::class, "getPossibleParticipants()")
return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SURVIVAL } return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SURVIVAL }
} }
fun getPossibleSpectators(): List<Player> { fun getPossibleSpectators(): List<Player> {
Logger.trace(ArenaUtil::class, "getPossibleSpectators()")
return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SPECTATOR } return Bukkit.getOnlinePlayers().filter { it.gameMode == GameMode.SPECTATOR }
} }
} }

View File

@ -1,6 +1,10 @@
package nl.kallestruik.darena.util package nl.kallestruik.darena.util
import nl.kallestruik.darena.exceptions.MaterialNotFoundException 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.Material
import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.configuration.file.YamlConfiguration
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
@ -9,6 +13,7 @@ import java.io.*
object ConfigHelper { object ConfigHelper {
fun getOrCreateConfig(file: File, template: String): YamlConfiguration { fun getOrCreateConfig(file: File, template: String): YamlConfiguration {
Logger.trace(ConfigHelper::class, "getOrCreateConfig(file: ${file.toString()}, template: $template)")
if (!file.parentFile.exists()) if (!file.parentFile.exists())
file.parentFile.mkdirs() file.parentFile.mkdirs()
if (!file.exists()) if (!file.exists())
@ -20,10 +25,12 @@ object ConfigHelper {
} }
private fun createConfig(file: File, template: String) { private fun createConfig(file: File, template: String) {
Logger.trace(ConfigHelper::class, "createConfig(file: ${file.toString()}, template: $template)")
try { try {
ConfigHelper.javaClass.getResourceAsStream("/$template").use { stream -> ConfigHelper.javaClass.getResourceAsStream("/$template").use { stream ->
FileOutputStream(file).use { resStreamOut -> FileOutputStream(file).use { resStreamOut ->
if (stream == null) { if (stream == null) {
Logger.error(ConfigHelper::class, "Cannot get resource \"$template\" from jar file.")
throw IOException("Cannot get resource \"$template\" from Jar file.") throw IOException("Cannot get resource \"$template\" from Jar file.")
} }
var readBytes: Int 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 <T: ConfigSaveable> saveMap(section: ConfigurationSection, map: Map<String, T>) {
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 <T: ConfigListSaveable> saveList(section: ConfigurationSection, list: List<T>) {
Logger.trace(ConfigHelper::class, "saveList(section: ${section.currentPath}, list: ${list.toString()})")
for (item in list) {
section.set(item.getKey(), item.getValue())
}
}
fun <R, T: ConfigLoadable<R>> loadMap(section: ConfigurationSection, loader: T): MutableMap<String, R> {
Logger.trace(ConfigHelper::class, "loadMap(section: ${section.currentPath}, loader: ${loader::class.qualifiedName})")
val map = mutableMapOf<String, R>()
for (key in section.getKeys(false)) {
map.put(key, loader.load(section.getConfigurationSection(key)!!))
}
return map
}
fun <R, T: ConfigListLoadable<R>> loadList(section: ConfigurationSection, loader: T): MutableList<R> {
Logger.trace(ConfigHelper::class, "loadList(section: ${section.currentPath}, loader: ${loader::class.qualifiedName})")
val list = mutableListOf<R>()
for (key in section.getKeys(false)) {
loader.loadFromList(key, section.get(key)!!)
}
return list
}
@Throws(MaterialNotFoundException::class) @Throws(MaterialNotFoundException::class)
fun matchMaterial(material: String): Material { 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<Int> { fun parseIntList(string: String): List<Int> {
Logger.trace(ConfigHelper::class, "parseIntList(string: $string)")
val list = mutableListOf<Int>() val list = mutableListOf<Int>()
for (key in string.split(" ")) { for (key in string.split(" ")) {
list.add(key.toInt()) list.add(key.toInt())
} }
return list return list
} }
fun intListToString(list: List<Int>): 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<String, List<Int>> { fun parseStringIntListMap(section: ConfigurationSection): Map<String, List<Int>> {
Logger.trace(ConfigHelper::class, "parseStringIntListMap(section: ${section.currentPath})")
val map = mutableMapOf<String, List<Int>>() val map = mutableMapOf<String, List<Int>>()
for (key in section.getKeys(true)) { for (key in section.getKeys(true)) {
map[key] = parseIntList(section.getString(key)!!) map[key] = parseIntList(section.getString(key)!!)

View File

@ -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
}
}
}

View File

@ -8,35 +8,30 @@
# z: 0 # z: 0
# yaw: 0 # yaw: 0
# pitch: 0 # pitch: 0
# loadout: "default"
# label2: # label2:
# x: 10 # x: 10
# y: 100 # y: 100
# z: 0 # z: 0
# yaw: 0 # yaw: 0
# pitch: 0 # pitch: 0
# loadout: "default"
# label3: # label3:
# x: 10 # x: 10
# y: 100 # y: 100
# z: 10 # z: 10
# yaw: 0 # yaw: 0
# pitch: 0 # pitch: 0
# loadout: "default"
# label4: # label4:
# x: 0 # x: 0
# y: 100 # y: 100
# z: 10 # z: 10
# yaw: 0 # yaw: 0
# pitch: 0 # pitch: 0
# loadout: "default"
# specatorSpawn: # specatorSpawn:
# x: 0 # x: 0
# y: 150 # y: 150
# z: 0 # z: 0
# yaw: 0 # yaw: 0
# pitch: 0 # pitch: 0
# loadout: "none"
#loadouts: #loadouts:
# default: # default:
# hotbar: # hotbar:
@ -76,7 +71,7 @@
# x: 10 # x: 10
# y: 10 # y: 10
# z: 10 # z: 10
# spawn: "label1" # spawnRule: "label1"
# checkpoint2: # checkpoint2:
# lower: # lower:
# x: 20 # x: 20
@ -86,7 +81,7 @@
# x: 30 # x: 30
# y: 10 # y: 10
# z: 30 # z: 30
# spawn: "label2" # spawnRule: "label2"
# finish: # finish:
# lower: # lower:
# x: 40 # x: 40
@ -96,7 +91,7 @@
# x: 50 # x: 50
# y: 10 # y: 10
# z: 50 # z: 50
# spawn: "spectatorSpawn" # spawnRule: "spectator"
#points: #points:
# kill: 10 5 # kill: 10 5
# last-man-standing: 10 5 3 0 # last-man-standing: 10 5 3 0
@ -104,3 +99,22 @@
# checkpoint1: 10 # checkpoint1: 10
# checkpoint2: 5 # checkpoint2: 5
# finish: 20 10 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"