Create 'Custom' Bukkit Plugin YAML File

2019-08-12 18:31发布

问题:

everyone. I have just recently gotten into writing Bukkit plugins for Minecraft. I've already got dev versions for my first two plugins running fine on my server, and they haven't given me much trouble at all. I'm currently working on a third, and I've run into some trouble.

I am trying to figure out how exactly to create a YAML file and read/write data from/to it. Just to clarify, I am NOT referring to a config.yml file, as I am not having any trouble with that. I know how to create a default config.yml file and read data from it, and all that is just fine and dandy. However, with my third plugin, I need to use a separate YAML file. I've looked around for help, but 95% of the answers I get involve someone telling me something about getConfig(), which is NOT what I'm looking for, or at least I'm 95% sure that's not what I'm looking for. After a few weeks of searching for a clear answer, I've decided to post my question here. As always, thanks in advance for any help!

I think I've figured out how to create a YAML file, but I'm stuck after that. I'll just give an example of my situation.

Let's say I had the following main class:

package ...

import ...

//Here is my main class
public class MyClass extends JavaPlugin {

    //I instantiate my File and FileConfiguration here
    //Should I do this? I need them for my other classes.
    public FileConfiguration myFileConfig = null;
    public File myFile;

    //On Enable
    @Override
    public void onEnable() {

        //Get/Create File
        myFile = new File(getDataFolder(), "myfile.yml");
        if (!myFile.exists()) {
            try {
                myFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

            //Load myfily.yml file configuration
        FileConfiguration myFileConfig = YamlConfiguration.loadConfiguration(myFile);

            //Register my command executor class
        getCommand("test").setExecutor(new myCommandExecutor());
    }

    //On Disable
    @Override
    public void onDisable() {

        //Irrelevant stuff here

    }

}

Now say I also had the following CommandExecutor class (the asterisks mark where important stuff happens. I left out all the nested if functions to save your time):

package ...

import ...

public class myCommandExecutor implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

        if (cmd.getName().equalsIgnoreCase("test")) {

            if (args.length > 0) {

****************//RIGHT HERE I WOULD ADD ALL THE COMMAND ARGUMENTS
****************//IMAGINE THE FOLLOWING USAGE FOR THE COMMAND
****************//USAGE: /test <add|del> <one|two|three> <name>
****************//IF THE USER EXECUTED THE FOLLOWING, THE CODE BELOW WOULD BE THE FINAL RESULT
****************//EXECUTED: /test add two hello
                YamlClass.addToFile(args[1], args[2]);

            } else {

                sender.sendMessage("Not enough arguments!");

            }

        }

    }

}

In the example above, if a user typed /test add two hello, I would want the last two arguments (two and hello) sent to a method in another class (in this example, addToFile(String a, String b) in the class YamlClass) in which args[1] and args[2] would be used to put a string into a file like this:

test:
  one:
  two:
    - hello
  three:

and if the user then ran /test add three goodbye the file would look like this:

test:
  one:
  two:
    - hello
  three:
    - goodbye

If a user were to then do /test add three test it would add 'test' to the section without replacing the 'goodbye' that was previously added. Could anyone give me some help or tips on how to go about doing this? Thanks!

[EDIT] I figured it out last night. I was actually doing everything correctly as far as the File and YamlCinfiguration go, there was something wrong with my CommandExecutor, but I fixed it. Thanks for the responses!

回答1:

Generally, zifnab06's answer isn't that wrong. I myself am working on a Bukkit plugin myself and got used to using the following piece of code for YAML files.

File f = new File("path/to/your/YAML/file.yml");
YamlConfiguration yamlFile = YamlConfiguration.loadConfiguration(f);

This creates a new instance of a YamlConfiguration which you can access with yamlFile.set("path", new Object()); for writing values and yamlFile.get("path"); for reading values (you don't necessarily need to use createSection(String) beforehand). All methods which can be used are contained in the JavaDoc.

If you want to save/create your .yml file, you just have to use this code:

try {
  yamlFile.save(f);
} catch(IOException e) {
  // Handle any IO exception here
  e.printStackTrace();
}

I hope this answered your question; if you need some code to work with, you can use my plugin's source code available on BitBucket.



回答2:

I believe what you are looking for is org.bukkit.configuration.file.YamlConfiguration. The javadoc is located here.

Quick example, based on your example above:

YamlConfiguration yaml = new YamlConfiguration();
yaml.createSection("test");
yaml.createSection("test.one");
yaml.createSection("test.two");
List<String> values = new ArrayList<String>();
values.add("hello");
values.add("goodbye");
values.add("test");
yaml.set("test.one", values)
yaml.save('/path/to/file/location.yml');


回答3:

I personally had no clue how to do this until just now, but I used a combination of these two first answers by zifnab06 and mezzodrinker and it worked out nicely. Here's what I have:

        YamlConfiguration yaml = new YamlConfiguration();
        yaml.createSection("test");
        yaml.createSection("test.one");
        yaml.createSection("test.two");
        List<String> values = new ArrayList<String>();
        values.add("hello");
        values.add("goodbye");
        values.add("test");
        yaml.set("test.one", values);
        try {
            yaml.save("plugins/PermaLocs/Locations.yml");
        } catch (IOException e) {
            e.printStackTrace();
        }

The result, for anyone who is new, is a file names Locations found in a folder named PermaLocs, and the file has the following inside:

test:
  one:
  - hello
  - goodbye
  - test
  two: {}

Hope that helped someone. :)