Skip to content

Config Manager

Redempt edited this page May 29, 2020 · 24 revisions

Handling config is always a pain. It seems there's no way to do it in a way that doesn't feel annoying - at least not with the Spigot API alone. With RedLib, all your config problems will go away.

Similarly to Command Manager, Config Manager uses annotations to hook into your code. Rather than methods, though, it hooks into fields.

In your main plugin class, you can put the following code:

private static ConfigManager config;

@Override
public void onEnable() {
	config = new ConfigManager(this).register(this).saveDefaults().load();
}

On its own, this really won't do anything. But it's important to note what all of these method calls mean, because they'll become relevant the moment we add a config hook. Instantiating the ConfigManager with a plugin as an argument just instantiates it for the default config, config.yml in your plugin's data folder. Calling register(this) registers your plugin's config hooks, meaning that's where the data will be loaded to and saved from. Calling saveDefaults() means that any values initialized in the hooked variables will be saved into the config. load() then loads all the data from config into the variables.

The variables in question should be annotated with @ConfigHook with the value being the path to the config value they represent.

@ConfigHook("delay")
int delay = 5;

When register() is called, it will find this variable. The "delay" in the ConfigHook annotation specifies that the path to the value in the config is delay. Notice that it has an initialized value of 5, meaning that when saveDefaults() is called, if there isn't a value with the path delay in the config, it will be set to 5 and saved. When load() is called, it will load whatever value is in the config at the path delay into your variable. It works for all types supported by Spigot's YAML parser, including string lists and ItemStacks.

If you call save() on the ConfigManager, it will save all the values currently in your variables to config.

But sometimes you need to load configuration sections, too. ConfigManager can do that as well. All you have to do is write a class with a variable for each value you want to load from each entry in the config section. One example would be if you want to make a grouping system:

public class Group {
	
	@ConfigHook("owner)
	private UUID owner;
	@ConfigHook("members")
	private List<UUID> members = ConfigManager.list(UUID.class);
	
	//A constructor with no arguments is required
	protected Group() {}
	
	public Group(UUID leader) {
		owner = leader;
		members = new ArrayList<>();
	}
	
}

Note the default constructor - that is needed for Config Manager to initialize the variable without passing anything to a constructor. Without it, instantiation is inaccessible.

And that's all we need, there's just one last step. In your main file again, you can add:

@ConfigHook("groups.*")
Map<String, Group> groups = ConfigManager.map(Group.class);

@Override
public void onEnable() {
	new ConfigManager(this).addConverter(UUID.class, UUID::fromString, UUID::toString)
		.register(this).saveDefaults().load();
}

Calling ConfigManager.map creates a ConfigMap, which extends HashMap<String, T> with T being the type of the class you give it. This will tell ConfigManager how to load data into the objects stored in the map.

Putting .* at the end is required, as it specifies that this will use the whole config section. When you call load() on your ConfigManager, it will load all the entries from the group section into the Map. The section would look like this:

groups:
	a:
		owner: UUID-here
		members:
		- member1-UUID
		- member2-UUID

You may also notice that a converter for UUID was added. This is because the Group class stores the owner's and members' UUIDs, which isn't a data type YAML lets you store directly. All that's needed is to give it the class, as well as a method to convert it from a string, then back to a string. This can work for any data type as long as you give it the converter. It also works for lists of types other than those supported, in a manner similar to config maps. You may notice that, in the Group class, the members variable is instantiated with ConfigManager.list(UUID.class). Similarly toConfigManager.map, this will create a special type of List that tells ConfigManager how to load data into it and allows it to use custom types.

Clone this wiki locally