· 5 years ago · Oct 15, 2020, 01:34 PM
1Welcome to the BukkitWiki!
2This Wiki is home to Bukkit's documentation and regulations surrounding the Bukkit Project and it's services. Want to help out? We would love to have you! Signup to get started!
3Home
4Configuration API Reference
5Read in another language
6Watch this page
7Edit
8This page has been suggested for inclusion in the Official Documentation
9This page has been marked for inclusion in the Bukkit Official Documentation section, Docs. You can deliberate about its inclusion on it's Talk page.
10
11The Configuration API is a set of tools to help developers quickly parse and emit configuration files that are human readable and editable. Despite the name, the API can easily be used to store plugin data in addition to plugin configuration. Presently only YAML configurations can be used. The API however was designed to be extensible and allow for other implementations.
12
13The Configuration API can be found in the org.bukkit.configuration and org.bukkit.configuration.file packages. Plugins that were created before version 1.1-R5 may have used an older and different implementation that resided in org.bukkit.util.configuration. These implementations are not compatible and the old package has since been removed.
14
15This introduction assumes that you have some knowledge about proper object oriented design, Java, and the core design of Bukkit plugins. This page is not a substitute for the JavaDocs for the FileConfiguration Class
16
17Basic Topics
18
19The Configuration Object
20Your plugin extends JavaPlugin, and in doing so, you inherited methods and fields from JavaPlugin. The inherited method, getConfig() returns an object of type FileConfiguration. This is the object that represents config.yml inside your plugin's data folder.
21
22The first time getConfig() is invoked on your plugin, config.yml is loaded from disk, and default values are loaded from the jar. Subsequent invocations of getConfig() will return the existing FileConfiguration object that is in memory. Operations performed on this object will not be written to disk unless explicitly saved. Likewise, any modifications done after the file has been loaded will not be reflected in the object. If config.yml does not exist in your data folder, it is equivalent to an empty config.yml, and will load an empty FileConfiguration.
23
24Warning Warning: if you assign the returned object from getConfig() DO NOT assign it to a static field
25Warning Warning: if you do the above, assign getConfig() to the variable AGAIN after a reloadConfig
26
27Lightbulb.png Note: it is better to just use getConfig() instead of assigning it to an instance variable
28Keys
29A configuration file is organized into key value pairs where all keys are Strings. The value for the other keys may be a ConfigurationSection or a single piece of data. The getKeys(boolean) method returns the set of keys for the current FileConfigurationSection. The boolean value determines if the returned set is recursive, if true it will return the keys of the given section and their children keys, if false will only return keys of the given section. To get the keys of a particular section, the getKeys(boolean) method must be invoked on that particular section. To get the section you will have to invoke getConfigurationSection(String).
30
31Lightbulb.png Note: The getKeys method returns a Set of Strings
32Paths
33The Configuration API uses Paths to form a unique key to value pairs. A path is the set of keys used to associate a value. Each level is separated by the path separator, which is by default the '.' (period). For example the following YAML file has the following set of paths.
34
35key: value
36one:
37 two: value
38 three:
39 - values
40 - values
41 - values
42 four:
43 five: value
44 *:
45 six: value
46 seven: value
47key
48one
49one.two
50one.three
51one.four
52one.four.five
53one.*
54one.*.six
55one.*.seven
56Default Values
57A default config.yml should be provided in your jar for users. In the case that a config.yml is missing or incomplete, values will be loaded from included config.yml. The provided file must be named config.yml and be placed in the same directory as your plugin.yml. The file should have the intended structure of your config.yml. This file can be copied as is into the datafolder by invoking saveDefaultConfig() on the Appropriate instance of JavaPlugin.
58
59this.saveDefaultConfig()
60If dynamic key-value pairs are required as default values, they can added as defaults to the configuration with invocations of addDefault(String, Object) and addDefaults(Map<String,Object>) methods.
61
62In certain cases if you wish to append new key-value pairs to an existing config.yml you can set the copyDefaults to true for the ConfigurationOptions object.
63
64this.getConfig().options().copyDefaults(true)
65Creating a copy of config.yml
66You can create a copy of config.yml from the jar into the plugin's data folder by invoking JavaPlugin's saveDefaultConfig() method. saveDefaultConfig() will not overwrite an existing file.
67
68Getting Values
69Reading values from the configuration involves invoking one of the many getter methods. A complete list of getters can be found here. Every getter method takes a configuration path detailed above. Some of the commonly used getter methods are as follows
70
71getBoolean(String)
72getInt(String)
73getString(String)
74getList(String)
75getStringList(String)
76HashMaps
77In the case of HashMaps as a value, they are treated differently than other forms of data. There is a restriction for Map types. It must use a String as a key, and the value but be either a boxed primitive, String, List, Map, or a ConfigurationSerializable type. They will lose their type.
78
79To get a HashMap, a ConfigurationSection must must first be retrieved. You can return the configuration with getConfigurationSection method. The getValues method will return the values in the ConfigurationSection as a map, it takes a boolean which controls if the nested maps will be returned in the map. You can obtain the original map by invoking getValues(false) on the returned ConfigurationSection. Due to the way Java handles generic classes, type information will be lost, thus a cast will need to be performed to set the original type information. The API makes no guarantees that the cast you perform will be safe.
80
81this.getConfig().getConfigurationSection("path.to.map").getValues(false)
82Setting Values
83Writing values involves invoking the set(String, Object) method on an instance of Configuration. Unlike the different get methods that FileConfiguration has, there is only one set method. Not all objects can be set, only primitive types, String, Lists, and types that implement ConfigurationSerializable, such as Vector and ItemStack, can be set. To erase a value supply null as a parameter. All changes made by set will only affect the copy of the configuration in memory, and will not persist beyond restarting the server until the configuration is saved. Following are some example uses:
84
85// setting a boolean value
86this.getConfig().set("path.to.boolean", true);
87
88// setting a String
89String stringValue = "Hello World!";
90this.getConfig().set("path.to.string", stringValue);
91
92// setting an int value
93int integerValue = 8;
94this.getConfig().set("path.to.integer", integerValue);
95
96// Setting a List of Strings
97// The List of Strings is first defined in this array
98List<String> listOfStrings = Arrays.asList("Hello World", "Welcome to Bukkit", "Have a Good Day!");
99this.getConfig().set("path.to.list", listOfStrings);
100
101// Setting a vector
102// event is assumed to be an existing event inside an "onEvent" method.
103Vector vector = event.getPlayer().getLocation().toVector();
104this.getConfig().set("path.to.vector", vector);
105
106// Erasing a value
107this.getConfig().set("path.to.value", null);
108
109
110HashMaps
111When HashMaps are used as a value, they are treated slightly differently. The Map must parameterized with a String type for the key, and the value must be parameterized as a boxed primitive, String, List, Map, or a ConfigurationSerializable.
112
113While you can use the set method to directly set a HashMap to a key, you cannot directly retrieve the Map back with the get method after reading directly from disk. The context above is to minimize unpredictability.
114
115To set a HashMap, a ConfigurationSection must be created for that HashMap. You can only set HashMap where the key is a string the the value is something that is ConfigurationSerializable. The createSectionMethod
116
117this.getConfig().createSection(String path, Map< String, Object > map)
118Saving the File
119If any changes are made to the FileConfiguration with the set methods, or any Lists are mutated, you will need to save the changes to disk if you wish to keep these changes after the plugin is disabled. To save the file to disk, invoke the saveConfig method for your plugin, it will overwrite the file already there.
120
121this.saveConfig();
122Reloading from Disk
123If you suspect that users have made changes to the config.yml in the data folder, those changes are not reflected in memory. Invoke the reloadConfig() method of your plugin to load from the disk again. It will destroy all changes in memory.
124
125this.reloadConfig();
126Using an alternate configuration file
127If for whatever reason you need another configuration file, you can use YamlConfiguration to make a new one.
128
129FileConfiguration data = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "data.yml"));
130This reads the file data.yml from your data folder, and returns a FileConfiguration. If the file does not exist, the FileConfiguration is empty. If you need a pre-made FileConfiguration to be used, you can instead use an InputStream.
131
132FileConfiguration data = YamlConfiguration.loadConfiguration(getResource("data.yml"));
133This takes the InputStream from getResource, which gets a file embedded in the jar, and retreives a FileConfiguration from that.
134
135Advanced Topics
136
137The following are some more advanced topics, meant for more advanced plugins. If you only require the default config.yml, creating custom methods for reading, and saving, you will not need to go this far.
138
139Options
140Every FileConfiguration instance is associated with a FileConfigurationOptions object. The FileConfigurationOptions object controls the behavior of the FileConfiguration it is associated with. FileConfiguration's options() method returns the FileConfigurationOption's responsible for it. With it you can check and set each option. There are currently four options. Be aware that the methods are overloaded, for example copyDefaults() which returns a boolean and copyDefaults(boolean) which returns it self, but has a side effect which changes the state.
141
142CopyDefaults
143The copyDefaults option changes the behavior of Configuration's save method. By default, the defaults of the configuration will not be written to the target save file. If set to true, it will write out the default values, to the target file. However, once written, you will not be able to tell the difference between a default and a value from the configuration.
144
145PathSeperator
146PathSeperator changes the character that is used to separate the different levels of the configuration. By default it is the "." (period) but it can be changed to any char.
147
148Header
149Header is the comment block at the top of a YAML file, it is applied to the save output. The header is the only comment that Configuration API knows how to copy.
150
151copyHeader
152If copyHeader() returns true then the header will be copied on save, from the default source.
153
154Arbitrary Configurations
155If you require additional YAML files, for storing configuration information or persisting additional game information you will need to write your own methods for accessing the additional configuration files. Modeled after JavaPlugin getConfig, reloadConfig, saveConfig methods, the following is an example how to write your own methods to read and save to custom configuration files. Since these config files belong to your plugin, you can put this method in your main class so that you can have the same access as you have with config.yml. You will have to write a set of these methods for each YAML file. The advantage here, is that you can use each set in the same manner as the provided methods for the default config.yml. Alternately, adding additional methods can keep the method count lower and allow access to multiple files.
156
157Mirroring the JavaPlugin implementation
158JavaPlugin implements methods for config.yml. A plugin needs to implement its own methods to access configuration files unique to the plugin. After implementing the methods for the plugin, they can be invoked in the same context as the inherited getConfig(), reloadConfig(), saveConfig(), and saveDefaultConfig() methods from JavaPlugin. The following can be made into a single class which allows access to any yaml file. Such a class can be found here
159
160First you will need to declare two fields and initialize them to null for each of the custom configuration files. One to hold the FileConfiguration object and one to hold the File object. The File object represents the file on the disk, and the FileConfiguration represents the contents of the configuration.
161
162private FileConfiguration customConfig = null;
163private File customConfigFile = null;
164Implementation for Reloading
165Then, write the method that is responsible for loading the config from disk. It will load the file, and search the jar for a default customConfig.yml.
166
167public void reloadCustomConfig() {
168 if (customConfigFile == null) {
169 customConfigFile = new File(getDataFolder(), "customConfig.yml");
170 }
171 customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
172
173 // Look for defaults in the jar
174 Reader defConfigStream = new InputStreamReader(this.getResource("customConfig.yml"), "UTF8");
175 if (defConfigStream != null) {
176 YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
177 customConfig.setDefaults(defConfig);
178 }
179}
180Implementation for Getting
181Next, you need to write the getter method. Check if customConfig is null, if it is load from disk.
182
183public FileConfiguration getCustomConfig() {
184 if (customConfig == null) {
185 reloadCustomConfig();
186 }
187 return customConfig;
188}
189Implementation for Saving
190Finally, write the save method, which saves changes and overwrites the file on disk.
191
192public void saveCustomConfig() {
193 if (customConfig == null || customConfigFile == null) {
194 return;
195 }
196 try {
197 getCustomConfig().save(customConfigFile);
198 } catch (IOException ex) {
199 getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);
200 }
201}
202Implementation for Defaults
203Optionally, you may want to write a method that mimics JavaPlugin's saveDefaultConfig() method.
204
205public void saveDefaultConfig() {
206 if (customConfigFile == null) {
207 customConfigFile = new File(getDataFolder(), "customConfig.yml");
208 }
209 if (!customConfigFile.exists()) {
210 plugin.saveResource("customConfig.yml", false);
211 }
212}
213Serializing and Deserializing Objects
214The Configuration API, as mentioned above can store Java objects that implement the ConfigurationSerializable Interface. Object serialization facilitates easy saving and loading so plugin authors can focus on other parts of their plugin. It greatly simplifies tasks such as storing a Location in YAML, a developer can serialize a wrapper class, which provide methods to retrieve a Location.
215
216Classes, in addition to implementing the ConfigurationSerializable interface must also implment one of the following as noted in the Javadoc, so that they can be serialized by the API:
217
218A constructor that accepts a single Map.
219A static method "deserialize" that accepts a single Map and returns the class.
220A static method "valueOf" that accepts a single Map and returns the class.
221In order for a serialized object to be deserialized, it must also be registered with ConfigurationSerialization. The static registerClass method must be invoked once per class that has been serialized.
222
223This statement must be placed in your onEnable method or some other location that gets called every time your plugin is initialized:
224
225ConfigurationSerialization.registerClass(Class<? extends ConfigurationSerializable>)
226Warning Warning: Do not use a static block to execute the above; if you do so, it will not be called a second time when /reload is used and you will encounter errors due to it not being registered!
227
228Aliases
229When classes are serialized they are marked with their fully qualified name.
230
231You can provide an alias to your class so that it does not serialize with the fully qualified name of your class, but the alias instead. You provide the alias with the SerializableAs annotation to the class implementing ConfigurationSerializable.
232
233@SerializableAs(String)
234When registering a class with an alias, the alias must be provided on registration.
235
236ConfigurationSerialization.registerClass(Class<? extends ConfigurationSerializable>, String)
237Example Use
238
239Below is the an example plugin that uses the new Configuration API to be display messages as an MOTD as players join, and for the player to retrieve the rules on command. It does not follow proper style and plugin layout to keep the number of lines to a minimum.
240
241import java.util.*;
242import org.bukkit.command.*;
243import org.bukkit.event.*;
244import org.bukkit.plugin.java.JavaPlugin;
245import org.bukkit.configuration.file.FileConfiguration;
246
247
248public class SimpleMOTD extends JavaPlugin {
249
250 @Override
251 public void onEnable() {
252 // Save a copy of the default config.yml if one is not there
253 this.saveDefaultConfig();
254
255 // Register a new listener
256 getServer().getPluginManager().registerEvents(new Listener() {
257
258 @EventHandler
259 public void playerJoin(PlayerJoinEvent event) {
260 // On player join send them the message from config.yml
261 event.getPlayer().sendMessage(this.getConfig().getString("message"));
262 }
263 }, this);
264
265 // Set the command executor for the rules command
266 this.getCommand("rules").setExecutor(new CommandExecutor() {
267
268 public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
269 // On command send the rules from config.yml to the sender of the command
270 List<String> rules = this.getConfig().getStringList("rules");
271 for (String s : rules){
272 sender.sendMessage(s);
273 }
274 return true;
275 }
276 });
277 }
278}
279The default config.yml that is in the plugin's jar
280
281# default config.yml
282message: Hello World and Welcome! :)
283rules:
284 - Play Nice
285 - Respect others
286 - Have Fun
287 - Dont swear
288Language English • беларуская • Deutsch • español • suomi • français • italiano • 한국어 • Nederlands • norsk • polski • português • русский • lietuvių • čeština