Build 1317 new config

Discussion in 'Plugin Development' started by Perdog, Oct 10, 2011.

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

    Perdog

    I'm honestly hoping I'm not the only one experiencing this but.. I can't figure out how to use the new config methods. I've searched through the API and stuff but I can't fix it. The new build has literally destroyed my plugin :/

    Can someone please contact me somehow and let me know how to use the new one? Or even post a link to a tut here so others with the same issue can find a solution?

    Thanks in advance... Hope I can figure this out soon :/
     
    Jogy34 likes this.
  2. Offline

    acuddlyheadcrab

    I'm not quite sure yet, but try checking with settings for your IDE. I've seen some people having issues with eclipse at first when they updated.

    EDIT: In some instances people have had bugs updating their bukkit resource with this build.
    The other "issue" is that the old config methods and interfaces are now deprecated, and we have a more... expandable way to do it now.

    http://forums.bukkit.org/threads/he...configureable-by-the-users.40981/#post-740663
     
  3. Offline

    desht

    I'm also trying to figure out the new API. Not having IDE problems, just working out how to migrate my code. I like to use Configuration/ConfigurationNode to persist object data to YAML files, so I have some work to do...

    Here's what I've worked out so far, and if I've gotten something wrong, someone please correct me:
    • Instead of something like Configuration conf = new Configuration("myconfig.yml"), you would say:
    PHP:
    YamlConfiguration conf = new YamlConfiguration();
    conf.load("myconfig.yml");
    // you will need to handle all the exceptions that load() can throw
    • conf.getStringList() is gone, you need to use conf.getList() and deal with type safety yourself
    • conf.set(path, value) instead of conf.setProperty(path, value)
    • Instead of conf.getNode() returning a ConfigurationNode, you would use conf.getConfigurationSection() to return a ConfigurationSection. The inheritance hierarchy seems to be the same - old: Configuration inherits from ConfigurationNode - new: YamlConfiguration (indirectly) inherits from ConfigurationSection.
    Am I right so far?

    Not pretty at all.

    This worked with the old API:

    PHP:
    config plugin.getConfiguration();
    List<
    String>nodes config.getStringList("sms.elevation.nodes");
    This returns a null list with the new API:

    PHP:
    YamlConfig config = new YamlConfig();
    config.load(new File(plugin.getDataFolder"config.yml"));
    // lots of exception handling
    List<String>nodes config.getList("sms.elevation.nodes");  // warning about with type-safety
    // nodes is null!
    And don't get me started on why I had to explicitly load the YAML config file instead of just doing plugin.getConfiguration() like I used to. plugin.getConfiguration() now returns a FileConfiguration object, not a YamlConfiguration object - why? I thought the default configuration file for plugins was config.yml... a YAML file?

    I'm sure there's a rationale for all this somewhere. I'd really like to know what that is, because this is a huge and seriously incompatible change. Wish I'd never used the original Bukkit Configuration API now, and this is seriously putting me off using any convenience APIs in Bukkit. There's no stability.

    Not happy :(

    Here's a another question. It used to be possible to do:
    Code:java
    1.  
    2. Configuration config = plugin.getConfiguration();
    3.  
    4. // do some stuff with config... maybe add a new field
    5.  
    6. config.save()
    7.  

    but with the new API:
    Code:java
    1.  
    2. Configuration config = plugin.getConfiguration();
    3.  
    4. // do some stuff with config... maybe add a new field
    5.  
    6. config.save(); // NOPE!
    7. config.save(new File(plugin.getDataFolder(), "config.yml")); // does this work?
    8.  

    ...so how do you save the plugin configuration back to the default file, config.yml? The save() method (which here comes from FileConfiguration) requires a filename, so you have to pass that explicitly now? That's pretty ugly.

    And as I mentioned previously, plugin.getConfiguration() gives you a FileConfiguration, not a YamlConfiguration object. Why?

    Oh, and what do you need to do now if you want the plugin to reload its config file (say, it's been edited externally) ? Since load() needs a filename now too, do you have to manually construct that as well?

    Yet more breakage:

    In the old API, you could do this:
    Code:java
    1.  
    2. Map<String,String> map = new HashMap<String,String>();
    3. // ...set up the hashmap appropriately...
    4. config.setProperty("somekey", map);
    5. config.save();
    6.  

    and all was well. With the new API:
    Code:java
    1.  
    2. Map<String,String> map = new HashMap<String,String>();
    3. // ...set up the hashmap appropriately...
    4. config.set("somekey", map);
    5. // BOOM!
    6.  

    Code:
    10:43:37 [WARNING] Task of 'ScrollingMenuSign' generated an exception
    java.lang.IllegalArgumentException: Cannot store {} into YamlConfiguration[path='', root='YamlConfiguration'], unsupported class
            at org.bukkit.configuration.MemorySection.prepForStorage(MemorySection.java:535)
            at org.bukkit.configuration.MemorySection.set(MemorySection.java:189)
            at me.desht.scrollingmenusign.SMSPersistence.save(SMSPersistence.java:53)
            at me.desht.scrollingmenusign.SMSMenu.autosave(SMSMenu.java:666)
            at me.desht.scrollingmenusign.SMSMenu.addMenu(SMSMenu.java:685)
            at me.desht.scrollingmenusign.SMSPersistence.loadMenus(SMSPersistence.java:175)
            at me.desht.scrollingmenusign.SMSPersistence.loadMenusAndViews(SMSPersistence.java:75)
            at me.desht.scrollingmenusign.ScrollingMenuSign.loadPersistedData(ScrollingMenuSign.java:191)
            at me.desht.scrollingmenusign.ScrollingMenuSign$1.run(ScrollingMenuSign.java:114)
            at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:137)
            at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:441)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:374)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:417)
    
    Seriously, WTF? Whose idea was this "improved" API??? Please just undeprecate the old API, and keep it. Maybe it wasn't "perfect", but it had the fairly overwhelming advantages of a) being simple and elegant to use, and b) actually working.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 20, 2016
  4. Offline

    Kalman Olah

    Gotten these working fine:
    Code:
        private static void write(String root, Object x) {
            YamlConfiguration config = load();
            config.set(root, x);
            try {
                config.save(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static String readString(String root) {
            YamlConfiguration config = load();
            return config.getString(root);
        }
    
        private static YamlConfiguration load() {
            try {
                YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
                return config;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    This one ALWAYS returns null:
    Code:
        @SuppressWarnings("unchecked")
        private static List<String> readStringList(String root) {
            YamlConfiguration config = load();
            return (List<String>)config.getList(root);
        }
     
  5. Offline

    md_5

    I havent actually checked, but it seems like WTF unless I see this work properly im just gonna ignore @depreceated for now.
     
  6. Offline

    Addramyr

    10 points to bukkit on a bad config api
     
    RazorFlint and Perdog like this.
  7. Offline

    codename_B

  8. Offline

    desht

    That's useful, thanks.

    Have you encountered problems with getList() returning null for valid keys, or the IllegalArgumentException when passing a HashMap as a value for set() ? Your library is a thin wrapper over the new API, so it won't address any fundamental brokenness... or maybe it's just me who's having all these problems (in a way, I hope it is).

    Also, your Configuration(JavaPlugin plugin) constructor might be better defined as this(new File(plugin.getDataFolder, "config.yml") - more portable than hardcoding '/' symbols in the path.
     
  9. Offline

    codename_B

    Alright, thanks for the feedback.

    My main issue is that to remove properties you have to set them to null according to the javadoc, but you get an exception if you set them to null...
     
  10. Offline

    Perdog

    It's not the ide's, bukkit has completely changed the method for generating a config, and it's slightly confusing at the moment because they didn't post anything about how to use the new methods :/

    It really isn't pretty, every time I try going a different route to get it to work a whole new load of warnings and errors appear :(

    I just spent all day yesterday adding new things to my config and making it look prettier and now all that work has gone to waste..

    I've tried changed
    Code:
    config = getConfiguration()
    
    to
    
    config = getConfig()
    But I don't think that's grabbing the right import :/

    I've also had the getStringList() issue, I change it to getList() and it tells me I need to add an unchecked warning to my onEnable. It no longer contains getHeader() so all the work on my header page is gone to sh**..

    For setProperty() I think the new one is addDefault?? I could be wrong but that's what I figured when I was trying to sort though it.

    As for loading the config and saving it... I couldn't figure that part out either. Personally I'm saying screw the new RB, I'm going back to 1240, until someone writes a good tutorial on how to convert from the old configuration to the new one.

    I wish I had read up about the new config and studied the brick wall that was hurtling towards us, before it had hit us.

    @EvilSeph @Dinnerbone @lukegb @PrettyMuchAnyBukkitTeamMember Could one of you maybe take the time to make a thread about converting from the old configuration to the new one?? It would make our lives so much easier and I will love you for all eternity :) (no homo)
     
  11. Offline

    Dinnerbone Bukkit Team Member

    http://forums.bukkit.org/threads/he...configureable-by-the-users.40981/#post-740663

     
  12. Offline

    Perdog

  13. Offline

    Dinnerbone Bukkit Team Member

    getList() and cast it to List<String>. Yes, casting sucks, but java generics is somewhat lacking in this department.

    I'm adding a method to reload a config now.
     
    Perdog likes this.
  14. Offline

    Perdog

    Awesome!! You are by far my new favourite mod on these forums ahaha
     
  15. Offline

    Dinnerbone Bukkit Team Member

    There's now a reloadConfig() in your plugin class :)
     
  16. Offline

    desht

    Thank you :)
     
  17. Offline

    Perdog

    This is in the dev build right?
     
  18. Offline

    Dinnerbone Bukkit Team Member

  19. Offline

    Zaros

    Mind = Blown
    More confused than a polar bear in hawaii, so I guess its study time...
    I miss the old config.
     
  20. Offline

    desht

    It looks I can implement ConfigurationSerializable in the classes that I want to persist to config files, yes?

    Any examples of using the ConfigurationSerializable and ConfigurationSerialization classes?
     
  21. Offline

    Dinnerbone Bukkit Team Member

    Check the javadocs of ConfigurationSerializable :)
     
  22. Offline

    drudigger

    anyone know how i can find out to use the new included permissions with bukkit cause it stops my old permissions plugin from working and now no one thats not op can use commands
     
  23. Offline

    desht

    I have :) I was hoping for a concrete example...

    Or... is it just a matter of implementing the serialize() method and appropriate deserialization method, and then my objects can just be passed as a value to conf.set() ?

    From the javadocs:

    These objects MUST implement one of the following, in addition to the methods as defined by this interface:

    What is meant by "a single <String,Object>" ? Is that supposed to read "Map<String,Object>" ?

     
  24. Offline

    Dinnerbone Bukkit Team Member

    Yeah, the javadoc is a little warped there. It's map<String, Object> in the code, not sure why it outputs that.

    That's all you need, one of those 3 methods and implement the interface. Optionally you can also add @SerializableAs("NameToSerializeAs") on your class declaration to make it save/load under a different name. (Use unique names though please, "MyPluginThing" instead of "Thing".)

    For examples, check out https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/util/Vector.java
     
  25. Offline

    Sagacious_Zed Bukkit Docs

    Just curious but what is exactly the issue with parameterizing the getList method. Or alternately just provide it as connivence methods (getStringList) in the API?

    EDIT: technical details would be nice, not scared! :p
     
  26. So loss of Hashmap -> YML, Having to rebuild all the config code across my plugins, and we have to handle the exceptions and Type Safety?

    Wow, I honestly didn't think the entire fiasco that came with the permissions API could be topped... Bukkit team once again outdoes themselves.

    Honestly, apart from the ConfigurationSerializable interface, what benefit does this new system give me over the old one @Dinnerbone ?

    Edit: Also, WHAT THE HELL? There's no save() method, there's ones to save using a File or String for the path, but none for just saving to the gorram file I just loaded from?
     
  27. Offline

    Smex

    @tehbeard
    try: saveConfig();

    It's so ridiculous..lightweight?No. Comfortable?No. What are the benefits???

    I have no idea how to get my IntList, there doesn't seem to be a method...

    @Dinnerbone
    This are your methods, at least, do a YT video or something, this is too hard
    to hook into and a not really benefitable thing. Sorry but this is too complicated.
     
  28. Unfortunatly i'm one of the 99% of devs that prefer have/had the config as a variable. So saveConfig() ain't much help. I could shift ALL the config to the "default" config, but then I have to write helper methods to access it and the question becomes why the hell should I have to do that?
     
  29. Offline

    Dinnerbone Bukkit Team Member

    Then save getConfig to something else. But it always returns the same object, it matters little if you use it or save it to a var.

    List of ints:
    Code:
    List<Integer> list =getList("something")
     
  30. Offline

    Smex

    I got that, but it doesnt catch it, it gives me a null exception.
    And the blog of your gf is taking my attention-.-


    Code:
        @Override
        public void onEnable() {
    
            //Configuration
            config = getConfig();
            config.addDefault("#If AEPonStart is false, the plugin has to be activated first!\n#If List is false, every block is not pickable!\n#Define the non-pickable blocks from endermans\n#Define the worlds in which Anti-EnderPick is actiavted", "");
            aepacti = config.getBoolean("AEPonStart", true);
            Listoption = config.getBoolean("List", false);
            intList = config.getList("Notpickable", intList); <----Underlined yellow = null exception?
            config.addDefault("Notpickable", intList);
            worlds = config.getString("Act-on-Worlds", "world");
            notPick = new HashSet<Integer>(intList);
            saveConfig();
    
            System.out.println("Anti-EnderPick v1.3 is enabled!");
            if(Listoption==true){
            System.out.println("Not-Pickable-Blocks" + intList);
            }
            //Ender Block
            for (String worldNameThing : worlds.split(", ")) {
    
                if (this.getServer().getWorld(worldNameThing) == null) {
    
                System.out.println("Invalid world specified in configuration: " + worldNameThing);
                return;
                }
                }
            System.out.println("Anti-EnderPick is activated on: " + worlds);
            pm = this.getServer().getPluginManager();
            Listener enderbock = new enderbock(this);
            pm.registerEvent(Event.Type.ENDERMAN_PICKUP, enderbock, Event.Priority.Normal, this);
    
            return;
        }
    
    }
     
Thread Status:
Not open for further replies.

Share This Page