Check all customconfig strings

Discussion in 'Spigot Plugin Development' started by KarmaConfigs, Sep 11, 2019 at 7:22 PM.

  1. Hi, my problem is that I have this code:

    Code (Java):
    package bubbax.welcome.message.handlers.Config;

    import bubbax.welcome.message.Main.Main;
    import bubbax.welcome.message.handlers.Messages.MessagesFile;
    import org.bukkit.ChatColor;
    import org.bukkit.Bukkit;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.YamlConfiguration;

    import java.io.File;

    public class ConfigFile {
        private static YamlConfiguration cfg;

        public static void checkFiles() {
            if (!Main.getInst().getDataFolder().exists()) {
                Main.getInst().getDataFolder().mkdir();
            }

            File config = new File(Main.getInst().getDataFolder(), "config.yml");
            if (!config.exists()) {
                Main.getInst().saveResource("config.yml", true);
                Bukkit.getConsoleSender().sendMessage(ChatColor.translateAlternateColorCodes('&', "&bBubbaxCome &8&l>> &a&lFile config.yml generated successfully"));
            }

            cfg = YamlConfiguration.loadConfiguration(config);
            Main.enable = Main.getInst().getConfig().getBoolean("enable");


        }


        public static YamlConfiguration getCfg() {
            return cfg;
        }

        public static void reloadConfig(CommandSender sender) {
            checkFiles();
            Main.getInst().reloadConfig();
            sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&bBubbaxCome &8&l>>&r " + MessagesFile.getMsg().getString("reload")));
        }

        public static void reloadConfigSecret() {
            checkFiles();
            Main.getInst().reloadConfig();
        }
    }
    So... the problem is that when I delete some String or boolean, when I restart the server or I reload the plugin, that boolean or string, isn't generated again, I've already checked configs apis and etc. And I didn't found anything that could help me, I don't want to use default config generator due some inconvenients, and I have a custom messages.yml file too, with the same problem, I only post the "config" code because the "messages" code its just the same, but changing "config" with "messages"
     
    #1 KarmaConfigs, Sep 11, 2019 at 7:22 PM
    Last edited: Sep 11, 2019 at 7:27 PM
  2. In some cases deleting a key and it remaining deleted is desired behaviour. If you don't wish to copy defaults, but want certain keys to _always_ exist, you probably want to set your config paths manually using cfg.set in cases where they don't exist.

    Depending on what you want, another option is to use defaults when using get calls from your config, so in cases where the path is not there, the default is used.

    If you want to iterate over all your keys, you can use the getKeys method and iterate over that (you can also load your internal config where needed & compare with that)
     

  3. Is there a "simple" way? I know something of java, and this... sounds a bit weird for my knowledge
     
  4. Something like this?
    Code (Java):
    YamlConfiguration internalConfig = YamlConfiguration.loadConfiguration(getClass().getResourceAsStream("/config.yml"));

    internalConfig.getKeys(true).stream().filter(key -> getConfig().get(key) == null).forEach(key -> getConfig().set(key, internalConfig.get(key));
    saveConfig();
     
    #4 alyphen, Sep 11, 2019 at 8:22 PM
    Last edited: Sep 13, 2019 at 8:45 AM

  5. Tested and it throws me an error, "Stream cannot be null"

    Anyway, I'm trying different ways to do it using your example as start point, but it throws the same error
     
    #5 KarmaConfigs, Sep 12, 2019 at 3:05 PM
    Last edited: Sep 12, 2019 at 3:22 PM
  6. What are you expecting this code to do exactly? ConfigurationSection#getKeys returns a list of keys that exist. This means none of the #get methods will ever return null.

    For reference, if you ConfigurationSection#set the path to null, the path is removed.

    If you do end up keeping an internal config with defaults, you'd need to check if all the keys contained within your defaults are present within the existing config.
    Bare in mind, however, that changes on the disk will not be reflected in the FileConfiguration object in the plugin until the object is reloaded (i.e JavaPlugin#reloadConfig).

    With all that said, why are you using a custom file manager for the default config anyway? You can trivially use the Configuration API and you've done so anyway. All you're doing is making your life more difficult by introducing another YamlConfiguration object that refers to the same config, but which you'd need to reload manually yourself.

    As a final note, please take a look at Beginner Programming Mistakes and Why You're Making Them and pay attention to the first section.
     
  7. Hi, How about you use FileConfigurationOptions#copyDefaults. This should copy the values directly from your default configuration file.

    In your case you would write this on initialization:
    Code (Text):
    cfg.options().copyDefaults(true);
     
  8. Before everything, I'm using a custom file manager due the default config doesn't generates the comments, just the headder, and that's bad for me, by the way, I've already check Configuration API and I didn't found anything that can help me. Anyway tanks for the "Beginner Programming Mistakes and Why You're Making Them" although this plugin is not going to be premium.

    But this will replace other strings and booleans for default ones, or not?
     
  9. It doesn't matter whether or not you're making it premium. If you want to make sure your project is scalable and maintainable, you'll need to stop your static abuse.

    No.
    This will mean that whenever something is not present in the config, the default is used instead. And again:
    So if someone changes the file on disk and doesn't reload the config, you'll have no idea of any changes in there.

    You can easily just use the regular config API to accomplish this. Just make sure never to use JavaPlugin#saveConfig and you'll be golden. Of course, this means you'll not be able to add new entries to the config without changing the values to default.
     
  10. Sorry, yes, this should have been for the internal config's keys, checking whether they exist in the normal config (internalConfig.getKeys(true)). If something is present in the internal config & not in the normal config, it should be added to the normal config.
    I realise now it's also flawed in the regard that using saveConfig will wipe comments, which doesn't achieve anything above what copyDefaults does.

    Sorry, this was my bad. Try getClass().getResourceAsStream("/config.yml") (with the preceding slash)

    I've updated my original post with these alterations, though I'm no longer sure this is exactly what you want.
     
  11. No it will only replace the things that are not present in the configuration.
     
  12. Doesn't works (I have this)

    A class that registers and manages config
    Code (Java):

    public class RegisterConfigs implements Listener {

        public RegisterConfigs() {
            ConfigFile.checkFiles();

            ConfigFile.getCfg().options().copyDefaults(true);

            if (ConfigFile.getConfig().exists()) {
                ConfigFile.getCfg().options().copyDefaults(true);

                ConfigFile.SaveConfig();
            }
        }
    }
     
    (This makes my config.yml having only this):
    Code (YAML):
    #
    #                        #
    #       BubbaxCome       #
    #                        #
     
    (This is my "header")


    And this is my Main
    Code (Java):
    public class Main extends JavaPlugin {

        public static Main inst;
        public static boolean enable;

        public Main() {
            Main.inst = this;
        }

        public static Main getInst() {
            return Main.inst;
        }

        @Override
        public void onEnable() {

            new MessageOnEnable();
            new RegisterEvents();
            new RegisterMessages();
            new RegisterConfigs();
        }

        @Override
        public void onDisable() {
            new MessageOnDisable();
        }
    }
     
  13. Wellp, it doesn't gives me any error, but doesn't do nothing, let me explain it, What I want is the plugin check if the config.yml and messages.yml have all the default strings, and if he can't find one, generate it with comments and all, as I said, I posted only config code due the messages code its the same, so I would use the method used in config for messages too
     
  14. Well, unfortunately, right now the static is the only way in what I know how to call something from other class, so.. It's like my "method" now, but I'll search other methods, because yeah, I know I'm abusing statics, and I don't like to

    Yeah, I don't care if the plugin doesn't know if the config had any change, because the plugin "reload" config on every plugin load, I don't want a "live config update" I just want a "classic config file" that regenerates strings or booleans if he can't read these

    I can't, this is out my knowledge, for now, so I'll search on "my friend" google these methods that you gave me, and again, thanks for you helping