Making additional yml files

Discussion in 'Plugin Development' started by Ricecutter0, Apr 25, 2015.

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

    Ricecutter0

    This is a question that many have asked, and I've been looking for a way to do this for a long, long time, but I've found one. The only problem is that I feel like it has a lot of unnecessary code which would cause lag in a server. Heres my code:

    Regular config.yml.. (Don't mind my weird method names..)
    Code:java
    1. private FileConfiguration Config = null;
    2. private File ConfigFile = null;
    3.  
    4. private void reloadConfig1() {
    5. if (ConfigFile == null) {
    6. ConfigFile = new File(getDataFolder(), "config.yml");
    7. }
    8. Config = YamlConfiguration.loadConfiguration(ConfigFile);
    9. Reader defConfigStream = null;
    10. try {
    11. defConfigStream = new InputStreamReader(this.getResource("config.yml"), "UTF8");
    12. e.printStackTrace();
    13. }
    14. if (defConfigStream != null) {
    15. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    16. Config.setDefaults(defConfig);
    17. }
    18. }
    19.  
    20. private FileConfiguration getRConfig(){
    21. if(Config == null){
    22. reloadConfig1();
    23. }
    24. return Config;
    25. }
    26.  
    27. public void saveConfigg() {
    28. if (Config == null || ConfigFile == null) {
    29. return;
    30. }
    31. try {
    32. getRConfig().save(ConfigFile);
    33. } catch (IOException ex) {
    34. getLogger().log(Level.SEVERE, "Could not save config to " + ConfigFile, ex);
    35. }
    36. }
    37.  
    38. private void saveDConfig(){
    39. if(ConfigFile == null){
    40. ConfigFile = new File(getDataFolder(), "config.yml");
    41. }
    42. if(!ConfigFile.exists()){
    43. this.saveResource("config.yml", false);
    44. }
    45. }
    46. }


    Additional file..
    Code:java
    1. private FileConfiguration customConfig = null;
    2. private File customConfigFile = null;
    3.  
    4. private void reloadCustomConfig() {
    5. if (customConfigFile == null) {
    6. customConfigFile = new File(getDataFolder(), "customConfig.yml");
    7. }
    8. customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
    9. Reader defConfigStream = null;
    10. try {
    11. defConfigStream = new InputStreamReader(this.getResource("customConfig.yml"), "UTF8");
    12. e.printStackTrace();
    13. }
    14. if (defConfigStream != null) {
    15. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    16. customConfig.setDefaults(defConfig);
    17. }
    18. }
    19.  
    20. private FileConfiguration getCustomConfigg(){
    21. if(customConfig == null){
    22. reloadCustomConfig();
    23. }
    24. return customConfig;
    25. }
    26.  
    27. public void saveCustomConfigg() {
    28. if (customConfig == null || customConfigFile == null) {
    29. return;
    30. }
    31. try {
    32. getCustomConfigg().save(customConfigFile);
    33. } catch (IOException ex) {
    34. getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);
    35. }
    36. }
    37.  
    38. private void saveDefaultConfigg(){
    39. if(customConfigFile == null){
    40. customConfigFile = new File(getDataFolder(), "customConfig.yml");
    41. }
    42. if(!customConfigFile.exists()){
    43. this.saveResource("customConfig.yml", false);
    44. }
    45. }


    If anyone would give me some ways or some other method to do this that wouldn't be as laggy as my current one? Thank you for reading.
     
  2. Offline

    dlange

  3. Offline

    mine-care

    Well we need to see where this code is called at because if it is called in move event for instance and a config is saved so frequently yes it will cause a great laagggggg
     
  4. Offline

    Totom3

    @Ricecutter0 Duplicate and redundant code will not necessarily cause lag, but I still have a few suggestions for you :D

    First of all, Bukkit will manage the default config (config.yml) for you. Use your main class instance to get and edit it:
    Code:
    plugin.getConfig(); // Get the default config
    plugin.saveConfig(); // Save the default config
    plugin.reloadConfig(); // method name says all
    // Be sure to check the others
    Now if you want to have multiple config files and manage them in a dynamic way (without duplicate/redundant code), use logic. Compare the method that loads config.yml to the one that does the exact same thing, but for customConfig.yml. The only thing that changes is the name of the file to be loaded. Now what you could do is, make the method take an argument: the name of the file. It will then load the file regardless of the value of the argument. Example to better visualize:
    Code:
    public FileConfiguration loadConfig(String fileName) {
        File customConfigFile = new File(getDataFolder(), fileName);
        InputStream defConfigStream = getResource(fileName);
        Reader defConfigStreamReader = [...]
      
        // [...]
    }
    Notice how my version is similar to yours. Instead of hard-coding the file path, I take a parameter to specify it. With the same method, you can then create as many config files you want. For example:
    Code:
    loadConfig("generalSettings.yml");
    loadConfig("chatSettings.yml");
    loadConfig("leaderboards.yml");
    // [...]
    Finally just make sure you aren't loading/saving the configs each time it is modified. Too many people repeat this error. To clarify, once a config file is loaded, it is stored and accessed via memory (RAM), not with the disk. When you make changes to it, the actual file isn't modified, until the config is saved. However there's no need to save after each modification, because the changes will take place and will be visible in memory without a save.
     
  5. Offline

    Ricecutter0

    With that.. how do I load the config I already made that's in the jar?

    [EDIT] Nevermind... You'd just put this.saveDefaultConfig();

    correct?

    And I'm still confused about that other method..

     
    Last edited: Apr 26, 2015
  6. Offline

    Totom3

    @Ricecutter0 It was an example. The only thing to retain here is that an argument is used to specify the file to load. In your method, instead of something like getResource("customConfig.yml"), you have getResource(fileName). I removed the rest of the method to only keep the relevant stuff (only what changed).
     
  7. Offline

    Ricecutter0

    Would I have to make another File and Fileconfiguration.. such as..
    Code:java
    1. private FileConfiguration customConfig = null;
    2. private File customConfigFile = null;

    when I want to make another file?

    @Totom3
     
  8. Offline

    Maxx_Qc

  9. Offline

    Totom3

    @Ricecutter0 Keep the FileConfiguration instance, not the File one.

    EDIT: @Maxx_Qc Is it me or you literally copy pasted his code? Or you two ended up with the same result? Anyways, why not let him figure it out?
     
  10. Offline

    Ricecutter0

    I'm pretty sure I got it officially this time... @Totom3
    Code:java
    1. private FileConfiguration customConfig = null;
    2. private File customConfigFile = null;
    3. /*
    4.   * [...] (add more files if wanted)
    5.   * Eg. private file anotherFile = null;
    6.   */
    7.  
    8. private void reloadCustomConfig(String fileName, File file) {
    9. if (file == null) {
    10. file = new File(getDataFolder(), fileName);
    11. }
    12. customConfig = YamlConfiguration.loadConfiguration(file);
    13. Reader defConfigStream = null;
    14. try {
    15. defConfigStream = new InputStreamReader(this.getResource(fileName), "UTF8");
    16. e.printStackTrace();
    17. }
    18. if (defConfigStream != null) {
    19. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    20. customConfig.setDefaults(defConfig);
    21. }
    22. }
    23.  
    24. private FileConfiguration getCustomConfigg(String fileName, File file){
    25. if(customConfig == null){
    26. reloadCustomConfig(fileName, file);
    27. }
    28. return customConfig;
    29. }
    30.  
    31. public void saveCustomConfigg(String fileName, File file) {
    32. if (customConfig == null || file == null) {
    33. return;
    34. }
    35. try {
    36. getCustomConfigg(fileName, file).save(file);
    37. } catch (IOException ex) {
    38. getLogger().log(Level.SEVERE, "Could not save config to " + file, ex);
    39. }
    40. }
    41.  
    42. private void saveDefaultConfigg(String fileName, File file){
    43. if(file == null){
    44. file = new File(getDataFolder(), fileName);
    45. }
    46. if(!file.exists()){
    47. this.saveResource(fileName, false);
    48. }
    49. }
     
  11. Offline

    Totom3

    @Ricecutter0 Nope, a few more things. If you want to keep the FileConfiguration and File instances, you'll have to put them in a Map, in which they would be indexed by their respective file or file name. Here's a problem that could occur with your current code: image a situation where I load "ParticleSettings.yml". getCustomConfig() calls reloadCustomConfig() which initializes customConfig. Then I load "PvPSettings.yml". getCustomConfig() is called and notices customConfig is not null, therefore it returns it. Problem is, customConfig is loaded with the contents of "ParticleSettings.yml". "PvPSettings.yml" is ignored. This can cause huge data corruption problems.

    So to come back to the Map, once a custom config is loaded, you'd index the appropriate FileConfiguration by the name of it's source file. To check if a custom config was loaded, you'd get the value in the map, and if it's not null then the config is loaded. To summarize:
    Code:
    // Here I am indexing the FileConfigurations by the file names
    // It would also work by indexing them by the File instances
    Map<String, FileConfiguration> customConfigs = [...];
    
    // To get a config:
    FileConfiguration config = customConfigs.get(fileName);
    
    // Check if a config is loaded.
    if (config == null) {
        // Config not loaded
    } else {
       // Config loaded
    }
    
    // See documentation of Map for how to put and remove elements.
    Also there might be a flaw in your save method. By calling getCustomConfig() it might make it load the config.... just to save it right after. Not sure if it was intentional, but in case it was: loading a file to just save it is useless, since no changes have been made.

    Thirdly I'm not sure why the methods take the filename AND the file to use? Only one of the two should be enough.

    There's another thing I'm not sure about: the UTF-8 charset might be named "UTF-8" instead of "UTF8". Just to be safe, you may want to use StandardCharsets.UTF-8, which represents the UTF-8 charset (you'd have guessed it).

    And by the way, config is spelled config, not configg. :p
     
  12. Offline

    caderape

    @Ricecutter0

    this is how i load, reload, and save file.
    Code:
        
    public File dataf;
    public FileConfiguration data;
    
    public void getFolderWorld(String world) {
            dataf = new File(plugin.getDataFolder()+File.separator+"Worlds"+File.separator+world, "gestion.yml");
            if (!dataf.exists()) {
                dataf.getParentFile().mkdirs();
                plugin.methods.Copy(plugin.getResource("gestion.yml"), dataf);
            } data = YamlConfiguration.loadConfiguration(dataf);
        }
    
    public void saveData() {
            try {data.save(dataf);} catch (IOException e) {e.printStackTrace();}
        }
    
    
    public void Copy(InputStream in, File file) {
            try {
                OutputStream out = new FileOutputStream(file);
                byte[] b = new byte[1024];
                int len;
                while ((len = in.read(b)) > 0) {
                    out.write(b, 0, len);
                } out.close(); in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    The method copy is one have found and it works well.
     
Thread Status:
Not open for further replies.

Share This Page