Successfully connecting to h2 database
This commit is contained in:
@@ -1,10 +1,5 @@
|
|||||||
import com.github.jengelman.gradle.plugins.shadow.relocation.RelocateClassContext
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.relocation.RelocatePathContext
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
||||||
import shadow.org.apache.tools.zip.ZipOutputStream
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.2.51"
|
kotlin("jvm") version "1.2.51"
|
||||||
@@ -33,14 +28,16 @@ dependencies {
|
|||||||
compile("org.jetbrains.exposed:exposed:0.10.3")
|
compile("org.jetbrains.exposed:exposed:0.10.3")
|
||||||
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||||
compile("com.zaxxer:HikariCP:3.2.0")
|
compile("com.zaxxer:HikariCP:3.2.0")
|
||||||
|
compile(files("../h2/bin/h2-client-1.4.197.jar"))
|
||||||
|
|
||||||
val jacksonVersion = "2.9.6"
|
val jacksonVersion = "2.9.6"
|
||||||
compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
|
compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
|
||||||
compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
|
compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
|
||||||
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion")
|
|
||||||
compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
|
compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
|
||||||
|
//compile("org.yaml:snakeyaml:1.21")
|
||||||
|
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion")
|
||||||
|
|
||||||
compile("org.slf4j:slf4j-api:1.7.25")
|
shadow("org.slf4j:slf4j-api:1.7.25")
|
||||||
compile("ch.qos.logback:logback-classic:1.2.3")
|
compile("ch.qos.logback:logback-classic:1.2.3")
|
||||||
|
|
||||||
testCompile("junit:junit:4.12")
|
testCompile("junit:junit:4.12")
|
||||||
@@ -73,4 +70,13 @@ tasks {
|
|||||||
|
|
||||||
relocate("kotlin", "kotlin")
|
relocate("kotlin", "kotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val relocateSnakeyamlJar by creating(ShadowJar::class) {
|
||||||
|
destinationDir = file("$rootDir/debug/plugins")
|
||||||
|
baseName = "parcels2-shaded"
|
||||||
|
relocate("org.yaml", "shadow.org.yaml")
|
||||||
|
|
||||||
|
from(*project.configurations.compile.map(::zipTree).toTypedArray())
|
||||||
|
with(jar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,6 @@ class Options {
|
|||||||
|
|
||||||
fun addWorld(name: String, options: WorldOptions) = (worlds as MutableMap).put(name, options)
|
fun addWorld(name: String, options: WorldOptions) = (worlds as MutableMap).put(name, options)
|
||||||
|
|
||||||
fun addDefaultWorld() = addWorld("plotworld", WorldOptions())
|
|
||||||
|
|
||||||
fun writeTo(writer: Writer) = yamlObjectMapper.writeValue(writer, this)
|
fun writeTo(writer: Writer) = yamlObjectMapper.writeValue(writer, this)
|
||||||
|
|
||||||
fun mergeFrom(reader: Reader) = yamlObjectMapper.readerForUpdating(this).readValue<Options>(reader)
|
fun mergeFrom(reader: Reader) = yamlObjectMapper.readerForUpdating(this).readValue<Options>(reader)
|
||||||
@@ -50,7 +48,7 @@ abstract class GeneratorOptions {
|
|||||||
|
|
||||||
abstract fun generatorFactory(): GeneratorFactory
|
abstract fun generatorFactory(): GeneratorFactory
|
||||||
|
|
||||||
fun getGenerator(worldName: String) = generatorFactory().newParcelGenerator(worldName, this)
|
fun getGenerator(worlds: Worlds, worldName: String) = generatorFactory().newParcelGenerator(worlds, worldName, this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,47 +13,49 @@ import org.bukkit.entity.Player
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.coroutines.experimental.buildSequence
|
import kotlin.coroutines.experimental.buildSequence
|
||||||
|
|
||||||
val worlds: Map<String, ParcelWorld> get() = _worlds
|
class Worlds {
|
||||||
private val _worlds: MutableMap<String, ParcelWorld> = HashMap()
|
val worlds: Map<String, ParcelWorld> get() = _worlds
|
||||||
|
private val _worlds: MutableMap<String, ParcelWorld> = HashMap()
|
||||||
|
|
||||||
fun getWorld(name: String): ParcelWorld? = _worlds.get(name)
|
fun getWorld(name: String): ParcelWorld? = _worlds.get(name)
|
||||||
|
|
||||||
fun getWorld(world: World): ParcelWorld? = getWorld(world.name)
|
fun getWorld(world: World): ParcelWorld? = getWorld(world.name)
|
||||||
|
|
||||||
fun getParcelAt(block: Block): Parcel? = getParcelAt(block.world, block.x, block.z)
|
fun getParcelAt(block: Block): Parcel? = getParcelAt(block.world, block.x, block.z)
|
||||||
|
|
||||||
fun getParcelAt(player: Player): Parcel? = getParcelAt(player.location)
|
fun getParcelAt(player: Player): Parcel? = getParcelAt(player.location)
|
||||||
|
|
||||||
fun getParcelAt(location: Location): Parcel? = getParcelAt(location.world, location.x.floor(), location.z.floor())
|
fun getParcelAt(location: Location): Parcel? = getParcelAt(location.world, location.x.floor(), location.z.floor())
|
||||||
|
|
||||||
fun getParcelAt(world: World, x: Int, z: Int): Parcel? = getParcelAt(world.name, x, z)
|
fun getParcelAt(world: World, x: Int, z: Int): Parcel? = getParcelAt(world.name, x, z)
|
||||||
|
|
||||||
fun getParcelAt(world: String, x: Int, z: Int): Parcel? {
|
fun getParcelAt(world: String, x: Int, z: Int): Parcel? {
|
||||||
with (getWorld(world) ?: return null) {
|
with(getWorld(world) ?: return null) {
|
||||||
return generator.parcelAt(x, z)
|
return generator.parcelAt(x, z)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadWorlds(options: Options) {
|
|
||||||
for ((worldName, worldOptions) in options.worlds.entries) {
|
|
||||||
val world: ParcelWorld
|
|
||||||
try {
|
|
||||||
world = ParcelWorld(worldName, worldOptions, worldOptions.generator.getGenerator(worldName))
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
ex.printStackTrace()
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_worlds.put(worldName, world)
|
fun loadWorlds(options: Options) {
|
||||||
|
for ((worldName, worldOptions) in options.worlds.entries) {
|
||||||
|
val world: ParcelWorld
|
||||||
|
try {
|
||||||
|
world = ParcelWorld(worldName, worldOptions, worldOptions.generator.getGenerator(this, worldName))
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_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())
|
||||||
|
}
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ParcelProvider {
|
interface ParcelProvider {
|
||||||
|
|||||||
@@ -1,15 +1,60 @@
|
|||||||
package io.dico.parcels2
|
package io.dico.parcels2
|
||||||
|
|
||||||
|
import io.dico.parcels2.storage.Storage
|
||||||
|
import io.dico.parcels2.storage.yamlObjectMapper
|
||||||
|
import io.dico.parcels2.util.tryCreate
|
||||||
|
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.util.logging.Level
|
||||||
|
|
||||||
val logger = LoggerFactory.getLogger("ParcelsPlugin")
|
val logger = LoggerFactory.getLogger("ParcelsPlugin")
|
||||||
|
|
||||||
|
private inline val plogger get() = logger
|
||||||
|
|
||||||
class ParcelsPlugin : JavaPlugin() {
|
class ParcelsPlugin : JavaPlugin() {
|
||||||
|
lateinit var optionsFile: File
|
||||||
|
lateinit var options: Options
|
||||||
|
lateinit var worlds: Worlds
|
||||||
|
lateinit var storage: Storage
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
super.onEnable()
|
if (!init()) {
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun init(): Boolean {
|
||||||
|
optionsFile = File(dataFolder, "options.yml")
|
||||||
|
options = Options()
|
||||||
|
worlds = Worlds()
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
storage = options.storage.newStorageInstance()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
plogger.error("Failed to connect to database", ex)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
worlds.loadWorlds(options)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
plogger.error("Error loading options", ex)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -71,19 +71,19 @@ interface GeneratorFactory {
|
|||||||
|
|
||||||
val optionsClass: KClass<out GeneratorOptions>
|
val optionsClass: KClass<out GeneratorOptions>
|
||||||
|
|
||||||
fun newParcelGenerator(worldName: String, options: GeneratorOptions): ParcelGenerator
|
fun newParcelGenerator(worlds: Worlds, worldName: String, options: GeneratorOptions): ParcelGenerator
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultParcelGenerator(name: String, private val o: DefaultGeneratorOptions) : ParcelGenerator() {
|
class DefaultParcelGenerator(val worlds: Worlds, val name: String, private val o: DefaultGeneratorOptions) : ParcelGenerator() {
|
||||||
override val world: ParcelWorld by lazy { TODO() }
|
override val world: ParcelWorld by lazy { worlds.getWorld(name)!! }
|
||||||
override val factory = Factory
|
override val factory = Factory
|
||||||
|
|
||||||
companion object Factory : GeneratorFactory {
|
companion object Factory : GeneratorFactory {
|
||||||
override val name get() = "default"
|
override val name get() = "default"
|
||||||
override val optionsClass get() = DefaultGeneratorOptions::class
|
override val optionsClass get() = DefaultGeneratorOptions::class
|
||||||
override fun newParcelGenerator(worldName: String, options: GeneratorOptions): ParcelGenerator {
|
override fun newParcelGenerator(worlds: Worlds, worldName: String, options: GeneratorOptions): ParcelGenerator {
|
||||||
return DefaultParcelGenerator(worldName, options as DefaultGeneratorOptions)
|
return DefaultParcelGenerator(worlds, worldName, options as DefaultGeneratorOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ fun getHikariDataSource(dialectName: String,
|
|||||||
// copied from github.com/lucko/LuckPerms
|
// copied from github.com/lucko/LuckPerms
|
||||||
if (dialectName.toLowerCase() == "mariadb") {
|
if (dialectName.toLowerCase() == "mariadb") {
|
||||||
addDataSourceProperty("properties", "useUnicode=true;characterEncoding=utf8")
|
addDataSourceProperty("properties", "useUnicode=true;characterEncoding=utf8")
|
||||||
|
} else if (dialectName.toLowerCase() == "h2") {
|
||||||
|
dataSourceProperties.remove("serverName")
|
||||||
|
dataSourceProperties.remove("port")
|
||||||
|
dataSourceProperties.remove("databaseName")
|
||||||
|
addDataSourceProperty("url", "jdbc:h2:tcp://$address/~/${dco.database}")
|
||||||
} else {
|
} else {
|
||||||
// doesn't exist on the MariaDB driver
|
// doesn't exist on the MariaDB driver
|
||||||
addDataSourceProperty("cachePrepStmts", "true")
|
addDataSourceProperty("cachePrepStmts", "true")
|
||||||
|
|||||||
@@ -34,10 +34,8 @@ val yamlObjectMapper = ObjectMapper(YAMLFactory()).apply {
|
|||||||
addSerializer(BlockDataSerializer())
|
addSerializer(BlockDataSerializer())
|
||||||
addDeserializer(BlockData::class.java, BlockDataDeserializer())
|
addDeserializer(BlockData::class.java, BlockDataDeserializer())
|
||||||
|
|
||||||
/*
|
|
||||||
addSerializer(StorageOptionsSerializer())
|
addSerializer(StorageOptionsSerializer())
|
||||||
addDeserializer(StorageOptions::class.java, StorageOptionsDeserializer())
|
addDeserializer(StorageOptions::class.java, StorageOptionsDeserializer())
|
||||||
*/
|
|
||||||
|
|
||||||
addDeserializer(GeneratorOptions::class.java, GeneratorOptionsDeserializer())
|
addDeserializer(GeneratorOptions::class.java, GeneratorOptionsDeserializer())
|
||||||
}
|
}
|
||||||
@@ -65,7 +63,6 @@ private class BlockDataDeserializer : StdDeserializer<BlockData>(BlockData::clas
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class StorageOptionsDeserializer : JsonDeserializer<StorageOptions>() {
|
class StorageOptionsDeserializer : JsonDeserializer<StorageOptions>() {
|
||||||
|
|
||||||
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): StorageOptions {
|
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): StorageOptions {
|
||||||
@@ -74,7 +71,7 @@ class StorageOptionsDeserializer : JsonDeserializer<StorageOptions>() {
|
|||||||
val optionsNode = node.get("options")
|
val optionsNode = node.get("options")
|
||||||
val factory = StorageFactory.getFactory(dialect) ?: throw IllegalStateException("Unknown storage dialect: $dialect")
|
val factory = StorageFactory.getFactory(dialect) ?: throw IllegalStateException("Unknown storage dialect: $dialect")
|
||||||
val options = p.codec.treeToValue(optionsNode, factory.optionsClass.java)
|
val options = p.codec.treeToValue(optionsNode, factory.optionsClass.java)
|
||||||
return StorageOptions(dialect, factory, options)
|
return StorageOptions(dialect, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -92,8 +89,6 @@ class StorageOptionsSerializer : StdSerializer<StorageOptions>(StorageOptions::c
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class GeneratorOptionsDeserializer : JsonDeserializer<GeneratorOptions>() {
|
class GeneratorOptionsDeserializer : JsonDeserializer<GeneratorOptions>() {
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.dico.parcels2.storage
|
package io.dico.parcels2.storage
|
||||||
|
|
||||||
import io.dico.parcels2.DataConnectionOptions
|
import io.dico.parcels2.DataConnectionOptions
|
||||||
|
import net.minecraft.server.v1_13_R1.WorldType.types
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
interface StorageFactory {
|
interface StorageFactory {
|
||||||
@@ -27,10 +28,10 @@ interface StorageFactory {
|
|||||||
class ConnectionStorageFactory : StorageFactory {
|
class ConnectionStorageFactory : StorageFactory {
|
||||||
override val optionsClass = DataConnectionOptions::class
|
override val optionsClass = DataConnectionOptions::class
|
||||||
|
|
||||||
private val types: Map<String, String> = with(HashMap<String, String>()) {
|
private val types: Map<String, String> = mutableMapOf(
|
||||||
put("mysql", "com.mysql.jdbc.jdbc2.optional.MysqlDataSource")
|
"mysql" to "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",
|
||||||
this
|
"h2" to "org.h2.jdbcx.JdbcDataSource"
|
||||||
}
|
)
|
||||||
|
|
||||||
fun register(companion: StorageFactory.StorageFactories) {
|
fun register(companion: StorageFactory.StorageFactories) {
|
||||||
types.keys.forEach {
|
types.keys.forEach {
|
||||||
|
|||||||
15
src/main/kotlin/io/dico/parcels2/util/MiscExtensions.kt
Normal file
15
src/main/kotlin/io/dico/parcels2/util/MiscExtensions.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package io.dico.parcels2.util
|
||||||
|
|
||||||
|
import io.dico.parcels2.logger
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import java.io.File
|
||||||
|
import java.io.PrintWriter
|
||||||
|
|
||||||
|
fun File.tryCreate(): Boolean {
|
||||||
|
val parent = parentFile
|
||||||
|
if (parent == null || !(parent.exists() || parent.mkdirs()) || !createNewFile()) {
|
||||||
|
logger.warn("Failed to create file ${canonicalPath}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ author: Dico
|
|||||||
main: io.dico.parcels2.ParcelsPlugin
|
main: io.dico.parcels2.ParcelsPlugin
|
||||||
version: 0.1
|
version: 0.1
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
load: STARTUP
|
||||||
Reference in New Issue
Block a user