diff options
author | Dico200 <dico.karssiens@gmail.com> | 2018-07-22 20:51:46 +0200 |
---|---|---|
committer | Dico200 <dico.karssiens@gmail.com> | 2018-07-22 20:51:46 +0200 |
commit | 9e31ea7e51762292301858b6821e27e971b3981b (patch) | |
tree | cbaa0c2444919f0d8717f2dbe06685773517e9e5 | |
parent | 8a0a77b8ba4a2e160558809b592e4bc393e7c997 (diff) |
Add a few development commands. World generation works
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/ParcelWorld.kt | 32 | ||||
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt | 49 | ||||
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/PlotCommands.kt | 25 | ||||
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/storage/Exposed.kt | 5 | ||||
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt | 74 | ||||
-rw-r--r-- | src/main/resources/logback.xml | 2 |
6 files changed, 168 insertions, 19 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt index 8acf7c8..495a770 100644 --- a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt +++ b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt @@ -2,7 +2,7 @@ package io.dico.parcels2 import io.dico.parcels2.math.Vec2i import io.dico.parcels2.math.floor -import kotlinx.coroutines.experimental.launch +import io.dico.parcels2.util.doAwait import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.World @@ -10,10 +10,11 @@ import org.bukkit.WorldCreator import org.bukkit.block.Block import org.bukkit.entity.Entity import org.bukkit.entity.Player +import org.bukkit.plugin.Plugin import java.util.* import kotlin.coroutines.experimental.buildSequence -class Worlds { +class Worlds(private val plugin: Plugin) { val worlds: Map<String, ParcelWorld> get() = _worlds private val _worlds: MutableMap<String, ParcelWorld> = HashMap() @@ -48,9 +49,26 @@ class Worlds { _worlds.put(worldName, world) if (Bukkit.getWorld(worldName) == null) { - val bworld = WorldCreator(worldName).generator(world.generator).createWorld() - val spawn = world.generator.getFixedSpawnLocation(bworld, null) - bworld.setSpawnLocation(spawn.x.floor(), spawn.y.floor(), spawn.z.floor()) + plugin.doAwait { + cond = { + try { + // server.getDefaultGameMode() throws an error before any worlds are initialized. + // createWorld() below calls that method. + // Plugin needs to load on STARTUP for generators to be registered correctly. + // Means we need to await the initial worlds getting loaded. + + plugin.server.defaultGameMode; true + } catch (ex: Throwable) { + false + } + } + + onSuccess = { + val bworld = WorldCreator(worldName).generator(world.generator).createWorld() + val spawn = world.generator.getFixedSpawnLocation(bworld, null) + bworld.setSpawnLocation(spawn.x.floor(), spawn.y.floor(), spawn.z.floor()) + } + } } } @@ -72,8 +90,8 @@ interface ParcelProvider { } class ParcelWorld(val name: String, - val options: WorldOptions, - val generator: ParcelGenerator) : ParcelProvider by generator { + val options: WorldOptions, + val generator: ParcelGenerator) : ParcelProvider by generator { val world: World by lazy { val tmp = Bukkit.getWorld(name) if (tmp == null) { diff --git a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt index 43ee65b..9e9fc10 100644 --- a/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt +++ b/src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt @@ -1,5 +1,8 @@ package io.dico.parcels2 +import io.dico.dicore.command.CommandBuilder +import io.dico.dicore.command.EOverridePolicy +import io.dico.dicore.command.ICommandDispatcher import io.dico.parcels2.storage.Storage import io.dico.parcels2.storage.yamlObjectMapper import io.dico.parcels2.util.tryCreate @@ -7,7 +10,6 @@ import org.bukkit.Bukkit import org.bukkit.plugin.java.JavaPlugin import org.slf4j.LoggerFactory import java.io.File -import java.util.logging.Level val logger = LoggerFactory.getLogger("ParcelsPlugin") @@ -18,28 +20,28 @@ class ParcelsPlugin : JavaPlugin() { lateinit var options: Options lateinit var worlds: Worlds lateinit var storage: Storage + private var cmdDispatcher: ICommandDispatcher? = null override fun onEnable() { if (!init()) { Bukkit.getPluginManager().disablePlugin(this) + return } + + registerCommands() + } + + override fun onDisable() { + cmdDispatcher?.unregisterFromCommandMap() } private fun init(): Boolean { optionsFile = File(dataFolder, "options.yml") options = Options() - worlds = Worlds() + worlds = Worlds(this) try { - if (optionsFile.exists()) { - yamlObjectMapper.readerForUpdating(options).readValue<Options>(optionsFile) - } else if (optionsFile.tryCreate()) { - options.addWorld("plotworld", WorldOptions()) - yamlObjectMapper.writeValue(optionsFile, options) - } else { - plogger.error("Failed to save options file ${optionsFile.canonicalPath}") - return false - } + if (!loadOptions()) return false try { storage = options.storage.newStorageInstance() @@ -57,4 +59,29 @@ class ParcelsPlugin : JavaPlugin() { return true } + fun loadOptions(): Boolean { + if (optionsFile.exists()) { + yamlObjectMapper.readerForUpdating(options).readValue<Options>(optionsFile) + } else if (optionsFile.tryCreate()) { + options.addWorld("plotworld", WorldOptions()) + yamlObjectMapper.writeValue(optionsFile, options) + } else { + plogger.error("Failed to save options file ${optionsFile.canonicalPath}") + return false + } + return true + } + + private fun registerCommands() { + //@formatting:off + cmdDispatcher = CommandBuilder() + .group("parcel", "plot", "plots", "p") + .registerCommands(PlotCommands(this)) + .parent() + .getDispatcher() + //@formatting:on + + cmdDispatcher!!.registerToCommandMap("parcels:", EOverridePolicy.FALLBACK_ONLY) + } + }
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/PlotCommands.kt b/src/main/kotlin/io/dico/parcels2/PlotCommands.kt new file mode 100644 index 0000000..0001067 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/PlotCommands.kt @@ -0,0 +1,25 @@ +package io.dico.parcels2 +import io.dico.dicore.command.CommandException +import io.dico.dicore.command.annotation.Cmd +import org.bukkit.Bukkit +import org.bukkit.entity.Player + + +class PlotCommands(val plugin: ParcelsPlugin) { + + @Cmd("reloadoptions") + fun reloadOptions() { + plugin.loadOptions() + } + + @Cmd("tpworld") + fun tpWorld(sender: Player, worldName: String): String { + if (worldName == "list") { + return Bukkit.getWorlds().joinToString("\n- ", "- ", "") + } + val world = Bukkit.getWorld(worldName) ?: throw CommandException("World $worldName is not loaded") + sender.teleport(world.spawnLocation) + return "Teleported you to $worldName spawn" + } + +}
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/storage/Exposed.kt b/src/main/kotlin/io/dico/parcels2/storage/Exposed.kt index ea02b8b..cbb5887 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/Exposed.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/Exposed.kt @@ -8,8 +8,10 @@ import kotlinx.coroutines.experimental.channels.ProducerScope import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.ReferenceOption import org.jetbrains.exposed.sql.Table +import org.jetbrains.exposed.sql.transactions.transaction import java.util.* import javax.sql.DataSource +import org.jetbrains.exposed.sql.SchemaUtils.create object ParcelsTable : Table() { val id = integer("id").autoIncrement().primaryKey() @@ -39,6 +41,9 @@ class ExposedBacking(val dataSource: DataSource) : Backing { override suspend fun init() { database = Database.connect(dataSource) + transaction(database) { + create(ParcelsTable, ParcelsAddedTable) + } } override suspend fun shutdown() { diff --git a/src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt b/src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt new file mode 100644 index 0000000..4ca549f --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt @@ -0,0 +1,74 @@ +package io.dico.parcels2.util + +import org.bukkit.plugin.Plugin +import org.bukkit.scheduler.BukkitTask + +inline fun Plugin.doAwait(checkNow: Boolean = true, configure: AwaitTask.() -> Unit) { + with(AwaitTask()) { + configure() + start(checkNow = checkNow) + } +} + +private typealias Action<T> = () -> T + +class AwaitTask : Runnable { + //@formatter:off + var cond: Action<Boolean>? = null ; set(value) { checkNotRunning(); field = value } + var onSuccess: Action<Unit>? = null ; set(value) { checkNotRunning(); field = value } + var onFailure: Action<Unit>? = null ; set(value) { checkNotRunning(); field = value } + var delay: Int = -1 ; set(value) { checkNotRunning(); field = value } + var interval: Int = 20 ; set(value) { checkNotRunning(); field = value } + var maxChecks: Int = 0 ; set(value) { checkNotRunning(); field = value } + + var task: BukkitTask? = null ; private set + var elapsedChecks = 0 ; private set + var cancelled = false ; private set + //@formatter:on + + fun Plugin.start(checkNow: Boolean = true) { + if (cancelled) throw IllegalStateException() + + requireNotNull(cond) + requireNotNull(onSuccess) + + if (checkNow && check()) { + cancel() + onSuccess!!.invoke() + return + } + + task = server.scheduler.runTaskTimer(this, this@AwaitTask, delay.toLong(), interval.toLong()) + } + + override fun run() { + if (task?.isCancelled != false) return + + if (check()) { + cancel() + onSuccess!!.invoke() + } + + elapsedChecks++ + + if (maxChecks in 1 until elapsedChecks) { + cancel() + onFailure?.invoke() + } + } + + private fun check(): Boolean { + elapsedChecks++ + return cond!!.invoke() + } + + fun cancel() { + task?.cancel() + cancelled = true + } + + private fun checkNotRunning() { + if (cancelled || task != null) throw IllegalStateException() + } + +}
\ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 351aba8..6617645 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,7 +1,7 @@ <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> - <pattern>%d{HH:mm:ss.SSS} %magenta(%-8.-8(%thread)) %highlight(%-5level) %boldCyan(%32.-32logger{32}) - %msg%n</pattern> + <pattern>%d{HH:mm:ss.SSS} %magenta(%-8.-8(%thread)) %highlight(%-5level) %boldCyan(%32.-32logger{32}) - %msg</pattern> </encoder> </appender> |