Solved Config Default Value

Discussion in 'Plugin Development' started by J3Kennard, May 17, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    J3Kennard

    Hello! Basically what I am trying to do is create a method that I can easily duplicate in each of my plugins (with tweaking/customization per plugin, of course) that makes it so I can add default values to my config if they aren't there.

    I've used this method in the past:
    Code:
    public void processConfig()
      {
        reloadConfig();
        saveDefaultConfig();
        if (!this.config.exists()) {
          getLogger().info("Config file created!");
        }
        getConfig().options().copyDefaults(true);
        saveConfig();
      }
    which has worked for what I wanted, though I want to be able to take into account the possibility of adding a config section with an unknown set of values (for example, one plugin is for custom chat channels) - I don't want it to automatically include the defaults for plugins like these.

    I also just tried to use this:
    Code:
    public void save()
        {
            File configFile = new File(discs.getDataFolder(), "config.yml");
            FileConfiguration config = discs.getConfig();
           
            if (!configFile.exists()) {
                  discs.getLogger().info("Config file created!");
              }
            discs.saveDefaultConfig();
           
            final Map<String, Object> defaults = new HashMap<String, Object>();
            defaults.put("on-join.enabled", true);
            defaults.put("on-join.disc", 1);
            defaults.put("on-join.random", false);
            defaults.put("on-move.enabled", false);
            defaults.put("on-move.disc", 1);
            defaults.put("on-move.random", false);
           
            config.options().copyHeader(true);
            for (final Entry<String, Object> e : defaults.entrySet()) {
                if (!config.contains(e.getKey())) {
                    config.set(e.getKey(), e.getValue());
                }
            }
           
            discs.saveConfig();
        }
    in one of my plugins called Discs, which basically makes it so players can play music discs remotely and/or when players join, first move, etc. The first code I shared worked well for this plugin, but again, I wanted to make sort of a "standard" config method that I can easily use in all of my plugins, even/especially those that include sections that can have an indefinite number of subsections (as mentioned above with the chat channels plugin).

    I'd appreciate any help!
     
  2. Offline

    ipodtouch0218

    So you're trying to check if a default variable isn't there for the given plugin, and then copy it into config.yml. This should work for all plugins that you make and can be copy/pasted.

    Correct?

    EDIT:
    Should the default variables be stored in the config.yml that compiles with the plugin or in the code itself?
     
  3. Offline

    J3Kennard

    So, I suppose I should clarify that basically I'm teaching myself Java. Also, as you can tell, I'm not great with Bukkit's configuration API.

    So I hope this answers your question:

    I have been good at learning to code especially because I am so OCD about consistency. I always try to organize my plugins the same way, with similar formats for commands, methods/operations, etc. One of these is configuration.

    The ways I mentioned could be completely wrong, but basically I just want an efficient way to do the following with config files, regardless of whether I have simple configurations with a set amount of keys/values or more complex configurations that have an unknown amount of keys/values or sections (like the channels plugin I mentioned, where admins can make an indefinite amount of chat channels):
    1. Save the default configuration - the config.yml I have in the plugin JAR file
    2. Amend a file/add variables (and the comments) that are in the default config.yml file, if they don't exist
    3. Be able to account for config sections where users can have an indefinite amount of things
    4. Do the following hopefully without doing what I did in the second block of code above, where I have to make a unique map of config variables for each plugin
    Here is an example:
    Code:
    enable-channel-lock: true
    default-permission-required: true
    channels:
        default:
            toggler: '#'
            prefix: '&4%player% > &c'
        staff:
            toggler: '@'
            prefix: '&3%player% > &b'
    I'd like to be able to save the 'enable-channel-lock', 'default-permission-required', and 'channels: []' if they don't exist, without forcing the creation of the default sections ('default' and 'staff') and their contents.

    Any ideas?
     
  4. Offline

    I Al Istannen

    @J3Kennard
    Saving the default config is easy. Just call "saveDefaultConfig()" somewhere in the onEnable. It will copy the config.yml with EVERYTHING from the jar to the Plugins data folder. If the config.yml already exists, it will do nothing. Sounds like what you want? You can then modify the config and save it with "saveDefaultConfig()". If you just include what you want in the config.yml inside the plugin jar file, only this will be saved. Just reply if I understood you wrong.
     
  5. Offline

    J3Kennard

    @I Al Istannen Did you mean saveConfig()?

    Also, say for instance that I have this as my default config loaded inside my JAR file:
    Code:
    enable-channel-lock: true
    default-permission-required: true
    channels: {}
    What if someone deletes one of these variables? Could I use getConfig().options.copyDefaults(true) to make it so all default variables are added?
     
    Last edited by a moderator: May 17, 2016
  6. Offline

    I Al Istannen

    @J3Kennard
    I meant saveDefaultConfig(). But that won't help if a user deletes a path. It preserves comments though, so you can tell the user he is dumb if he deletes it :p I never needed to do what you want and don't have much time to play around right now, so I can't really help you with that. I will reply tomorrow again (if I don't forget it) if there is no solution.
     
  7. Offline

    J3Kennard

    @I Al Istannen Ah thanks, I appreciate it. I think what I might do as far as comments go is just put the comments in the header, as most of my variables are pretty self explanatory anyway. Thanks for the help.

    If anyone else has any idea if what I said in my last post would work, speak up :p Or, of course, if you have any other clue of how to do what I've said in previous posts, I would appreciate some enlightenment :)
     
  8. Offline

    I Al Istannen

    @J3Kennard
    Code:
            getConfig().addDefault("test path", "hey2");
            getConfig().addDefault("second path", "lol");
            getConfig().addDefault("third path", "lol");
            getConfig().options().copyDefaults(true);
            saveConfig();
    Seems to do what you want. The only new line is
    "getConfig().options().copyDefaults(true);". I think it works, and doesn't overwrite user preferences, but adds new things. Doesn't preserve comments though.

    The cool thing is the following though (this makes the whole thing universally applicable, no matter in which plugin and saves you from needing to type the getConfig.addDefault(... over and over again.)

    You can dynamically add the defaults from the internal config file, to prevent you from needing to make the map. To do this, create a new YamlConfiguration using YamlConfiguration.load(Reader reader). The reader is a "new InputStreamReader(InputStream stream)". The inputstream is JavaPlugin#getResource("config.yml");. As it is in your onEnable(), you can just call "this.getResource("config.yml");" to get the input stream. This returns a new YamlConfig. Now call YamlConfiguration#getValues(boolean deep) and pass deep = true, to also copy things like "this.is.a.nested.one". Then call Map#entrySet() to get an entry set from the map, which you can loop through. Inside the loop call getConfig.addDefault(entry#getKey(), entry#getValue). The entry is the entry of the entry set. The key will be the path and the value the value. Then just call config.#copyDefaults() and saveConfig() and be happy :p

    It looks quite much, but it's just 6 lines in Java code. If you have any questions, ask. I am not that good at explaining.

    I don't know if more experienced members will crucify me, but it works... :D
     
  9. Offline

    J3Kennard

    Not gonna lie, I have no idea what you're saying lol. Would you mind putting what you said in that paragraph into a code format? The way you said it makes it really hard to understand and visualize.
     
  10. Offline

    I Al Istannen

    @J3Kennard
    Code:
            YamlConfiguration config = YamlConfiguration.loadConfiguration(new InputStreamReader(this.getResource("config.yml")));
            for (Entry<String, Object> entry : config.getValues(true).entrySet()) {
                getConfig().addDefault(entry.getKey(), entry.getValue());
            }
            getConfig().options().copyDefaults(true);
            saveConfig();
    Spoonfeeding?
     
  11. Offline

    J3Kennard

    :p Please, I'm just a baby. I appreciate it!

    Edit: Before you said this, I had this method, which I called in onEnable():
    Code:
    public void save()
        {
            File configFile = new File(getDataFolder(), "config.yml");
            FileConfiguration config = getConfig();
           
            if (!configFile.exists()) {
                  getLogger().info("Config file created!");
              }
            saveDefaultConfig();
           
            config.options().copyHeader(true);
            config.options().copyDefaults(true);
           
            saveConfig();
        }
    and it seemed to work. It would add/fix the header comments from the config.yml located in my JAR into the user's config.yml, and did the same thing for missing values in the config. What exactly does what you said do, compared to this code?

    Sorry again for my lack of knowledge - I'm pretty stupid at this point.
     
    Last edited by a moderator: May 17, 2016
  12. Offline

    I Al Istannen

    @J3Kennard
    Probably nothing :) I was just toying around as you were. I thought it didn't work for you and therefore tried some other things. If it works with what you have, use it ;)

    The "Spoonfeeding?" was more a question whether that is spoonfeeding, as that is not really wanted on this forum, which is totally reasonable. But i figured you would be advanced enough to understand it better than some long, badly-written Text ;)

    Also sorry for spelling mistakes in this post, writing it from a phone with german autocorrect...
     
    Last edited: May 18, 2016
  13. Offline

    J3Kennard

    Haha, again, I appreciate everything man! Hopefully this continues to work :)
     
Thread Status:
Not open for further replies.

Share This Page