Start working on multi world support
This commit is contained in:
parent
d36250d6ea
commit
98ff252eba
9 changed files with 148 additions and 8 deletions
|
@ -21,6 +21,7 @@ repositories {
|
|||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
implementation(kotlin("reflect"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7")
|
||||
implementation("commons-codec:commons-codec:1.14")
|
||||
compileOnly("com.comphenix.protocol", "ProtocolLib", "4.5.0")
|
||||
compileOnly("org.spigotmc", "spigot-api", "1.15.2-R0.1-SNAPSHOT")
|
||||
|
|
|
@ -5,6 +5,7 @@ import de.moritzruth.spigot_ttt.game.InfoCommand
|
|||
import de.moritzruth.spigot_ttt.game.ReviveCommand
|
||||
import de.moritzruth.spigot_ttt.game.StartCommand
|
||||
import de.moritzruth.spigot_ttt.game.items.AddItemSpawnCommand
|
||||
import de.moritzruth.spigot_ttt.worlds.WorldCommand
|
||||
|
||||
object CommandManager {
|
||||
fun initializeCommands() {
|
||||
|
@ -15,5 +16,6 @@ object CommandManager {
|
|||
ResourcepackCommand()
|
||||
ReloadTTTConfigCommand()
|
||||
InfoCommand()
|
||||
WorldCommand()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package de.moritzruth.spigot_ttt
|
||||
|
||||
import de.moritzruth.spigot_ttt.game.GameManager
|
||||
import de.moritzruth.spigot_ttt.worlds.WorldManager
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
|
@ -12,6 +13,8 @@ class TTTPlugin: JavaPlugin() {
|
|||
override fun onEnable() {
|
||||
saveDefaultConfig()
|
||||
|
||||
WorldManager.removeNeglectedWorlds()
|
||||
|
||||
CommandManager.initializeCommands()
|
||||
GameManager.initialize()
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@ package de.moritzruth.spigot_ttt.utils
|
|||
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.nio.file.Paths
|
||||
import java.io.File
|
||||
|
||||
class ConfigurationFile(name: String): YamlConfiguration() {
|
||||
private val filePath = Paths.get(plugin.dataFolder.absolutePath, "$name.yml").toAbsolutePath().toString()
|
||||
class ConfigurationFile(private val file: File): YamlConfiguration() {
|
||||
constructor(name: String) : this(plugin.dataFolder.resolve("$name.yml"))
|
||||
|
||||
init {
|
||||
try {
|
||||
load(filePath)
|
||||
load(file)
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
|
||||
fun save() {
|
||||
save(filePath)
|
||||
save(file)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@ import org.bukkit.command.CommandSender
|
|||
import org.bukkit.command.TabCompleter
|
||||
|
||||
fun createTabCompleter(fn: (sender: CommandSender, index: Int) -> List<String>?) =
|
||||
createTabCompleter { sender, index, _ -> fn(sender, index) }
|
||||
|
||||
fun createTabCompleter(fn: (sender: CommandSender, index: Int, args: List<String>) -> List<String>?) =
|
||||
TabCompleter { sender, _, _, args ->
|
||||
val index = args.count()
|
||||
|
||||
val completions =
|
||||
if (index == 0) emptyList()
|
||||
else fn(sender, index) ?: emptyList()
|
||||
else fn(sender, index, args.toList()) ?: emptyList()
|
||||
|
||||
completions.filter { it.startsWith(args.last(), true) }
|
||||
}
|
||||
|
|
73
src/main/kotlin/de/moritzruth/spigot_ttt/worlds/TTTWorld.kt
Normal file
73
src/main/kotlin/de/moritzruth/spigot_ttt/worlds/TTTWorld.kt
Normal file
|
@ -0,0 +1,73 @@
|
|||
package de.moritzruth.spigot_ttt.worlds
|
||||
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.bukkit.WorldCreator
|
||||
|
||||
class TTTWorld(val sourceWorld: WorldManager.SourceWorld) {
|
||||
var state: State = State.NOT_COPIED; private set
|
||||
enum class State {
|
||||
NOT_COPIED,
|
||||
COPYING,
|
||||
COPIED,
|
||||
LOADED,
|
||||
UNLOADING
|
||||
}
|
||||
|
||||
val id = WorldManager.tttWorlds.count()
|
||||
val actualWorldName = "${WORLD_PREFIX}${id}"
|
||||
private val worldDir = plugin.server.worldContainer.resolve("./$actualWorldName")
|
||||
|
||||
init {
|
||||
WorldManager.tttWorlds.add(this)
|
||||
}
|
||||
|
||||
suspend fun copy() {
|
||||
if (state != State.NOT_COPIED) throw IllegalStateException("The world was already copied")
|
||||
state = State.COPYING
|
||||
|
||||
coroutineScope {
|
||||
launch(Dispatchers.IO) {
|
||||
sourceWorld.dir.copyRecursively(worldDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun load() {
|
||||
if (state != State.COPIED) throw IllegalStateException("The world was not copied yet or already loaded")
|
||||
plugin.server.createWorld(WorldCreator.name(actualWorldName))
|
||||
}
|
||||
|
||||
suspend fun save() {
|
||||
if (state != State.LOADED) throw IllegalStateException("The world must be loaded")
|
||||
|
||||
coroutineScope {
|
||||
launch(Dispatchers.IO) {
|
||||
val tempWorldDir = WorldManager.worldsDir.resolve("./${sourceWorld.name}_$id")
|
||||
worldDir.copyRecursively(tempWorldDir)
|
||||
sourceWorld.dir.deleteRecursively()
|
||||
tempWorldDir.renameTo(sourceWorld.dir)
|
||||
state = State.NOT_COPIED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun unloadAndRemove() {
|
||||
if (state != State.LOADED) throw IllegalStateException("The world must be loaded")
|
||||
state = State.UNLOADING
|
||||
plugin.server.unloadWorld(actualWorldName, false)
|
||||
|
||||
coroutineScope {
|
||||
launch(Dispatchers.IO) {
|
||||
worldDir.deleteRecursively()
|
||||
state = State.NOT_COPIED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val WORLD_PREFIX = "tempworld_"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package de.moritzruth.spigot_ttt.worlds
|
||||
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import de.moritzruth.spigot_ttt.utils.createTabCompleter
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandExecutor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class WorldCommand: CommandExecutor {
|
||||
init {
|
||||
val command = plugin.getCommand("world")!!
|
||||
command.setExecutor(this)
|
||||
command.tabCompleter = createTabCompleter { _, index, args ->
|
||||
return@createTabCompleter when(index) {
|
||||
0 -> listOf("load", "save", "join", "list")
|
||||
1 -> when(args[0].toLowerCase()) {
|
||||
"load" -> WorldManager.sourceWorlds.map { it.name }
|
||||
"save", "join" -> WorldManager.tttWorlds.map { it.id.toString() }
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package de.moritzruth.spigot_ttt.worlds
|
||||
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import de.moritzruth.spigot_ttt.utils.ConfigurationFile
|
||||
import java.io.File
|
||||
|
||||
object WorldManager {
|
||||
data class SourceWorld(val dir: File) {
|
||||
val name: String = dir.name
|
||||
val config = ConfigurationFile(dir.resolve("config.yml"))
|
||||
}
|
||||
|
||||
val worldsDir = plugin.dataFolder.resolve("./worlds").also { it.mkdirs() }
|
||||
val sourceWorlds = worldsDir.listFiles(File::isDirectory)!!.map { SourceWorld(it) }
|
||||
|
||||
val tttWorlds = mutableSetOf<TTTWorld>()
|
||||
|
||||
fun removeNeglectedWorlds() {
|
||||
plugin.server.worldContainer.listFiles { file ->
|
||||
file.isDirectory && file.name.startsWith(TTTWorld.WORLD_PREFIX) &&
|
||||
tttWorlds.find { it.actualWorldName == file.name } != null
|
||||
}!!.forEach { it.deleteRecursively() }
|
||||
}
|
||||
}
|
|
@ -23,12 +23,12 @@ commands:
|
|||
description: Add an item spawn
|
||||
|
||||
revive:
|
||||
usage: /revive [player] ['here']
|
||||
usage: /revive [Player] ['here']
|
||||
permission: ttt.revive
|
||||
description: Revive yourself or another player at the world spawn or at your location
|
||||
|
||||
info:
|
||||
usage: /info [player]
|
||||
usage: /info [Player]
|
||||
permission: ttt.info
|
||||
description: Show information about all players or a specific player
|
||||
|
||||
|
@ -45,3 +45,8 @@ commands:
|
|||
permission: ttt.reload
|
||||
aliases:
|
||||
- rt
|
||||
|
||||
world:
|
||||
usage: /world load <Name> OR /world <'join'|'save'> <World ID> OR /world list
|
||||
description: Perform world operations
|
||||
permission: ttt.world
|
||||
|
|
Reference in a new issue