DArena/src/main/kotlin/nl/kallestruik/darena/managers/ArenaManager.kt

145 lines
4.8 KiB
Kotlin

package nl.kallestruik.darena.managers
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import nl.kallestruik.darena.arenas.Arena
import nl.kallestruik.darena.arenas.ArenaConfig
import nl.kallestruik.darena.exceptions.ArenaCreationException
import nl.kallestruik.darena.exceptions.ArenaEndAbortedException
import nl.kallestruik.darena.exceptions.ArenaStartAbortedException
import nl.kallestruik.darena.types.ArenaFeature
import nl.kallestruik.darena.types.Reloadable
import nl.kallestruik.darena.util.Logger
import nl.kallestruik.dlib.config.ConfigHelper.toConfigSchema
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin
import java.io.File
import java.nio.file.Files
class ArenaManager(
private val teamManager: TeamManager,
private val pointsManager: PointsManager,
private val configManager: ConfigManager,
private val plugin: JavaPlugin,
private val arenaFolder: File,
schemaFile: File,
): Reloadable {
lateinit var editManager: EditManager;
private val arenas: MutableMap<String, Arena> = mutableMapOf()
var currentArena: Arena? = null
override fun reload() {
arenas.clear()
loadArenas()
}
init {
schemaFile.parentFile.mkdirs()
schemaFile.writeText(Json.encodeToString(ArenaConfig.serializer().descriptor.toConfigSchema(listOf())))
}
fun loadArenas() {
Logger.trace(ArenaManager::class, "loadArenas()")
arenaFolder.mkdirs()
Files.walk(arenaFolder.toPath()).use { walk ->
walk.forEach { path ->
if (Files.isDirectory(path))
return@forEach
if (path.toString().endsWith(".yml")) {
Logger.info(ArenaManager::class, "Skipping legacy config at $path")
return@forEach
}
Logger.info(ArenaManager::class, "Loading arena from: $path")
val config = ArenaConfig.load(path.toFile())
arenas[config.name] = Arena(
config,
plugin,
configManager,
this,
teamManager,
pointsManager,
)
}
}
}
@Throws(ArenaStartAbortedException::class)
fun start(arena: Arena, loadingTimeOverride: Int, spectatorTimeOverride: Int, beforeStartTimeOverride: Int) {
Logger.trace(ArenaManager::class, "start(arena: ${arena.config.name}, loadingTimeOverride: $loadingTimeOverride, spectatorTimeOverride: $spectatorTimeOverride, beforeStartTimeOverride: $beforeStartTimeOverride)")
if (currentArena != null)
throw ArenaStartAbortedException("There is currently another arena in progress. Please end that one first.")
if (editManager.isEditing())
throw ArenaStartAbortedException("There is currently an arena being edited. Please finish that first.")
// Try to start the arena. If something goes wrong clean it up and throw the exception again so the user can be informed.
arena.start(loadingTimeOverride, spectatorTimeOverride, beforeStartTimeOverride)
currentArena = arena
}
@Throws(ArenaEndAbortedException::class)
fun end() {
Logger.trace(ArenaManager::class, "end()")
if (currentArena == null)
throw ArenaEndAbortedException("There is currently no arena in progress.")
currentArena!!.end()
currentArena = null
}
@Throws(ArenaCreationException::class)
fun createArena(name: String) {
if (arenas.contains(name))
throw ArenaCreationException("Arena with name $name already exists!")
val config = ArenaConfig(name = name)
config.file = File(arenaFolder, "$name.json")
arenas[config.name] = Arena(
config,
plugin,
configManager,
this,
teamManager,
pointsManager,
)
config.save(false)
}
fun saveConfig(arena: Arena) {
arena.config.save(false)
}
fun getArena(name: String): Arena? {
Logger.trace(ArenaManager::class, "getArena(name: $name)")
return arenas[name]
}
fun getAllArenaNames(): Collection<String> {
Logger.trace(ArenaManager::class, "getAllArenaNames()")
return arenas.keys
}
fun shouldProcessEvent(feature: ArenaFeature, player: Player?): Boolean {
if (currentArena == null)
return false
if (!currentArena!!.session!!.isInProgress)
return false
if (feature != ArenaFeature.ALWAYS && !currentArena!!.hasFeature(feature))
return false
if ((player != null && !currentArena!!.session!!.participants.contains(player)))
return false
return true
}
}