summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2018-07-22 20:51:46 +0200
committerDico200 <dico.karssiens@gmail.com>2018-07-22 20:51:46 +0200
commit9e31ea7e51762292301858b6821e27e971b3981b (patch)
treecbaa0c2444919f0d8717f2dbe06685773517e9e5
parent8a0a77b8ba4a2e160558809b592e4bc393e7c997 (diff)
Add a few development commands. World generation works
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelWorld.kt32
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelsPlugin.kt49
-rw-r--r--src/main/kotlin/io/dico/parcels2/PlotCommands.kt25
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/Exposed.kt5
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt74
-rw-r--r--src/main/resources/logback.xml2
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>