1
0
Fork 0

Start working on multi world support

This commit is contained in:
Moritz Ruth 2020-06-20 00:04:40 +02:00
parent d36250d6ea
commit 98ff252eba
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
9 changed files with 148 additions and 8 deletions

View file

@ -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")

View file

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

View file

@ -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()

View file

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

View 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) }
}

View 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_"
}
}

View file

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

View file

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

View file

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