Configurations
Zora has a powerful and easy to use configuration system that allows easy object-relational mapping, with automatic hot reloading of your configuration files. It uses the Configurate library to provide a powerful and flexible system for loading and saving configuration files.
Currently, the Zora configuration system supports YAML and JSON (via Gson) configuration files. Support for
other formats, including database-backed configurations, is planned for the future.
Creating a Configuration
Unlike a traditional Bukkit plugin, the Zora configuration system never relies on a configuration file being present on the filesystem initially, nor does it expect you to put a default configuration file in your plugin's resources. Instead, you can create a configuration object that will be used to store your configuration values, and then load it from a configuration file. If the configuration file does not exist, it will be created automatically.
Configuration Files
A Configuration File is always associated with a single configuration class, and is used to store the values of that configuration class.
The expectation is that any class that extends ZoraConfig will be a standalone configuration
file. As such, all ZoraConfig derived classes must be annotated with @ConfigMetadata, and will also be treated
as a singleton.
@ConfigMetadata(
fileName = "fruit-quantities",
fileType = ConfigurationFileType.JSON
)
@ConfigSerializable
public class FruitQuantities extends ZoraConfig {
@Setting
public int apples = 0;
@Setting
public int oranges = 0;
@Setting
public int bananas = 0;
}
Configuration Sections
You can create standalone sections of your configuration files, which can be an easy way of grouping related settings.
@ConfigMetadata(
fileName = "example",
fileType = ConfigurationFileType.YAML
)
@ConfigSerializable
public class ExampleSectionFile extends ZoraConfig {
public MySection mySection = new MySection();
}
@ConfigSerializable
public class MySection {
@Setting
public String myString = "Hello, world!";
}
Annotations
ConfigMetadata
The @ConfigMetadata annotation is used to specify the name of the configuration file, and the type of the configuration
file. It acts as the descriptor for the configuration file, and is required for all configuration classes.
Note that @ConfigMetadata should only be applied to classes that extend ZoraConfig, and only for standalone files
(rather than sections within existing files.)
ConfigSerializable
Annotating a class with @ConfigSerializable marks it as a configuration class within Configurate, and is required
for all configuration classes.
Setting
This is an optional annotation that can be applied to fields within a configuration class. It is used to specify the
name of the setting within the configuration file, and is required for all fields within a configuration class. If in
the ZoraConfigSystemBuilder you specify strictSettings(true), then any fields that are not annotated with @Setting
will be ignored. More on this is covered in the next section.
Initialising the Configuration System
Like all Zora systems, unless you specifically enable it, Zora will not automatically initialise the configuration system.
You must register configurations in the #init() method of your plugin, otherwise the configuration system will not
detect, load or save any configuration files.
The API to do so follows the same standard pattern as all other Zora systems. In your plugin's #init() method, invoke
the usesConfigs() method, which allows you to configure the builder as so:
public final class MyPlugin extends ZoraPlugin {
@Override
public void init() {
this.usesConfigs()
.registerConfigs("com.example.myplugin.configs")
.registerConfigs(MyAdditionalConfig.class)
.configDirectory("Zora/Extras")
.strictSettings(true)
.typeSerializer(MyType.class, new MyTypeSerializer())
.build();
}
}
Registering Configurations
The registerConfigs() method allows you to register configuration classes. You can either specify a package name, in
which case all configuration classes within that package (and its subpackages) will be registered, or you can specify
a single configuration class (which must extend ZoraConfig) to be registered.
You can call registerConfigs() multiple times, and it will add the specified configuration classes to the list of
registered configuration classes.
You must call registerConfigs() at least once, otherwise the configuration system will not be initialised.
Configuration Directory
The configDirectory() method allows you to specify the directory in which configuration files will be stored. This
starts from the world container (which is the directory your server is installed in, e.g. /home/servers/skyblock), and
is Zora by default.
It is recommended to avoid changing this unless you have a specific reason to do so.
Strict Settings
The strictSettings() method allows you to specify whether the configuration system should ignore fields not annotated
with @Setting in configuration classes. By default, this is false.
Type Serializers
Registering a type serializer will register it for any Zora plugin. As such, if you intend to write serializers for types that are not specific to your plugin, this only needs to be done in one plugin. The loading order of your plugins is irrelevant.
You can register custom type serializers for any type that is not supported by Configurate by default. This is done
using the typeSerializer() method, which takes a class and a serializer. The class must be the class of the type you
wish to register a serializer for, and the serializer must be an instance of TypeSerializer.
Read more about Type Serializers on the Configurate Wiki.
Accessing your Configuration
Accessing a configuration should always be done via the Zora utility class:
Zora.getConfig(MyConfig.class);
It is also generally recommended to avoid storing a reference to your configuration class, and instead to use the
Zora utility class to access it. This is because the configuration system will automatically reload your configuration
files when they are changed, and so storing a reference to your configuration class may result in you accessing an old
version of the configuration.
Putting it all together
Here's a complete example of the Zora configuration system in action. We'll create a simple Zora plugin which registers
a file message.json and a command /myplugin broadcastmessage which broadcasts the message in the configuration file
to all players.
We aren't using the Zora messaging system here, but you can read more about it in the Messaging section (this is to keep the example simple).
- MyPlugin.java
- MyConfig.java
- MyCommand.java
package com.example.myplugin;
public final class MyPlugin extends ZoraPlugin {
@Override
public void init() {
instance = this;
this.usesConfigs()
.registerConfigs("com.example.myplugin.configs")
.init();
this.usesCommands()
.registerCommands("com.example.myplugin.commands")
.init();
}
@Override
public void enable() {
}
@Override
public void disable() {
}
}
package com.example.myplugin.configs;
@ConfigMetadata(
fileName = "message",
fileType = ConfigurationFileType.JSON
)
@ConfigSerializable
public class MyConfig extends ZoraConfig {
@Setting
private String message = "Hello, world!";
public String getMessage() {
return message;
}
}
package com.example.myplugin.commands;
public class MyCommand extends ZoraCommand {
@CommandMethod("myplugin broadcastmessage")
public void onCommand(Player player) {
MyConfig config = Zora.getConfig(MyConfig.class);
Bukkit.broadcastMessage(Component.text(config.getMessage()));
}
}