[OUTDATED] How to create a plugin configuration file

(Moderation Edit) ** PLEASE NOTE: **

This guide is no longer updated and therefore lacking new information plus may contain (now) false information. Please head over to the SpongeDocs to get the latest information including updates.

How to create a plugin configuration file:

Using zml2008’s “Configurate” library, you can easily create a default configuration file for your plugin.

You can view the Configurate library code on GitHub here.

Step 1: Add the following imports to the top of your main plugin class

import java.io.File;
import org.spongepowered.api.service.config.DefaultConfig;
import com.google.inject.Inject;
import org.slf4j.Logger;
import java.io.IOException;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.loader.ConfigurationLoader;

Step 2: Add the following code inside your plugin’s main class, above the ServerStartingEvent

@Inject
@DefaultConfig(sharedRoot = true)
private ConfigurationLoader configManager;

@Inject
@DefaultConfig(sharedRoot = true)
private File defaultConfig;

Step 3: Place the following code inside your ServerStartingEvent - This will create the config file pluginname.conf in /config/ if it doesn’t already exist, and add the config defaults

ConfigurationNode config = null;

try {
     if (!defaultConfig.exists()) {
        defaultConfig.createNewFile();
        config = configManager.load();
          
        config.getNode("version").setValue(1);
        config.getNode("doStuff").setValue(true);
        config.getNode("doMoreStuff").setValue(false);
        configManager.save(config);
    }
    config = configManager.load();

} catch (IOException exception) {
    getLogger().error("The default configuration could not be loaded or created!");
}

Step 4: To get information out of the configuration, write the following - You may use any of the following: getString(), getInt(), getBoolean(), getLong(), getDouble(), getFloat()

String myString = config.getNode("MyString").getString(); // myString would equal "Testing 123!" given the example above

Step 5: To edit config values later on, use the following

config.getNode("version").setValue(2);
configManager.save(config);

Shout out to @Minecrell for the assistance in getting this working & @zml for the library.

6 Likes

Eww, who uses Maven POM anymore

Gradle plz

dependencies {
    compile 'ninja.leaping.configurate:configurate-hocon:0.1'
}
2 Likes

@simon816 So true… build.gradle above pom.xml :smile:

Is it needed to add The dependency in maven/gadle? I think it works without that, because it is a sponge dependency.

@DanielRHarris Good job on this guide. If you are interested, it would be much appreciated if you could create a pull request to update the configuration guide on SpongeDocs, as that guide still uses the Typesafe configuration library. I can do it if you’d rather not, though.

@boformer That is correct.

4 Likes

@boformer Ah didn’t realize that had been added yet, thanks.

@Tyrannokapi Thanks, and I would be happy to. Edit: Just submitted the pull request.

Edit: Improved the method of default creation, and editing.

1 Like

And there is no way to specify a simple fallback config that is bundled with the jar?

The original HOCON Config class has a setFallback(Config config) method:

URL fallbackUrl = getClass().getClassLoader().getResource("DoubleCheck.conf");
ConfigFile config = ConfigFile.parseFile(configFile).withFallback(fallbackUrl);
config.save(true);

I found out how to initially load a config from a jar file and save it to the defaultConfig file using the new library, but it doesn’t fully replace the fallback method that also restores partial configs and helps when a new version of the plugin wants to update it:

@Inject
@DefaultConfig(sharedRoot = true)
private ConfigurationLoader configLoader;

@Inject
@DefaultConfig(sharedRoot = true)
private File configFile;
    
private URL fallbackConfigURL = getClass().getResource("/DoubleCheck.conf");
...

if (!configFile.exists()) 
{
    configFile.createNewFile();
    
    ConfigurationLoader initialConfigLoader = HoconConfigurationLoader.builder()
    .setSource(Resources.asCharSource(fallbackConfigURL, UTF8_CHARSET))
    .setSink(Files.asCharSink(configFile, UTF8_CHARSET)).build();

    initialConfigLoader.save(initialConfigLoader.load());
}
    
1 Like

I believe Configurate is still a work in progress, and I’m sure we’ll see something of the sort in the future, but for now, the way you outlined seems to be the best method for this. I’ll ask @zml about it.

For restoring partial configs, you could always do some sort of node null check…

Yes, but that’s a standard job.

Absolutely. Just mentioning a temporary solution for future visitors to the thread.

Might want to add that this also makes use of Google Guice. Can’t assume everyone uses it (especially all the newbies =w=).

Where would the plugin folder be generated if the plugin does not use the shared directory?

It doesn’t get generated. You have to do that on your own if you choose not to use the shared directory.
If your plugin is simple enough that it doesn’t need anything but a simple configuration file, then you shouldn’t use the shared directory, otherwise you should to store all files related to it inside it. My way of doing it is letting it inject the filepath to the default configuration file (plugin-id.conf) inside its directory and store everything in there.

@Inject
private File defaultConfig;

public File getPluginDirectory() 
    return defaultConfig().getParentFile();
}

They have ConfigRoot for this, but it has yet to be implemented.

EDIT:
By default, shared directory is generated in /config/plugin-id/ for the Sponge implementation. Do not hardcode this in, as you have to worry about if the plugin is used in the Granite implementation, and hardcoding this can cause directory inconsistency.

1 Like