Add a few development commands. World generation works
This commit is contained in:
@@ -2,7 +2,7 @@ package io.dico.parcels2
|
|||||||
|
|
||||||
import io.dico.parcels2.math.Vec2i
|
import io.dico.parcels2.math.Vec2i
|
||||||
import io.dico.parcels2.math.floor
|
import io.dico.parcels2.math.floor
|
||||||
import kotlinx.coroutines.experimental.launch
|
import io.dico.parcels2.util.doAwait
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.World
|
import org.bukkit.World
|
||||||
@@ -10,10 +10,11 @@ import org.bukkit.WorldCreator
|
|||||||
import org.bukkit.block.Block
|
import org.bukkit.block.Block
|
||||||
import org.bukkit.entity.Entity
|
import org.bukkit.entity.Entity
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.coroutines.experimental.buildSequence
|
import kotlin.coroutines.experimental.buildSequence
|
||||||
|
|
||||||
class Worlds {
|
class Worlds(private val plugin: Plugin) {
|
||||||
val worlds: Map<String, ParcelWorld> get() = _worlds
|
val worlds: Map<String, ParcelWorld> get() = _worlds
|
||||||
private val _worlds: MutableMap<String, ParcelWorld> = HashMap()
|
private val _worlds: MutableMap<String, ParcelWorld> = HashMap()
|
||||||
|
|
||||||
@@ -48,9 +49,26 @@ class Worlds {
|
|||||||
_worlds.put(worldName, world)
|
_worlds.put(worldName, world)
|
||||||
|
|
||||||
if (Bukkit.getWorld(worldName) == null) {
|
if (Bukkit.getWorld(worldName) == null) {
|
||||||
val bworld = WorldCreator(worldName).generator(world.generator).createWorld()
|
plugin.doAwait {
|
||||||
val spawn = world.generator.getFixedSpawnLocation(bworld, null)
|
cond = {
|
||||||
bworld.setSpawnLocation(spawn.x.floor(), spawn.y.floor(), spawn.z.floor())
|
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,
|
class ParcelWorld(val name: String,
|
||||||
val options: WorldOptions,
|
val options: WorldOptions,
|
||||||
val generator: ParcelGenerator) : ParcelProvider by generator {
|
val generator: ParcelGenerator) : ParcelProvider by generator {
|
||||||
val world: World by lazy {
|
val world: World by lazy {
|
||||||
val tmp = Bukkit.getWorld(name)
|
val tmp = Bukkit.getWorld(name)
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package io.dico.parcels2
|
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.Storage
|
||||||
import io.dico.parcels2.storage.yamlObjectMapper
|
import io.dico.parcels2.storage.yamlObjectMapper
|
||||||
import io.dico.parcels2.util.tryCreate
|
import io.dico.parcels2.util.tryCreate
|
||||||
@@ -7,7 +10,6 @@ import org.bukkit.Bukkit
|
|||||||
import org.bukkit.plugin.java.JavaPlugin
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.logging.Level
|
|
||||||
|
|
||||||
val logger = LoggerFactory.getLogger("ParcelsPlugin")
|
val logger = LoggerFactory.getLogger("ParcelsPlugin")
|
||||||
|
|
||||||
@@ -18,28 +20,28 @@ class ParcelsPlugin : JavaPlugin() {
|
|||||||
lateinit var options: Options
|
lateinit var options: Options
|
||||||
lateinit var worlds: Worlds
|
lateinit var worlds: Worlds
|
||||||
lateinit var storage: Storage
|
lateinit var storage: Storage
|
||||||
|
private var cmdDispatcher: ICommandDispatcher? = null
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
if (!init()) {
|
if (!init()) {
|
||||||
Bukkit.getPluginManager().disablePlugin(this)
|
Bukkit.getPluginManager().disablePlugin(this)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisable() {
|
||||||
|
cmdDispatcher?.unregisterFromCommandMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun init(): Boolean {
|
private fun init(): Boolean {
|
||||||
optionsFile = File(dataFolder, "options.yml")
|
optionsFile = File(dataFolder, "options.yml")
|
||||||
options = Options()
|
options = Options()
|
||||||
worlds = Worlds()
|
worlds = Worlds(this)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (optionsFile.exists()) {
|
if (!loadOptions()) return false
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
storage = options.storage.newStorageInstance()
|
storage = options.storage.newStorageInstance()
|
||||||
@@ -57,4 +59,29 @@ class ParcelsPlugin : JavaPlugin() {
|
|||||||
return true
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
25
src/main/kotlin/io/dico/parcels2/PlotCommands.kt
Normal file
25
src/main/kotlin/io/dico/parcels2/PlotCommands.kt
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,8 +8,10 @@ import kotlinx.coroutines.experimental.channels.ProducerScope
|
|||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.jetbrains.exposed.sql.ReferenceOption
|
import org.jetbrains.exposed.sql.ReferenceOption
|
||||||
import org.jetbrains.exposed.sql.Table
|
import org.jetbrains.exposed.sql.Table
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.sql.DataSource
|
import javax.sql.DataSource
|
||||||
|
import org.jetbrains.exposed.sql.SchemaUtils.create
|
||||||
|
|
||||||
object ParcelsTable : Table() {
|
object ParcelsTable : Table() {
|
||||||
val id = integer("id").autoIncrement().primaryKey()
|
val id = integer("id").autoIncrement().primaryKey()
|
||||||
@@ -39,6 +41,9 @@ class ExposedBacking(val dataSource: DataSource) : Backing {
|
|||||||
|
|
||||||
override suspend fun init() {
|
override suspend fun init() {
|
||||||
database = Database.connect(dataSource)
|
database = Database.connect(dataSource)
|
||||||
|
transaction(database) {
|
||||||
|
create(ParcelsTable, ParcelsAddedTable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun shutdown() {
|
override suspend fun shutdown() {
|
||||||
|
|||||||
74
src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt
Normal file
74
src/main/kotlin/io/dico/parcels2/util/BukkitAwait.kt
Normal file
@@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<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>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user