Skip to content

Configuration

Gabriel Souza edited this page Jul 26, 2020 · 5 revisions

KotlinBukkitAPI uses for configuration the Kotlinx.serialization and embed on the plugin the Kotlinx.serialization runtime and the YAML extension to be used.

We chose the Kotlinx.serialization because is the biggest serialization library for PURE Kotlin and is built by Jetbrains.

Usage

KotlinBukkitAPI provides a module apart for using Kotlinx.serialization.

Add this following dependency to your gradle build.

compileOnly("br.com.devsrsouza.kotlinbukkitapi:architecture:$kotlinbukkitapi_version")

And setup your project with Kotlinx.serialization gradle plugin. This configuration can be found at the Kotlinx.serialization README.

KotlinPlugin

For setup your configuration file using Kotlinx.serialization and KotlinBukkitAPI you will need to declare with in a KotlinPlugin class.

First declare your example configuration models.

@Serializable
data class YourConfig(
  @ChangeColor
  val noPermissionMessage: String = "&cYou don't have permission to use this command",
  val commandsMessages: CommandsMessage = CommandsMessages()
)

@Serializable
data class CommandsMessage(
  @ChangeColor
  val onTeleportHome: String = "&eYou teleport to your home."
)

And now create declare at your config at KotlinPlugin.

Notes that the KotlinBukkitAPI will create the file and set the defaultModel as the default for the configuration and will load from the file.

class MyPlugin : KotlinPlugin() {
  val yourConfig = config(
      "config.yml",
      YourConfig(),
      YourConfig.serializer()
  )
}

We can do more with the config()

fun <T : Any> KotlinPlugin.config(
        file: String,
        defaultModel: T,
        serializer: KSerializer<T>,
        type: StringFormat = Yaml(BukkitSerialModule()),
        loadOnEnable: Boolean = false,
        saveOnDisable: Boolean = false,
        alwaysRestoreDefaults: Boolean = true
): SerializationConfig<T>
  • You can use custom StringFormats from Kotlinx.serialization like Json with the type parameter.
  • You can set to your config only loads on the Plugin onEnable with loadOnEnable.
  • You can set to your config be saved when the plugins disable/server closes with saveOnDisable.

Bukkit Objects Serialization

KotlinBukkitAPI has built-in serializations for Kotlinx.serialization that is provided in runtime by using @ContexualSerialization.

The currently supported type are:

  • Block
  • Chunk
  • Location
  • MaterialData
  • Material
  • World

Custom annotations

@ChangeColor

You can see in your above configuration that we use a Custom annotation provided by KotlinBukkitAPI called @ChangeColor what this does is that when saving and loading your configuration, will automatically translate the color codes, this means that when saving into the Config will be used & and when loading from the Config §.

Recommendations

The recommendation is to always set your configurations with default values, only not in Entity models. The reason for that is that KotlinBukkitAPI will load your configuration and saves the loaded Model again, this makes the removed keys from the Configuration File be restore for the user always have to configurable, this could be change by updating the alwaysRestoreDefaults value to false.

The entity use case

Think about a Kit object that should ALWAYS have a name and a price. In this case, is not allowed to have a kit that does not have this properties and in this case should throw an error.

@Serialiable
data class Kit(
  val name: String,
  val price: Double,
  @ContexualSerialization
  val icon: MaterialData = Material.PAPER.asMaterialData(),
  val items: List<String> = listOf()
)

@Serializable
data class TestConfig(
  val kits: List<Kit>
)

LifecycleListener extensions

For an easy way to access a Config from a LifecycleListener( Your manager ) you can use delegate properties config.

class YourManager(override val plugin: YourPlugin) : LifecycleListener<YourPlugin> {

  val yourConfig: YourConfig by config<YourConfig>()

}

You can use a mapper to get a specific property that you want.

  val kits: List<Kit> by config<YourConfig> { kits }
inline fun <reified T : Any, R> LifecycleListener<*>.config(
        noinline deep: T.() -> R
): ConfigDelegate<T, R>