How do I add comments to my config file?

Discussion in 'Spigot Plugin Development' started by joehot200, Dec 12, 2014.

  1. I currently add values to my config file like this:
    Code (Java):

    if (config.get("Forcefield.CheckTime") == null) {
                config.addDefault("Forcefield.CheckTime", 5);
            }
     
    But, how do I add comments to the file? Like,
    Code (Java):

    #This config value will change the time each player is checked.
    if (config.get("Forcefield.CheckTime") == null) {
                config.addDefault("Forcefield.CheckTime", 5);
            }
     
     
    • Like Like x 2
  2. JamesJ

    Supporter

    I use a saveDefaultConfig method so I can save the comments too.
     
    • Like Like x 1
    • Agree Agree x 1
  3. Code plz.
    I use

    Code (Java):

            config.options().copyDefaults(true);
            config.options().copyHeader(true);
            saveDefaultConfig();
     
     
  4. You don't need defaults(and no copyDefaults(true); ) if you use saveDefaultConfig();, you have to have a file in your packet instead, for example a config.yml with the defaults and comments in the packet your plugin.yml-file is in, too. There is a great bukkit config tutorial btw :)
    BUT: If you use saveDefaultConfig(); you can never ever ever use saveConfig();, otherwise all comments disappear. If that is a problem create your own config class.
     
    #4 MyzelYam, Dec 12, 2014
    Last edited: Dec 13, 2014
  5. Just using saveDefaultConfig() isn't working.
     
  6. Can u show me a bit more code? I can't see the problem in just three lines of code.
    You could also use java's new filesystem api to do everything on your own; I wonder if there is already a library to do that.
     
  7. vemacs

    Artist

    Loads a resource with file name from JAR if it doesn't exist in your plugin's data folder:

    Code (Text):
        public static File loadResource(Plugin plugin, String resource) {
            File folder = plugin.getDataFolder();
            if (!folder.exists())
                folder.mkdir();
            File resourceFile = new File(folder, resource);
            try {
                if (!resourceFile.exists()) {
                    resourceFile.createNewFile();
                    try (InputStream in = plugin.getResource(resource);
                         OutputStream out = new FileOutputStream(resourceFile)) {
                        ByteStreams.copy(in, out);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return resourceFile;
        }
    For YAML files, this preserves comments, as it copies the raw file. You can load it as a FileConfiguration with YamlConfiguration.loadConfiguration(). Basically, just replace saveDefaultConfig() with this, and override getConfig() to return this instead.

    Instead of using methods to create your default config, do it by hand.
     
    • Like Like x 2
    • Useful Useful x 2
    • Informative Informative x 1
  8. Really useful. Thanks :).
    Out of interest, how do I add a new config value (with comments) without overwriting the old probably-changed-by-the-user values?
     
    #8 joehot200, Dec 13, 2014
    Last edited: Dec 13, 2014
  9. vemacs

    Artist

    That's a toss-up, I honestly can't think of an easy way.
     
  10. How about something like the following (untested and never implemented myself, to be honest)
    Code (Text):

    Map comments; // Mapped path -> comment
    Map oldmap; // oldmap is a Map with the previous values (pre edit)

    function print_r(map)
    {
        print_r(loadMapFromFile(), map, "", 0)
    }

    // filemap is a Map with the values from the config
    function print_r(filemap, map, parentpath, depth)
    {
        prefix = ""
        if parentpath != ""
            prefix = parentpath + "."
        current = ""
        for each k -> v
        {
            current = prefix + k
            if comments contains current
                print(depth, comments.get(current))
            // If no player edits were made
            if(filemap.get(current) is the same as oldmap.get(current))
                v = filemap.get(current); // Make sure this overrides the value in map!
         
            if(newvalue is map)
                print_r(filemap, map, current, depth + 1)
            else
            {
                newvalue = parse(newvalue) // Make sure Lists and stuff are written correctly!
                print(depth, newvalue)
            }
        }
        if(depth == 0)
            oldmap = map
    }

    // Write line to file, with the correct identation
    function print(depth, line)
    {
        // Implement as you like. Should write line with an additional newline to the config file
    }
     
  11. Try Yamler, it supports comments natively via annotations. The downside, however, is that you have to define your configs in a static format, since it reads the structure from a class. It also uses a different serialisation method, which may arise problems if you have ConfigurationSerializable objects. (Also your users would need to install an extra plugin) Of course, comments are static, but I really doubt you're gonna need to change them dynamically. An example for how I use Yamler can be found here. The Resources page also provides an example.
     

Share This Page