Skip to content

Commit

Permalink
Plugin configurations (#201)
Browse files Browse the repository at this point in the history
* Add A Plugin Configuration Page

* Add URL

* Added a comment on how to load custom configs and about saving

* Address Some comments

* Change Warning message

* Address Comments

* Change y -> z

* Un-British Docs and Address Comments

* Finalising Changes

* Invoke a new CI Run

* bump

---------

Co-authored-by: MiniDigger | Martin <admin@benndorf.dev>
  • Loading branch information
olijeffers0n and MiniDigger authored Aug 12, 2023
1 parent c6d2272 commit 20bd56b
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 1 deletion.
1 change: 1 addition & 0 deletions config/sidebar.paper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const paper: SidebarsConfig = {
"dev/api/pdc",
"dev/api/custom-inventory-holder",
"dev/api/plugin-messaging",
"dev/api/plugin-configs",
],
},
{
Expand Down
158 changes: 158 additions & 0 deletions docs/paper/dev/api/plugin-configs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
slug: /dev/plugin-configurations
---

# Plugin Configurations

Configuration files allow users to change certain behavior and functionality of Plugins. This guide will outline how to use them.

## Format

By default, plugins use a YAML configuration format (`.yml` file). Other formats such as JSON or TOML can be used,
however these are not natively supported by Paper so will not be covered in this guide.

YAML works by having a tree-like `key: value` pair structure as you would have seen in your [plugin.yml](../getting-started/plugin-yml.md).
An example would look like this:

```yaml
root:
one-key: 10
another-key: David
```
When accessing indented values, you separate the levels with `.`'s. For example, the key for the "David" string would be `root.another-key`

## Creating a config.yml

By placing a `config.yml` file inside your plugin, you can specify the default values for certain settings.
This will be located in the `resources` directory:
```
example-plugin
└── src
└── main
├── java
└── resources
├── config.yml
└── plugin.yml
```

Then, when your plugin is initialised you must save this resource into the plugins data directory so that a user can edit the values.
Here is an example of how you would do this in your plugin's `onEnable`:

```java
public class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
saveResource("config.yml", /* replace */ false);
// You can also use this for configuration files:
saveDefaultConfig();
// Where the default config.yml will be saved if it does not already exist
// getConfig()...
}
}
```

:::info[`replace` parameter]

The boolean `replace` parameter specifies whether it should replace an existing file if one exists.
If set to true, the configuration will be overwritten on every call.

:::

## Getting and setting data

The `FileConfiguration` of the plugin can be fetched with `JavaPlugin#getConfig` once it has been saved. This will allow
data to be fetched and set with the respective `#get...(key)` and `set(key, value)`. By default, most basic data types are supported
by YAML. These can be fetched simply with `#getString` or `#getBoolean`.

However, some more complex Bukkit data types are also supported. A few of these include `ItemStack`, `Location` and `Vector`s.
Here is an example of loading a value from the config for teleporting a player:

:::info[Saving Configs]

Whenever setting data in configurations, you must call `FileConfiguration#save` for the changes to persist on disk

:::

```java
public class TestPlugin extends JavaPlugin {
public void teleportPlayer(Player player) {
Location to = getConfig().getLocation("target_location");
player.teleport(to);
}
}
```

This is possible as they implement `ConfigurationSerializable`. You can use this yourself, by implementing and registering a custom class.

```java
public class TeleportOptions implements ConfigurationSerializable {
private int chunkX;
private int chunkZ;
private String name;
public TeleportOptions(int chunkX, int chunkZ, String name) {
// Set the values
}
public Map<String, Object> serialize() {
Map<String, Object> data = new HashMap<>();
data.put("chunk-x", this.chunkX);
data.put("chunk-z", this.chunkZ);
data.put("name", this.name);
return data;
}
public static TeleportOptions deserialize(Map<String, Object> args) {
return new TeleportOptions(
(int) args.get("chunk-x"),
(int) args.get("chunk-z"),
(String) args.get("name")
);
}
}
```

Here we can see that we have an instance based `serialize` method which returns a map and then a static `deserialize`
method that takes a Map as a parameter and then returns an instance of the `TeleportOptions` Class. Finally, for this to work we must call:
`ConfigurationSerialization.registerClass(TeleportOptions.class)`

:::warning

If you do not call `ConfigurationSerialization.registerClass` with Paper Plugins,
you will not be able to load / save your custom classes.

:::

## Custom Configuration Files

It is highly likely that you will have many different things to configure in your plugin. If you choose to split these
across multiple different files you can still use the Bukkit `FileConfiguration` API to read the data from these.
It is as simple as:

```java
File file = new File(plugin.getDataFolder(), "items.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
// Work with config here
config.save(file);
```

This example reads the `items.yml` file from your plugin data directory. This file must exist and an error will be thrown if it doesn't.

:::danger[Blocking I/O]

Loading and saving files on the main thread will slow your server. `load` and `save` operations should be executed asynchronously.

:::

## Configurate

Configurate is a third party library for working with configurations maintained by the Sponge project. This project is
used internally by Paper for our configurations and offers many features that plain YAML files do not. See their project
[here](https://github.com/SpongePowered/Configurate) for more information.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function itself. For per-world configuration, see the

- **default**: true
- **description**: Collisions with boats and minecarts are often subject to client/server
disagreement, which may cause glitchy behaviour for players. This setting attempts to mitigate
disagreement, which may cause glitchy behavior for players. This setting attempts to mitigate
this desync by sending precise locations for entities involved in collisions. Having this enabled
will use more bandwidth; however, in the majority of cases, this is a worthy tradeoff.

Expand Down

0 comments on commit 20bd56b

Please sign in to comment.